(1 of 2) Refactor and move Autotest downloader to the Dev Server.
Added two new Dev Server handlers:
1. Given GS url, download and install the build image.
2. Return the control file for a particular build.
BUG=chromium-os:22954
TEST=manual
Change-Id: Id3914a5ee429bea8c9b64fe74a21958459669a20
Reviewed-on: https://gerrit.chromium.org/gerrit/12802
Commit-Ready: Frank Farzan <frankf@chromium.org>
Reviewed-by: Frank Farzan <frankf@chromium.org>
Tested-by: Frank Farzan <frankf@chromium.org>
diff --git a/downloader.py b/downloader.py
new file mode 100755
index 0000000..dc7a07f
--- /dev/null
+++ b/downloader.py
@@ -0,0 +1,73 @@
+#!/usr/bin/python
+#
+# Copyright (c) 2011 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.
+
+import cherrypy
+import shutil
+import tempfile
+
+import devserver_util
+
+
+class Downloader(object):
+ """Download images to the devsever.
+
+ Given a URL to a build on the archive server:
+
+ - Determine if the build already exists.
+ - Download and extract the build to a staging directory.
+ - Package autotest tests.
+ - Install components to static dir.
+ """
+
+ def __init__(self, static_dir):
+ self._static_dir = static_dir
+
+ def Download(self, archive_url):
+ # Parse archive_url into board and build.
+ # e.g. gs://chromeos-image-archive/{board}/{build}
+ archive_url = archive_url.strip('/')
+ board, build = archive_url.rsplit('/', 2)[-2:]
+
+ # Bind build_dir and staging_dir here so we can tell if we need to do any
+ # cleanup after an exception occurs before build_dir is set.
+ build_dir = staging_dir = None
+ lock_tag = '/'.join([board, build])
+ try:
+ # Create Dev Server directory for this build and tell other Downloader
+ # instances we have processed this build.
+ try:
+ build_dir = devserver_util.AcquireLock(static_dir=self._static_dir,
+ tag=lock_tag)
+ except devserver_util.DevServerUtilError, e:
+ cherrypy.log('Refused lock "%s". Assuming build has already been'
+ 'processed: %s' % (lock_tag, str(e)), 'DOWNLOAD')
+ return 'Success'
+
+ cherrypy.log('Downloading build from %s' % archive_url, 'DOWNLOAD')
+ staging_dir = tempfile.mkdtemp(suffix=archive_url.replace('/', '_'))
+ devserver_util.DownloadBuildFromGS(
+ staging_dir=staging_dir, archive_url=archive_url, build=build)
+
+ cherrypy.log('Packaging autotest tests.', 'DOWNLOAD')
+ devserver_util.PrepareAutotestPkgs(staging_dir)
+
+ cherrypy.log('Installing build components.', 'DOWNLOAD')
+ devserver_util.InstallBuild(
+ staging_dir=staging_dir, build_dir=build_dir)
+ except Exception:
+ # Release processing lock, which will remove build components directory
+ # so future runs can retry.
+ if build_dir:
+ devserver_util.ReleaseLock(static_dir=self._static_dir, tag=lock_tag)
+ raise
+ finally:
+ # Always cleanup after ourselves.
+ if staging_dir:
+ cherrypy.log('Cleaning up staging directory %s' % staging_dir,
+ 'DOWNLOAD')
+ shutil.rmtree(staging_dir)
+
+ return 'Success'