Home | History | Annotate | Download | only in provision_AndroidUpdate
      1 # Copyright 2016 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 
      5 import logging
      6 
      7 from autotest_lib.client.common_lib import error
      8 from autotest_lib.client.common_lib import global_config
      9 from autotest_lib.server import afe_utils
     10 from autotest_lib.server import test
     11 from autotest_lib.server.hosts import testbed
     12 
     13 
     14 _CONFIG = global_config.global_config
     15 # pylint: disable-msg=E1120
     16 _IMAGE_URL_PATTERN = _CONFIG.get_config_value(
     17         'ANDROID', 'image_url_pattern', type=str)
     18 
     19 
     20 class provision_AndroidUpdate(test.test):
     21     """A test that can provision a machine to the correct Android version."""
     22     version = 1
     23 
     24     def initialize(self, host, value, force=False, is_test_na=False,
     25                    repair=False):
     26         """Initialize.
     27 
     28         @param host: The host object to update to |value|.
     29         @param value: String of the image we want to install on the host.
     30         @param force: not used by initialize.
     31         @param is_test_na: boolean, if True, will simply skip the test
     32                            and emit TestNAError. The control file
     33                            determines whether the test should be skipped
     34                            and passes the decision via this argument. Note
     35                            we can't raise TestNAError in control file as it won't
     36                            be caught and handled properly.
     37         @param repair: not used by initialize.
     38         """
     39         if is_test_na:
     40             raise error.TestNAError('Provisioning not applicable.')
     41         # We check value in initialize so that it fails faster.
     42         if not (value or repair):
     43             raise error.TestFail('No build version specified.')
     44 
     45 
     46     def run_once(self, host, value=None, force=False, repair=False, board=None,
     47                  os=None):
     48         """The method called by the control file to start the test.
     49 
     50         @param host: The host object to update to |value|.
     51         @param value: The host object to provision with a build corresponding
     52                       to |value|.
     53         @param force: True iff we should re-provision the machine regardless of
     54                       the current image version.  If False and the image
     55                       version matches our expected image version, no
     56                       provisioning will be done.
     57         @param repair: If True, we are doing a repair provision, therefore the
     58                        build to provision is looked up from the AFE's
     59                        get_stable_version RPC.
     60         @param board: Board name of the device. For host created in testbed,
     61                       it does not have host labels and attributes. Therefore,
     62                       the board name needs to be passed in from the testbed
     63                       repair call.
     64         @param os: OS of the device. For host created in testbed, it does not
     65                    have host labels and attributes. Therefore, the OS needs to
     66                    be passed in from the testbed repair call.
     67 
     68         """
     69         logging.debug('Start provisioning %s to %s', host, value)
     70 
     71         if not value and not repair:
     72             raise error.TestFail('No build provided and this is not a repair '
     73                                  ' job.')
     74 
     75         info = host.host_info_store.get()
     76         # If the host is already on the correct build, we have nothing to do.
     77         if not force and info.build == value:
     78             # We can't raise a TestNA, as would make sense, as that makes
     79             # job.run_test return False as if the job failed.  However, it'd
     80             # still be nice to get this into the status.log, so we manually
     81             # emit an INFO line instead.
     82             self.job.record('INFO', None, None,
     83                             'Host already running %s' % value)
     84             return
     85 
     86         board = board or info.board
     87         os = os or info.os
     88         logging.debug('Host %s is board type: %s, OS type: %s', host, board, os)
     89         if repair:
     90             # TODO(kevcheng): remove the board.split() line when all android
     91             # devices have their board label updated to have no android in
     92             # there.
     93             board = board.split('-')[-1]
     94             value = afe_utils.get_stable_android_version(board)
     95             if not value:
     96                 raise error.TestFail('No stable version assigned for board: '
     97                                      '%s' % board)
     98             logging.debug('Stable version found for board %s: %s', board, value)
     99 
    100         if not isinstance(host, testbed.TestBed):
    101             url, _ = host.stage_build_for_install(value, os_type=os)
    102             logging.debug('Installing image from: %s', url)
    103             args = {'build_url': url, 'os_type': os}
    104         else:
    105             logging.debug('Installing image: %s', value)
    106             args = {'image': value}
    107         try:
    108             afe_utils.machine_install_and_update_labels(
    109                     host, **args)
    110         except error.InstallError as e:
    111             logging.error(e)
    112             raise error.TestFail(str(e))
    113         logging.debug('Finished provisioning %s to %s', host, value)
    114