blob: 005078405686de08dc8b93cbe95cf5532782a58b [file] [log] [blame]
# Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
"""An API for issuing Omaha requests."""
import urllib2
# An Omaha update check template.
_OMAHA_UPDATE_CHECK_TEMPLATE = (
'<?xml version="1.0" encoding="UTF-8"?>'
'<o:gupdate'
' xmlns:o="http://www.google.com/update2/request"'
' protocol="2.0">'
' <o:app'
' appid="%(appid)s"'
' version="0.0.0.0"'
' track="%(channel)s-channel"'
' hardware_class="%(hwid)s">'
' <o:updatecheck/>'
' </o:app>'
'</o:gupdate>')
class OmahaError(BaseException):
"""Error pertaining to the use of Omaha."""
pass
def omaha_request(request_data, url_path='service/update2'):
"""Issues a request to Omaha, returns response.
@param request_data: XML data carrying the actual request
@param url_path: path component of the Omaha URL
@return The Omaha response data.
@raise OmahaError if an error occurred.
"""
url = 'http://tools.google.com/%s' % url_path
try:
conn = urllib2.urlopen(url, data=request_data)
try:
return conn.read()
finally:
conn.close()
except IOError, e:
raise OmahaError('error talking to omaha: %s' % e)
def find_latest_release(hwid, appid, channel):
"""Returns the latest MP-signed Chrome OS release.
The current release version is obtained by pinging Omaha with a zero
current release version field.
@param hwid: the hwid attribute of the desired board
@param appid: the appid attribute of the application
@param channel: the channel from which an image is needed
@return The most recent release available for given combination of
arguments.
@raise OmahaError if an error occurred.
"""
if not (appid and hwid and channel):
raise OmahaError('missing arguments')
request_data = _OMAHA_UPDATE_CHECK_TEMPLATE % locals()
resp_data = omaha_request(request_data)
match = re.search('.*ChromeOSVersion="([0-9]+.[0-9]+.[0-9]+)" ', resp_data)
if not match:
raise OmahaError('cannot find release information in omaha response')
return match.group(1)