gsi_util: adding flash_gsi subcommand

This change implements the flash_gsi subcommand:
  1. Erase userdata/cache partition
  2. Erase metadata partition (optional)
  3. Flash generic system image
  4. Disable Android Verified Boot (optional)
  5. Reboot the device

Bug: 70253882
Test: make gsi_util
Test: gsi_util flash_gsi
Test: gsi_util --debug flash_gsi --image system.img
Change-Id: I552c04aaf227c6fca2e5c3caab26d713e2f6f5d0
This commit is contained in:
Bowgo Tsai
2017-12-18 14:59:59 +08:00
parent ac3ee581a8
commit b510ae3a33
4 changed files with 112 additions and 1 deletions

View File

@@ -20,6 +20,9 @@ python_binary_host {
"gsi_util/commands/*.py",
"gsi_util/utils/*.py",
],
required: [
"avbtool",
],
version: {
py2: {
enabled: true,

View File

@@ -28,7 +28,7 @@ class GsiUtil(object):
# Adds gsi_util COMMAND here.
# TODO(bowgotsai): auto collect from gsi_util/commands/*.py
_COMMANDS = ['hello']
_COMMANDS = ['flash_gsi', 'hello']
_LOGGING_FORMAT = '%(message)s'
_LOGGING_LEVEL = logging.WARNING

View File

@@ -0,0 +1,63 @@
# Copyright 2017 - The Android Open Source Project
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Implementation of gsi_util flash_gsi command."""
from gsi_util.utils import cmd_utils
from gsi_util.utils import fastboot_utils
from gsi_util.utils import file_utils
def do_flash_gsi(args):
"""Flashes a GSI image (system.img).
Also erases userdata/metadata partition and disables
Android Verified Boot (AVB).
Args:
args: flash_gsi command arguments.
"""
fastboot_utils.erase() # erases userdata/cache partition
# Not every device has metadata partition, so allow_error is True.
fastboot_utils.erase('metadata', allow_error=True)
# Flashes GSI.
fastboot_utils.flash('system', args.image)
# Disables AVB.
with file_utils.UnopenedTemporaryFile() as vbmeta_image:
# vbmeta flag 2 means disable entire AVB verification.
cmd_utils.run_command(['avbtool', 'make_vbmeta_image',
'--flag', '2',
'--padding_size', '4096',
'--output', vbmeta_image])
# Not every device uses AVB, so allow_error is True.
fastboot_utils.flash('vbmeta', vbmeta_image, allow_error=True)
# Reboots the device.
fastboot_utils.reboot()
def setup_command_args(subparsers):
"""Sets up command args for 'flash_gsi'."""
parser = subparsers.add_parser(
'flash_gsi', help='flash a GSI image',
description=('Flash a GSI image - '
'including erasing userdata, '
'disabling AVB (if the device supports AVB) '
'and erasing metadata partition (if the device has).'))
parser.add_argument('-i', '--image',
help='the GSI image to flash', type=str)
parser.set_defaults(func=do_flash_gsi)

View File

@@ -0,0 +1,45 @@
# Copyright 2017 - The Android Open Source Project
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Fastboot-related commands."""
from gsi_util.utils.cmd_utils import run_command
def flash(partition_name, image_name=None, allow_error=False):
"""fastboot flash a partition with a given image."""
cmd = ['fastboot', 'flash', partition_name]
# image_name can be None, for `fastboot` to flash
# ${ANDROID_PRODUCT_OUT}/{partition_name}.img.
if image_name is not None:
cmd.append(image_name)
run_command(cmd, raise_on_error=not allow_error)
def erase(partition_name=None, allow_error=False):
"""fastboot erase a partition."""
if partition_name is None:
run_command(['fastboot', '-w'], raise_on_error=not allow_error)
else:
run_command(['fastboot', 'erase', partition_name],
raise_on_error=not allow_error)
def reboot():
"""fastboot reboot a device."""
run_command(['fastboot', 'reboot'], raise_on_error=False)