1#!/usr/bin/env vpython3 2# Copyright 2021 The ChromiumOS Authors 3# Use of this source code is governed by a BSD-style license that can be 4# found in the LICENSE file. 5"""Join program stubs from project payloads to make full payloads. Projects 6set a Program instance with only the ID set. We need to lookup that program 7in the full set of flattened configs and populate it before materializing the 8flattened protos. 9""" 10import argparse 11import logging 12 13from checker import io_utils 14 15from chromiumos.config.payload.config_bundle_pb2 import ConfigBundleList 16from chromiumos.config.payload.flat_config_pb2 import FlatConfigList 17 18 19def main(opts): 20 """Perform Program join operation on project configs.""" 21 logging.debug('Reading program configs') 22 program_configs = io_utils.read_json_proto( 23 ConfigBundleList(), 24 opts.program_configs, 25 ) 26 27 logging.debug('Reading project configs') 28 project_configs = io_utils.read_json_proto( 29 FlatConfigList(), 30 opts.project_configs, 31 ) 32 33 # Map program id => program proto 34 logging.debug('Generating program map') 35 program_map = {} 36 for config in program_configs.values: 37 for program in config.program_list: 38 program_id = program.id.value.lower() 39 logging.info('Saw config for program %s', program_id) 40 program_map[program_id] = program 41 42 # Fill in project configs 43 logging.debug('Populating program payloads') 44 for config in project_configs.values: 45 program_id = config.hw_design.program_id.value.lower() 46 program_config = program_map.get(program_id) 47 if program_config: 48 logging.debug( 49 ' Linking design %s to program %s', 50 config.hw_design_config.id.value, 51 config.program.id.value, 52 ) 53 config.program.CopyFrom(program_config) 54 55 logging.debug('Writing output') 56 io_utils.write_message_json(project_configs, opts.output) 57 58 if opts.binary_output: 59 io_utils.write_message_binary(project_configs, opts.binary_output) 60 61 62if __name__ == "__main__": 63 parser = argparse.ArgumentParser(description=__doc__) 64 parser.add_argument( 65 '-o', 66 '--output', 67 type=str, 68 required=True, 69 help='file to write joined payload to') 70 71 parser.add_argument( 72 '-b', 73 '--binary-output', 74 type=str, 75 help=('file to write the joined payload to in binary wire format, in ' 76 'addition to the jsonpb written to --output.')) 77 78 parser.add_argument( 79 '-i', 80 '--project-configs', 81 type=str, 82 required=True, 83 help='file containing FlatConfigList with project ConfigBundles to join') 84 85 parser.add_argument( 86 '-p', 87 '--program-configs', 88 type=str, 89 required=True, 90 help='file containing ConfigBundleList with program ConfigBundles') 91 92 parser.add_argument( 93 "-v", "--verbose", help="increase output verbosity", action="store_true") 94 parser.add_argument("-l", "--log", type=str, help='set logging level') 95 96 args = parser.parse_args() 97 98 LOGLEVEL = logging.INFO if args.verbose else logging.WARNING 99 if args.log: 100 LOGLEVEL = { 101 "critical": logging.CRITICAL, 102 "debug": logging.DEBUG, 103 "error": logging.ERROR, 104 "info": logging.INFO, 105 "warning": logging.WARNING, 106 }.get(args.log.lower()) 107 108 if not LOGLEVEL: 109 logging.error("invalid value for -l/--log '%s'", args.log) 110 111 logging.basicConfig( 112 level=LOGLEVEL, 113 format='%(asctime)s %(levelname)-8s %(message)s', 114 datefmt='%Y-%m-%dT%H:%M:%S', 115 ) 116 117 main(args) 118