provision_AutoUpdate.py revision 9a02729492e28168aebec0cc18c6a581e1c45717
1# Copyright (c) 2013 The Chromium OS 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 5import logging 6 7from autotest_lib.client.common_lib import error 8from autotest_lib.client.common_lib import global_config 9from autotest_lib.client.common_lib.cros import dev_server 10from autotest_lib.server import test 11from autotest_lib.server.cros import provision 12 13 14_CONFIG = global_config.global_config 15# pylint: disable-msg=E1120 16_IMAGE_URL_PATTERN = _CONFIG.get_config_value( 17 'CROS', 'image_url_pattern', type=str) 18 19 20class provision_AutoUpdate(test.test): 21 """A test that can provision a machine to the correct ChromeOS version.""" 22 version = 1 23 24 def run_once(self, host, value): 25 """The method called by the control file to start the test. 26 27 @param host: The host object to update to |value|. 28 @param value: The build type and version to install on the host. 29 30 """ 31 image = value 32 33 # If the host is already on the correct build, we have nothing to do. 34 # Note that this means we're not doing any sort of stateful-only 35 # update, and that we're relying more on cleanup to do cleanup. 36 # We could just not pass |force_update=True| to |machine_install|, 37 # but I'd like the semantics that a provision test 'returns' TestNA 38 # if the machine is already properly provisioned. 39 if host.get_build() == value: 40 # We can't raise a TestNA, as would make sense, as that makes 41 # job.run_test return False as if the job failed. However, it'd 42 # still be nice to get this into the status.log, so we manually 43 # emit an INFO line instead. 44 self.job.record('INFO', None, None, 45 'Host already running %s' % value) 46 return 47 48 # We're about to reimage a machine, so we need full_payload and 49 # stateful. If something happened where the devserver doesn't have one 50 # of these, then it's also likely that it'll be missing autotest. 51 # Therefore, we require the devserver to also have autotest staged, so 52 # that the test that runs after this provision finishes doesn't error 53 # out because the devserver that its job_repo_url is set to is missing 54 # autotest test code. 55 # TODO(milleral): http://crbug.com/249426 56 # Add an asynchronous staging call so that we can ask the devserver to 57 # fetch autotest in the background here, and then wait on it after 58 # reimaging finishes or at some other point in the provisioning. 59 try: 60 ds = dev_server.ImageServer.resolve(image) 61 ds.stage_artifacts(image, ['full_payload', 'stateful', 'autotest']) 62 except dev_server.DevServerException as e: 63 raise error.TestFail(str(e)) 64 65 url = _IMAGE_URL_PATTERN % (ds.url(), image) 66 67 # Installing a build on a host assumes that a label of 68 # 'cros-version:<build>' has already been created, so we need to make 69 # sure that one exists. 70 # TODO(milleral): http://crbug.com/249424 71 # Consider making the add-a-label-to-a-host call automatically create a 72 # label if it does not already exist. 73 provision.ensure_label_exists(provision.cros_version_to_label(image)) 74 75 try: 76 host.machine_install(force_update=True, update_url=url) 77 except error.InstallError as e: 78 logging.error(e) 79 raise error.TestFail(str(e)) 80