Xiaochu Liu | deed023 | 2018-06-26 10:25:34 -0700 | [diff] [blame] | 1 | # -*- coding: utf-8 -*- |
| 2 | # Copyright 2018 The Chromium OS Authors. All rights reserved. |
| 3 | # Use of this source code is governed by a BSD-style license that can be |
| 4 | # found in the LICENSE file. |
Xiaochu Liu | deed023 | 2018-06-26 10:25:34 -0700 | [diff] [blame] | 5 | """Script to generate a DLC (Downloadable Content) artifact.""" |
| 6 | |
| 7 | from __future__ import print_function |
| 8 | |
Andrew | eff865f | 2020-04-24 13:39:44 -0700 | [diff] [blame] | 9 | import sys |
Xiaochu Liu | deed023 | 2018-06-26 10:25:34 -0700 | [diff] [blame] | 10 | |
Andrew | 5743d38 | 2020-06-16 09:55:04 -0700 | [diff] [blame^] | 11 | from chromite.lib import dlc_lib |
Xiaochu Liu | deed023 | 2018-06-26 10:25:34 -0700 | [diff] [blame] | 12 | from chromite.lib import commandline |
Amin Hassani | b97a5ee | 2019-01-23 14:44:43 -0800 | [diff] [blame] | 13 | from chromite.lib import cros_logging as logging |
Xiaochu Liu | deed023 | 2018-06-26 10:25:34 -0700 | [diff] [blame] | 14 | |
| 15 | |
Andrew | eff865f | 2020-04-24 13:39:44 -0700 | [diff] [blame] | 16 | assert sys.version_info >= (3, 6), 'This module requires Python 3.6+' |
| 17 | |
Jae Hoon Kim | faca4b0 | 2020-01-09 13:49:03 -0800 | [diff] [blame] | 18 | |
Xiaochu Liu | deed023 | 2018-06-26 10:25:34 -0700 | [diff] [blame] | 19 | def GetParser(): |
Amin Hassani | b97a5ee | 2019-01-23 14:44:43 -0800 | [diff] [blame] | 20 | """Creates an argument parser and returns it.""" |
Xiaochu Liu | deed023 | 2018-06-26 10:25:34 -0700 | [diff] [blame] | 21 | parser = commandline.ArgumentParser(description=__doc__) |
Amin Hassani | b97a5ee | 2019-01-23 14:44:43 -0800 | [diff] [blame] | 22 | # This script is used both for building an individual DLC or copying all final |
Andrew | 5743d38 | 2020-06-16 09:55:04 -0700 | [diff] [blame^] | 23 | # DLCs images to their final destination nearby chromiumos_test_image.bin, |
Amin Hassani | b97a5ee | 2019-01-23 14:44:43 -0800 | [diff] [blame] | 24 | # etc. These two arguments are required in both cases. |
Jae Hoon Kim | faca4b0 | 2020-01-09 13:49:03 -0800 | [diff] [blame] | 25 | parser.add_argument( |
| 26 | '--sysroot', |
| 27 | type='path', |
| 28 | metavar='DIR', |
Jae Hoon Kim | faca4b0 | 2020-01-09 13:49:03 -0800 | [diff] [blame] | 29 | help="The root path to the board's build root, e.g. " |
| 30 | '/build/eve') |
Andrew | 67b5fa7 | 2020-02-05 14:14:48 -0800 | [diff] [blame] | 31 | # TODO(andrewlassalle): Remove src-dir in the future(2021?) if nobody uses it. |
| 32 | parser.add_argument( |
| 33 | '--src-dir', |
| 34 | type='path', |
| 35 | metavar='SRC_DIR_PATH', |
| 36 | help='Override the default Root directory path that contains all DLC ' |
| 37 | 'files to be packed.') |
Jae Hoon Kim | faca4b0 | 2020-01-09 13:49:03 -0800 | [diff] [blame] | 38 | parser.add_argument( |
| 39 | '--install-root-dir', |
| 40 | type='path', |
| 41 | metavar='DIR', |
Jae Hoon Kim | faca4b0 | 2020-01-09 13:49:03 -0800 | [diff] [blame] | 42 | help='If building a specific DLC, it is the root path to' |
| 43 | ' install DLC images (%s) and metadata (%s). Otherwise it' |
| 44 | ' is the target directory where the Chrome OS images gets' |
| 45 | ' dropped in build_image, e.g. ' |
Andrew | 5743d38 | 2020-06-16 09:55:04 -0700 | [diff] [blame^] | 46 | 'src/build/images/<board>/latest.' % (dlc_lib.DLC_BUILD_DIR, |
| 47 | dlc_lib.DLC_META_DIR)) |
Amin Hassani | 22a25eb | 2019-01-11 14:25:02 -0800 | [diff] [blame] | 48 | |
Amin Hassani | b97a5ee | 2019-01-23 14:44:43 -0800 | [diff] [blame] | 49 | one_dlc = parser.add_argument_group('Arguments required for building only ' |
| 50 | 'one DLC') |
Jae Hoon Kim | faca4b0 | 2020-01-09 13:49:03 -0800 | [diff] [blame] | 51 | one_dlc.add_argument( |
Andrew | 67b5fa7 | 2020-02-05 14:14:48 -0800 | [diff] [blame] | 52 | '--rootfs', |
Jae Hoon Kim | faca4b0 | 2020-01-09 13:49:03 -0800 | [diff] [blame] | 53 | type='path', |
Andrew | 67b5fa7 | 2020-02-05 14:14:48 -0800 | [diff] [blame] | 54 | metavar='ROOT_FS_PATH', |
| 55 | help='Path to the platform rootfs.') |
Jae Hoon Kim | faca4b0 | 2020-01-09 13:49:03 -0800 | [diff] [blame] | 56 | one_dlc.add_argument( |
| 57 | '--pre-allocated-blocks', |
| 58 | type=int, |
| 59 | metavar='PREALLOCATEDBLOCKS', |
| 60 | help='Number of blocks (block size is 4k) that need to' |
| 61 | 'be pre-allocated on device.') |
Amin Hassani | b97a5ee | 2019-01-23 14:44:43 -0800 | [diff] [blame] | 62 | one_dlc.add_argument('--version', metavar='VERSION', help='DLC Version.') |
| 63 | one_dlc.add_argument('--id', metavar='ID', help='DLC ID (unique per DLC).') |
Jae Hoon Kim | faca4b0 | 2020-01-09 13:49:03 -0800 | [diff] [blame] | 64 | one_dlc.add_argument( |
| 65 | '--package', |
| 66 | metavar='PACKAGE', |
| 67 | help='The package ID that is unique within a DLC, One' |
| 68 | ' DLC cannot have duplicate package IDs.') |
| 69 | one_dlc.add_argument( |
| 70 | '--name', metavar='NAME', help='A human-readable name for the DLC.') |
| 71 | one_dlc.add_argument( |
Jae Hoon Kim | 6ef6317 | 2020-04-06 12:39:04 -0700 | [diff] [blame] | 72 | '--description', |
| 73 | help='The description for the DLC.') |
| 74 | one_dlc.add_argument( |
Andrew | 06a5f81 | 2020-01-23 08:08:32 -0800 | [diff] [blame] | 75 | '--board', metavar='BOARD', help='The target board we are building for.') |
| 76 | one_dlc.add_argument('--fullnamerev', metavar='FULL_NAME_REV', |
| 77 | help='The full ebuild package name.') |
| 78 | one_dlc.add_argument( |
Jae Hoon Kim | faca4b0 | 2020-01-09 13:49:03 -0800 | [diff] [blame] | 79 | '--fs-type', |
| 80 | metavar='FS_TYPE', |
Andrew | 5743d38 | 2020-06-16 09:55:04 -0700 | [diff] [blame^] | 81 | default=dlc_lib.SQUASHFS_TYPE, |
| 82 | choices=(dlc_lib.SQUASHFS_TYPE, dlc_lib.EXT4_TYPE), |
Jae Hoon Kim | faca4b0 | 2020-01-09 13:49:03 -0800 | [diff] [blame] | 83 | help='File system type of the image.') |
| 84 | one_dlc.add_argument( |
| 85 | '--preload', |
| 86 | default=False, |
| 87 | action='store_true', |
| 88 | help='Allow preloading of DLC.') |
Andrew | 67b5fa7 | 2020-02-05 14:14:48 -0800 | [diff] [blame] | 89 | one_dlc.add_argument( |
Andrew | 5743d38 | 2020-06-16 09:55:04 -0700 | [diff] [blame^] | 90 | '--used-by', default=dlc_lib.USED_BY_SYSTEM, |
| 91 | choices=(dlc_lib.USED_BY_USER, dlc_lib.USED_BY_SYSTEM), |
Amin Hassani | 160e12e | 2020-04-13 14:29:36 -0700 | [diff] [blame] | 92 | help='Defines how this DLC will be used so dlcservice can take proper ' |
| 93 | 'actions based on the type of usage. For example, if "user" is passed, ' |
| 94 | 'dlcservice does ref counting when DLC is installed/uninstalled. For ' |
| 95 | '"system", there will be no such provisions.') |
| 96 | one_dlc.add_argument( |
Andrew | 67b5fa7 | 2020-02-05 14:14:48 -0800 | [diff] [blame] | 97 | '--build-package', |
| 98 | default=False, |
| 99 | action='store_true', |
| 100 | help='Flag to indicate if the script is executed during the ' |
| 101 | 'build_packages phase.') |
Xiaochu Liu | deed023 | 2018-06-26 10:25:34 -0700 | [diff] [blame] | 102 | return parser |
| 103 | |
| 104 | |
Andrew | 67b5fa7 | 2020-02-05 14:14:48 -0800 | [diff] [blame] | 105 | def ValidateArguments(parser, opts, req_flags, invalid_flags): |
Amin Hassani | b97a5ee | 2019-01-23 14:44:43 -0800 | [diff] [blame] | 106 | """Validates the correctness of the passed arguments. |
| 107 | |
| 108 | Args: |
Andrew | 67b5fa7 | 2020-02-05 14:14:48 -0800 | [diff] [blame] | 109 | parser: Arguments parser. |
Amin Hassani | b97a5ee | 2019-01-23 14:44:43 -0800 | [diff] [blame] | 110 | opts: Parsed arguments. |
Andrew | 67b5fa7 | 2020-02-05 14:14:48 -0800 | [diff] [blame] | 111 | req_flags: all the required flags. |
| 112 | invalid_flags: all the flags that are not allowed. |
Amin Hassani | b97a5ee | 2019-01-23 14:44:43 -0800 | [diff] [blame] | 113 | """ |
| 114 | # Make sure if the intention is to build one DLC, all the required arguments |
Andrew | 67b5fa7 | 2020-02-05 14:14:48 -0800 | [diff] [blame] | 115 | # are passed and none of the invalid ones are passed. This will ensure the |
| 116 | # script is called twice per DLC. |
| 117 | if opts.id: |
| 118 | if not all(vars(opts)[x] is not None for x in req_flags): |
| 119 | parser.error('If the intention is to build only one DLC, all the flags' |
| 120 | '%s required for it should be passed.' % req_flags) |
| 121 | if any(vars(opts)[x] is not None for x in invalid_flags): |
| 122 | parser.error('If the intention is to build only one DLC, all the flags' |
| 123 | '%s should be passed in the build_packages phase, not in ' |
| 124 | 'the build_image phase.' % invalid_flags) |
| 125 | |
Andrew | 5743d38 | 2020-06-16 09:55:04 -0700 | [diff] [blame^] | 126 | if opts.fs_type == dlc_lib.EXT4_TYPE: |
Andrew | 67b5fa7 | 2020-02-05 14:14:48 -0800 | [diff] [blame] | 127 | parser.error('ext4 unsupported for DLC, see https://crbug.com/890060') |
Amin Hassani | b97a5ee | 2019-01-23 14:44:43 -0800 | [diff] [blame] | 128 | |
Amin Hassani | bc1a479 | 2019-10-24 14:39:57 -0700 | [diff] [blame] | 129 | if opts.id: |
Andrew | 5743d38 | 2020-06-16 09:55:04 -0700 | [diff] [blame^] | 130 | dlc_lib.ValidateDlcIdentifier(opts.id) |
Amin Hassani | bc1a479 | 2019-10-24 14:39:57 -0700 | [diff] [blame] | 131 | if opts.package: |
Andrew | 5743d38 | 2020-06-16 09:55:04 -0700 | [diff] [blame^] | 132 | dlc_lib.ValidateDlcIdentifier(opts.package) |
Amin Hassani | bc1a479 | 2019-10-24 14:39:57 -0700 | [diff] [blame] | 133 | |
Amin Hassani | b97a5ee | 2019-01-23 14:44:43 -0800 | [diff] [blame] | 134 | |
Xiaochu Liu | deed023 | 2018-06-26 10:25:34 -0700 | [diff] [blame] | 135 | def main(argv): |
Andrew | 67b5fa7 | 2020-02-05 14:14:48 -0800 | [diff] [blame] | 136 | parser = GetParser() |
| 137 | opts = parser.parse_args(argv) |
Xiaochu Liu | deed023 | 2018-06-26 10:25:34 -0700 | [diff] [blame] | 138 | opts.Freeze() |
Andrew | 67b5fa7 | 2020-02-05 14:14:48 -0800 | [diff] [blame] | 139 | per_dlc_req_args = ['id'] |
| 140 | per_dlc_invalid_args = [] |
| 141 | if opts.build_package: |
| 142 | per_dlc_req_args += ['pre_allocated_blocks', 'version', 'name', |
Jae Hoon Kim | 6ef6317 | 2020-04-06 12:39:04 -0700 | [diff] [blame] | 143 | 'description', 'package', 'install_root_dir'] |
Andrew | 67b5fa7 | 2020-02-05 14:14:48 -0800 | [diff] [blame] | 144 | per_dlc_invalid_args += ['src_dir', 'sysroot'] |
Amin Hassani | b97a5ee | 2019-01-23 14:44:43 -0800 | [diff] [blame] | 145 | else: |
Andrew | 06a5f81 | 2020-01-23 08:08:32 -0800 | [diff] [blame] | 146 | per_dlc_req_args += ['sysroot', 'board'] |
Andrew | 67b5fa7 | 2020-02-05 14:14:48 -0800 | [diff] [blame] | 147 | per_dlc_invalid_args += ['name', 'pre_allocated_blocks', 'version', |
| 148 | 'package'] |
| 149 | |
| 150 | ValidateArguments(parser, opts, per_dlc_req_args, per_dlc_invalid_args) |
| 151 | |
| 152 | if opts.build_package: |
| 153 | logging.info('Building package: DLC %s', opts.id) |
Andrew | 5743d38 | 2020-06-16 09:55:04 -0700 | [diff] [blame^] | 154 | params = dlc_lib.EbuildParams( |
Jae Hoon Kim | 6ef6317 | 2020-04-06 12:39:04 -0700 | [diff] [blame] | 155 | dlc_id=opts.id, |
| 156 | dlc_package=opts.package, |
| 157 | fs_type=opts.fs_type, |
| 158 | name=opts.name, |
| 159 | description=opts.description, |
| 160 | pre_allocated_blocks=opts.pre_allocated_blocks, |
| 161 | version=opts.version, |
Amin Hassani | 160e12e | 2020-04-13 14:29:36 -0700 | [diff] [blame] | 162 | preload=opts.preload, |
Andrew | 06a5f81 | 2020-01-23 08:08:32 -0800 | [diff] [blame] | 163 | used_by=opts.used_by, |
| 164 | fullnamerev=opts.fullnamerev) |
Andrew | 67b5fa7 | 2020-02-05 14:14:48 -0800 | [diff] [blame] | 165 | params.StoreDlcParameters(install_root_dir=opts.install_root_dir, sudo=True) |
| 166 | |
| 167 | else: |
Andrew | 5743d38 | 2020-06-16 09:55:04 -0700 | [diff] [blame^] | 168 | dlc_lib.InstallDlcImages( |
Jae Hoon Kim | 5f411e4 | 2020-01-09 13:30:56 -0800 | [diff] [blame] | 169 | sysroot=opts.sysroot, |
Andrew | 67b5fa7 | 2020-02-05 14:14:48 -0800 | [diff] [blame] | 170 | dlc_id=opts.id, |
Jae Hoon Kim | 5f411e4 | 2020-01-09 13:30:56 -0800 | [diff] [blame] | 171 | install_root_dir=opts.install_root_dir, |
Andrew | 67b5fa7 | 2020-02-05 14:14:48 -0800 | [diff] [blame] | 172 | preload=opts.preload, |
| 173 | src_dir=opts.src_dir, |
Andrew | 06a5f81 | 2020-01-23 08:08:32 -0800 | [diff] [blame] | 174 | rootfs=opts.rootfs, |
| 175 | board=opts.board) |