blob: a775250c6579978ee8c488f83c63b63cb13b39f1 [file] [log] [blame]
Frank Farzan37761d12011-12-01 14:29:08 -08001#!/usr/bin/python
2#
Scott Zawalski51ccf9e2012-03-28 08:16:01 -07003# Copyright (c) 2011 The Chromium OS Authors. All rights reserved.
Frank Farzan37761d12011-12-01 14:29:08 -08004# Use of this source code is governed by a BSD-style license that can be
5# found in the LICENSE file.
6
7import cherrypy
8import shutil
9import tempfile
10
11import devserver_util
12
13
14class Downloader(object):
15 """Download images to the devsever.
16
17 Given a URL to a build on the archive server:
18
19 - Determine if the build already exists.
20 - Download and extract the build to a staging directory.
21 - Package autotest tests.
22 - Install components to static dir.
23 """
24
25 def __init__(self, static_dir):
26 self._static_dir = static_dir
27
Scott Zawalski51ccf9e2012-03-28 08:16:01 -070028 def Download(self, archive_url):
Frank Farzan37761d12011-12-01 14:29:08 -080029 # Parse archive_url into board and build.
30 # e.g. gs://chromeos-image-archive/{board}/{build}
Scott Zawalski51ccf9e2012-03-28 08:16:01 -070031 archive_url = archive_url.strip('/')
32 board, build = archive_url.rsplit('/', 2)[-2:]
Frank Farzan37761d12011-12-01 14:29:08 -080033
34 # Bind build_dir and staging_dir here so we can tell if we need to do any
35 # cleanup after an exception occurs before build_dir is set.
Scott Zawalski51ccf9e2012-03-28 08:16:01 -070036 build_dir = staging_dir = None
37 lock_tag = '/'.join([board, build])
Frank Farzan37761d12011-12-01 14:29:08 -080038 try:
39 # Create Dev Server directory for this build and tell other Downloader
40 # instances we have processed this build.
41 try:
Scott Zawalski51ccf9e2012-03-28 08:16:01 -070042 build_dir = devserver_util.AcquireLock(static_dir=self._static_dir,
43 tag=lock_tag)
Frank Farzan37761d12011-12-01 14:29:08 -080044 except devserver_util.DevServerUtilError, e:
45 cherrypy.log('Refused lock "%s". Assuming build has already been'
Scott Zawalski51ccf9e2012-03-28 08:16:01 -070046 'processed: %s' % (lock_tag, str(e)), 'DOWNLOAD')
Frank Farzan37761d12011-12-01 14:29:08 -080047 return 'Success'
48
Scott Zawalski51ccf9e2012-03-28 08:16:01 -070049 cherrypy.log('Downloading build from %s' % archive_url, 'DOWNLOAD')
50 staging_dir = tempfile.mkdtemp(suffix='_'.join([board, build]))
51 devserver_util.DownloadBuildFromGS(
52 staging_dir=staging_dir, archive_url=archive_url, build=build)
Frank Farzan37761d12011-12-01 14:29:08 -080053
Scott Zawalski51ccf9e2012-03-28 08:16:01 -070054 cherrypy.log('Packaging autotest tests.', 'DOWNLOAD')
55 devserver_util.PrepareAutotestPkgs(staging_dir)
Frank Farzan37761d12011-12-01 14:29:08 -080056
Scott Zawalski51ccf9e2012-03-28 08:16:01 -070057 cherrypy.log('Installing build components.', 'DOWNLOAD')
58 devserver_util.InstallBuild(
59 staging_dir=staging_dir, build_dir=build_dir)
60 except Exception:
Frank Farzan37761d12011-12-01 14:29:08 -080061 # Release processing lock, which will remove build components directory
62 # so future runs can retry.
Scott Zawalski51ccf9e2012-03-28 08:16:01 -070063 if build_dir:
64 devserver_util.ReleaseLock(static_dir=self._static_dir, tag=lock_tag)
Frank Farzan37761d12011-12-01 14:29:08 -080065 raise
Scott Zawalski51ccf9e2012-03-28 08:16:01 -070066 finally:
67 # Always cleanup after ourselves.
68 if staging_dir:
69 cherrypy.log('Cleaning up staging directory %s' % staging_dir,
70 'DOWNLOAD')
71 shutil.rmtree(staging_dir)
Frank Farzan37761d12011-12-01 14:29:08 -080072
73 return 'Success'