blob: 5ec36e1e862639c5cc6c2fdbab37f8ca561e6ca8 [file] [log] [blame]
# Copyright 2017 The Chromium OS Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
import logging
import urlparse
from chromite.lib import auto_updater_transfer
from chromite.scripts import cros_update
class ChromiumOSTestPlatform(object):
"""Represents a CrOS device during autoupdate.
This class is used with autoupdate_EndToEndTest. It has functions for all
the device specific things that we need during an update: reboot,
check active slot, login, get logs, start an update etc.
"""
def __init__(self, host, autotest_devserver, results_dir):
"""Initialize the class.
@param: host: The DUT host.
@param: autotest_devserver: The devserver to stage payloads on.
@param: results_dir: Where to save the autoupdate logs files.
"""
self._host = host
self._autotest_devserver = autotest_devserver
self._results_dir = results_dir
def install_version_without_cros_au_rpc(self, payload_uri,
clobber_stateful=False):
"""Installs the specified payload onto the DUT.
This method calls the cros_update.CrOSUpdateTrigger directly which in
turn calls the auto_updater.ChromiumOSUpdater that updates the device
using nebraska.py. This method requires the payload_uri to be already
staged on a devserver.
TODO(crbug.com/1071483): Eventually, the call to
cros_update.CrOSUpdateTrigger should be replaced by a call to
auto_updater.ChromiumOSUpdater for a much cleaner update process. At
this time, cros_update.CrOSUpdateTrigger is being called because cros_au
ends up triggering the update process via cros_update.CrOSUpdateTrigger
which does not call the RunUpdate() method in
auto_updater.ChromiumOSUpdater, but calls the individual update methods
to perform the autoupdate. Since changing the call to cros_au is
disruptive enough, it was decided that only the cros_au call will be
taken out but rest of the flow will be kept as is to minimize the number
of potential fallouts.
@param payload_uri: GS URI of the payload to install.
@param clobber_stateful: force a reinstall of the stateful image.
@return path to the directory where the auto_updater stores its logs.
"""
build_name, payload_file = self._get_update_parameters_from_uri(
payload_uri)
logging.info('Installing %s on the DUT', payload_uri)
self.cros_updater = cros_update.CrOSUpdateTrigger(
host_name=self._host.hostname,
build_name=build_name,
static_dir='',
force_update=True,
full_update=True,
payload_filename=payload_file,
clobber_stateful=clobber_stateful,
staging_server=self._autotest_devserver.url(),
transfer_class=auto_updater_transfer.LabEndToEndPayloadTransfer)
self.cros_updater.TriggerAU()
def _install_version(self, payload_uri, clobber_stateful=False):
"""Install the specified payload.
This method calls the cros_au RPC on the devserver that in turn calls
the auto_updater.ChromiumOSUpdater via cros_update script.
TODO(crbug.com/1067394): Delete this method once all usages of
cros_AU RPC have been deprecated.
@param payload_uri: GS URI of the payload to install.
@param clobber_stateful: force a reinstall of the stateful image.
"""
build_name, payload_file = self._get_update_parameters_from_uri(
payload_uri)
logging.info('Installing %s on the DUT', payload_uri)
try:
ds = self._autotest_devserver
_, pid = ds.auto_update(host_name=self._host.hostname,
build_name=build_name,
force_update=True,
full_update=True,
log_dir=self._results_dir,
payload_filename=payload_file,
clobber_stateful=clobber_stateful)
except:
logging.fatal('ERROR: Failed to install image on the DUT.')
raise
return pid
@staticmethod
def _get_update_parameters_from_uri(payload_uri):
"""Extract vars needed to update with a Google Storage payload URI.
The two values we need are:
(1) A build_name string e.g dev-channel/samus/9583.0.0
(2) A filename of the exact payload file to use for the update. This
payload needs to have already been staged on the devserver.
@param payload_uri: Google Storage URI to extract values from
"""
# gs://chromeos-releases/dev-channel/samus/9334.0.0/payloads/blah.bin
# build_name = dev-channel/samus/9334.0.0
# payload_file = payloads/blah.bin
build_name = payload_uri[:payload_uri.index('payloads/')]
build_name = urlparse.urlsplit(build_name).path.strip('/')
payload_file = payload_uri[payload_uri.index('payloads/'):]
logging.debug('Extracted build_name: %s, payload_file: %s from %s.',
build_name, payload_file, payload_uri)
return build_name, payload_file
def install_source_image(self, source_payload_uri):
"""Install source payload on device.
TODO(crbug.com/1067394): Delete this method once all usages of
cros_AU RPC have been deprecated.
"""
if source_payload_uri:
self._install_version(source_payload_uri, clobber_stateful=True)
def install_target_image(self, target_payload_uri):
"""Install target payload on the device.
TODO(crbug.com/1067394): Delete this method once all usages of
cros_AU RPC have been deprecated.
"""
logging.info('Updating device to target image.')
return self._install_version(target_payload_uri)