| Index: autoupdate.py
|
| diff --git a/autoupdate.py b/autoupdate.py
|
| index f8fb57b92fa449a82f5e5863e47599ca6c9a6be9..1add0250664e0762387b26e8555fb08ae19ea4b4 100644
|
| --- a/autoupdate.py
|
| +++ b/autoupdate.py
|
| @@ -16,8 +16,9 @@ import urlparse
|
| def _LogMessage(message):
|
| cherrypy.log(message, 'UPDATE')
|
|
|
| -UPDATE_FILE='update.gz'
|
| -STATEFUL_FILE='stateful.tgz'
|
| +UPDATE_FILE = 'update.gz'
|
| +STATEFUL_FILE = 'stateful.tgz'
|
| +CACHE_DIR = 'cache'
|
|
|
|
|
| def _ChangeUrlPort(url, new_port):
|
| @@ -82,8 +83,8 @@ class Autoupdate(BuildObject):
|
| self.board = board
|
| self.copy_to_static_root = copy_to_static_root
|
|
|
| - # Track update pregeneration, so we don't recopy if not needed.
|
| - self.pregenerated = False
|
| + # Path to pre-generated file.
|
| + self.pregenerated_path = None
|
|
|
| def _GetSecondsSinceMidnight(self):
|
| """Returns the seconds since midnight as a decimal value."""
|
| @@ -252,7 +253,7 @@ class Autoupdate(BuildObject):
|
| src_image))
|
| _LogMessage(mkupdate_command)
|
| if os.system(mkupdate_command) != 0:
|
| - _LogMessage('Failed to create base update file')
|
| + _LogMessage('Failed to create update payload')
|
| return None
|
|
|
| return UPDATE_FILE
|
| @@ -284,17 +285,17 @@ class Autoupdate(BuildObject):
|
| yet. The directory will be inside static_image_dir, and of the form:
|
|
|
| Non-delta updates:
|
| - cache/12345678
|
| + CACHE_DIR/12345678
|
|
|
| Delta updates:
|
| - cache/12345678_12345678
|
| + CACHE_DIR/12345678_12345678
|
| """
|
| # If there is no src, we only have an image file, check image for changes
|
| if not src_image:
|
| - return os.path.join('cache', self._GetMd5(dest_image))
|
| + return os.path.join(CACHE_DIR, self._GetMd5(dest_image))
|
|
|
| # If we have src and dest, we are a delta, and check both for changes
|
| - return os.path.join('cache',
|
| + return os.path.join(CACHE_DIR,
|
| "%s_%s" % (self._GetMd5(src_image),
|
| self._GetMd5(dest_image)))
|
|
|
| @@ -323,14 +324,9 @@ class Autoupdate(BuildObject):
|
|
|
| if update_file and stateful_update_file:
|
| return update_file
|
| -
|
| - _LogMessage('Failed to generate update')
|
| -
|
| - # Cleanup incomplete files, if they exist
|
| - if update_file and os.path.exists(update_file):
|
| - os.remove(update_file)
|
| -
|
| - return None
|
| + else:
|
| + _LogMessage('Failed to generate update.')
|
| + return None
|
|
|
| def GenerateUpdateImageWithCache(self, image_path, static_image_dir):
|
| """Force generates an update payload based on the given image_path.
|
| @@ -340,56 +336,60 @@ class Autoupdate(BuildObject):
|
| static_image_dir: the directory to move images to after generating.
|
| Returns:
|
| update filename (not directory) relative to static_image_dir on success,
|
| - or None
|
| + or None.
|
| """
|
| _LogMessage('Generating update for src %s image %s' % (self.src_image,
|
| image_path))
|
|
|
| - # If it was pregenerated, don't regenerate
|
| - if self.pregenerated:
|
| - return UPDATE_FILE
|
| + # If it was pregenerated_path, don't regenerate
|
| + if self.pregenerated_path:
|
| + return self.pregenerated_path
|
|
|
| # Which sub_dir of static_image_dir should hold our cached update image
|
| cache_sub_dir = self.FindCachedUpdateImageSubDir(self.src_image, image_path)
|
| _LogMessage('Caching in sub_dir "%s"' % cache_sub_dir)
|
|
|
| + update_path = os.path.join(cache_sub_dir, UPDATE_FILE)
|
| +
|
| # The cached payloads exist in a cache dir
|
| cache_update_payload = os.path.join(static_image_dir,
|
| - cache_sub_dir,
|
| - UPDATE_FILE)
|
| + update_path)
|
| cache_stateful_payload = os.path.join(static_image_dir,
|
| cache_sub_dir,
|
| STATEFUL_FILE)
|
|
|
| - # The final results exist directly in static
|
| - update_payload = os.path.join(static_image_dir,
|
| - UPDATE_FILE)
|
| - stateful_payload = os.path.join(static_image_dir,
|
| - STATEFUL_FILE)
|
| -
|
| - # If there isn't a cached payload, make one
|
| - if not os.path.exists(cache_update_payload):
|
| + # Check to see if this cache directory is valid.
|
| + if not os.path.exists(cache_update_payload) or not os.path.exists(
|
| + cache_stateful_payload):
|
| full_cache_dir = os.path.join(static_image_dir, cache_sub_dir)
|
| -
|
| - # Create the directory for the cache values
|
| - if not os.path.exists(full_cache_dir):
|
| - os.makedirs(full_cache_dir)
|
| -
|
| - result = self.GenerateUpdateImage(image_path,
|
| - full_cache_dir)
|
| -
|
| - if not result:
|
| - # Clean up cache dir if it's not valid
|
| - os.system("rm -rf %s" % os.path.join(static_image_dir, cache_sub_dir))
|
| + # Clean up stale state.
|
| + os.system('rm -rf "%s"' % full_cache_dir)
|
| + os.makedirs(full_cache_dir)
|
| + return_path = self.GenerateUpdateImage(image_path,
|
| + full_cache_dir)
|
| +
|
| + # Clean up cache dir since it's not valid.
|
| + if not return_path:
|
| + os.system('rm -rf "%s"' % full_cache_dir)
|
| return None
|
| + else:
|
| + assert (return_path == update_path,
|
| + 'Returned path %s not equal to %s' % (return_path, update_path))
|
| +
|
| + self.pregenerated_path = update_path
|
|
|
| # Generation complete, copy if requested.
|
| if self.copy_to_static_root:
|
| + # The final results exist directly in static
|
| + update_payload = os.path.join(static_image_dir,
|
| + UPDATE_FILE)
|
| + stateful_payload = os.path.join(static_image_dir,
|
| + STATEFUL_FILE)
|
| self._Copy(cache_update_payload, update_payload)
|
| self._Copy(cache_stateful_payload, stateful_payload)
|
| -
|
| - # Return just the filename in static_image_dir.
|
| - return UPDATE_FILE
|
| + return UPDATE_FILE
|
| + else:
|
| + return self.pregenerated_path
|
|
|
| def GenerateLatestUpdateImage(self, board_id, client_version,
|
| static_image_dir):
|
| @@ -528,7 +528,6 @@ class Autoupdate(BuildObject):
|
| # If the forced payload is not already in our static_image_dir,
|
| # copy it there.
|
| src_path = os.path.abspath(self.forced_payload)
|
| -
|
| src_stateful = os.path.join(os.path.dirname(src_path),
|
| STATEFUL_FILE)
|
|
|
| @@ -567,24 +566,25 @@ class Autoupdate(BuildObject):
|
| client_version,
|
| static_image_dir)
|
|
|
| - _LogMessage('You must set --board for pre-generating latest update.')
|
| + _LogMessage('Failed to genereate update. '
|
| + 'You must set --board when pre-generating latest update.')
|
| return None
|
|
|
| def PreGenerateUpdate(self):
|
| - """Pre-generates an update. Returns True on success.
|
| + """Pre-generates an update and prints out the relative path it.
|
| +
|
| + Returns relative path of the update on success.
|
| """
|
| # Does not work with factory config.
|
| assert(not self.factory_config)
|
| _LogMessage('Pre-generating the update payload.')
|
| # Does not work with labels so just use static dir.
|
| - if self.GenerateUpdatePayloadForNonFactory(self.board, '0.0.0.0',
|
| - self.static_dir):
|
| - _LogMessage('Pre-generated update successfully.')
|
| - self.pregenerated = True
|
| - return True
|
| - else:
|
| - _LogMessage('Failed to pre-generate update.')
|
| - return False
|
| + pregenerated_update = self.GenerateUpdatePayloadForNonFactory(
|
| + self.board, '0.0.0.0', self.static_dir)
|
| + if pregenerated_update:
|
| + print 'PREGENERATED_UPDATE=%s' % pregenerated_update
|
| +
|
| + return pregenerated_update
|
|
|
| def HandleUpdatePing(self, data, label=None):
|
| """Handles an update ping from an update client.
|
|
|