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

Unified Diff: src/platform/dev/autoupdate.py

Issue 1596016: Dev server: Support image hosting for factory install. (Closed)
Patch Set: support state,oem partitions Created 10 years, 8 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | src/platform/dev/devserver.py » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/platform/dev/autoupdate.py
diff --git a/src/platform/dev/autoupdate.py b/src/platform/dev/autoupdate.py
index 004f86bc6382d14e8af7ac4fa055b0c4bb1ef99b..b3d4751e819469cbadf6620dfcf988bbcf4c8a81 100644
--- a/src/platform/dev/autoupdate.py
+++ b/src/platform/dev/autoupdate.py
@@ -7,6 +7,7 @@ from xml.dom import minidom
import os
import shutil
+import sys
import web
class Autoupdate(BuildObject):
@@ -15,6 +16,7 @@ class Autoupdate(BuildObject):
# TODO(rtc): Clean this code up and write some tests.
def __init__(self, serve_only=None, test_image=False, urlbase=None,
+ factory_config_path=None, validate_factory_config=None,
*args, **kwargs):
super(Autoupdate, self).__init__(*args, **kwargs)
self.serve_only = serve_only
@@ -32,6 +34,8 @@ class Autoupdate(BuildObject):
os.unlink('static/archive')
else:
os.symlink(self.static_dir, 'static/archive')
+ if factory_config_path is not None:
+ self.ImportFactoryConfigFile(factory_config_path, validate_factory_config)
def GetUpdatePayload(self, hash, size, url):
payload = """<?xml version="1.0" encoding="UTF-8"?>
@@ -138,24 +142,101 @@ class Autoupdate(BuildObject):
def GetHash(self, update_path):
cmd = "cat %s | openssl sha1 -binary | openssl base64 | tr \'\\n\' \' \';" \
% update_path
- web.debug(cmd)
- return os.popen(cmd).read()
+ return os.popen(cmd).read().rstrip()
+ def ImportFactoryConfigFile(self, filename, validate_checksums=False):
+ """Imports a factory-floor server configuration file. The file should
+ be in this format:
+ config = [
+ {
+ 'qual_ids': set([1, 2, 3, "x86-generic"]),
+ 'factory_image': 'generic-factory.gz',
+ 'factory_checksum': 'AtiI8B64agHVN+yeBAyiNMX3+HM=',
+ 'release_image': 'generic-release.gz',
+ 'release_checksum': 'AtiI8B64agHVN+yeBAyiNMX3+HM=',
+ 'oempartitionimg_image': 'generic-oem.gz',
+ 'oempartitionimg_checksum': 'AtiI8B64agHVN+yeBAyiNMX3+HM=',
+ 'stateimg_image': 'generic-state.gz',
+ 'stateimg_checksum': 'AtiI8B64agHVN+yeBAyiNMX3+HM='
+ },
+ {
+ 'qual_ids': set([6]),
+ 'factory_image': '6-factory.gz',
+ 'factory_checksum': 'AtiI8B64agHVN+yeBAyiNMX3+HM=',
+ 'release_image': '6-release.gz',
+ 'release_checksum': 'AtiI8B64agHVN+yeBAyiNMX3+HM=',
+ 'oempartitionimg_image': '6-oem.gz',
+ 'oempartitionimg_checksum': 'AtiI8B64agHVN+yeBAyiNMX3+HM=',
+ 'stateimg_image': '6-state.gz',
+ 'stateimg_checksum': 'AtiI8B64agHVN+yeBAyiNMX3+HM='
+ },
+ ]
+ The server will look for the files by name in the static files
+ directory.
+
+ If validate_checksums is True, validates checksums and exits. If
+ a checksum mismatch is found, it's printed to the screen.
+ """
+ f = open(filename, 'r')
+ output = {}
+ exec(f.read(), output)
+ self.factory_config = output['config']
+ success = True
+ for stanza in self.factory_config:
+ for kind in ('factory', 'oempartitionimg', 'release', 'stateimg'):
+ stanza[kind + '_size'] = \
+ os.path.getsize(self.static_dir + '/' + stanza[kind + '_image'])
+ if validate_checksums:
+ factory_checksum = self.GetHash(self.static_dir + '/' +
+ stanza[kind + '_image'])
+ if factory_checksum != stanza[kind + '_checksum']:
+ print 'Error: checksum mismatch for %s. Expected "%s" but file ' \
+ 'has checksum "%s".' % (stanza[kind + '_image'],
+ stanza[kind + '_checksum'],
+ factory_checksum)
+ success = False
+ if validate_checksums:
+ if success is False:
+ raise Exception('Checksum mismatch in conf file.')
+ print 'Config file looks good.'
+
+ def GetFactoryImage(self, board_id, channel):
+ kind = channel.rsplit('-', 1)[0]
+ for stanza in self.factory_config:
+ if board_id not in stanza['qual_ids']:
+ continue
+ return (stanza[kind + '_image'],
+ stanza[kind + '_checksum'],
+ stanza[kind + '_size'])
def HandleUpdatePing(self, data, label=None):
+ web.debug('handle update ping')
update_dom = minidom.parseString(data)
root = update_dom.firstChild
query = root.getElementsByTagName('o:app')[0]
client_version = query.getAttribute('version')
+ channel = query.getAttribute('track')
board_id = query.hasAttribute('board') and query.getAttribute('board') \
or 'x86-generic'
latest_image_path = self.GetLatestImagePath(board_id)
latest_version = self.GetLatestVersion(latest_image_path)
+ hostname = web.ctx.host
+
+ # If this is a factory floor server, return the image here:
+ if self.factory_config:
+ (filename, checksum, size) = \
+ self.GetFactoryImage(board_id, channel)
+ if filename is None:
+ web.debug('unable to find image for board %s' % board_id)
+ return self.GetNoUpdatePayload()
+ url = 'http://%s/static/%s' % (hostname, filename)
+ web.debug('returning update payload ' + url)
+ return self.GetUpdatePayload(checksum, size, url)
+
if client_version != 'ForcedUpdate' \
and not self.CanUpdate(client_version, latest_version):
web.debug('no update')
return self.GetNoUpdatePayload()
- hostname = web.ctx.host
if label:
web.debug('Client requested version %s' % label)
# Check that matching build exists
« no previous file with comments | « no previous file | src/platform/dev/devserver.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698