Adds a few fixes for the dev server and refactors the update logic into a class.
Review URL: http://chromereview.prom.corp.google.com/1180044
git-svn-id: svn://chrome-svn/chromeos/trunk@156 06c00378-0e64-4dae-be16-12b19f9950a1
diff --git a/autoupdate.py b/autoupdate.py
index cad0be4..e622563 100644
--- a/autoupdate.py
+++ b/autoupdate.py
@@ -7,112 +7,114 @@
import os
import web
-# TODO(rtc): This is redundant with devserver.py. Move this code to a
-# common location.
-app_id = "87efface-864d-49a5-9bb3-4b050a7c227a"
-root_dir = "/usr/local/google/home/rtc/chromeos/trunk/src"
-scripts_dir = "%s/scripts" % root_dir
-app_dir = os.popen("pwd").read().strip()
-static_dir = "%s/static" % app_dir
+class Autoupdate:
-# Basic functionality of handling ChromeOS autoupdate pings
-# and building/serving update images.
-# TODO(rtc): Clean this code up and write some tests.
+ def __init__(self, root_dir, static_dir):
+ # TODO(rtc): This is redundant with devserver.py. Move this code to a
+ # common location.
+ self.app_id = "87efface-864d-49a5-9bb3-4b050a7c227a"
+ self.root_dir = root_dir
+ self.scripts_dir = "%s/scripts" % self.root_dir
+ self.static_dir = static_dir
-def GetUpdatePayload(hash, size, url, id):
- payload = """<?xml version="1.0" encoding="UTF-8"?>
- <gupdate xmlns="http://www.google.com/update2/response" protocol="2.0">
- <app appid="{%s}" status="ok">
- <ping status="ok"/>
- <updatecheck
- codebase="%s"
- hash="%s"
- needsadmin="false"
- size="%s"
- status="ok"/>
- </app>
- </gupdate>
- """
- return payload % (id, url, hash, size)
+ # Basic functionality of handling ChromeOS autoupdate pings
+ # and building/serving update images.
+ # TODO(rtc): Clean this code up and write some tests.
-def GetNoUpdatePayload(id):
- payload = """<?xml version="1.0" encoding="UTF-8"?>
- <gupdate xmlns="http://www.google.com/update2/response" protocol="2.0">
- <app appid="{%s}" status="ok">
- <ping status="ok"/>
- <updatecheck status="noupdate"/>
- </app>
- </gupdate>
- """
- return payload % id
+ def GetUpdatePayload(self, hash, size, url):
+ payload = """<?xml version="1.0" encoding="UTF-8"?>
+ <gupdate xmlns="http://www.google.com/update2/response" protocol="2.0">
+ <app appid="{%s}" status="ok">
+ <ping status="ok"/>
+ <updatecheck
+ codebase="%s"
+ hash="%s"
+ needsadmin="false"
+ size="%s"
+ status="ok"/>
+ </app>
+ </gupdate>
+ """
+ return payload % (self.app_id, url, hash, size)
-def GetLatestImagePath():
- cmd = "%s/get_latest_image.sh" % scripts_dir
- return os.popen(cmd).read().strip()
+ def GetNoUpdatePayload(self):
+ payload = """<?xml version="1.0" encoding="UTF-8"?>
+ <gupdate xmlns="http://www.google.com/update2/response" protocol="2.0">
+ <app appid="{%s}" status="ok">
+ <ping status="ok"/>
+ <updatecheck status="noupdate"/>
+ </app>
+ </gupdate>
+ """
+ return payload % self.app_id
-def GetLatestVersion(latest_image_path):
- latest_version = latest_image_path.split('/')[-1]
- return latest_version.split('-')[0]
+ def GetLatestImagePath(self):
+ cmd = "%s/get_latest_image.sh" % self.scripts_dir
+ return os.popen(cmd).read().strip()
-def CanUpdate(client_version, latest_version):
- """
- Returns true iff the latest_version is greater than the client_version.
- """
- client_tokens = client_version.split('.')
- latest_tokens = latest_version.split('.')
- web.debug("client version %s latest version %s" % (client_version, latest_version))
- for i in range(0,4):
- if int(latest_tokens[i]) == int(client_tokens[i]):
- continue
- return int(latest_tokens[i]) > int(client_tokens[i])
- return False
+ def GetLatestVersion(self, latest_image_path):
+ latest_version = latest_image_path.split('/')[-1]
+ return latest_version.split('-')[0]
-def BuildUpdateImage(image_path):
- image_file = "%s/rootfs.image" % image_path
- web.debug("checking image file %s/update.gz" % image_path)
- if not os.path.exists("%s/update.gz" % image_path):
- mkupdate = "%s/mk_memento_images.sh %s" % (scripts_dir, image_file)
- web.debug(mkupdate)
- err = os.system(mkupdate)
- if err != 0:
- web.debug("failed to create update image")
- return False
-
- web.debug("Found an image, copying it to static")
- err = os.system("cp %s/update.gz %s" % (image_path, static_dir))
- if err != 0:
- web.debug("Unable to move update.gz from %s to %s" % (image_path, static_dir))
+ def CanUpdate(self, client_version, latest_version):
+ """
+ Returns true iff the latest_version is greater than the client_version.
+ """
+ client_tokens = client_version.split('.')
+ latest_tokens = latest_version.split('.')
+ web.debug("client version %s latest version %s" % (client_version, latest_version))
+ for i in range(0,4):
+ if int(latest_tokens[i]) == int(client_tokens[i]):
+ continue
+ return int(latest_tokens[i]) > int(client_tokens[i])
return False
- return True
-def GetSize(update_path):
- return os.path.getsize(update_path)
+ def BuildUpdateImage(self, image_path):
+ image_file = "%s/rootfs.image" % image_path
+ web.debug("checking image file %s/update.gz" % image_path)
+ if not os.path.exists("%s/update.gz" % image_path):
+ mkupdate = "%s/mk_memento_images.sh %s" % (self.scripts_dir, image_file)
+ web.debug(mkupdate)
+ err = os.system(mkupdate)
+ if err != 0:
+ web.debug("failed to create update image")
+ return False
-def GetHash(update_path):
- cmd = "cat %s | openssl sha1 -binary | openssl base64 | tr \'\\n\' \' \';" % update_path
- web.debug(cmd)
- return os.popen(cmd).read()
+ web.debug("Found an image, copying it to static")
+ err = os.system("cp %s/update.gz %s" % (image_path, self.static_dir))
+ if err != 0:
+ web.debug("Unable to move update.gz from %s to %s" % (image_path, self.static_dir))
+ return False
+ return True
-def HandleUpdatePing(data):
- update_dom = minidom.parseString(data)
- root = update_dom.firstChild
- query = root.getElementsByTagName("o:app")[0]
- client_version = query.attributes['version'].value
- latest_image_path = GetLatestImagePath();
- latest_version = GetLatestVersion(latest_image_path);
- if not CanUpdate(client_version, latest_version):
- web.debug("no update")
- return GetNoUpdatePayload(app_id)
+ def GetSize(self, update_path):
+ return os.path.getsize(update_path)
- web.debug("update found %s " % latest_version)
- ok = BuildUpdateImage(latest_image_path)
- if ok != True:
- web.debug("Failed to build an update image")
- return GetNoUpdatePayload(app_id)
+ 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()
- hash = GetHash("%s/update.gz" % static_dir)
- size = GetSize("%s/update.gz" % static_dir)
- hostname = web.ctx.host
- url = "http://%s/static/update.gz" % hostname
- return GetUpdatePayload(hash, size, url, app_id)
+ def HandleUpdatePing(self, data):
+ update_dom = minidom.parseString(data)
+ root = update_dom.firstChild
+ query = root.getElementsByTagName("o:app")[0]
+ client_version = query.attributes['version'].value
+ latest_image_path = self.GetLatestImagePath();
+ latest_version = self.GetLatestVersion(latest_image_path);
+ if not self.CanUpdate(client_version, latest_version):
+ web.debug("no update")
+ return self.GetNoUpdatePayload()
+
+ web.debug("update found %s " % latest_version)
+ ok = self.BuildUpdateImage(latest_image_path)
+ if ok != True:
+ web.debug("Failed to build an update image")
+ return self.GetNoUpdatePayload()
+
+ hash = self.GetHash("%s/update.gz" % self.static_dir)
+ size = self.GetSize("%s/update.gz" % self.static_dir)
+ hostname = web.ctx.host
+ url = "http://%s/static/update.gz" % hostname
+ return self.GetUpdatePayload(hash, size, url)