blob: 1c3f80a917029def7d58f85a0101f6121b1ce132 [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
Gregory Nisbet7fe11c22019-11-22 11:06:06 -080013import logging
Gregory Nisbet8e2fbb22019-12-05 11:36:37 -080014import traceback
Sanika Kulkarni000fe8c2020-01-22 11:13:29 -080015import urlparse
16
xixuan5dc64ea2016-05-20 17:27:51 -070017from autotest_lib.client.common_lib import global_config
Kirtika Ruchandanifcc8aad2019-12-16 19:52:12 +000018from autotest_lib.server.cros import autoupdater
Rohit Makasanadf0a3a32017-06-30 13:55:18 -070019from autotest_lib.server.cros import provision
Simran Basi5ace6f22016-01-06 17:30:44 -080020from autotest_lib.server.cros.dynamic_suite import frontend_wrappers
Gregory Nisbet7fe11c22019-11-22 11:06:06 -080021from autotest_lib.site_utils import stable_version_classify as sv
Gregory Nisbet265a52c2019-12-10 20:38:42 -080022from autotest_lib.server import site_utils as server_utils
Sanika Kulkarni000fe8c2020-01-22 11:13:29 -080023from autotest_lib.server.cros.dynamic_suite import constants as ds_constants
24from autotest_lib.server.cros.dynamic_suite import tools
25
26from chromite.lib import auto_updater
27from chromite.lib import remote_access
Dan Shi8190eb82016-02-11 17:15:58 -080028
Simran Basi5ace6f22016-01-06 17:30:44 -080029
30AFE = frontend_wrappers.RetryingAFE(timeout_min=5, delay_sec=10)
Richard Barnette260cbd02016-10-06 12:23:28 -070031_CROS_VERSION_MAP = AFE.get_stable_version_map(AFE.CROS_IMAGE_TYPE)
Richard Barnettee50453e2016-10-10 16:43:44 -070032_FIRMWARE_VERSION_MAP = AFE.get_stable_version_map(AFE.FIRMWARE_IMAGE_TYPE)
Richard Barnette260cbd02016-10-06 12:23:28 -070033_FAFT_VERSION_MAP = AFE.get_stable_version_map(AFE.FAFT_IMAGE_TYPE)
Simran Basi5ace6f22016-01-06 17:30:44 -080034
xixuan5dc64ea2016-05-20 17:27:51 -070035_CONFIG = global_config.global_config
36ENABLE_DEVSERVER_TRIGGER_AUTO_UPDATE = _CONFIG.get_config_value(
37 'CROS', 'enable_devserver_trigger_auto_update', type=bool,
38 default=False)
39
Simran Basi5ace6f22016-01-06 17:30:44 -080040
Richard Barnette260cbd02016-10-06 12:23:28 -070041def _host_in_lab(host):
Simran Basi5ace6f22016-01-06 17:30:44 -080042 """Check if the host is in the lab and an object the AFE knows.
43
44 This check ensures that autoserv and the host's current job is running
45 inside a fully Autotest instance, aka a lab environment. If this is the
46 case it then verifies the host is registed with the configured AFE
47 instance.
48
49 @param host: Host object to verify.
50
51 @returns The host model object.
52 """
Simran Basiaa467ad2016-02-03 16:56:22 -080053 if not host.job or not host.job.in_lab:
Simran Basi5ace6f22016-01-06 17:30:44 -080054 return False
Kevin Cheng05ae2a42016-06-06 10:12:48 -070055 return host._afe_host
Simran Basi5ace6f22016-01-06 17:30:44 -080056
57
Gregory Nisbet265a52c2019-12-10 20:38:42 -080058def _log_image_name(image_name):
59 try:
60 logging.debug("_log_image_name: image (%s)", image_name)
61 server_utils.ParseBuildName(name=image_name)
62 except Exception:
63 logging.error(traceback.format_exc())
64
65
66def _format_image_name(board, version):
67 return "%s-release/%s" % (board, version)
68
69
Gregory Nisbet7fe11c22019-11-22 11:06:06 -080070def get_stable_cros_image_name_v2(info, _config_override=None):
71 if sv.classify_board(info.board, _config_override=_config_override) == sv.FROM_HOST_CONFIG:
72 logging.debug("get_stable_cros_image_name_v2: board %s from host_info_store" % info.board)
Gregory Nisbet265a52c2019-12-10 20:38:42 -080073 out = _format_image_name(board=info.board, version=info.cros_stable_version)
74 _log_image_name(out)
75 return out
Gregory Nisbet7fe11c22019-11-22 11:06:06 -080076 logging.debug("get_stable_cros_image_name_v2: board %s from autotest frontend" % info.board)
Gregory Nisbet9b9c7612019-11-26 09:50:53 -080077 return get_stable_cros_image_name(info.board)
Gregory Nisbet7fe11c22019-11-22 11:06:06 -080078
79
Gregory Nisbet8e2fbb22019-12-05 11:36:37 -080080def get_stable_servo_cros_image_name_v2(servo_version_from_hi, board, _config_override=None):
81 """
82 @param servo_version_from_hi (string or None) : the stable version image name taken from the host info store.
83 A value of None means that that the host_info_store does not exist or
84 ultimately not contain a servo_stable_version field.
85 @param board (string) : the board of the labstation or servo v3 that we're getting the stable version of
86 """
87 logging.debug("get_stable_servo_cros_image_name_v2: servo_version_from_hi (%s) board (%s)" % (servo_version_from_hi, board))
88 if sv.classify_board(board, _config_override=_config_override) != sv.FROM_HOST_CONFIG:
89 logging.debug("get_stable_servo_cros_image_name_v2: servo version for board (%s) from afe" % board)
90 return get_stable_cros_image_name(board)
91 if servo_version_from_hi is not None:
92 logging.debug("get_stable_servo_cros_image_name_v2: servo version (%s) from host_info_store" % servo_version_from_hi)
Gregory Nisbet265a52c2019-12-10 20:38:42 -080093 out = _format_image_name(board=board, version=servo_version_from_hi)
94 _log_image_name(out)
95 return out
Gregory Nisbet8e2fbb22019-12-05 11:36:37 -080096 logging.debug("get_stable_servo_cros_image_name_v2: no servo version provided. board is (%s)" % board)
97 logging.debug("get_stable_servo_cros_image_name_v2: falling back to afe if possible")
98 out = None
99 # get_stable_cros_image_name uses the AFE as the source of truth.
100 try:
101 out = get_stable_cros_image_name(board)
102 except Exception:
103 logging.error("get_stable_servo_cros_image_name_v2: error falling back to AFE (%s)" % traceback.format_exc())
104 return out
105
106
Richard Barnette383ef9c2016-12-13 11:56:49 -0800107def get_stable_cros_image_name(board):
108 """Retrieve the Chrome OS stable image name for a given board.
Simran Basibeb2bb22016-02-03 15:25:48 -0800109
110 @param board: Board to lookup.
Simran Basibeb2bb22016-02-03 15:25:48 -0800111
Richard Barnette383ef9c2016-12-13 11:56:49 -0800112 @returns Name of a Chrome OS image to be installed in order to
Richard Barnette260cbd02016-10-06 12:23:28 -0700113 repair the given board.
Simran Basibeb2bb22016-02-03 15:25:48 -0800114 """
Richard Barnette383ef9c2016-12-13 11:56:49 -0800115 return _CROS_VERSION_MAP.get_image_name(board)
Richard Barnette260cbd02016-10-06 12:23:28 -0700116
117
Gregory Nisbet7fe11c22019-11-22 11:06:06 -0800118def get_stable_firmware_version_v2(info, _config_override=None):
119 if sv.classify_model(info.model, _config_override=_config_override) == sv.FROM_HOST_CONFIG:
120 logging.debug("get_stable_firmware_version_v2: model %s from host_info_store" % info.model)
121 return info.firmware_stable_version
122 logging.debug("get_stable_cros_image_name_v2: model %s from autotest frontend" % info.model)
Gregory Nisbet9b9c7612019-11-26 09:50:53 -0800123 return get_stable_firmware_version(info.model)
Gregory Nisbet7fe11c22019-11-22 11:06:06 -0800124
125
Ningning Xia05af7402018-02-13 18:19:10 -0800126def get_stable_firmware_version(model):
127 """Retrieve the stable firmware version for a given model.
Richard Barnettee50453e2016-10-10 16:43:44 -0700128
Ningning Xia05af7402018-02-13 18:19:10 -0800129 @param model: Model to lookup.
Richard Barnettee50453e2016-10-10 16:43:44 -0700130
131 @returns A version of firmware to be installed via
132 `chromeos-firmwareupdate` from a repair build.
133 """
Ningning Xia05af7402018-02-13 18:19:10 -0800134 return _FIRMWARE_VERSION_MAP.get_version(model)
Richard Barnettee50453e2016-10-10 16:43:44 -0700135
136
Gregory Nisbet7fe11c22019-11-22 11:06:06 -0800137def get_stable_faft_version_v2(info, _config_override=None):
138 if sv.classify_board(info.board, _config_override=_config_override) == sv.FROM_HOST_CONFIG:
139 logging.debug("get_stable_faft_version_v2: model %s from host_info_store" % info.model)
140 return info.faft_stable_version
141 logging.debug("get_stable_faft_version_v2: model %s from autotest frontend" % info.model)
142 return get_stable_faft_version(info.board)
143
144
Richard Barnette260cbd02016-10-06 12:23:28 -0700145def get_stable_faft_version(board):
146 """Retrieve the stable firmware version for FAFT DUTs.
147
148 @param board: Board to lookup.
149
150 @returns A version of firmware to be installed in order to
151 repair firmware on a DUT used for FAFT testing.
152 """
153 return _FAFT_VERSION_MAP.get_version(board)
154
155
Xixuan Wuf9e11612019-10-15 12:32:47 -0700156def clean_provision_labels(host):
157 """Clean provision-related labels.
Dan Shi8190eb82016-02-11 17:15:58 -0800158
Xixuan Wuf9e11612019-10-15 12:32:47 -0700159 @param host: Host object.
Dan Shi8190eb82016-02-11 17:15:58 -0800160 """
Xixuan Wuf9e11612019-10-15 12:32:47 -0700161 info = host.host_info_store.get()
162 info.clear_version_labels()
Dan Shibe3636a2016-02-14 22:48:01 -0800163 attributes = host.get_attributes_to_clear_before_provision()
Prathmesh Prabhu368abdf2017-02-14 11:23:47 -0800164 for key in attributes:
Xixuan Wuf9e11612019-10-15 12:32:47 -0700165 info.attributes.pop(key, None)
166
167 host.host_info_store.commit(info)
168
169
170def add_provision_labels(host, version_prefix, image_name,
171 provision_attributes={}):
172 """Add provision labels for host.
173
174 @param host: Host object.
175 @param version_prefix: a string version prefix, e.g. "cros-version:"
176 @param image_name: a string image name, e.g. peppy-release/R70-11011.0.0.
177 @param provision_attributes: a map, including attributes for provisioning,
178 e.g. {"job_repo_url": "http://..."}
179 """
180 info = host.host_info_store.get()
181 info.attributes.update(provision_attributes)
182 info.set_version_label(version_prefix, image_name)
183 host.host_info_store.commit(info)
Dan Shi8190eb82016-02-11 17:15:58 -0800184
185
Richard Barnette60e759e2018-07-21 20:56:59 -0700186def machine_install_and_update_labels(host, update_url,
187 use_quick_provision=False,
Sanika Kulkarni000fe8c2020-01-22 11:13:29 -0800188 with_cheets=False, staging_server=None):
Richard Barnette044927e2018-07-21 20:50:39 -0700189 """Install a build and update the version labels on a host.
Dan Shibe3636a2016-02-14 22:48:01 -0800190
Richard Barnette044927e2018-07-21 20:50:39 -0700191 @param host: Host object where the build is to be installed.
Richard Barnette71013222018-05-05 19:00:45 +0000192 @param update_url: URL of the build to install.
Richard Barnette60e759e2018-07-21 20:56:59 -0700193 @param use_quick_provision: If true, then attempt to use
194 quick-provision for the update.
Richard Barnette71013222018-05-05 19:00:45 +0000195 @param with_cheets: If true, installation is for a specific, custom
196 version of Android for a target running ARC.
Sanika Kulkarni000fe8c2020-01-22 11:13:29 -0800197 @param staging_server: Sever where images have been staged. Typically,
198 an instance of dev_server.ImageServer.
Dan Shibe3636a2016-02-14 22:48:01 -0800199 """
Xixuan Wuf9e11612019-10-15 12:32:47 -0700200 clean_provision_labels(host)
Sanika Kulkarni000fe8c2020-01-22 11:13:29 -0800201 # TODO(crbug.com/1049346): The try-except block exists to catch failures in
202 # chromite auto_updater that may occur due to autotest/chromite version
203 # mismatch. This should be removed once that bug is resolved.
204 try:
205 # Get image_name in the format <board>-release/Rxx-12345.0.0 from the
206 # update_url.
207 image_name = '/'.join(urlparse.urlparse(update_url).path.split('/')[-2:])
208 with remote_access.ChromiumOSDeviceHandler(host.ip) as device:
209 updater = auto_updater.ChromiumOSUpdater(
210 device, build_name=None, payload_dir=image_name,
211 staging_server=staging_server.url())
212 updater.CheckPayloads()
213 updater.PreparePayloadPropsFile()
214 updater.RunUpdate()
215 repo_url = tools.get_package_url(staging_server.url(), image_name)
216 host_attributes = {ds_constants.JOB_REPO_URL: repo_url}
217 except Exception as e:
218 logging.warning(
219 "Chromite auto_updater has failed with the exception: %s", e)
220 logging.debug("Attempting to provision with quick provision.")
221 updater = autoupdater.ChromiumOSUpdater(
Qijiang Fan31e08062020-01-16 17:48:10 +0000222 update_url, host=host, use_quick_provision=use_quick_provision)
Sanika Kulkarni000fe8c2020-01-22 11:13:29 -0800223 image_name, host_attributes = updater.run_update()
Richard Barnette71013222018-05-05 19:00:45 +0000224 if with_cheets:
Rohit Makasanadf0a3a32017-06-30 13:55:18 -0700225 image_name += provision.CHEETS_SUFFIX
Sanika Kulkarni000fe8c2020-01-22 11:13:29 -0800226 add_provision_labels(host, host.VERSION_PREFIX, image_name,
227 host_attributes)