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: |
| 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, |
| 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 |