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

Unified Diff: chromite/lib/binpkg.py

Issue 4969003: Update cbuildbot.py to upload prebuilts from preflight buildbot. (Closed) Base URL: ssh://git@gitrw.chromium.org:9222/crosutils.git@master
Patch Set: Add lots more unit tests. 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 side-by-side diff with in-line comments
Download patch
Index: chromite/lib/binpkg.py
diff --git a/chromite/lib/binpkg.py b/chromite/lib/binpkg.py
new file mode 100644
index 0000000000000000000000000000000000000000..31febfdcc25ffe6d48e4b4cad7fa64c5ff741f22
--- /dev/null
+++ b/chromite/lib/binpkg.py
@@ -0,0 +1,153 @@
+# Copyright (c) 2010 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.
+#
+# Adapted from portage/getbinpkg.py -- Portage binary-package helper functions
+# Copyright 2003-2004 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+
+import operator
+import os
+import time
+import urllib2
+
+class PackageIndex(object):
dianders 2010/11/23 21:47:39 Docstring? ...would be nice to include a spec for
davidjames 2010/11/23 22:53:14 Thanks for all the feedback! Will address your fee
davidjames 2010/11/29 21:18:55 Done. (See http://codereview.chromium.org/5344002/
+
+ def __init__(self):
+ """Constructor."""
dianders 2010/11/23 21:47:39 All of these members are public? Can you document
davidjames 2010/11/29 21:18:55 Done.
+ self.header = {}
+ self.packages = []
+ self.modified = False
+
+ def _ReadPkgIndex(self, pkgfile):
+ """Read entry from packages file.
dianders 2010/11/23 21:47:39 Read entries (plural).
davidjames 2010/11/29 21:18:55 Done.
+
dianders 2010/11/23 21:47:39 Docstring: This will read entries that look like
davidjames 2010/11/29 21:18:55 Done.
+ Args:
+ pkgfile: A python file object.
dianders 2010/11/23 21:47:39 Returns: ?
davidjames 2010/11/29 21:18:55 Done.
+ """
+ d = {}
+ for line in pkgfile:
+ line = line.rstrip('\n')
+ if not line:
+ break
+ line = line.split(': ', 1)
+ if len(line) == 2:
+ k, v = line
+ d[k] = v
+ return d
+
+ def _WritePkgIndex(self, pkgfile, items):
+ """Write entry to packages file.
+
dianders 2010/11/23 21:47:39 This will terminate the list of items with a blank
davidjames 2010/11/29 21:18:55 Done.
+ Args:
+ pkgfile: A python file object.
+ items: A list of tuples containing the entries to write.
dianders 2010/11/23 21:47:39 ...containing (key, value) pairs to write.
davidjames 2010/11/29 21:18:55 Done.
+ """
+ for k, v in items:
dianders 2010/11/23 21:47:39 assert ':' not in k
davidjames 2010/11/29 21:18:55 Skipped this one.
+ pkgfile.write('%s: %s\n' % (k, v))
+ pkgfile.write('\n')
+
+ def Read(self, pkgfile):
+ """Read entire packages file.
+
dianders 2010/11/23 21:47:39 This is a shortcut for calling ReadHeader() and Re
davidjames 2010/11/29 21:18:55 Made those two functions private.
+ Args:
+ pkgfile: A python file object.
+ """
+ self.ReadHeader(pkgfile)
+ self.ReadBody(pkgfile)
+
+ def ReadHeader(self, pkgfile):
+ """Read header of packages file.
+
+ Args:
+ pkgfile: A python file object.
+ """
+ self.header.update(self._ReadPkgIndex(pkgfile))
+
+ def ReadBody(self, pkgfile):
+ """Read body of packages file.
+
+ Args:
+ pkgfile: A python file object.
dianders 2010/11/23 21:47:39 The header and the blank line following the header
+ """
dianders 2010/11/23 21:47:39 Comment: Read all the sections in the body by loop
+ while True:
+ d = self._ReadPkgIndex(pkgfile)
+ if not d:
+ break
dianders 2010/11/23 21:47:39 In order to be a valid body section, there must be
+ if d.get('CPV'):
dianders 2010/11/23 21:47:39 if 'CPV' in d:
+ self.packages.append(d)
+
+ def Write(self, pkgfile):
+ """Write a packages file to disk.
+
dianders 2010/11/23 21:47:39 Document: This has a side effect of updating the T
davidjames 2010/11/23 22:53:14 That'd be a better name, but Portage calls the var
+ Args:
+ pkgfile: A python file object.
+ """
+ if self.modified:
+ self.header['TIMESTAMP'] = str(long(time.time()))
+ self.header['PACKAGES'] = str(len(self.packages))
dianders 2010/11/23 21:47:39 Should we be clearing .modified?
+ keys = list(self.header)
+ keys.sort()
+ self._WritePkgIndex(pkgfile, [(k, self.header[k]) \
+ for k in keys if self.header[k]])
dianders 2010/11/23 21:47:39 AKA: self._WritePkgIndex(pkgfile, sorted((k, v) f
+ for metadata in sorted(self.packages, key=operator.itemgetter('CPV')):
dianders 2010/11/23 21:47:39 Comment: Will write each item in self.packages (is
+ cpv = metadata['CPV']
+ keys = list(metadata)
+ keys.sort()
+ self._WritePkgIndex(pkgfile,
+ [(k, metadata[k]) for k in keys if metadata[k]])
+
+
+def GrabRemotePackageIndex(binhost_url):
dianders 2010/11/23 21:47:39 Technically, this could be a class method on Packa
+ """Grab the latest binary package database from the specified URL.
+
+ Args:
+ binhost_url: Base URL of remote packages (PORTAGE_BINHOST).
+
+ Returns:
+ A PackageIndex object
dianders 2010/11/23 21:47:39 COmment: Might return None in certain error condit
+ """
+
+ def _RetryUrlOpen(url, tries=3):
dianders 2010/11/23 21:47:39 Why does this need to be an encapsulated function?
+ """Open the specified url, retrying if we run into temporary errors.
+
+ We retry for both network errors and 5xx Server Errors. We do not retry
+ for HTTP errors with a non-5xx code.
dianders 2010/11/23 21:47:39 Does this timeout, or can it ever get stuck foreve
dianders 2010/11/23 21:47:39 Comment: We will sleep for 10 seconds before retry
+
+ Args:
+ url: The specified url.
+ tries: The number of times to try.
+
+ Returns:
+ The result of urllib2.urlopen(url).
dianders 2010/11/23 21:47:39 This is a file-like object.
+ """
+ for i in range(tries):
+ try:
+ return urllib2.urlopen(url)
+ except urllib2.HTTPError as e:
+ if i + 1 >= tries or e.code < 500:
+ raise
+ else:
+ print 'Cannot GET %s: %s' % (url, str(e))
+ except urllib2.URLError as e:
+ if i + 1 >= tries:
+ raise
+ else:
+ print 'Cannot GET %s: %s' % (url, str(e))
+ print "Sleeping for 10 seconds before retrying..."
+ time.sleep(10)
+
+ url = os.path.join(binhost_url, 'Packages')
dianders 2010/11/23 21:47:39 No, not os.path.join. This will fail on windows o
+ try:
+ f = _RetryUrlOpen(url)
+ except urllib2.HTTPError as e:
+ if e.code == 404:
+ return None
+ raise
+
+ pkgindex = PackageIndex()
+ pkgindex.Read(f)
+ f.close()
+ return pkgindex
+
+

Powered by Google App Engine
This is Rietveld 408576698