Justin Suen | f9095ee | 2021-06-25 18:25:44 +0000 | [diff] [blame] | 1 | #!/usr/bin/env python3 |
| 2 | # -*- coding: utf-8 -*- |
| 3 | |
| 4 | # Copyright 2021 The Chromium OS Authors. All rights reserved. |
| 5 | # Use of this source code is governed by a BSD-style license that can be |
| 6 | # found in the LICENSE file. |
Justin Suen | 0d7a909 | 2021-09-07 17:41:38 +0000 | [diff] [blame^] | 7 | """Marshal various scheduling configs. Store them into the UFS datastore |
Justin Suen | 84529bd | 2021-07-22 18:06:48 +0000 | [diff] [blame] | 8 | through the Google datastore API. |
Justin Suen | f9095ee | 2021-06-25 18:25:44 +0000 | [diff] [blame] | 9 | |
Justin Suen | 84529bd | 2021-07-22 18:06:48 +0000 | [diff] [blame] | 10 | By default, this script converts a few config-related protos into datastore |
| 11 | entities: |
| 12 | |
| 13 | 1. ConfigBundleList from 'hw_design/generated/configs.jsonproto' |
| 14 | 2. DutAttributeList from 'dut_attributes/generated/dut_attributes.jsonproto' |
Justin Suen | 5aaa7cd | 2021-09-01 08:55:53 +0000 | [diff] [blame] | 15 | 3. FlatConfigList from 'hw_design/generated/flattened.jsonproto' |
Justin Suen | 0d7a909 | 2021-09-07 17:41:38 +0000 | [diff] [blame^] | 16 | 4. DeviceStabilityList from |
| 17 | '.../chromiumos/infra/config/testingconfig/generated/device_stability.cfg' |
Justin Suen | 84529bd | 2021-07-22 18:06:48 +0000 | [diff] [blame] | 18 | |
| 19 | The lists are parsed and individual entities are extracted. Using the datastore |
| 20 | client specified, it encodes the protos as datastore entities and stores them |
| 21 | into the UFS datastore. |
Justin Suen | f9095ee | 2021-06-25 18:25:44 +0000 | [diff] [blame] | 22 | """ |
| 23 | |
| 24 | import argparse |
| 25 | import datetime |
| 26 | import logging |
Justin Suen | 0d7a909 | 2021-09-07 17:41:38 +0000 | [diff] [blame^] | 27 | import os |
Justin Suen | f9095ee | 2021-06-25 18:25:44 +0000 | [diff] [blame] | 28 | |
| 29 | from google.cloud import datastore |
| 30 | |
| 31 | from checker import io_utils |
| 32 | from common import proto_utils |
| 33 | |
| 34 | # type constants |
Justin Suen | 84529bd | 2021-07-22 18:06:48 +0000 | [diff] [blame] | 35 | CB_INPUT_TYPE = 'chromiumos.config.payload.ConfigBundleList' |
| 36 | CB_OUTPUT_TYPE = 'chromiumos.config.payload.ConfigBundle' |
| 37 | DA_INPUT_TYPE = 'chromiumos.test.api.DutAttributeList' |
| 38 | DA_OUTPUT_TYPE = 'chromiumos.test.api.DutAttribute' |
Justin Suen | 5aaa7cd | 2021-09-01 08:55:53 +0000 | [diff] [blame] | 39 | FC_INPUT_TYPE = 'chromiumos.config.payload.FlatConfigList' |
| 40 | FC_OUTPUT_TYPE = 'chromiumos.config.payload.FlatConfig' |
Justin Suen | 0d7a909 | 2021-09-07 17:41:38 +0000 | [diff] [blame^] | 41 | DEV_STAB_INPUT_TYPE = 'chromiumos.test.dut.DeviceStabilityList' |
| 42 | DEV_STAB_OUTPUT_TYPE = 'chromiumos.test.dut.DeviceStability' |
Justin Suen | f9095ee | 2021-06-25 18:25:44 +0000 | [diff] [blame] | 43 | |
| 44 | # UFS services |
| 45 | UFS_DEV_PROJECT = 'unified-fleet-system-dev' |
| 46 | UFS_PROD_PROJECT = 'unified-fleet-system' |
| 47 | |
| 48 | # datastore constants |
| 49 | CONFIG_BUNDLE_KIND = 'ConfigBundle' |
Justin Suen | 84529bd | 2021-07-22 18:06:48 +0000 | [diff] [blame] | 50 | DUT_ATTRIBUTE_KIND = 'DutAttribute' |
Justin Suen | 5aaa7cd | 2021-09-01 08:55:53 +0000 | [diff] [blame] | 51 | FLAT_CONFIG_KIND = 'FlatConfig' |
Justin Suen | 0d7a909 | 2021-09-07 17:41:38 +0000 | [diff] [blame^] | 52 | DEVICE_STABILITY_KIND = 'DeviceStability' |
Justin Suen | f9095ee | 2021-06-25 18:25:44 +0000 | [diff] [blame] | 53 | |
| 54 | |
| 55 | def get_ufs_project(env): |
| 56 | """Return project name based on env argument.""" |
| 57 | if env == 'dev': |
| 58 | return UFS_DEV_PROJECT |
| 59 | if env == 'prod': |
| 60 | return UFS_PROD_PROJECT |
| 61 | raise RuntimeError('get_ufs_project: environment %s not supported' % env) |
| 62 | |
| 63 | |
Justin Suen | 5aaa7cd | 2021-09-01 08:55:53 +0000 | [diff] [blame] | 64 | def generate_config_bundle_id(bundle): |
Justin Suen | f9095ee | 2021-06-25 18:25:44 +0000 | [diff] [blame] | 65 | """Generate ConfigBundleEntity id as ${program_id}-${design_id}.""" |
| 66 | return bundle.design_list[0].program_id.value + '-' + bundle.design_list[ |
| 67 | 0].id.value |
| 68 | |
| 69 | |
Justin Suen | 0d7a909 | 2021-09-07 17:41:38 +0000 | [diff] [blame^] | 70 | def handle_config_bundle_list(cb_list_path, client): |
Justin Suen | 84529bd | 2021-07-22 18:06:48 +0000 | [diff] [blame] | 71 | """Take a path to a ConfigBundleList, iterate through the list and store into |
| 72 | UFS datastore based on env. |
| 73 | """ |
| 74 | cb_list = io_utils.read_json_proto( |
| 75 | protodb.GetSymbol(CB_INPUT_TYPE)(), cb_list_path) |
| 76 | |
| 77 | for config_bundle in cb_list.values: |
Justin Suen | 0d7a909 | 2021-09-07 17:41:38 +0000 | [diff] [blame^] | 78 | update_config(config_bundle, client, flat=False) |
Justin Suen | 84529bd | 2021-07-22 18:06:48 +0000 | [diff] [blame] | 79 | |
| 80 | |
Justin Suen | 5aaa7cd | 2021-09-01 08:55:53 +0000 | [diff] [blame] | 81 | def generate_flat_config_id(bundle): |
| 82 | """Generate FlatConfigEntity id as ${program_id}-${design_id}-${design_config_id} |
| 83 | if design_config_id is available. Else ${program_id}-${design_id}.""" |
| 84 | if bundle.hw_design_config.id.value: |
| 85 | return bundle.hw_design.program_id.value + '-' + bundle.hw_design.id.value \ |
| 86 | + '-' + bundle.hw_design_config.id.value |
| 87 | return bundle.hw_design.program_id.value + '-' + bundle.hw_design.id.value |
| 88 | |
| 89 | |
Justin Suen | 0d7a909 | 2021-09-07 17:41:38 +0000 | [diff] [blame^] | 90 | def handle_flat_config_list(fc_list_path, client): |
Justin Suen | 5aaa7cd | 2021-09-01 08:55:53 +0000 | [diff] [blame] | 91 | """Take a path to a FlatConfigList, iterate through the list and store into |
| 92 | UFS datastore based on env. |
| 93 | """ |
| 94 | fc_list = io_utils.read_json_proto( |
| 95 | protodb.GetSymbol(FC_INPUT_TYPE)(), fc_list_path) |
| 96 | |
| 97 | for flat_config in fc_list.values: |
Justin Suen | 0d7a909 | 2021-09-07 17:41:38 +0000 | [diff] [blame^] | 98 | update_config(flat_config, client, flat=True) |
Justin Suen | 5aaa7cd | 2021-09-01 08:55:53 +0000 | [diff] [blame] | 99 | |
| 100 | |
Justin Suen | 0d7a909 | 2021-09-07 17:41:38 +0000 | [diff] [blame^] | 101 | def update_config(config, client, flat=False): |
Justin Suen | 5aaa7cd | 2021-09-01 08:55:53 +0000 | [diff] [blame] | 102 | """Take a ConfigBundle or FlatConfig and store it an an entity in the UFS datastore.""" |
| 103 | if flat: |
| 104 | kind = FLAT_CONFIG_KIND |
| 105 | eid = generate_flat_config_id(config) |
| 106 | else: |
| 107 | kind = CONFIG_BUNDLE_KIND |
| 108 | eid = generate_config_bundle_id(config) |
| 109 | logging.info('update_config: handling %s', eid) |
Justin Suen | f9095ee | 2021-06-25 18:25:44 +0000 | [diff] [blame] | 110 | |
Justin Suen | 5aaa7cd | 2021-09-01 08:55:53 +0000 | [diff] [blame] | 111 | key = client.key(kind, eid) |
Justin Suen | f9095ee | 2021-06-25 18:25:44 +0000 | [diff] [blame] | 112 | entity = datastore.Entity( |
| 113 | key=key, |
| 114 | exclude_from_indexes=['ConfigData'], |
| 115 | ) |
Justin Suen | 5aaa7cd | 2021-09-01 08:55:53 +0000 | [diff] [blame] | 116 | entity['ConfigData'] = config.SerializeToString() |
Justin Suen | f9095ee | 2021-06-25 18:25:44 +0000 | [diff] [blame] | 117 | entity['updated'] = datetime.datetime.now() |
| 118 | |
Justin Suen | 5aaa7cd | 2021-09-01 08:55:53 +0000 | [diff] [blame] | 119 | logging.info('update_config: putting entity into datastore for %s', eid) |
Justin Suen | 84529bd | 2021-07-22 18:06:48 +0000 | [diff] [blame] | 120 | client.put(entity) |
| 121 | |
| 122 | |
Justin Suen | 0d7a909 | 2021-09-07 17:41:38 +0000 | [diff] [blame^] | 123 | def handle_dut_attribute_list(dut_attr_list_path, client): |
Justin Suen | 84529bd | 2021-07-22 18:06:48 +0000 | [diff] [blame] | 124 | """Take a path to a DutAttributeList, iterate through the list and store into |
| 125 | UFS datastore based on env. |
| 126 | """ |
| 127 | dut_attr_list = io_utils.read_json_proto( |
| 128 | protodb.GetSymbol(DA_INPUT_TYPE)(), dut_attr_list_path) |
| 129 | |
| 130 | for dut_attribute in dut_attr_list.dut_attributes: |
Justin Suen | 0d7a909 | 2021-09-07 17:41:38 +0000 | [diff] [blame^] | 131 | update_dut_attribute(dut_attribute, client) |
Justin Suen | 84529bd | 2021-07-22 18:06:48 +0000 | [diff] [blame] | 132 | |
| 133 | |
Justin Suen | 0d7a909 | 2021-09-07 17:41:38 +0000 | [diff] [blame^] | 134 | def update_dut_attribute(attr, client): |
Justin Suen | 84529bd | 2021-07-22 18:06:48 +0000 | [diff] [blame] | 135 | """Take a DutAttribute and store it in the UFS datastore as a DutAttributeEntity.""" |
| 136 | eid = attr.id.value |
| 137 | logging.info('update_dut_attribute: handling %s', eid) |
| 138 | |
Justin Suen | 84529bd | 2021-07-22 18:06:48 +0000 | [diff] [blame] | 139 | key = client.key(DUT_ATTRIBUTE_KIND, eid) |
| 140 | entity = datastore.Entity( |
| 141 | key=key, |
| 142 | exclude_from_indexes=['AttributeData'], |
| 143 | ) |
| 144 | entity['AttributeData'] = attr.SerializeToString() |
| 145 | entity['updated'] = datetime.datetime.now() |
| 146 | |
| 147 | logging.info('update_dut_attribute: putting entity into datastore for %s', |
| 148 | eid) |
| 149 | client.put(entity) |
Justin Suen | f9095ee | 2021-06-25 18:25:44 +0000 | [diff] [blame] | 150 | |
| 151 | |
Justin Suen | 0d7a909 | 2021-09-07 17:41:38 +0000 | [diff] [blame^] | 152 | def handle_device_stability_list(dev_stab_list_path, client): |
| 153 | """Take a path to a DeviceStabilityList, iterate through the list and store |
| 154 | into UFS datastore based on env. |
| 155 | """ |
| 156 | dev_stab_list = io_utils.read_json_proto( |
| 157 | protodb.GetSymbol(DEV_STAB_INPUT_TYPE)(), dev_stab_list_path) |
| 158 | |
| 159 | for dev_stab in dev_stab_list.values: |
| 160 | update_device_stability(dev_stab, client) |
| 161 | |
| 162 | |
| 163 | def update_device_stability(dev_stab, client): |
| 164 | """Take a DeviceStability and store it in the UFS datastore as a |
| 165 | DeviceStabilityEntity. |
| 166 | """ |
| 167 | # TODO (justinsuen): May need to change this eventually. This assumes the use |
| 168 | # of a single model (DutAttribute ID design_id) when defining a |
| 169 | # DeviceStability entry. |
| 170 | # http://cs/chromeos_internal/infra/config/testingconfig/target_test_requirements_config_helper.star?l=155 |
| 171 | for eid in dev_stab.dut_criteria[0].values: |
| 172 | logging.info('update_device_stability: handling %s', eid) |
| 173 | |
| 174 | key = client.key(DEVICE_STABILITY_KIND, eid) |
| 175 | entity = datastore.Entity( |
| 176 | key=key, |
| 177 | exclude_from_indexes=['StabilityData'], |
| 178 | ) |
| 179 | entity['StabilityData'] = dev_stab.SerializeToString() |
| 180 | entity['updated'] = datetime.datetime.now() |
| 181 | |
| 182 | logging.info( |
| 183 | 'update_device_stability: putting entity into datastore for %s', eid) |
| 184 | client.put(entity) |
| 185 | |
| 186 | |
Justin Suen | f9095ee | 2021-06-25 18:25:44 +0000 | [diff] [blame] | 187 | if __name__ == '__main__': |
| 188 | logging.basicConfig(level=logging.INFO) |
| 189 | parser = argparse.ArgumentParser( |
| 190 | description=__doc__, |
| 191 | formatter_class=argparse.RawDescriptionHelpFormatter, |
| 192 | ) |
| 193 | |
| 194 | parser.add_argument( |
Justin Suen | f9095ee | 2021-06-25 18:25:44 +0000 | [diff] [blame] | 195 | '--env', |
| 196 | type=str, |
| 197 | default='dev', |
| 198 | help='environment flag for UFS service', |
| 199 | ) |
| 200 | |
| 201 | # load database of protobuffer name -> Type |
| 202 | protodb = proto_utils.create_symbol_db() |
Justin Suen | f9095ee | 2021-06-25 18:25:44 +0000 | [diff] [blame] | 203 | options = parser.parse_args() |
Justin Suen | 0d7a909 | 2021-09-07 17:41:38 +0000 | [diff] [blame^] | 204 | ufs_ds_client = datastore.Client(project=get_ufs_project(options.env),) |
| 205 | script_dir = os.path.dirname(os.path.realpath(__file__)) |
Justin Suen | f9095ee | 2021-06-25 18:25:44 +0000 | [diff] [blame] | 206 | |
Justin Suen | 84529bd | 2021-07-22 18:06:48 +0000 | [diff] [blame] | 207 | handle_config_bundle_list("hw_design/generated/configs.jsonproto", |
Justin Suen | 0d7a909 | 2021-09-07 17:41:38 +0000 | [diff] [blame^] | 208 | ufs_ds_client) |
Justin Suen | 84529bd | 2021-07-22 18:06:48 +0000 | [diff] [blame] | 209 | handle_dut_attribute_list("dut_attributes/generated/dut_attributes.jsonproto", |
Justin Suen | 0d7a909 | 2021-09-07 17:41:38 +0000 | [diff] [blame^] | 210 | ufs_ds_client) |
Justin Suen | 5aaa7cd | 2021-09-01 08:55:53 +0000 | [diff] [blame] | 211 | handle_flat_config_list("hw_design/generated/flattened.jsonproto", |
Justin Suen | 0d7a909 | 2021-09-07 17:41:38 +0000 | [diff] [blame^] | 212 | ufs_ds_client) |
| 213 | handle_device_stability_list( |
| 214 | os.path.realpath( |
| 215 | os.path.join( |
| 216 | script_dir, |
| 217 | "/../../../infra/config/testingconfig/generated/device_stability.cfg" |
| 218 | )), ufs_ds_client) |