Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(511)

Side by Side Diff: autoupdate.py

Issue 3533003: Fix devserver with handling custom labels. (Closed) Base URL: http://git.chromium.org/git/dev-util.git
Patch Set: petkov Created 10 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | devserver.py » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 # Copyright (c) 2009-2010 The Chromium OS Authors. All rights reserved. 1 # Copyright (c) 2009-2010 The Chromium OS Authors. All rights reserved.
2 # Use of this source code is governed by a BSD-style license that can be 2 # Use of this source code is governed by a BSD-style license that can be
3 # found in the LICENSE file. 3 # found in the LICENSE file.
4 4
5 from buildutil import BuildObject 5 from buildutil import BuildObject
6 from xml.dom import minidom 6 from xml.dom import minidom
7 7
8 import os 8 import os
9 import shutil 9 import shutil
10 import time 10 import time
11 import web 11 import web
12 12
13 13
14 class Autoupdate(BuildObject): 14 class Autoupdate(BuildObject):
15 """Class that contains functionality that handles Chrome OS update pings. 15 """Class that contains functionality that handles Chrome OS update pings.
16 16
17 Members: 17 Members:
18 serve_only: Serve images from a pre-built image.zip file. static_dir 18 serve_only: Serve images from a pre-built image.zip file. static_dir
19 must be set to the location of the image.zip. 19 must be set to the location of the image.zip.
20 factory_config: Path to the factory config file if handling factory 20 factory_config: Path to the factory config file if handling factory
21 requests. 21 requests.
22 use_test_image: Use chromiumos_test_image.bin rather than the standard. 22 use_test_image: Use chromiumos_test_image.bin rather than the standard.
23 static_url_base: base URL, other than devserver, for update images. 23 static_url_base: base URL, other than devserver, for update images.
24 client_prefix: The prefix for the update engine client. 24 client_prefix: The prefix for the update engine client.
25 forced_image: Path to an image to use for all updates. 25 forced_image: Path to an image to use for all updates.
26 """ 26 """
27 27
28 def __init__(self, serve_only=None, test_image=False, urlbase=None, 28 def __init__(self, serve_only=None, test_image=False, urlbase=None,
29 factory_config_path=None, client_prefix=None, forced_image=None, 29 factory_config_path=None, client_prefix=None, forced_image=None,
30 *args, **kwargs): 30 use_cached=False, *args, **kwargs):
31 super(Autoupdate, self).__init__(*args, **kwargs) 31 super(Autoupdate, self).__init__(*args, **kwargs)
32 self.serve_only = serve_only 32 self.serve_only = serve_only
33 self.factory_config = factory_config_path 33 self.factory_config = factory_config_path
34 self.use_test_image = test_image 34 self.use_test_image = test_image
35 self.static_urlbase = urlbase 35 if urlbase:
36 self.static_urlbase = urlbase
37 elif self.serve_only:
38 self.static_urlbase = 'http://%(host)s/static/archive'
39 else:
40 self.static_urlbase = 'http://%(host)s/static'
41
36 self.client_prefix = client_prefix 42 self.client_prefix = client_prefix
37 self.forced_image = forced_image 43 self.forced_image = forced_image
44 self.use_cached = use_cached
38 45
39 def _GetSecondsSinceMidnight(self): 46 def _GetSecondsSinceMidnight(self):
40 """Returns the seconds since midnight as a decimal value.""" 47 """Returns the seconds since midnight as a decimal value."""
41 now = time.localtime() 48 now = time.localtime()
42 return now[3] * 3600 + now[4] * 60 + now[5] 49 return now[3] * 3600 + now[4] * 60 + now[5]
43 50
44 def _GetDefaultBoardID(self): 51 def _GetDefaultBoardID(self):
45 """Returns the default board id stored in .default_board.""" 52 """Returns the default board id stored in .default_board."""
46 board_file = '%s/.default_board' % (self.scripts_dir) 53 board_file = '%s/.default_board' % (self.scripts_dir)
47 try: 54 try:
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
102 """Returns the name of the image that should be used.""" 109 """Returns the name of the image that should be used."""
103 if self.use_test_image: 110 if self.use_test_image:
104 image_name = 'chromiumos_test_image.bin' 111 image_name = 'chromiumos_test_image.bin'
105 else: 112 else:
106 image_name = 'chromiumos_image.bin' 113 image_name = 'chromiumos_image.bin'
107 return image_name 114 return image_name
108 115
109 def _IsImageNewerThanCached(self, image_path, cached_file_path): 116 def _IsImageNewerThanCached(self, image_path, cached_file_path):
110 """Returns true if the image is newer than the cached image.""" 117 """Returns true if the image is newer than the cached image."""
111 if os.path.exists(cached_file_path) and os.path.exists(image_path): 118 if os.path.exists(cached_file_path) and os.path.exists(image_path):
112 web.debug('Usable cached image found.') 119 web.debug('Usable cached image found at %s.' % cached_file_path)
113 return os.path.getmtime(image_path) > os.path.getmtime(cached_file_path) 120 return os.path.getmtime(image_path) > os.path.getmtime(cached_file_path)
114 elif not os.path.exists(cached_file_path) and not os.path.exists(image_path) : 121 elif not os.path.exists(cached_file_path) and not os.path.exists(image_path) :
115 raise Exception('Image does not exist and cached image missing') 122 raise Exception('Image does not exist and cached image missing')
116 else: 123 else:
117 # Only one is missing, figure out which one. 124 # Only one is missing, figure out which one.
118 if os.path.exists(image_path): 125 if os.path.exists(image_path):
119 web.debug('No cached image found - image generation required.') 126 web.debug('No cached image found - image generation required.')
120 return True 127 return True
121 else: 128 else:
122 web.debug('Only cached image found to serve.') 129 web.debug('Cached image found to serve at %s.' % cached_file_path)
123 return False 130 return False
124 131
125 def _GetSize(self, update_path): 132 def _GetSize(self, update_path):
126 """Returns the size of the file given.""" 133 """Returns the size of the file given."""
127 return os.path.getsize(update_path) 134 return os.path.getsize(update_path)
128 135
129 def _GetHash(self, update_path): 136 def _GetHash(self, update_path):
130 """Returns the sha1 of the file given.""" 137 """Returns the sha1 of the file given."""
131 cmd = ('cat %s | openssl sha1 -binary | openssl base64 | tr \'\\n\' \' \';' 138 cmd = ('cat %s | openssl sha1 -binary | openssl base64 | tr \'\\n\' \' \';'
132 % update_path) 139 % update_path)
(...skipping 300 matching lines...) Expand 10 before | Expand all | Expand 10 after
433 Args: 440 Args:
434 data: xml blob from client. 441 data: xml blob from client.
435 label: optional label for the update. 442 label: optional label for the update.
436 Returns: 443 Returns:
437 Update payload message for client. 444 Update payload message for client.
438 """ 445 """
439 web.debug('handling update ping: %s' % data) 446 web.debug('handling update ping: %s' % data)
440 update_dom = minidom.parseString(data) 447 update_dom = minidom.parseString(data)
441 root = update_dom.firstChild 448 root = update_dom.firstChild
442 449
450 # Parse host if not done yet.
451 if '%(host)' in self.static_urlbase:
452 self.static_urlbase = self.static_urlbase % {'host' : web.ctx.host}
453
443 # Check the client prefix to make sure you can support this type of update. 454 # Check the client prefix to make sure you can support this type of update.
444 if (root.hasAttribute('updaterversion') and 455 if (root.hasAttribute('updaterversion') and
445 not root.getAttribute('updaterversion').startswith(self.client_prefix)): 456 not root.getAttribute('updaterversion').startswith(self.client_prefix)):
446 web.debug('Got update from unsupported updater:' + 457 web.debug('Got update from unsupported updater:' +
447 root.getAttribute('updaterversion')) 458 root.getAttribute('updaterversion'))
448 return self.GetNoUpdatePayload() 459 return self.GetNoUpdatePayload()
449 460
450 # We only generate update payloads for updatecheck requests. 461 # We only generate update payloads for updatecheck requests.
451 update_check = root.getElementsByTagName('o:updatecheck') 462 update_check = root.getElementsByTagName('o:updatecheck')
452 if not update_check: 463 if not update_check:
(...skipping 12 matching lines...) Expand all
465 476
466 # Separate logic as Factory requests have static url's that override 477 # Separate logic as Factory requests have static url's that override
467 # other options. 478 # other options.
468 if self.factory_config: 479 if self.factory_config:
469 return self.HandleFactoryRequest(hostname, board_id, channel) 480 return self.HandleFactoryRequest(hostname, board_id, channel)
470 else: 481 else:
471 static_image_dir = self.static_dir 482 static_image_dir = self.static_dir
472 if label: 483 if label:
473 static_image_dir = os.path.join(static_image_dir, label) 484 static_image_dir = os.path.join(static_image_dir, label)
474 485
475 # Not for factory, find and serve the correct image given the options. 486 # Prefer cached image if it exists.
476 if self.forced_image: 487 if self.use_cached and os.path.exists(os.path.join(static_image_dir,
477 has_built_image = self.GenerateUpdateImage( 488 'update.gz')):
478 self.forced_image, move_to_static_dir=True, 489 web.debug('Using cached image regardless of timestamps.')
479 static_image_dir=static_image_dir) 490 has_built_image = True
480 # Now that we've generated it, clear out so that other pings of same
481 # devserver instance do not generate new images.
482 self.forced_image = None
483 elif self.serve_only:
484 has_built_image = self.GenerateImageFromZip(static_image_dir)
485 else: 491 else:
486 has_built_image = self.GenerateLatestUpdateImage(board_id, 492 if self.forced_image:
487 client_version, 493 has_built_image = self.GenerateUpdateImage(
488 static_image_dir) 494 self.forced_image, move_to_static_dir=True,
495 static_image_dir=static_image_dir)
496 # Now that we've generated it, clear out so that other pings of same
497 # devserver instance do not generate new images.
498 self.forced_image = None
499 elif self.serve_only:
500 has_built_image = self.GenerateImageFromZip(static_image_dir)
501 else:
502 has_built_image = self.GenerateLatestUpdateImage(board_id,
503 client_version,
504 static_image_dir)
489 505
490 if has_built_image: 506 if has_built_image:
491 hash = self._GetHash(os.path.join(static_image_dir, 'update.gz')) 507 hash = self._GetHash(os.path.join(static_image_dir, 'update.gz'))
492 sha256 = self._GetSHA256(os.path.join(static_image_dir, 'update.gz')) 508 sha256 = self._GetSHA256(os.path.join(static_image_dir, 'update.gz'))
493 size = self._GetSize(os.path.join(static_image_dir, 'update.gz')) 509 size = self._GetSize(os.path.join(static_image_dir, 'update.gz'))
494 if self.static_urlbase and label: 510 if label:
495 url = '%s/%s/update.gz' % (self.static_urlbase, label) 511 url = '%s/%s/update.gz' % (self.static_urlbase, label)
496 elif self.serve_only:
497 url = 'http://%s/static/archive/update.gz' % hostname
498 else: 512 else:
499 url = 'http://%s/static/update.gz' % hostname 513 url = '%s/update.gz' % self.static_urlbase
514
515 web.debug('Responding to client to use url %s to get image.' % url)
500 return self.GetUpdatePayload(hash, sha256, size, url) 516 return self.GetUpdatePayload(hash, sha256, size, url)
501 else: 517 else:
502 return self.GetNoUpdatePayload() 518 return self.GetNoUpdatePayload()
OLDNEW
« no previous file with comments | « no previous file | devserver.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698