cros_flash: Deprecate calling old AU flash
Also deprecate cros flash args that is not being used anymore.
BUG=b:172212406
TEST=cros flash
Change-Id: I5cd16c9d4e187cd0cb9bbb453c46cd3e7778e447
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/chromite/+/2798995
Tested-by: Amin Hassani <ahassani@chromium.org>
Commit-Queue: Amin Hassani <ahassani@chromium.org>
Reviewed-by: Jae Hoon Kim <kimjae@chromium.org>
diff --git a/cli/flash.py b/cli/flash.py
index a63f36a..6eec74a 100644
--- a/cli/flash.py
+++ b/cli/flash.py
@@ -12,13 +12,10 @@
import re
import shutil
import sys
-import tempfile
from chromite.cli import device_imager
from chromite.cli.cros import cros_chrome_sdk
-from chromite.lib import auto_updater
-from chromite.lib import auto_updater_transfer
from chromite.lib import commandline
from chromite.lib import cros_build_lib
from chromite.lib import cros_logging as logging
@@ -28,11 +25,6 @@
from chromite.lib import path_util
from chromite.lib import remote_access
-from chromite.lib.paygen import paygen_payload_lib
-from chromite.lib.paygen import paygen_stateful_payload_lib
-
-from chromite.lib.xbuddy import artifact_info
-
assert sys.version_info >= (3, 6), 'This module requires Python 3.6+'
@@ -321,215 +313,11 @@
logging.error('Failed to copy image %s to %s', image_path, self.device)
-class RemoteDeviceUpdater(object):
- """Performs update on a remote device."""
- STATEFUL_UPDATE_BIN = '/usr/bin/stateful_update'
- UPDATE_ENGINE_BIN = 'update_engine_client'
- # Root working directory on the device. This directory is in the
- # stateful partition and thus has enough space to store the payloads.
- DEVICE_BASE_DIR = '/usr/local/tmp/cros-flash'
- UPDATE_CHECK_INTERVAL_PROGRESSBAR = 0.5
- UPDATE_CHECK_INTERVAL_NORMAL = 10
-
- def __init__(self, ssh_hostname, ssh_port, image, stateful_update=True,
- rootfs_update=True, clobber_stateful=False, reboot=True,
- board=None, src_image_to_delta=None, wipe=True, debug=False,
- yes=False, force=False, ssh_private_key=None, ping=True,
- disable_verification=False, send_payload_in_parallel=False,
- clear_tpm_owner=False, version=None,
- copy_payloads_to_device=True):
- """Initializes RemoteDeviceUpdater"""
- if not stateful_update and not rootfs_update:
- raise ValueError('No update operation to perform; either stateful or'
- ' rootfs partitions must be updated.')
- self.tempdir = tempfile.mkdtemp(prefix='cros-flash')
- self.ssh_hostname = ssh_hostname
- self.ssh_port = ssh_port
- self.image = image
- self.board = board
- self.src_image_to_delta = src_image_to_delta
- self.do_stateful_update = stateful_update
- self.do_rootfs_update = rootfs_update
- self.disable_verification = disable_verification
- self.clobber_stateful = clobber_stateful
- self.clear_tpm_owner = clear_tpm_owner
- self.reboot = reboot
- self.debug = debug
- self.ssh_private_key = ssh_private_key
- self.ping = ping
- # Do not wipe if debug is set.
- self.wipe = wipe and not debug
- self.yes = yes
- self.force = force
- self.send_payload_in_parallel = send_payload_in_parallel
- self.version = version
- self.copy_payloads_to_device = copy_payloads_to_device
-
- def Cleanup(self):
- """Cleans up the temporary directory."""
- if self.wipe:
- logging.info('Cleaning up temporary working directory...')
- osutils.RmDir(self.tempdir)
- else:
- logging.info('You can find the log files and/or payloads in %s',
- self.tempdir)
-
- def GetPayloadPaths(self, device):
- """Get directory of payload and rootfs payload file name for update.
-
- This method is used to obtain the directory of payload for cros-flash. The
- given path 'self.image' is passed in when initializing RemoteDeviceUpdater.
-
- If self.image is a directory, we directly use the provided update payload(s)
- in this directory.
-
- If self.image is an image, we will generate payloads for it and put them in
- our temporary directory. The reason is that people may modify a local image
- or override it (on the same path) with a different image, so in order to be
- safe each time we need to generate the payloads and not cache them.
-
- If non of the above cases, we use the xbuddy to first obtain the image path
- (and possibly download it). Then we will generate the payloads in the same
- directory the image is located. The reason is that this is what devserver
- used to do. The path to the image generated by the devserver (or xbuddy) is
- unique and normally nobody override its image with a different one. That is
- why I think it is safe to put the payloads next to the image. This is a poor
- man's version of caching but it makes cros flash faster for users who flash
- the same image multiple times (without doing any change to the image).
-
- Args:
- device: A ChromiumOSDevice object.
-
- Returns:
- A string tuple (payload_dir, rootfs_filename). payload_dir is the
- directory where the update payloads are located. rootfs_filename is the
- name of the rootfs update payload (sometimes update.gz).
- """
- rootfs_filename = auto_updater_transfer.ROOTFS_FILENAME
-
- if os.path.isdir(self.image):
- # The given path is a directory.
- logging.info('Using provided payloads in %s', self.image)
- return self.image, rootfs_filename
-
- image_path = self.image
- payload_dir = self.tempdir
-
- if not os.path.isfile(self.image):
- # Assuming it is an xbuddy path.
- self.board = cros_build_lib.GetBoard(
- device_board=device.board or GetDefaultBoard(),
- override_board=self.board,
- force=self.yes,
- strict=True)
- if not self.force and self.board != device.board:
- # If a board was specified, it must be compatible with the device.
- raise FlashError('Device (%s) is incompatible with board %s' %
- (device.board, self.board))
- logging.info('Board is %s', self.board)
-
- # TODO(crbug.com/872441): Once devserver code has been moved to chromite,
- # use xbuddy library directly instead of the devserver_wrapper.
- # Fetch the full payload and properties, and stateful files. If this
- # fails, fallback to downloading the image.
- try:
- _, local_path = ds_wrapper.GetImagePathWithXbuddy(
- os.path.join(self.image, artifact_info.FULL_PAYLOAD),
- self.board, self.version, silent=True)
- payload_dir, rootfs_filename = os.path.split(local_path)
-
- ds_wrapper.GetImagePathWithXbuddy(
- os.path.join(self.image, artifact_info.STATEFUL_PAYLOAD),
- self.board, self.version, silent=True)
- fetch_image = False
- except (ds_wrapper.ImagePathError, ds_wrapper.ArtifactDownloadError):
- logging.info('Could not find full_payload or stateful for "%s"',
- self.image)
- fetch_image = True
-
- # We didn't find the full_payload, attempt to download the image.
- if fetch_image:
- _, image_path = ds_wrapper.GetImagePathWithXbuddy(
- self.image, self.board, self.version)
- payload_dir = os.path.join(os.path.dirname(image_path), 'payloads')
- logging.notice('Using image path %s and payload directory %s',
- image_path, payload_dir)
-
- # Generate rootfs and stateful update payloads if they do not exist.
- payload_path = os.path.join(payload_dir, rootfs_filename)
- if not os.path.exists(payload_path):
- paygen_payload_lib.GenerateUpdatePayload(
- image_path, payload_path, src_image=self.src_image_to_delta)
- if not os.path.exists(os.path.join(
- payload_dir, auto_updater_transfer.STATEFUL_FILENAME)):
- paygen_stateful_payload_lib.GenerateStatefulPayload(image_path,
- payload_dir)
- return payload_dir, rootfs_filename
-
- def Run(self):
- """Perform remote device update.
-
- The update process includes:
- 1. initialize a device instance for the given remote device.
- 2. achieve payload_dir which contains the required payloads for updating.
- 3. initialize an auto-updater instance to do RunUpdate().
- 4. After auto-update, all temp files and dir will be cleaned up.
- """
- try:
- with remote_access.ChromiumOSDeviceHandler(
- self.ssh_hostname, port=self.ssh_port, base_dir=self.DEVICE_BASE_DIR,
- private_key=self.ssh_private_key, ping=self.ping) as device:
-
- try:
- # Get payload directory
- logging.notice('Staging payloads...')
- payload_dir, rootfs_filename = self.GetPayloadPaths(device)
-
- # Do auto-update
- chromeos_AU = auto_updater.ChromiumOSUpdater(
- device=device,
- build_name=None,
- payload_dir=payload_dir,
- payload_filename=rootfs_filename,
- tempdir=self.tempdir,
- do_rootfs_update=self.do_rootfs_update,
- do_stateful_update=self.do_stateful_update,
- reboot=self.reboot,
- disable_verification=self.disable_verification,
- clobber_stateful=self.clobber_stateful,
- clear_tpm_owner=self.clear_tpm_owner,
- yes=self.yes,
- send_payload_in_parallel=self.send_payload_in_parallel,
- resolve_app_id_mismatch=True,
- transfer_class=auto_updater_transfer.LocalTransfer,
- copy_payloads_to_device=self.copy_payloads_to_device)
- chromeos_AU.RunUpdate()
-
- except Exception:
- logging.error('Device update failed.')
- lsb_entries = sorted(device.lsb_release.items())
- logging.info(
- 'Following are the LSB version details of the device:\n%s',
- '\n'.join('%s=%s' % (k, v) for k, v in lsb_entries))
- raise
-
- logging.notice('Update performed successfully.')
-
- except remote_access.RemoteAccessException:
- logging.error('Remote device failed to initialize.')
- raise
-
- finally:
- self.Cleanup()
-
-
-def Flash(device, image, board=None, src_image_to_delta=None,
- rootfs_update=True, stateful_update=True, clobber_stateful=False,
- reboot=True, wipe=True, ssh_private_key=None, ping=True,
+def Flash(device, image, board=None, version=None,
+ no_rootfs_update=False, no_stateful_update=False,
+ clobber_stateful=False, reboot=True, ssh_private_key=None, ping=True,
disable_rootfs_verification=False, clear_cache=False, yes=False,
- force=False, debug=False, send_payload_in_parallel=False,
- clear_tpm_owner=False, version=None, copy_payloads_to_device=True,
- exp_new_flash=False):
+ force=False, debug=False, clear_tpm_owner=False):
"""Flashes a device, USB drive, or file with an image.
This provides functionality common to `cros flash` and `brillo flash`
@@ -541,14 +329,12 @@
image: Path (string) to the update image. Can be a local or xbuddy path;
non-existant local paths are converted to xbuddy.
board: Board to use; None to automatically detect.
- src_image_to_delta: Local path to an image to be used as the base to
- generate delta payloads; SSH |device| scheme only.
- rootfs_update: Update rootfs partition; SSH |device| scheme only.
- stateful_update: Update stateful partition; SSH |device| scheme only.
+ no_rootfs_update: Don't update rootfs partition; SSH |device| scheme only.
+ no_stateful_update: Don't update stateful partition; SSH |device| scheme
+ only.
clobber_stateful: Clobber stateful partition; SSH |device| scheme only.
clear_tpm_owner: Clear the TPM owner on reboot; SSH |device| scheme only.
reboot: Reboot device after update; SSH |device| scheme only.
- wipe: Wipe temporary working directory; SSH |device| scheme only.
ssh_private_key: Path to an SSH private key file; None to use test keys.
ping: Ping the device before attempting update; SSH |device| scheme only.
disable_rootfs_verification: Remove rootfs verification after update; SSH
@@ -557,13 +343,7 @@
yes: Assume "yes" for any prompt.
force: Ignore sanity checks and prompts. Overrides |yes| if True.
debug: Print additional debugging messages.
- send_payload_in_parallel: Transfer payloads in chunks in parallel to speed
- up transmissions for long haul between endpoints.
version: Default version.
- copy_payloads_to_device: If True, update payloads are copied to the
- Chromium OS device first. Otherwise, they are piped through SSH.
- Currently, this only applies to the stateful payloads.
- exp_new_flash: Whether to use device_imager.
Raises:
FlashError: An unrecoverable error occured.
@@ -585,45 +365,20 @@
hostname, port = None, None
logging.notice('Preparing to update the remote device %s', hostname)
- if exp_new_flash:
- with remote_access.ChromiumOSDeviceHandler(
- hostname, port=port,
- private_key=ssh_private_key, ping=ping) as device_p:
- device_imager.DeviceImager(
- device_p,
- image,
- board=board,
- version=version,
- no_rootfs_update=not rootfs_update,
- no_stateful_update=not stateful_update,
- no_reboot=not reboot,
- disable_verification=disable_rootfs_verification,
- clobber_stateful=clobber_stateful,
- clear_tpm_owner=clear_tpm_owner).Run()
- return
-
- updater = RemoteDeviceUpdater(
- hostname,
- port,
- image,
- board=board,
- src_image_to_delta=src_image_to_delta,
- rootfs_update=rootfs_update,
- stateful_update=stateful_update,
- clobber_stateful=clobber_stateful,
- clear_tpm_owner=clear_tpm_owner,
- reboot=reboot,
- wipe=wipe,
- debug=debug,
- yes=yes,
- force=force,
- ssh_private_key=ssh_private_key,
- ping=ping,
- disable_verification=disable_rootfs_verification,
- send_payload_in_parallel=send_payload_in_parallel,
- version=version,
- copy_payloads_to_device=copy_payloads_to_device)
- updater.Run()
+ with remote_access.ChromiumOSDeviceHandler(
+ hostname, port=port,
+ private_key=ssh_private_key, ping=ping) as device_p:
+ device_imager.DeviceImager(
+ device_p,
+ image,
+ board=board,
+ version=version,
+ no_rootfs_update=no_rootfs_update,
+ no_stateful_update=no_stateful_update,
+ no_reboot=not reboot,
+ disable_verification=disable_rootfs_verification,
+ clobber_stateful=clobber_stateful,
+ clear_tpm_owner=clear_tpm_owner).Run()
elif device.scheme == commandline.DEVICE_SCHEME_USB:
path = osutils.ExpandPath(device.path) if device.path else ''
logging.info('Preparing to image the removable device %s', path)