blob: 0d1d28e6cf6ca8ee5728c7432cddc3ec6b0e2c42 [file] [log] [blame]
Chris Masone8abb6fc2012-01-31 09:27:36 -08001# Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
Dale Curtis386eea72011-09-21 18:43:04 -07002# Use of this source code is governed by a BSD-style license that can be
3# found in the LICENSE file.
4
Chris Masone8abb6fc2012-01-31 09:27:36 -08005import logging
Eric Lia11a0452010-01-07 22:01:58 -08006import os
Chris Sosa3ee5d5c2012-02-23 11:18:41 -08007from autotest_lib.client.common_lib import error, global_config
Chris Masone8abb6fc2012-01-31 09:27:36 -08008from autotest_lib.server import installable_object, autoserv_parser
Eric Li2eb800f2011-04-21 16:52:58 -07009
10
11config = global_config.global_config
12parser = autoserv_parser.autoserv_parser
13
Eric Lia11a0452010-01-07 22:01:58 -080014
15class SiteAutotest(installable_object.InstallableObject):
16
Chris Sosa3ee5d5c2012-02-23 11:18:41 -080017 def get(self, location=None):
Eric Lia11a0452010-01-07 22:01:58 -080018 if not location:
19 location = os.path.join(self.serverdir, '../client')
20 location = os.path.abspath(location)
21 installable_object.InstallableObject.get(self, location)
22 self.got = True
23
Eric Lic7444bd2011-02-15 17:12:10 -080024
Chris Masone8abb6fc2012-01-31 09:27:36 -080025 def _get_fetch_location_from_host_attribute(self):
26 """Get repo to use for packages from host attribute, if possible.
27
28 Hosts are tagged with an attribute containing the URL
29 from which to source packages when running a test on that host.
30 If self.host is set, attempt to look this attribute up by calling out
31 to the AFE.
32
33 @returns value of the 'job_repo_url' host attribute, if present.
34 """
35 try:
36 from autotest_lib.server import frontend
37 if self.host:
38 afe = frontend.AFE(debug=False)
39 hosts = afe.get_hosts(hostname=self.host.hostname)
40 if 'job_repo_url' in hosts[0].attributes:
41 return hosts[0].attributes['job_repo_url']
Chris Masone2e204982012-02-13 13:26:13 -080042 logging.warning("No job_repo_url for %s", self.host)
Chris Masone8abb6fc2012-01-31 09:27:36 -080043 except ImportError:
Chris Masone2e204982012-02-13 13:26:13 -080044 logging.warning('Not attempting to look for job_repo_url')
Chris Masone8abb6fc2012-01-31 09:27:36 -080045 pass
46 return None
47
48
Eric Li2eb800f2011-04-21 16:52:58 -070049 def get_fetch_location(self):
Chris Masone8abb6fc2012-01-31 09:27:36 -080050 """Generate list of locations where autotest can look for packages.
51
52 Old n' busted: Autotest packages are always stored at a URL that can
53 be derived from the one passed via the voodoo magic --image argument.
54 New hotness: Hosts are tagged with an attribute containing the URL
55 from which to source packages when running a test on that host.
56
57 @returns the list of candidate locations to check for packages.
58 """
Dale Curtis386eea72011-09-21 18:43:04 -070059 repos = super(SiteAutotest, self).get_fetch_location()
Chris Masone8abb6fc2012-01-31 09:27:36 -080060
Dale Curtis386eea72011-09-21 18:43:04 -070061 if parser.options.image:
Chris Masonebe78eb02012-02-23 14:28:19 -080062 # The old way.
Dale Curtis386eea72011-09-21 18:43:04 -070063 # Add our new repo to the end, the package manager will later
64 # reverse the list of repositories resulting in ours being first.
65 repos.append(parser.options.image.replace(
66 'update', 'static/archive').rstrip('/') + '/autotest')
Chris Masonebe78eb02012-02-23 14:28:19 -080067 else:
68 # The new way.
69 found_repo = self._get_fetch_location_from_host_attribute()
70 if found_repo is not None:
71 # Add our new repo to the end, the package manager will
72 # later reverse the list of repositories resulting in ours
73 # being first
74 repos.append(found_repo)
Eric Li2eb800f2011-04-21 16:52:58 -070075
Dale Curtis386eea72011-09-21 18:43:04 -070076 return repos
Eric Li2eb800f2011-04-21 16:52:58 -070077
78
Chris Masone8abb6fc2012-01-31 09:27:36 -080079 def install(self, host=None, autodir=None):
80 """Install autotest. If |host| is not None, stores it in |self.host|.
81
82 @param host A Host instance on which autotest will be installed
83 @param autodir Location on the remote host to install to
84 """
85 if host:
86 self.host = host
87
88 super(SiteAutotest, self).install(host=host, autodir=autodir)
89
90
Chris Sosa3ee5d5c2012-02-23 11:18:41 -080091class SiteClientLogger(object):
92 """Overrides default client logger to allow for using a local package cache.
93 """
94
95 def _process_line(self, line):
96 """Returns the package checksum file if it exists."""
97 logging.debug(line)
98 fetch_package_match = self.fetch_package_parser.search(line)
99 if fetch_package_match:
100 pkg_name, dest_path, fifo_path = fetch_package_match.groups()
101 serve_packages = global_config.global_config.get_config_value(
102 "PACKAGES", "serve_packages_from_autoserv", type=bool)
103 if serve_packages and pkg_name == 'packages.checksum':
104 package_served = False
105 try:
106 checksum_file = os.path.join(
107 self.job.pkgmgr.pkgmgr_dir, 'packages', pkg_name)
108 if os.path.exists(checksum_file):
109 self.host.send_file(checksum_file, dest_path)
110 package_served = True
111 except error.AutoservRunError:
112 msg = "Package checksum file not found, continuing anyway"
113 logging.exception(msg)
114
115 if package_served:
116 try:
117 # When fetching a package, the client expects to be
118 # notified when the fetching is complete. Autotest
119 # does this pushing a B to a fifo queue to the client.
120 self.host.run("echo B > %s" % fifo_path)
121 except error.AutoservRunError:
122 msg = "Checksum installation failed, continuing anyway"
123 logging.exception(msg)
124 finally:
125 return
126
127 # Fall through to process the line using the default method.
128 super(SiteClientLogger, self)._process_line(line)
129
130
131 def _send_tarball(self, pkg_name, remote_dest):
132 """Uses tarballs in package manager by default."""
133 try:
134 server_package = os.path.join(self.job.pkgmgr.pkgmgr_dir,
135 'packages', pkg_name)
136 if os.path.exists(server_package):
137 self.host.send_file(server_package, remote_dest)
138 return
139
140 except error.AutoservRunError:
141 msg = ("Package %s could not be sent from the package cache." %
142 pkg_name)
143 logging.exception(msg)
144
145 # Fall through to send tarball the default method.
146 super(SiteClientLogger, self)._send_tarball(pkg_name, remote_dest)
147
148
Eric Lic7444bd2011-02-15 17:12:10 -0800149class _SiteRun(object):
150 pass