blob: 65c1d46355932a11de556e201117b742eb80c7fa [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
Simran Basi5ace6f22016-01-06 17:30:44 -080014from autotest_lib.server import utils
15from autotest_lib.server.cros.dynamic_suite import frontend_wrappers
Dan Shi8190eb82016-02-11 17:15:58 -080016
Simran Basi5ace6f22016-01-06 17:30:44 -080017
18AFE = frontend_wrappers.RetryingAFE(timeout_min=5, delay_sec=10)
19
20
21def host_in_lab(host):
22 """Check if the host is in the lab and an object the AFE knows.
23
24 This check ensures that autoserv and the host's current job is running
25 inside a fully Autotest instance, aka a lab environment. If this is the
26 case it then verifies the host is registed with the configured AFE
27 instance.
28
29 @param host: Host object to verify.
30
31 @returns The host model object.
32 """
Simran Basiaa467ad2016-02-03 16:56:22 -080033 if not host.job or not host.job.in_lab:
Simran Basi5ace6f22016-01-06 17:30:44 -080034 return False
35 return AFE.get_hosts(hostname=host.hostname)
36
37
38def get_build(host):
Dan Shib3b6db32016-02-03 14:54:05 -080039 """Retrieve the current build for a given host from the AFE.
Simran Basi5ace6f22016-01-06 17:30:44 -080040
41 Looks through a host's labels in the AFE to determine its build.
42
Dan Shib3b6db32016-02-03 14:54:05 -080043 @param host: Host object to get build.
Simran Basi5ace6f22016-01-06 17:30:44 -080044
45 @returns The current build or None if it could not find it or if there
46 were multiple build labels assigned to the host.
47 """
48 if not host_in_lab(host):
49 return None
50 return utils.get_build_from_afe(host.hostname, AFE)
51
52
Simran Basibeb2bb22016-02-03 15:25:48 -080053def get_board(host):
54 """Retrieve the board for a given host from the AFE.
55
56 Contacts the AFE to retrieve the board for a given host.
57
58 @param host: Host object to get board.
59
60 @returns The current board or None if it could not find it.
61 """
62 if not host_in_lab(host):
63 return None
64 return utils.get_board_from_afe(host.hostname, AFE)
65
66
Simran Basi5ace6f22016-01-06 17:30:44 -080067def clear_version_labels(host):
68 """Clear version labels for a given host.
69
70 @param host: Host whose version labels to clear.
71 """
72 if not host_in_lab(host):
73 return
74
75 host_list = [host.hostname]
76 labels = AFE.get_labels(
77 name__startswith=host.VERSION_PREFIX,
78 host__hostname=host.hostname)
79
80 for label in labels:
81 label.remove_hosts(hosts=host_list)
82
83
84def add_version_label(host, image_name):
85 """Add version labels to a host.
86
87 @param host: Host to add the version label for.
88 @param image_name: Name of the build version to add to the host.
89 """
90 if not host_in_lab(host):
91 return
92 label = '%s:%s' % (host.VERSION_PREFIX, image_name)
93 AFE.run('label_add_hosts', id=label, hosts=[host.hostname])
94
95
Simran Basibeb2bb22016-02-03 15:25:48 -080096def get_stable_version(board, android=False):
97 """Retrieves a board's stable version from the AFE.
98
99 @param board: Board to lookup.
100 @param android: If True, indicates we are looking up a Android/Brillo-based
101 board. There is no default version that works for all
102 Android/Brillo boards. If False, we are looking up a Chrome
103 OS based board.
104
105 @returns Stable version of the given board.
106 """
107 return AFE.run('get_stable_version', board=board, android=android)
Dan Shi8190eb82016-02-11 17:15:58 -0800108
109
Dan Shie4256c82016-02-18 00:23:49 -0800110def lookup_job_repo_url(host):
Dan Shi8190eb82016-02-11 17:15:58 -0800111 """Looks up the job_repo_url for the host.
112
Dan Shie4256c82016-02-18 00:23:49 -0800113 The method is kept for backwards compatibility with test
114 autoupdate_EndToEndTest in existing builds. It should not be used for new
115 code.
116 TODO(dshi): Update autoupdate_EndToEndTest to use get_host_attribute after
117 lab is updated. After R50 is in stable channel, this method can be removed.
118
119 @param host: A Host object to lookup for job_repo_url.
120
121 @returns Host attribute `job_repo_url` of the given host.
122 """
123 return get_host_attribute(host, host.job_repo_url_attribute)
124
125
126def get_host_attribute(host, attribute):
127 """Looks up the value of host attribute for the host.
128
Dan Shibe3636a2016-02-14 22:48:01 -0800129 @param host: A Host object to lookup for attribute value.
130 @param attribute: Name of the host attribute.
Dan Shi8190eb82016-02-11 17:15:58 -0800131
Dan Shibe3636a2016-02-14 22:48:01 -0800132 @returns value for the given attribute or None if not found.
Dan Shi8190eb82016-02-11 17:15:58 -0800133
Dan Shie4256c82016-02-18 00:23:49 -0800134 @raises KeyError if the host does not have the given attribute.
Dan Shi8190eb82016-02-11 17:15:58 -0800135 """
Dan Shibe3636a2016-02-14 22:48:01 -0800136 local_value = host.host_attributes.get(attribute)
137 if not host_in_lab(host):
138 return local_value
139
Dan Shi8190eb82016-02-11 17:15:58 -0800140 hosts = AFE.get_hosts(hostname=host.hostname)
Dan Shibe3636a2016-02-14 22:48:01 -0800141 if hosts and attribute in hosts[0].attributes:
142 return hosts[0].attributes[attribute]
Dan Shi8190eb82016-02-11 17:15:58 -0800143 else:
Dan Shibe3636a2016-02-14 22:48:01 -0800144 return local_value
Dan Shi8190eb82016-02-11 17:15:58 -0800145
146
Dan Shibe3636a2016-02-14 22:48:01 -0800147def clear_host_attributes_before_provision(host):
Dan Shie4256c82016-02-18 00:23:49 -0800148 """Clear host attributes before provision, e.g., job_repo_url.
Dan Shi8190eb82016-02-11 17:15:58 -0800149
Dan Shibe3636a2016-02-14 22:48:01 -0800150 @param host: A Host object to clear attributes before provision.
Dan Shi8190eb82016-02-11 17:15:58 -0800151 """
Dan Shibe3636a2016-02-14 22:48:01 -0800152 attributes = host.get_attributes_to_clear_before_provision()
153 for attribute in attributes:
154 if attribute in host.host_attributes:
155 del host.host_attributes[attribute]
Dan Shi8190eb82016-02-11 17:15:58 -0800156 if not host_in_lab(host):
157 return
Dan Shibe3636a2016-02-14 22:48:01 -0800158
159 for attribute in attributes:
160 update_host_attribute(host, attribute, None)
Dan Shi8190eb82016-02-11 17:15:58 -0800161
162
Dan Shibe3636a2016-02-14 22:48:01 -0800163def update_host_attribute(host, attribute, value):
164 """Updates the host attribute with given value.
Dan Shi8190eb82016-02-11 17:15:58 -0800165
Dan Shibe3636a2016-02-14 22:48:01 -0800166 @param host: A Host object to update attribute value.
167 @param attribute: Name of the host attribute.
168 @param value: Value for the host attribute.
Dan Shi8190eb82016-02-11 17:15:58 -0800169
Dan Shie4256c82016-02-18 00:23:49 -0800170 @raises AutoservError: If we failed to update the attribute.
Dan Shi8190eb82016-02-11 17:15:58 -0800171 """
Dan Shibe3636a2016-02-14 22:48:01 -0800172 host.host_attributes[attribute] = value
Dan Shi8190eb82016-02-11 17:15:58 -0800173 if not host_in_lab(host):
174 return
175
Dan Shibe3636a2016-02-14 22:48:01 -0800176 AFE.set_host_attribute(attribute, value, hostname=host.hostname)
177 if get_host_attribute(host, attribute) != value:
178 raise error.AutoservError(
179 'Failed to update host attribute `%s` with %s, host %s' %
180 (attribute, value, host.hostname))
181
182
183def machine_install_and_update_labels(host, *args, **dargs):
184 """Calls machine_install and updates the version labels on a host.
185
186 @param host: Host object to run machine_install on.
187 @param *args: Args list to pass to machine_install.
188 @param **dargs: dargs dict to pass to machine_install.
189 """
190 clear_version_labels(host)
191 clear_host_attributes_before_provision(host)
192 image_name, host_attributes = host.machine_install(*args, **dargs)
193 add_version_label(host, image_name)
194 for attribute, value in host_attributes.items():
195 update_host_attribute(host, attribute, value)