Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 cherrypy | 8 import cherrypy |
| 9 import os | 9 import os |
| 10 import shutil | 10 import shutil |
| (...skipping 13 matching lines...) Expand all Loading... | |
| 24 must be set to the location of the image.zip. | 24 must be set to the location of the image.zip. |
| 25 factory_config: Path to the factory config file if handling factory | 25 factory_config: Path to the factory config file if handling factory |
| 26 requests. | 26 requests. |
| 27 use_test_image: Use chromiumos_test_image.bin rather than the standard. | 27 use_test_image: Use chromiumos_test_image.bin rather than the standard. |
| 28 static_url_base: base URL, other than devserver, for update images. | 28 static_url_base: base URL, other than devserver, for update images. |
| 29 client_prefix: The prefix for the update engine client. | 29 client_prefix: The prefix for the update engine client. |
| 30 forced_image: Path to an image to use for all updates. | 30 forced_image: Path to an image to use for all updates. |
| 31 """ | 31 """ |
| 32 | 32 |
| 33 def __init__(self, serve_only=None, test_image=False, urlbase=None, | 33 def __init__(self, serve_only=None, test_image=False, urlbase=None, |
| 34 factory_config_path=None, client_prefix=None, forced_image=None, | 34 factory_config_path=None, client_prefix=None, |
| 35 forced_image=None, forced_payload=None, | |
| 35 port=8080, src_image='', vm=False, board=None, | 36 port=8080, src_image='', vm=False, board=None, |
| 36 *args, **kwargs): | 37 *args, **kwargs): |
| 37 super(Autoupdate, self).__init__(*args, **kwargs) | 38 super(Autoupdate, self).__init__(*args, **kwargs) |
| 38 self.serve_only = serve_only | 39 self.serve_only = serve_only |
| 39 self.factory_config = factory_config_path | 40 self.factory_config = factory_config_path |
| 40 self.use_test_image = test_image | 41 self.use_test_image = test_image |
| 41 if urlbase: | 42 if urlbase: |
| 42 self.urlbase = urlbase | 43 self.urlbase = urlbase |
| 43 else: | 44 else: |
| 44 self.urlbase = None | 45 self.urlbase = None |
| 45 | 46 |
| 46 self.client_prefix = client_prefix | 47 self.client_prefix = client_prefix |
| 47 self.forced_image = forced_image | 48 self.forced_image = forced_image |
| 49 self.forced_payload = forced_payload | |
| 48 self.src_image = src_image | 50 self.src_image = src_image |
| 49 self.vm = vm | 51 self.vm = vm |
| 50 self.board = board | 52 self.board = board |
| 51 self.crosutils = os.path.join(os.path.dirname(__file__), '../../scripts') | 53 self.crosutils = os.path.join(os.path.dirname(__file__), '../../scripts') |
| 52 | 54 |
| 53 def _GetSecondsSinceMidnight(self): | 55 def _GetSecondsSinceMidnight(self): |
| 54 """Returns the seconds since midnight as a decimal value.""" | 56 """Returns the seconds since midnight as a decimal value.""" |
| 55 now = time.localtime() | 57 now = time.localtime() |
| 56 return now[3] * 3600 + now[4] * 60 + now[5] | 58 return now[3] * 3600 + now[4] * 60 + now[5] |
| 57 | 59 |
| (...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 134 """Returns the sha256 of the file given.""" | 136 """Returns the sha256 of the file given.""" |
| 135 cmd = ('cat %s | openssl dgst -sha256 -binary | openssl base64' % | 137 cmd = ('cat %s | openssl dgst -sha256 -binary | openssl base64' % |
| 136 update_path) | 138 update_path) |
| 137 return os.popen(cmd).read().rstrip() | 139 return os.popen(cmd).read().rstrip() |
| 138 | 140 |
| 139 def _GetMd5(self, update_path): | 141 def _GetMd5(self, update_path): |
| 140 """Returns the md5 checksum of the file given.""" | 142 """Returns the md5 checksum of the file given.""" |
| 141 cmd = ("md5sum %s | awk '{print $1}'" % update_path) | 143 cmd = ("md5sum %s | awk '{print $1}'" % update_path) |
| 142 return os.popen(cmd).read().rstrip() | 144 return os.popen(cmd).read().rstrip() |
| 143 | 145 |
| 144 def _Symlink(self, source, dest): | 146 def _Copy(self, source, dest): |
| 145 """Creates a symlink at dest to source""" | 147 """Copies a file from dest to source (if different)""" |
| 146 if os.path.exists(dest): | 148 _LogMessage('Copy File %s -> %s' % (source, dest)) |
| 149 if os.path.lexists(dest): | |
| 147 os.remove(dest) | 150 os.remove(dest) |
| 148 os.symlink(source, dest) | 151 shutil.copy(source, dest) |
| 149 | 152 |
| 150 def GetUpdatePayload(self, hash, sha256, size, url, is_delta_format): | 153 def GetUpdatePayload(self, hash, sha256, size, url, is_delta_format): |
| 151 """Returns a payload to the client corresponding to a new update. | 154 """Returns a payload to the client corresponding to a new update. |
| 152 | 155 |
| 153 Args: | 156 Args: |
| 154 hash: hash of update blob | 157 hash: hash of update blob |
| 155 sha256: SHA-256 hash of update blob | 158 sha256: SHA-256 hash of update blob |
| 156 size: size of update blob | 159 size: size of update blob |
| 157 url: where to find update blob | 160 url: where to find update blob |
| 158 Returns: | 161 Returns: |
| (...skipping 186 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 345 return None | 348 return None |
| 346 | 349 |
| 347 # Verify they were created with the expected names | 350 # Verify they were created with the expected names |
| 348 new_update_payload, new_stateful_payload = payloads | 351 new_update_payload, new_stateful_payload = payloads |
| 349 | 352 |
| 350 _LogMessage('"%s" "%s"' % (new_update_payload, cache_update_payload)) | 353 _LogMessage('"%s" "%s"' % (new_update_payload, cache_update_payload)) |
| 351 assert new_update_payload == cache_update_payload | 354 assert new_update_payload == cache_update_payload |
| 352 _LogMessage('"%s" "%s"' % (new_stateful_payload, cache_stateful_payload)) | 355 _LogMessage('"%s" "%s"' % (new_stateful_payload, cache_stateful_payload)) |
| 353 assert new_stateful_payload == cache_stateful_payload | 356 assert new_stateful_payload == cache_stateful_payload |
| 354 | 357 |
| 355 # If the generation worked, create symlinks | 358 # If the generation worked, copy files |
| 356 self._Symlink(cache_update_payload, update_payload) | 359 self._Copy(cache_update_payload, update_payload) |
| 357 self._Symlink(cache_stateful_payload, stateful_payload) | 360 self._Copy(cache_stateful_payload, stateful_payload) |
| 358 | 361 |
| 359 # return just the filename which is symlink in static_image_dir | 362 # return just the filename which is symlink in static_image_dir |
| 360 return 'update.gz' | 363 return 'update.gz' |
| 361 | 364 |
| 362 def GenerateLatestUpdateImage(self, board_id, client_version, | 365 def GenerateLatestUpdateImage(self, board_id, client_version, |
| 363 static_image_dir): | 366 static_image_dir): |
| 364 """Generates an update using the latest image that has been built. | 367 """Generates an update using the latest image that has been built. |
| 365 | 368 |
| 366 This will only generate an update if the newest update is newer than that | 369 This will only generate an update if the newest update is newer than that |
| 367 on the client or client_version is 'ForcedUpdate'. | 370 on the client or client_version is 'ForcedUpdate'. |
| (...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 510 # setting sha-256 to an empty string. | 513 # setting sha-256 to an empty string. |
| 511 return self.GetUpdatePayload(checksum, '', size, url, is_delta_format) | 514 return self.GetUpdatePayload(checksum, '', size, url, is_delta_format) |
| 512 | 515 |
| 513 def GenerateUpdatePayloadForNonFactory(self, board_id, client_version, | 516 def GenerateUpdatePayloadForNonFactory(self, board_id, client_version, |
| 514 static_image_dir): | 517 static_image_dir): |
| 515 """Generates an update for non-factory image. | 518 """Generates an update for non-factory image. |
| 516 | 519 |
| 517 Returns: | 520 Returns: |
| 518 file name relative to static_image_dir on success. | 521 file name relative to static_image_dir on success. |
| 519 """ | 522 """ |
| 520 if self.forced_image: | 523 if self.forced_payload: |
|
sosa
2010/11/18 01:47:43
No indention for multiline comments
dgarrett
2013/05/30 21:02:28
Done.
| |
| 524 # If the forced payload is not already in our static_image_dir, | |
| 525 # copy it there. | |
| 526 if (os.path.dirname(os.path.abspath(self.forced_payload)) != | |
| 527 os.path.abspath(static_image_dir)): | |
| 528 self._Copy(self.forced_payload, os.path.join(static_image_dir, | |
|
sosa
2010/11/18 01:47:43
Why not just symlink like the caches?
| |
| 529 'update.gz')) | |
| 530 | |
| 531 self._Copy(os.path.join(os.path.dirname(self.forced_payload), | |
| 532 'stateful.tgz'), | |
| 533 os.path.join(static_image_dir, | |
| 534 'stateful.tgz')) | |
| 535 | |
| 536 return 'update.gz' | |
| 537 elif self.forced_image: | |
| 521 return self.GenerateUpdateImageWithCache( | 538 return self.GenerateUpdateImageWithCache( |
| 522 self.forced_image, | 539 self.forced_image, |
| 523 static_image_dir=static_image_dir) | 540 static_image_dir=static_image_dir) |
| 524 elif self.serve_only: | 541 elif self.serve_only: |
| 525 return self.GenerateImageFromZip(static_image_dir) | 542 return self.GenerateImageFromZip(static_image_dir) |
| 526 else: | 543 else: |
| 527 if board_id: | 544 if board_id: |
| 528 return self.GenerateLatestUpdateImage(board_id, | 545 return self.GenerateLatestUpdateImage(board_id, |
| 529 client_version, | 546 client_version, |
| 530 static_image_dir) | 547 static_image_dir) |
| (...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 613 is_delta_format = self._IsDeltaFormatFile(filename) | 630 is_delta_format = self._IsDeltaFormatFile(filename) |
| 614 if label: | 631 if label: |
| 615 url = '%s/%s/%s' % (static_urlbase, label, payload_path) | 632 url = '%s/%s/%s' % (static_urlbase, label, payload_path) |
| 616 else: | 633 else: |
| 617 url = '%s/%s' % (static_urlbase, payload_path) | 634 url = '%s/%s' % (static_urlbase, payload_path) |
| 618 | 635 |
| 619 _LogMessage('Responding to client to use url %s to get image.' % url) | 636 _LogMessage('Responding to client to use url %s to get image.' % url) |
| 620 return self.GetUpdatePayload(hash, sha256, size, url, is_delta_format) | 637 return self.GetUpdatePayload(hash, sha256, size, url, is_delta_format) |
| 621 else: | 638 else: |
| 622 return self.GetNoUpdatePayload() | 639 return self.GetNoUpdatePayload() |
| OLD | NEW |