1*105f6285SAndroid Build Coastguard Worker# Copyright 2020 Google LLC 2*105f6285SAndroid Build Coastguard Worker# 3*105f6285SAndroid Build Coastguard Worker# Licensed under the Apache License, Version 2.0 (the "License"); 4*105f6285SAndroid Build Coastguard Worker# you may not use this file except in compliance with the License. 5*105f6285SAndroid Build Coastguard Worker# You may obtain a copy of the License at 6*105f6285SAndroid Build Coastguard Worker# 7*105f6285SAndroid Build Coastguard Worker# https://www.apache.org/licenses/LICENSE-2.0 8*105f6285SAndroid Build Coastguard Worker# 9*105f6285SAndroid Build Coastguard Worker# Unless required by applicable law or agreed to in writing, software 10*105f6285SAndroid Build Coastguard Worker# distributed under the License is distributed on an "AS IS" BASIS, 11*105f6285SAndroid Build Coastguard Worker# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12*105f6285SAndroid Build Coastguard Worker# See the License for the specific language governing permissions and 13*105f6285SAndroid Build Coastguard Worker# limitations under the License. 14*105f6285SAndroid Build Coastguard Worker"""Builds an Android target in a secure sandbox.""" 15*105f6285SAndroid Build Coastguard Worker 16*105f6285SAndroid Build Coastguard Workerimport argparse 17*105f6285SAndroid Build Coastguard Workerimport os 18*105f6285SAndroid Build Coastguard Workerfrom . import config 19*105f6285SAndroid Build Coastguard Workerfrom . import nsjail 20*105f6285SAndroid Build Coastguard Workerfrom . import rbe 21*105f6285SAndroid Build Coastguard Worker 22*105f6285SAndroid Build Coastguard Worker_DEFAULT_COMMAND_WRAPPER = \ 23*105f6285SAndroid Build Coastguard Worker '/src/tools/treble/build/sandbox/build_android_target.sh' 24*105f6285SAndroid Build Coastguard Worker 25*105f6285SAndroid Build Coastguard Worker 26*105f6285SAndroid Build Coastguard Workerdef build(build_target, 27*105f6285SAndroid Build Coastguard Worker release_target, 28*105f6285SAndroid Build Coastguard Worker variant, 29*105f6285SAndroid Build Coastguard Worker nsjail_bin, 30*105f6285SAndroid Build Coastguard Worker chroot, 31*105f6285SAndroid Build Coastguard Worker dist_dir, 32*105f6285SAndroid Build Coastguard Worker build_id, 33*105f6285SAndroid Build Coastguard Worker max_cpus, 34*105f6285SAndroid Build Coastguard Worker build_goals, 35*105f6285SAndroid Build Coastguard Worker config_file=None, 36*105f6285SAndroid Build Coastguard Worker command_wrapper=_DEFAULT_COMMAND_WRAPPER, 37*105f6285SAndroid Build Coastguard Worker use_rbe=False, 38*105f6285SAndroid Build Coastguard Worker readonly_bind_mounts=[], 39*105f6285SAndroid Build Coastguard Worker env=[]): 40*105f6285SAndroid Build Coastguard Worker """Builds an Android target in a secure sandbox. 41*105f6285SAndroid Build Coastguard Worker 42*105f6285SAndroid Build Coastguard Worker Args: 43*105f6285SAndroid Build Coastguard Worker build_target: A string with the name of the build target. 44*105f6285SAndroid Build Coastguard Worker release_target: The release target config, e.g., next, trunk_food, ... 45*105f6285SAndroid Build Coastguard Worker variant: A string with the build variant. 46*105f6285SAndroid Build Coastguard Worker nsjail_bin: A string with the path to the nsjail binary. 47*105f6285SAndroid Build Coastguard Worker chroot: A string with the path to the chroot of the NsJail sandbox. 48*105f6285SAndroid Build Coastguard Worker dist_dir: A string with the path to the Android dist directory. 49*105f6285SAndroid Build Coastguard Worker build_id: A string with the Android build identifier. 50*105f6285SAndroid Build Coastguard Worker max_cpus: An integer with maximum number of CPUs. 51*105f6285SAndroid Build Coastguard Worker build_goals: A list of strings with the goals and options to provide to the 52*105f6285SAndroid Build Coastguard Worker build command. 53*105f6285SAndroid Build Coastguard Worker config_file: A string path to an overlay configuration file. 54*105f6285SAndroid Build Coastguard Worker command_wrapper: A string path to the command wrapper. 55*105f6285SAndroid Build Coastguard Worker use_rbe: If true, will attempt to use RBE for the build. 56*105f6285SAndroid Build Coastguard Worker readonly_bind_mounts: A list of string paths to be mounted as read-only. 57*105f6285SAndroid Build Coastguard Worker env: An array of environment variables to define in the NsJail sandbox in 58*105f6285SAndroid Build Coastguard Worker the `var=val` syntax. 59*105f6285SAndroid Build Coastguard Worker 60*105f6285SAndroid Build Coastguard Worker Returns: 61*105f6285SAndroid Build Coastguard Worker A list of commands that were executed. Each command is a list of strings. 62*105f6285SAndroid Build Coastguard Worker """ 63*105f6285SAndroid Build Coastguard Worker if config_file: 64*105f6285SAndroid Build Coastguard Worker cfg = config.Config(config_file) 65*105f6285SAndroid Build Coastguard Worker android_target = cfg.get_build_config_android_target(build_target) 66*105f6285SAndroid Build Coastguard Worker if cfg.has_tag(build_target, 'skip'): 67*105f6285SAndroid Build Coastguard Worker print('Warning: skipping build_target "{}" due to tag being set'.format( 68*105f6285SAndroid Build Coastguard Worker build_target)) 69*105f6285SAndroid Build Coastguard Worker return [] 70*105f6285SAndroid Build Coastguard Worker else: 71*105f6285SAndroid Build Coastguard Worker android_target = build_target 72*105f6285SAndroid Build Coastguard Worker 73*105f6285SAndroid Build Coastguard Worker # All builds are required to run with the root of the 74*105f6285SAndroid Build Coastguard Worker # Android source tree as the current directory. 75*105f6285SAndroid Build Coastguard Worker source_dir = os.getcwd() 76*105f6285SAndroid Build Coastguard Worker command = [ 77*105f6285SAndroid Build Coastguard Worker command_wrapper, 78*105f6285SAndroid Build Coastguard Worker '%s-%s-%s' % (android_target, release_target, variant), 79*105f6285SAndroid Build Coastguard Worker '/src', 80*105f6285SAndroid Build Coastguard Worker 'make', 81*105f6285SAndroid Build Coastguard Worker '-j', 82*105f6285SAndroid Build Coastguard Worker ] + build_goals 83*105f6285SAndroid Build Coastguard Worker 84*105f6285SAndroid Build Coastguard Worker extra_nsjail_args = [] 85*105f6285SAndroid Build Coastguard Worker cleanup = lambda: None 86*105f6285SAndroid Build Coastguard Worker nsjail_wrapper = [] 87*105f6285SAndroid Build Coastguard Worker if use_rbe: 88*105f6285SAndroid Build Coastguard Worker cleanup = rbe.setup(env) 89*105f6285SAndroid Build Coastguard Worker env = rbe.prepare_env(env) 90*105f6285SAndroid Build Coastguard Worker extra_nsjail_args.extend(rbe.get_extra_nsjail_args()) 91*105f6285SAndroid Build Coastguard Worker readonly_bind_mounts.extend(rbe.get_readonlybind_mounts()) 92*105f6285SAndroid Build Coastguard Worker nsjail_wrapper = rbe.get_nsjail_bin_wrapper() 93*105f6285SAndroid Build Coastguard Worker 94*105f6285SAndroid Build Coastguard Worker ret = nsjail.run( 95*105f6285SAndroid Build Coastguard Worker nsjail_bin=nsjail_bin, 96*105f6285SAndroid Build Coastguard Worker chroot=chroot, 97*105f6285SAndroid Build Coastguard Worker overlay_config=config_file, 98*105f6285SAndroid Build Coastguard Worker source_dir=source_dir, 99*105f6285SAndroid Build Coastguard Worker command=command, 100*105f6285SAndroid Build Coastguard Worker build_target=build_target, 101*105f6285SAndroid Build Coastguard Worker dist_dir=dist_dir, 102*105f6285SAndroid Build Coastguard Worker build_id=build_id, 103*105f6285SAndroid Build Coastguard Worker max_cpus=max_cpus, 104*105f6285SAndroid Build Coastguard Worker extra_nsjail_args=extra_nsjail_args, 105*105f6285SAndroid Build Coastguard Worker readonly_bind_mounts=readonly_bind_mounts, 106*105f6285SAndroid Build Coastguard Worker env=env, 107*105f6285SAndroid Build Coastguard Worker nsjail_wrapper=nsjail_wrapper) 108*105f6285SAndroid Build Coastguard Worker 109*105f6285SAndroid Build Coastguard Worker cleanup() 110*105f6285SAndroid Build Coastguard Worker 111*105f6285SAndroid Build Coastguard Worker return ret 112*105f6285SAndroid Build Coastguard Worker 113*105f6285SAndroid Build Coastguard Worker 114*105f6285SAndroid Build Coastguard Workerdef arg_parser(): 115*105f6285SAndroid Build Coastguard Worker """Returns an ArgumentParser for sanboxed android builds.""" 116*105f6285SAndroid Build Coastguard Worker # Use the top level module docstring for the help description 117*105f6285SAndroid Build Coastguard Worker parser = argparse.ArgumentParser( 118*105f6285SAndroid Build Coastguard Worker description=__doc__, formatter_class=argparse.RawDescriptionHelpFormatter) 119*105f6285SAndroid Build Coastguard Worker parser.add_argument('--build_target', help='The build target.') 120*105f6285SAndroid Build Coastguard Worker parser.add_argument( 121*105f6285SAndroid Build Coastguard Worker '--release_target', 122*105f6285SAndroid Build Coastguard Worker required=True, 123*105f6285SAndroid Build Coastguard Worker help='Release target config, e.g., next, trunk_food, trunk_staging, ...') 124*105f6285SAndroid Build Coastguard Worker parser.add_argument( 125*105f6285SAndroid Build Coastguard Worker '--variant', default='userdebug', help='The Android build variant.') 126*105f6285SAndroid Build Coastguard Worker parser.add_argument( 127*105f6285SAndroid Build Coastguard Worker '--nsjail_bin', required=True, help='Path to NsJail binary.') 128*105f6285SAndroid Build Coastguard Worker parser.add_argument( 129*105f6285SAndroid Build Coastguard Worker '--chroot', 130*105f6285SAndroid Build Coastguard Worker required=True, 131*105f6285SAndroid Build Coastguard Worker help='Path to the chroot to be used for building the Android ' 132*105f6285SAndroid Build Coastguard Worker 'platform. This will be mounted as the root filesystem in the ' 133*105f6285SAndroid Build Coastguard Worker 'NsJail sandbox.') 134*105f6285SAndroid Build Coastguard Worker parser.add_argument( 135*105f6285SAndroid Build Coastguard Worker '--config_file', 136*105f6285SAndroid Build Coastguard Worker required=True, 137*105f6285SAndroid Build Coastguard Worker help='Path to the overlay configuration file.') 138*105f6285SAndroid Build Coastguard Worker parser.add_argument( 139*105f6285SAndroid Build Coastguard Worker '--command_wrapper', 140*105f6285SAndroid Build Coastguard Worker default=_DEFAULT_COMMAND_WRAPPER, 141*105f6285SAndroid Build Coastguard Worker help='Path to the command wrapper. ' 142*105f6285SAndroid Build Coastguard Worker 'Defaults to \'%s\'.' % _DEFAULT_COMMAND_WRAPPER) 143*105f6285SAndroid Build Coastguard Worker parser.add_argument( 144*105f6285SAndroid Build Coastguard Worker '--readonly_bind_mount', 145*105f6285SAndroid Build Coastguard Worker type=str, 146*105f6285SAndroid Build Coastguard Worker default=[], 147*105f6285SAndroid Build Coastguard Worker action='append', 148*105f6285SAndroid Build Coastguard Worker help='Path to the a path to be mounted as readonly inside the secure ' 149*105f6285SAndroid Build Coastguard Worker 'build sandbox. Can be specified multiple times') 150*105f6285SAndroid Build Coastguard Worker parser.add_argument( 151*105f6285SAndroid Build Coastguard Worker '--env', 152*105f6285SAndroid Build Coastguard Worker '-e', 153*105f6285SAndroid Build Coastguard Worker type=str, 154*105f6285SAndroid Build Coastguard Worker default=[], 155*105f6285SAndroid Build Coastguard Worker action='append', 156*105f6285SAndroid Build Coastguard Worker help='Specify an environment variable to the NSJail sandbox. Can be specified ' 157*105f6285SAndroid Build Coastguard Worker 'muliple times. Syntax: var_name=value') 158*105f6285SAndroid Build Coastguard Worker parser.add_argument( 159*105f6285SAndroid Build Coastguard Worker '--dist_dir', 160*105f6285SAndroid Build Coastguard Worker help='Path to the Android dist directory. This is where ' 161*105f6285SAndroid Build Coastguard Worker 'Android platform release artifacts will be written.') 162*105f6285SAndroid Build Coastguard Worker parser.add_argument( 163*105f6285SAndroid Build Coastguard Worker '--build_id', 164*105f6285SAndroid Build Coastguard Worker help='Build identifier what will label the Android platform ' 165*105f6285SAndroid Build Coastguard Worker 'release artifacts.') 166*105f6285SAndroid Build Coastguard Worker parser.add_argument( 167*105f6285SAndroid Build Coastguard Worker '--max_cpus', 168*105f6285SAndroid Build Coastguard Worker type=int, 169*105f6285SAndroid Build Coastguard Worker help='Limit of concurrent CPU cores that the NsJail sanbox ' 170*105f6285SAndroid Build Coastguard Worker 'can use.') 171*105f6285SAndroid Build Coastguard Worker parser.add_argument( 172*105f6285SAndroid Build Coastguard Worker '--context', 173*105f6285SAndroid Build Coastguard Worker action='append', 174*105f6285SAndroid Build Coastguard Worker default=[], 175*105f6285SAndroid Build Coastguard Worker help='One or more contexts used to select build goals from the ' 176*105f6285SAndroid Build Coastguard Worker 'configuration.') 177*105f6285SAndroid Build Coastguard Worker parser.add_argument( 178*105f6285SAndroid Build Coastguard Worker '--use_rbe', action='store_true', help='Executes the build on RBE') 179*105f6285SAndroid Build Coastguard Worker return parser 180*105f6285SAndroid Build Coastguard Worker 181*105f6285SAndroid Build Coastguard Worker 182*105f6285SAndroid Build Coastguard Workerdef parse_args(parser): 183*105f6285SAndroid Build Coastguard Worker """Parses command line arguments. 184*105f6285SAndroid Build Coastguard Worker 185*105f6285SAndroid Build Coastguard Worker Returns: 186*105f6285SAndroid Build Coastguard Worker A dict of all the arguments parsed. 187*105f6285SAndroid Build Coastguard Worker """ 188*105f6285SAndroid Build Coastguard Worker # Convert the Namespace object to a dict 189*105f6285SAndroid Build Coastguard Worker return vars(parser.parse_args()) 190*105f6285SAndroid Build Coastguard Worker 191*105f6285SAndroid Build Coastguard Worker 192*105f6285SAndroid Build Coastguard Workerdef main(): 193*105f6285SAndroid Build Coastguard Worker args = parse_args(arg_parser()) 194*105f6285SAndroid Build Coastguard Worker 195*105f6285SAndroid Build Coastguard Worker # The --build_target argument could not be required 196*105f6285SAndroid Build Coastguard Worker # using the standard 'required' argparse option because 197*105f6285SAndroid Build Coastguard Worker # the argparser is reused by merge_android_sandboxed.py which 198*105f6285SAndroid Build Coastguard Worker # does not require --build_target. 199*105f6285SAndroid Build Coastguard Worker if args['build_target'] is None: 200*105f6285SAndroid Build Coastguard Worker raise ValueError('--build_target is required.') 201*105f6285SAndroid Build Coastguard Worker 202*105f6285SAndroid Build Coastguard Worker cfg = config.Config(args['config_file']) 203*105f6285SAndroid Build Coastguard Worker build_goals = cfg.get_build_goals(args['build_target'], set(args['context'])) 204*105f6285SAndroid Build Coastguard Worker build_flags = cfg.get_build_flags(args['build_target'], set(args['context'])) 205*105f6285SAndroid Build Coastguard Worker 206*105f6285SAndroid Build Coastguard Worker build( 207*105f6285SAndroid Build Coastguard Worker build_target=args['build_target'], 208*105f6285SAndroid Build Coastguard Worker release_target=args['release_target'], 209*105f6285SAndroid Build Coastguard Worker variant=args['variant'], 210*105f6285SAndroid Build Coastguard Worker nsjail_bin=args['nsjail_bin'], 211*105f6285SAndroid Build Coastguard Worker chroot=args['chroot'], 212*105f6285SAndroid Build Coastguard Worker config_file=args['config_file'], 213*105f6285SAndroid Build Coastguard Worker command_wrapper=args['command_wrapper'], 214*105f6285SAndroid Build Coastguard Worker readonly_bind_mounts=args['readonly_bind_mount'], 215*105f6285SAndroid Build Coastguard Worker env=args['env'], 216*105f6285SAndroid Build Coastguard Worker dist_dir=args['dist_dir'], 217*105f6285SAndroid Build Coastguard Worker build_id=args['build_id'], 218*105f6285SAndroid Build Coastguard Worker max_cpus=args['max_cpus'], 219*105f6285SAndroid Build Coastguard Worker use_rbe=args['use_rbe'], 220*105f6285SAndroid Build Coastguard Worker build_goals=build_goals + build_flags) 221*105f6285SAndroid Build Coastguard Worker 222*105f6285SAndroid Build Coastguard Worker 223*105f6285SAndroid Build Coastguard Workerif __name__ == '__main__': 224*105f6285SAndroid Build Coastguard Worker main() 225