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

Side by Side Diff: autoupdate.py

Issue 4906001: Reworked devserver so that update images generated are cached in directories named after (Closed) Base URL: ssh://git@gitrw.chromium.org:9222/dev-util.git@master
Patch Set: Restore changes accidentally removed during merge. Created 10 years, 1 month 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 | autoupdate_unittest.py » ('j') | devserver.py » ('J')
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 import cherrypy 8 import cherrypy
8 import os 9 import os
9 import shutil 10 import shutil
10 import subprocess 11 import subprocess
11 import tempfile
12 import time 12 import time
13 13
14
15 def _LogMessage(message): 14 def _LogMessage(message):
16 cherrypy.log(message, 'UPDATE') 15 cherrypy.log(message, 'UPDATE')
17 16
18 17
19 class Autoupdate(BuildObject): 18 class Autoupdate(BuildObject):
20 """Class that contains functionality that handles Chrome OS update pings. 19 """Class that contains functionality that handles Chrome OS update pings.
21 20
22 Members: 21 Members:
23 serve_only: Serve images from a pre-built image.zip file. static_dir 22 serve_only: Serve images from a pre-built image.zip file. static_dir
24 must be set to the location of the image.zip. 23 must be set to the location of the image.zip.
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after
99 return os.system('cd %s && unzip -n image.zip' % image_dir) == 0 98 return os.system('cd %s && unzip -n image.zip' % image_dir) == 0
100 99
101 def _GetImageName(self): 100 def _GetImageName(self):
102 """Returns the name of the image that should be used.""" 101 """Returns the name of the image that should be used."""
103 if self.use_test_image: 102 if self.use_test_image:
104 image_name = 'chromiumos_test_image.bin' 103 image_name = 'chromiumos_test_image.bin'
105 else: 104 else:
106 image_name = 'chromiumos_image.bin' 105 image_name = 'chromiumos_image.bin'
107 return image_name 106 return image_name
108 107
109 def _IsImageNewerThanCached(self, image_path, cached_file_path):
110 """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):
112 _LogMessage('Usable cached image found at %s.' % cached_file_path)
113 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) :
115 raise Exception('Image does not exist and cached image missing')
116 else:
117 # Only one is missing, figure out which one.
118 if os.path.exists(image_path):
119 _LogMessage('No cached image found - image generation required.')
120 return True
121 else:
122 _LogMessage('Cached image found to serve at %s.' % cached_file_path)
123 return False
124
125 def _GetSize(self, update_path): 108 def _GetSize(self, update_path):
126 """Returns the size of the file given.""" 109 """Returns the size of the file given."""
127 return os.path.getsize(update_path) 110 return os.path.getsize(update_path)
128 111
129 def _GetHash(self, update_path): 112 def _GetHash(self, update_path):
130 """Returns the sha1 of the file given.""" 113 """Returns the sha1 of the file given."""
131 cmd = ('cat %s | openssl sha1 -binary | openssl base64 | tr \'\\n\' \' \';' 114 cmd = ('cat %s | openssl sha1 -binary | openssl base64 | tr \'\\n\' \' \';'
132 % update_path) 115 % update_path)
133 return os.popen(cmd).read().rstrip() 116 return os.popen(cmd).read().rstrip()
134 117
(...skipping 10 matching lines...) Expand all
145 # it takes advantage of reduced I/O and multiple processors. Something like: 128 # it takes advantage of reduced I/O and multiple processors. Something like:
146 # % tee < FILE > /dev/null \ 129 # % tee < FILE > /dev/null \
147 # >( openssl dgst -sha256 -binary | openssl base64 ) \ 130 # >( openssl dgst -sha256 -binary | openssl base64 ) \
148 # >( openssl sha1 -binary | openssl base64 ) 131 # >( openssl sha1 -binary | openssl base64 )
149 def _GetSHA256(self, update_path): 132 def _GetSHA256(self, update_path):
150 """Returns the sha256 of the file given.""" 133 """Returns the sha256 of the file given."""
151 cmd = ('cat %s | openssl dgst -sha256 -binary | openssl base64' % 134 cmd = ('cat %s | openssl dgst -sha256 -binary | openssl base64' %
152 update_path) 135 update_path)
153 return os.popen(cmd).read().rstrip() 136 return os.popen(cmd).read().rstrip()
154 137
138 def _GetMd5(self, update_path):
139 """Returns the md5 checksum of the file given."""
140 cmd = ("md5sum %s | awk '{print $1}'" % update_path)
141 return os.popen(cmd).read().rstrip()
142
155 def GetUpdatePayload(self, hash, sha256, size, url, is_delta_format): 143 def GetUpdatePayload(self, hash, sha256, size, url, is_delta_format):
156 """Returns a payload to the client corresponding to a new update. 144 """Returns a payload to the client corresponding to a new update.
157 145
158 Args: 146 Args:
159 hash: hash of update blob 147 hash: hash of update blob
160 sha256: SHA-256 hash of update blob 148 sha256: SHA-256 hash of update blob
161 size: size of update blob 149 size: size of update blob
162 url: where to find update blob 150 url: where to find update blob
163 Returns: 151 Returns:
164 Xml string to be passed back to client. 152 Xml string to be passed back to client.
(...skipping 26 matching lines...) Expand all
191 < gupdate xmlns = "http://www.google.com/update2/response" protocol = "2.0 " > 179 < gupdate xmlns = "http://www.google.com/update2/response" protocol = "2.0 " >
192 < daystart elapsed_seconds = "%s" /> 180 < daystart elapsed_seconds = "%s" />
193 < app appid = "{%s}" status = "ok" > 181 < app appid = "{%s}" status = "ok" >
194 < ping status = "ok" /> 182 < ping status = "ok" />
195 < updatecheck status = "noupdate" /> 183 < updatecheck status = "noupdate" />
196 </ app > 184 </ app >
197 </ gupdate > 185 </ gupdate >
198 """ 186 """
199 return payload % (self._GetSecondsSinceMidnight(), self.app_id) 187 return payload % (self._GetSecondsSinceMidnight(), self.app_id)
200 188
201 def GenerateUpdateFile(self, image_path): 189 def GenerateUpdateFile(self, src_image, image_path, static_image_dir):
202 """Generates an update gz given a full path to an image. 190 """Generates an update gz given a full path to an image.
203 191
204 Args: 192 Args:
205 image_path: Full path to image. 193 image_path: Full path to image.
206 Returns: 194 Returns:
207 Path to created update_payload or None on error. 195 Path to created update_payload or None on error.
208 """ 196 """
209 image_dir = os.path.dirname(image_path) 197 image_dir = os.path.dirname(image_path)
210 update_path = os.path.join(image_dir, 'update.gz') 198 update_path = os.path.join(static_image_dir, 'update.gz')
211 patch_kernel_flag = '--patch_kernel' 199 patch_kernel_flag = '--patch_kernel'
212 _LogMessage('Generating update image %s' % update_path) 200 _LogMessage('Generating update image %s' % update_path)
213 201
214 # Don't patch the kernel for vm images as they don't need the patch. 202 # Don't patch the kernel for vm images as they don't need the patch.
215 if self.vm: 203 if self.vm:
216 patch_kernel_flag = '' 204 patch_kernel_flag = ''
217 205
218 mkupdate_command = ( 206 mkupdate_command = (
219 '%s/cros_generate_update_payload --image="%s" --output="%s" ' 207 '%s/cros_generate_update_payload --image="%s" --output="%s" '
220 '%s --noold_style --src_image="%s"' % ( 208 '%s --noold_style --src_image="%s"' % (
221 self.scripts_dir, image_path, update_path, patch_kernel_flag, 209 self.scripts_dir, image_path, update_path, patch_kernel_flag,
222 self.src_image)) 210 src_image))
223 _LogMessage(mkupdate_command) 211 _LogMessage(mkupdate_command)
224 if os.system(mkupdate_command) != 0: 212 if os.system(mkupdate_command) != 0:
225 _LogMessage('Failed to create base update file') 213 _LogMessage('Failed to create base update file')
226 return None 214 return None
227 215
228 return update_path 216 return update_path
229 217
230 def GenerateStatefulFile(self, image_path): 218 def GenerateStatefulFile(self, image_path, static_image_dir):
231 """Generates a stateful update given a full path to an image. 219 """Generates a stateful update gz given a full path to an image.
232 220
233 Args: 221 Args:
234 image_path: Full path to image. 222 image_path: Full path to image.
235 Returns: 223 Returns:
236 Path to created stateful update_payload. 224 Path to created stateful update_payload or None on error.
237 Raises: 225 Raises:
238 A subprocess exception if the update generator fails to generate a 226 A subprocess exception if the update generator fails to generate a
239 stateful payload. 227 stateful payload.
240 """ 228 """
241 work_dir = os.path.dirname(image_path) 229
242 output_gz = os.path.join(work_dir, 'stateful.tgz') 230 output_gz = os.path.join(static_image_dir, 'stateful.tgz')
243 subprocess.check_call( 231 subprocess.check_call(
244 ['%s/cros_generate_stateful_update_payload' % self.crosutils, 232 ['%s/cros_generate_stateful_update_payload' % self.crosutils,
245 '--image=%s' % image_path, 233 '--image=%s' % image_path,
246 '--output_dir=%s' % work_dir, 234 '--output_dir=%s' % static_image_dir,
247 ]) 235 ])
248 return output_gz 236 return output_gz
249 237
250 def MoveImagesToStaticDir(self, update_path, stateful_update_path, 238 def FindCachedUpdateImageSubDir(self, src_image, dest_image):
sosa 2010/11/15 21:59:17 docstring
dgarrett 2010/11/15 23:32:39 Done.
251 static_image_dir): 239 """Given one, or two images for an update, this finds which
252 """Moves gz files from their directories to serving directories. 240 cache directory should hold the udpate files, even if they don't exist ye t.
sosa 2010/11/15 21:59:17 spelling
dgarrett 2010/11/15 23:32:39 Done.
241 The directory will be inside static_image_dir, and of the form:
253 242
254 Args: 243 Non-delta updates:
255 update_path: full path to main update gz. 244 cache/12345678
256 stateful_update_path: full path to stateful partition gz.
257 static_image_dir: where to put files.
258 Returns:
259 Returns True if the files were moved over successfully.
260 """
261 try:
262 shutil.copy(update_path, static_image_dir)
263 shutil.copy(stateful_update_path, static_image_dir)
264 os.remove(update_path)
265 os.remove(stateful_update_path)
266 except Exception:
267 _LogMessage('Failed to move %s and %s to %s' % (update_path,
268 stateful_update_path,
269 static_image_dir))
270 return False
271 245
272 return True 246 Delta updates:
247 cache/12345678_12345678
248 """
273 249
274 def GenerateUpdateImage(self, image_path, move_to_static_dir=False, 250 # If there is no src, we only have an image file, check image for changes
275 static_image_dir=None): 251 if not src_image:
276 """Generates an update payload based on the given image_path. 252 return os.path.join('cache', self._GetMd5(dest_image))
253
254 # If we have src and dest, we are a delta, and check both for changes
255 return os.path.join('cache',
256 "%s_%s" % (self._GetMd5(src_image),
257 self._GetMd5(dest_image)))
258
259 def GenerateUpdateImage(self, src_image, image_path, static_image_dir):
260 """Force generates an update payload based on the given image_path.
277 261
278 Args: 262 Args:
279 image_path: full path to the image. 263 image_path: full path to the image.
280 move_to_static_dir: Moves the files from their dir to the static dir. 264 move_to_static_dir: Moves the files from their dir to the static dir.
281 static_image_dir: the directory to move images to after generating. 265 static_image_dir: the directory to move images to after generating.
282 Returns: 266 Returns:
283 True if the update payload was created successfully. 267 update filename (not directory) on success, or None
284 """ 268 """
269
270 update_file = None
271 stateful_update_file = None
272
273 # Actually do the generation
285 _LogMessage('Generating update for image %s' % image_path) 274 _LogMessage('Generating update for image %s' % image_path)
286 update_path = self.GenerateUpdateFile(image_path) 275 update_file = self.GenerateUpdateFile(src_image,
287 if update_path: 276 image_path,
288 stateful_update_path = self.GenerateStatefulFile(image_path)
289 if move_to_static_dir:
290 return self.MoveImagesToStaticDir(update_path, stateful_update_path,
291 static_image_dir) 277 static_image_dir)
292 return True 278
279 if update_file:
280 stateful_update_file = self.GenerateStatefulFile(image_path,
281 static_image_dir)
282
283 if update_file and stateful_update_file:
284 return os.path.basename(update_file)
293 285
294 _LogMessage('Failed to generate update') 286 _LogMessage('Failed to generate update')
295 return False 287
288 # Cleanup incomplete files, if they exist
289 if update_file and os.path.exists(update_file):
290 os.remove(update_file)
291
292 if stateful_update_file and os.path.exists(stateful_update_file):
sosa 2010/11/15 21:59:17 This case isn't possible.
293 os.remove(stateful_update_file)
294
295 return None
296
297 def GenerateUpdateImageWithCache(self, image_path, static_image_dir):
298 """Force generates an update payload based on the given image_path.
299
300 Args:
301 image_path: full path to the image.
302 move_to_static_dir: Moves the files from their dir to the static dir.
303 static_image_dir: the directory to move images to after generating.
304 Returns:
305 update filename (not directory) relative to static_image_dir on success,
sosa 2010/11/15 21:59:17 Use path rather than filename .. relative path
306 or None
307 """
308
309 _LogMessage('Generating update for src %s image %s' % (self.src_image,
310 image_path))
311
312 # Which sub_dir of static_image_dir should hold our cached update image
313 cache_sub_dir = self.FindCachedUpdateImageSubDir(self.src_image, image_path)
314 _LogMessage('Caching in sub_dir "%s"' % cache_sub_dir)
315
316 # Check for a cached image to use
317 if os.path.exists(os.path.join(static_image_dir, cache_sub_dir, 'update.gz') ):
sosa 2010/11/15 21:59:17 80 char
318 return os.path.join(cache_sub_dir, 'update.gz')
319
320 full_cache_dir = os.path.join(static_image_dir, cache_sub_dir)
321 src_image = ""
sosa 2010/11/15 21:59:17 Use '' not "" to be consistent unless it is a docs
sosa 2010/11/15 21:59:17 You never use src_image
322 dest_image = os.path.join(full_cache_dir, 'dest_image.bin')
sosa 2010/11/15 21:59:17 What's the point of this var?
dgarrett 2010/11/15 23:32:39 Both src_iamge and dest_image were left over for t
323
324 # Create the directory for the cache values
325 if not os.path.exists(full_cache_dir):
326 os.makedirs(full_cache_dir)
327
328 gen_image = self.GenerateUpdateImage(self.src_image,
329 image_path,
330 full_cache_dir)
331
332 # If the generation worked
333 if gen_image:
334 return os.path.join(cache_sub_dir, gen_image)
335 else:
336 return None
337
296 338
297 def GenerateLatestUpdateImage(self, board_id, client_version, 339 def GenerateLatestUpdateImage(self, board_id, client_version,
298 static_image_dir=None): 340 static_image_dir):
299 """Generates an update using the latest image that has been built. 341 """Generates an update using the latest image that has been built.
300 342
301 This will only generate an update if the newest update is newer than that 343 This will only generate an update if the newest update is newer than that
302 on the client or client_version is 'ForcedUpdate'. 344 on the client or client_version is 'ForcedUpdate'.
303 345
304 Args: 346 Args:
305 board_id: Name of the board. 347 board_id: Name of the board.
306 client_version: Current version of the client or 'ForcedUpdate' 348 client_version: Current version of the client or 'ForcedUpdate'
307 static_image_dir: the directory to move images to after generating. 349 static_image_dir: the directory to move images to after generating.
308 Returns: 350 Returns:
309 True if the update payload was created successfully. 351 Name of the update image relative to static_image_dir or None
310 """ 352 """
311 latest_image_dir = self._GetLatestImageDir(board_id) 353 latest_image_dir = self._GetLatestImageDir(board_id)
312 latest_version = self._GetVersionFromDir(latest_image_dir) 354 latest_version = self._GetVersionFromDir(latest_image_dir)
313 latest_image_path = os.path.join(latest_image_dir, self._GetImageName()) 355 latest_image_path = os.path.join(latest_image_dir, self._GetImageName())
314 356
315 _LogMessage('Preparing to generate update from latest built image %s.' % 357 _LogMessage('Preparing to generate update from latest built image %s.' %
316 latest_image_path) 358 latest_image_path)
317 359
318 # Check to see whether or not we should update. 360 # Check to see whether or not we should update.
319 if client_version != 'ForcedUpdate' and not self._CanUpdate( 361 if client_version != 'ForcedUpdate' and not self._CanUpdate(
320 client_version, latest_version): 362 client_version, latest_version):
321 _LogMessage('no update') 363 _LogMessage('no update')
322 return False 364 return None
323 365
324 cached_file_path = os.path.join(static_image_dir, 'update.gz') 366 return self.GenerateUpdateImageWithCache(latest_image_path,
325 if (os.path.exists(cached_file_path) and 367 static_image_dir=static_image_dir)
326 not self._IsImageNewerThanCached(latest_image_path, cached_file_path)):
327 return True
328
329 return self.GenerateUpdateImage(latest_image_path, move_to_static_dir=True,
330 static_image_dir=static_image_dir)
331 368
332 def GenerateImageFromZip(self, static_image_dir): 369 def GenerateImageFromZip(self, static_image_dir):
333 """Generates an update from an image zip file. 370 """Generates an update from an image zip file.
334 371
335 This method assumes you have an image.zip in directory you are serving 372 This method assumes you have an image.zip in directory you are serving
336 from. If this file is newer than a previously cached file, it will unzip 373 from. If this file is newer than a previously cached file, it will unzip
337 this file, create a payload and serve it. 374 this file, create a payload and serve it.
338 375
339 Args: 376 Args:
340 static_image_dir: Directory where the zip file exists. 377 static_image_dir: Directory where the zip file exists.
341 Returns: 378 Returns:
342 True if the update payload was created successfully. 379 Name of the update payload relative to static_image_dir if successful.
343 """ 380 """
344 _LogMessage('Preparing to generate update from zip in %s.' % static_image_di r) 381 _LogMessage('Preparing to generate update from zip in %s.' % static_image_di r)
345 image_path = os.path.join(static_image_dir, self._GetImageName()) 382 image_path = os.path.join(static_image_dir, self._GetImageName())
346 cached_file_path = os.path.join(static_image_dir, 'update.gz')
347 zip_file_path = os.path.join(static_image_dir, 'image.zip') 383 zip_file_path = os.path.join(static_image_dir, 'image.zip')
348 if not self._IsImageNewerThanCached(zip_file_path, cached_file_path): 384
349 return True 385 # XXX Work this into new path
sosa 2010/11/15 21:59:17 What's this here for?
386 #cached_file_path = os.path.join(static_image_dir, 'update.gz')
387 #if not self._IsImageNewerThanCached(zip_file_path, cached_file_path):
388 # return 'update.gz'
350 389
351 if not self._UnpackZip(static_image_dir): 390 if not self._UnpackZip(static_image_dir):
352 _LogMessage('unzip image.zip failed.') 391 _LogMessage('unzip image.zip failed.')
353 return False 392 return None
354 393
355 return self.GenerateUpdateImage(image_path, move_to_static_dir=False, 394 return self.GenerateUpdateImageWithCache(image_path,
356 static_image_dir=None) 395 static_image_dir=static_image_dir)
357 396
358 def ImportFactoryConfigFile(self, filename, validate_checksums=False): 397 def ImportFactoryConfigFile(self, filename, validate_checksums=False):
359 """Imports a factory-floor server configuration file. The file should 398 """Imports a factory-floor server configuration file. The file should
360 be in this format: 399 be in this format:
361 config = [ 400 config = [
362 { 401 {
363 'qual_ids': set([1, 2, 3, "x86-generic"]), 402 'qual_ids': set([1, 2, 3, "x86-generic"]),
364 'factory_image': 'generic-factory.gz', 403 'factory_image': 'generic-factory.gz',
365 'factory_checksum': 'AtiI8B64agHVN+yeBAyiNMX3+HM=', 404 'factory_checksum': 'AtiI8B64agHVN+yeBAyiNMX3+HM=',
366 'release_image': 'generic-release.gz', 405 'release_image': 'generic-release.gz',
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after
443 return self.GetNoUpdatePayload() 482 return self.GetNoUpdatePayload()
444 url = '%s/static/%s' % (self.hostname, filename) 483 url = '%s/static/%s' % (self.hostname, filename)
445 is_delta_format = self._IsDeltaFormatFile(filename) 484 is_delta_format = self._IsDeltaFormatFile(filename)
446 _LogMessage('returning update payload ' + url) 485 _LogMessage('returning update payload ' + url)
447 # Factory install is using memento updater which is using the sha-1 hash so 486 # Factory install is using memento updater which is using the sha-1 hash so
448 # setting sha-256 to an empty string. 487 # setting sha-256 to an empty string.
449 return self.GetUpdatePayload(checksum, '', size, url, is_delta_format) 488 return self.GetUpdatePayload(checksum, '', size, url, is_delta_format)
450 489
451 def GenerateUpdatePayloadForNonFactory(self, board_id, client_version, 490 def GenerateUpdatePayloadForNonFactory(self, board_id, client_version,
452 static_image_dir): 491 static_image_dir):
453 """Generates an update for non-factory and returns True on success.""" 492 """Generates an update for non-factory and returns file name relative to
sosa 2010/11/15 21:59:17 One line for first line in doc string
454 if self.use_cached and os.path.exists(os.path.join(static_image_dir, 493 static_image_dir on success.
455 'update.gz')): 494
456 _LogMessage('Using cached image regardless of timestamps.') 495 Returns the update file relative to the static_image_dir on success."""
sosa 2010/11/15 21:59:17 """ on new line
sosa 2010/11/15 21:59:17 file relative? or just the base name?
dgarrett 2010/11/15 23:32:39 File relative.
dgarrett 2010/11/15 23:32:39 Done.
457 return True 496
497 if self.forced_image:
498 return self.GenerateUpdateImageWithCache(
499 self.forced_image,
500 static_image_dir=static_image_dir)
501 elif self.serve_only:
502 return self.GenerateImageFromZip(static_image_dir)
458 else: 503 else:
459 if self.forced_image: 504 if board_id:
460 has_built_image = self.GenerateUpdateImage( 505 return self.GenerateLatestUpdateImage(board_id,
461 self.forced_image, move_to_static_dir=True, 506 client_version,
462 static_image_dir=static_image_dir) 507 static_image_dir)
463 return has_built_image
464 elif self.serve_only:
465 return self.GenerateImageFromZip(static_image_dir)
466 else:
467 if board_id:
468 return self.GenerateLatestUpdateImage(board_id,
469 client_version,
470 static_image_dir)
471 508
472 _LogMessage('You must set --board for pre-generating latest update.') 509 _LogMessage('You must set --board for pre-generating latest update.')
473 return False 510 return None
474 511
475 def PreGenerateUpdate(self): 512 def PreGenerateUpdate(self):
476 """Pre-generates an update. Returns True on success.""" 513 """Pre-generates an update. Returns True on success."""
477 # Does not work with factory config. 514 # Does not work with factory config.
478 assert(not self.factory_config) 515 assert(not self.factory_config)
479 _LogMessage('Pre-generating the update payload.') 516 _LogMessage('Pre-generating the update payload.')
480 # Does not work with labels so just use static dir. 517 # Does not work with labels so just use static dir.
481 if self.GenerateUpdatePayloadForNonFactory(self.board, '0.0.0.0', 518 if self.GenerateUpdatePayloadForNonFactory(self.board, '0.0.0.0',
482 self.static_dir): 519 self.static_dir):
483 # Force the devserver to use the pre-generated payload.
484 self.use_cached = True
485 _LogMessage('Pre-generated update successfully.') 520 _LogMessage('Pre-generated update successfully.')
486 return True 521 return True
487 else: 522 else:
488 _LogMessage('Failed to pre-generate update.') 523 _LogMessage('Failed to pre-generate update.')
489 return False 524 return False
490 525
491 def HandleUpdatePing(self, data, label=None): 526 def HandleUpdatePing(self, data, label=None):
492 """Handles an update ping from an update client. 527 """Handles an update ping from an update client.
493 528
494 Args: 529 Args:
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
536 571
537 # Separate logic as Factory requests have static url's that override 572 # Separate logic as Factory requests have static url's that override
538 # other options. 573 # other options.
539 if self.factory_config: 574 if self.factory_config:
540 return self.HandleFactoryRequest(board_id, channel) 575 return self.HandleFactoryRequest(board_id, channel)
541 else: 576 else:
542 static_image_dir = self.static_dir 577 static_image_dir = self.static_dir
543 if label: 578 if label:
544 static_image_dir = os.path.join(static_image_dir, label) 579 static_image_dir = os.path.join(static_image_dir, label)
545 580
546 if self.GenerateUpdatePayloadForNonFactory(board_id, client_version, 581 update_name = self.GenerateUpdatePayloadForNonFactory(board_id,
sosa 2010/11/15 21:59:17 update name seems a little unclear. How about pay
dgarrett 2010/11/15 23:32:39 Done.
547 static_image_dir): 582 client_version,
548 filename = os.path.join(static_image_dir, 'update.gz') 583 static_image_dir)
584 if update_name:
585 filename = os.path.join(static_image_dir, update_name)
549 hash = self._GetHash(filename) 586 hash = self._GetHash(filename)
550 sha256 = self._GetSHA256(filename) 587 sha256 = self._GetSHA256(filename)
551 size = self._GetSize(filename) 588 size = self._GetSize(filename)
552 is_delta_format = self._IsDeltaFormatFile(filename) 589 is_delta_format = self._IsDeltaFormatFile(filename)
553 if label: 590 if label:
554 url = '%s/%s/update.gz' % (static_urlbase, label) 591 url = '%s/%s/%s' % (static_urlbase, label, update_name)
555 else: 592 else:
556 url = '%s/update.gz' % static_urlbase 593 url = '%s/%s' % (static_urlbase, update_name)
557 594
558 _LogMessage('Responding to client to use url %s to get image.' % url) 595 _LogMessage('Responding to client to use url %s to get image.' % url)
559 return self.GetUpdatePayload(hash, sha256, size, url, is_delta_format) 596 return self.GetUpdatePayload(hash, sha256, size, url, is_delta_format)
560 else: 597 else:
561 return self.GetNoUpdatePayload() 598 return self.GetNoUpdatePayload()
OLDNEW
« no previous file with comments | « no previous file | autoupdate_unittest.py » ('j') | devserver.py » ('J')

Powered by Google App Engine
This is Rietveld 408576698