blob: 9dbf46ac2f822511a0db249bd50b2059c5abc702 [file] [log] [blame]
Simran Basi5ace6f22016-01-06 17:30:44 -08001# Copyright 2016 The Chromium Authors. All rights reserved.
2# Use of this source code is governed by a BSD-style license that can be
3# found in the LICENSE file.
4
Simran Basiaa467ad2016-02-03 16:56:22 -08005"""Utility functions for AFE-based interactions.
6
7NOTE: This module should only be used in the context of a running test. Any
8 utilities that require accessing the AFE, should do so by creating
9 their own instance of the AFE client and interact with it directly.
10"""
Simran Basi5ace6f22016-01-06 17:30:44 -080011
12import common
Dan Shi8190eb82016-02-11 17:15:58 -080013from autotest_lib.client.common_lib import error
Kevin Cheng84a71ba2016-07-14 11:03:57 -070014from autotest_lib.server.cros import provision
15from autotest_lib.server.cros.dynamic_suite import constants
Simran Basi5ace6f22016-01-06 17:30:44 -080016from autotest_lib.server.cros.dynamic_suite import frontend_wrappers
Dan Shi8190eb82016-02-11 17:15:58 -080017
Simran Basi5ace6f22016-01-06 17:30:44 -080018
19AFE = frontend_wrappers.RetryingAFE(timeout_min=5, delay_sec=10)
20
21
22def host_in_lab(host):
23 """Check if the host is in the lab and an object the AFE knows.
24
25 This check ensures that autoserv and the host's current job is running
26 inside a fully Autotest instance, aka a lab environment. If this is the
27 case it then verifies the host is registed with the configured AFE
28 instance.
29
30 @param host: Host object to verify.
31
32 @returns The host model object.
33 """
Simran Basiaa467ad2016-02-03 16:56:22 -080034 if not host.job or not host.job.in_lab:
Simran Basi5ace6f22016-01-06 17:30:44 -080035 return False
Kevin Cheng05ae2a42016-06-06 10:12:48 -070036 return host._afe_host
Simran Basi5ace6f22016-01-06 17:30:44 -080037
38
Kevin Cheng84a71ba2016-07-14 11:03:57 -070039def get_labels(host, prefix=None):
40 """Get labels of a host with name started with given prefix.
Simran Basi5ace6f22016-01-06 17:30:44 -080041
Kevin Cheng84a71ba2016-07-14 11:03:57 -070042 @param prefix: Prefix of label names, if None, return all labels.
43
44 @returns List of labels that match the prefix or if prefix is None, all
45 labels.
46 """
47 if not prefix:
48 return host._afe_host.labels
49
50 return [label for label in host._afe_host.labels
51 if label.startswith(prefix)]
52
53
54def get_build(host):
55 """Retrieve the current build for a given host stored inside host._afe_host.
56
57 Looks through a host's labels in host._afe_host.labels to determine
58 its build.
Simran Basi5ace6f22016-01-06 17:30:44 -080059
Dan Shib3b6db32016-02-03 14:54:05 -080060 @param host: Host object to get build.
Simran Basi5ace6f22016-01-06 17:30:44 -080061
62 @returns The current build or None if it could not find it or if there
63 were multiple build labels assigned to the host.
64 """
Kevin Cheng84a71ba2016-07-14 11:03:57 -070065 for label_prefix in [provision.CROS_VERSION_PREFIX,
66 provision.ANDROID_BUILD_VERSION_PREFIX,
67 provision.TESTBED_BUILD_VERSION_PREFIX]:
68 full_label_prefix = label_prefix + ':'
69 build_labels = get_labels(host, full_label_prefix)
70 if build_labels:
71 return build_labels[0][len(full_label_prefix):]
72 return None
73
74
75def get_boards(host):
76 """Retrieve all boards for a given host stored inside host._afe_host.
77
78 @param host: Host object to get board.
79
80 @returns List of all boards.
81 """
82 return [board[len(constants.BOARD_PREFIX):]
83 for board in get_labels(host, constants.BOARD_PREFIX)]
Simran Basi5ace6f22016-01-06 17:30:44 -080084
85
Simran Basibeb2bb22016-02-03 15:25:48 -080086def get_board(host):
Kevin Cheng84a71ba2016-07-14 11:03:57 -070087 """Retrieve the board for a given host stored inside host._afe_host.
Simran Basibeb2bb22016-02-03 15:25:48 -080088
89 @param host: Host object to get board.
90
91 @returns The current board or None if it could not find it.
92 """
Kevin Cheng84a71ba2016-07-14 11:03:57 -070093 boards = get_boards(host)
94 if not boards:
Simran Basibeb2bb22016-02-03 15:25:48 -080095 return None
Kevin Cheng84a71ba2016-07-14 11:03:57 -070096 return boards[0]
97
Simran Basibeb2bb22016-02-03 15:25:48 -080098
99
Simran Basi5ace6f22016-01-06 17:30:44 -0800100def clear_version_labels(host):
101 """Clear version labels for a given host.
102
103 @param host: Host whose version labels to clear.
104 """
105 if not host_in_lab(host):
106 return
107
108 host_list = [host.hostname]
109 labels = AFE.get_labels(
110 name__startswith=host.VERSION_PREFIX,
111 host__hostname=host.hostname)
112
113 for label in labels:
114 label.remove_hosts(hosts=host_list)
115
116
117def add_version_label(host, image_name):
118 """Add version labels to a host.
119
120 @param host: Host to add the version label for.
121 @param image_name: Name of the build version to add to the host.
122 """
123 if not host_in_lab(host):
124 return
125 label = '%s:%s' % (host.VERSION_PREFIX, image_name)
126 AFE.run('label_add_hosts', id=label, hosts=[host.hostname])
127
128
Simran Basibeb2bb22016-02-03 15:25:48 -0800129def get_stable_version(board, android=False):
130 """Retrieves a board's stable version from the AFE.
131
132 @param board: Board to lookup.
133 @param android: If True, indicates we are looking up a Android/Brillo-based
134 board. There is no default version that works for all
135 Android/Brillo boards. If False, we are looking up a Chrome
136 OS based board.
137
138 @returns Stable version of the given board.
139 """
140 return AFE.run('get_stable_version', board=board, android=android)
Dan Shi8190eb82016-02-11 17:15:58 -0800141
142
Dan Shie4256c82016-02-18 00:23:49 -0800143def lookup_job_repo_url(host):
Dan Shi8190eb82016-02-11 17:15:58 -0800144 """Looks up the job_repo_url for the host.
145
Dan Shie4256c82016-02-18 00:23:49 -0800146 The method is kept for backwards compatibility with test
147 autoupdate_EndToEndTest in existing builds. It should not be used for new
148 code.
149 TODO(dshi): Update autoupdate_EndToEndTest to use get_host_attribute after
150 lab is updated. After R50 is in stable channel, this method can be removed.
151
152 @param host: A Host object to lookup for job_repo_url.
153
154 @returns Host attribute `job_repo_url` of the given host.
155 """
156 return get_host_attribute(host, host.job_repo_url_attribute)
157
158
Kevin Cheng05ae2a42016-06-06 10:12:48 -0700159def get_host_attribute(host, attribute, use_local_value=True):
Dan Shie4256c82016-02-18 00:23:49 -0800160 """Looks up the value of host attribute for the host.
161
Dan Shibe3636a2016-02-14 22:48:01 -0800162 @param host: A Host object to lookup for attribute value.
163 @param attribute: Name of the host attribute.
Kevin Cheng05ae2a42016-06-06 10:12:48 -0700164 @param use_local_value: Boolean to indicate if the local value or AFE value
165 should be retrieved.
Dan Shi8190eb82016-02-11 17:15:58 -0800166
Dan Shibe3636a2016-02-14 22:48:01 -0800167 @returns value for the given attribute or None if not found.
Dan Shi8190eb82016-02-11 17:15:58 -0800168 """
Kevin Cheng05ae2a42016-06-06 10:12:48 -0700169 local_value = host._afe_host.attributes.get(attribute)
170 if not host_in_lab(host) or use_local_value:
Dan Shibe3636a2016-02-14 22:48:01 -0800171 return local_value
172
Dan Shi8190eb82016-02-11 17:15:58 -0800173 hosts = AFE.get_hosts(hostname=host.hostname)
Dan Shibe3636a2016-02-14 22:48:01 -0800174 if hosts and attribute in hosts[0].attributes:
175 return hosts[0].attributes[attribute]
Dan Shi8190eb82016-02-11 17:15:58 -0800176 else:
Dan Shibe3636a2016-02-14 22:48:01 -0800177 return local_value
Dan Shi8190eb82016-02-11 17:15:58 -0800178
179
Dan Shibe3636a2016-02-14 22:48:01 -0800180def clear_host_attributes_before_provision(host):
Dan Shie4256c82016-02-18 00:23:49 -0800181 """Clear host attributes before provision, e.g., job_repo_url.
Dan Shi8190eb82016-02-11 17:15:58 -0800182
Dan Shibe3636a2016-02-14 22:48:01 -0800183 @param host: A Host object to clear attributes before provision.
Dan Shi8190eb82016-02-11 17:15:58 -0800184 """
Dan Shibe3636a2016-02-14 22:48:01 -0800185 attributes = host.get_attributes_to_clear_before_provision()
186 for attribute in attributes:
Kevin Cheng05ae2a42016-06-06 10:12:48 -0700187 host._afe_host.attributes.pop(attribute, None)
Dan Shi8190eb82016-02-11 17:15:58 -0800188 if not host_in_lab(host):
189 return
Dan Shibe3636a2016-02-14 22:48:01 -0800190
191 for attribute in attributes:
192 update_host_attribute(host, attribute, None)
Dan Shi8190eb82016-02-11 17:15:58 -0800193
194
Dan Shibe3636a2016-02-14 22:48:01 -0800195def update_host_attribute(host, attribute, value):
196 """Updates the host attribute with given value.
Dan Shi8190eb82016-02-11 17:15:58 -0800197
Dan Shibe3636a2016-02-14 22:48:01 -0800198 @param host: A Host object to update attribute value.
199 @param attribute: Name of the host attribute.
200 @param value: Value for the host attribute.
Dan Shi8190eb82016-02-11 17:15:58 -0800201
Dan Shie4256c82016-02-18 00:23:49 -0800202 @raises AutoservError: If we failed to update the attribute.
Dan Shi8190eb82016-02-11 17:15:58 -0800203 """
Kevin Cheng05ae2a42016-06-06 10:12:48 -0700204 host._afe_host.attributes[attribute] = value
Dan Shi8190eb82016-02-11 17:15:58 -0800205 if not host_in_lab(host):
206 return
207
Dan Shibe3636a2016-02-14 22:48:01 -0800208 AFE.set_host_attribute(attribute, value, hostname=host.hostname)
Kevin Cheng05ae2a42016-06-06 10:12:48 -0700209 if get_host_attribute(host, attribute, use_local_value=False) != value:
Dan Shibe3636a2016-02-14 22:48:01 -0800210 raise error.AutoservError(
211 'Failed to update host attribute `%s` with %s, host %s' %
212 (attribute, value, host.hostname))
213
214
215def machine_install_and_update_labels(host, *args, **dargs):
216 """Calls machine_install and updates the version labels on a host.
217
218 @param host: Host object to run machine_install on.
219 @param *args: Args list to pass to machine_install.
220 @param **dargs: dargs dict to pass to machine_install.
221 """
222 clear_version_labels(host)
223 clear_host_attributes_before_provision(host)
224 image_name, host_attributes = host.machine_install(*args, **dargs)
225 add_version_label(host, image_name)
226 for attribute, value in host_attributes.items():
227 update_host_attribute(host, attribute, value)
Dan Shi6450e142016-03-11 11:52:20 -0800228
229
Kevin Cheng212880e2016-06-28 12:09:01 -0700230def get_os(host):
Kevin Cheng84a71ba2016-07-14 11:03:57 -0700231 """Retrieve the os for a given host stored inside host._afe_host.
Kevin Cheng212880e2016-06-28 12:09:01 -0700232
233 @param host: Host object to get board.
234
235 @returns The os or None if it could not find it.
236 """
Kevin Cheng84a71ba2016-07-14 11:03:57 -0700237 full_os_prefix = constants.OS_PREFIX + ':'
238 os_labels = get_labels(host, full_os_prefix)
239 if not os_labels:
Kevin Cheng212880e2016-06-28 12:09:01 -0700240 return None
Kevin Cheng84a71ba2016-07-14 11:03:57 -0700241 return os_labels[0][len(full_os_prefix):]