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 | 84529bd | 2021-07-22 18:06:48 +0000 | [diff] [blame] | 7 | """Marshal ConfigBundles and DutAttributes. Store them into the UFS datastore |
| 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' |
| 15 | |
| 16 | The lists are parsed and individual entities are extracted. Using the datastore |
| 17 | client specified, it encodes the protos as datastore entities and stores them |
| 18 | into the UFS datastore. |
Justin Suen | f9095ee | 2021-06-25 18:25:44 +0000 | [diff] [blame] | 19 | """ |
| 20 | |
| 21 | import argparse |
| 22 | import datetime |
| 23 | import logging |
| 24 | |
| 25 | from google.cloud import datastore |
| 26 | |
| 27 | from checker import io_utils |
| 28 | from common import proto_utils |
| 29 | |
| 30 | # type constants |
Justin Suen | 84529bd | 2021-07-22 18:06:48 +0000 | [diff] [blame] | 31 | CB_INPUT_TYPE = 'chromiumos.config.payload.ConfigBundleList' |
| 32 | CB_OUTPUT_TYPE = 'chromiumos.config.payload.ConfigBundle' |
| 33 | DA_INPUT_TYPE = 'chromiumos.test.api.DutAttributeList' |
| 34 | DA_OUTPUT_TYPE = 'chromiumos.test.api.DutAttribute' |
Justin Suen | f9095ee | 2021-06-25 18:25:44 +0000 | [diff] [blame] | 35 | |
| 36 | # UFS services |
| 37 | UFS_DEV_PROJECT = 'unified-fleet-system-dev' |
| 38 | UFS_PROD_PROJECT = 'unified-fleet-system' |
| 39 | |
| 40 | # datastore constants |
| 41 | CONFIG_BUNDLE_KIND = 'ConfigBundle' |
Justin Suen | 84529bd | 2021-07-22 18:06:48 +0000 | [diff] [blame] | 42 | DUT_ATTRIBUTE_KIND = 'DutAttribute' |
Justin Suen | f9095ee | 2021-06-25 18:25:44 +0000 | [diff] [blame] | 43 | |
| 44 | |
| 45 | def get_ufs_project(env): |
| 46 | """Return project name based on env argument.""" |
| 47 | if env == 'dev': |
| 48 | return UFS_DEV_PROJECT |
| 49 | if env == 'prod': |
| 50 | return UFS_PROD_PROJECT |
| 51 | raise RuntimeError('get_ufs_project: environment %s not supported' % env) |
| 52 | |
| 53 | |
| 54 | def generate_entity_id(bundle): |
| 55 | """Generate ConfigBundleEntity id as ${program_id}-${design_id}.""" |
| 56 | return bundle.design_list[0].program_id.value + '-' + bundle.design_list[ |
| 57 | 0].id.value |
| 58 | |
| 59 | |
Justin Suen | 84529bd | 2021-07-22 18:06:48 +0000 | [diff] [blame] | 60 | def handle_config_bundle_list(cb_list_path, env): |
| 61 | """Take a path to a ConfigBundleList, iterate through the list and store into |
| 62 | UFS datastore based on env. |
| 63 | """ |
| 64 | cb_list = io_utils.read_json_proto( |
| 65 | protodb.GetSymbol(CB_INPUT_TYPE)(), cb_list_path) |
| 66 | |
| 67 | for config_bundle in cb_list.values: |
| 68 | update_config_bundle(config_bundle, get_ufs_project(env)) |
| 69 | |
| 70 | |
Justin Suen | f9095ee | 2021-06-25 18:25:44 +0000 | [diff] [blame] | 71 | def update_config_bundle(bundle, project): |
| 72 | """Take a ConfigBundle and store it in the UFS datastore as a ConfigBundleEntity.""" |
| 73 | eid = generate_entity_id(bundle) |
| 74 | logging.info('update_config_bundle: handling %s', eid) |
| 75 | |
| 76 | client = datastore.Client(project=project,) |
| 77 | key = client.key(CONFIG_BUNDLE_KIND, eid) |
| 78 | entity = datastore.Entity( |
| 79 | key=key, |
| 80 | exclude_from_indexes=['ConfigData'], |
| 81 | ) |
| 82 | entity['ConfigData'] = bundle.SerializeToString() |
| 83 | entity['updated'] = datetime.datetime.now() |
| 84 | |
Justin Suen | 84529bd | 2021-07-22 18:06:48 +0000 | [diff] [blame] | 85 | logging.info('update_config_bundle: putting entity into datastore for %s', |
| 86 | eid) |
| 87 | client.put(entity) |
| 88 | |
| 89 | |
| 90 | def handle_dut_attribute_list(dut_attr_list_path, env): |
| 91 | """Take a path to a DutAttributeList, iterate through the list and store into |
| 92 | UFS datastore based on env. |
| 93 | """ |
| 94 | dut_attr_list = io_utils.read_json_proto( |
| 95 | protodb.GetSymbol(DA_INPUT_TYPE)(), dut_attr_list_path) |
| 96 | |
| 97 | for dut_attribute in dut_attr_list.dut_attributes: |
| 98 | update_dut_attribute(dut_attribute, get_ufs_project(env)) |
| 99 | |
| 100 | |
| 101 | def update_dut_attribute(attr, project): |
| 102 | """Take a DutAttribute and store it in the UFS datastore as a DutAttributeEntity.""" |
| 103 | eid = attr.id.value |
| 104 | logging.info('update_dut_attribute: handling %s', eid) |
| 105 | |
| 106 | client = datastore.Client(project=project,) |
| 107 | key = client.key(DUT_ATTRIBUTE_KIND, eid) |
| 108 | entity = datastore.Entity( |
| 109 | key=key, |
| 110 | exclude_from_indexes=['AttributeData'], |
| 111 | ) |
| 112 | entity['AttributeData'] = attr.SerializeToString() |
| 113 | entity['updated'] = datetime.datetime.now() |
| 114 | |
| 115 | logging.info('update_dut_attribute: putting entity into datastore for %s', |
| 116 | eid) |
| 117 | client.put(entity) |
Justin Suen | f9095ee | 2021-06-25 18:25:44 +0000 | [diff] [blame] | 118 | |
| 119 | |
| 120 | if __name__ == '__main__': |
| 121 | logging.basicConfig(level=logging.INFO) |
| 122 | parser = argparse.ArgumentParser( |
| 123 | description=__doc__, |
| 124 | formatter_class=argparse.RawDescriptionHelpFormatter, |
| 125 | ) |
| 126 | |
| 127 | parser.add_argument( |
Justin Suen | f9095ee | 2021-06-25 18:25:44 +0000 | [diff] [blame] | 128 | '--env', |
| 129 | type=str, |
| 130 | default='dev', |
| 131 | help='environment flag for UFS service', |
| 132 | ) |
| 133 | |
| 134 | # load database of protobuffer name -> Type |
| 135 | protodb = proto_utils.create_symbol_db() |
Justin Suen | f9095ee | 2021-06-25 18:25:44 +0000 | [diff] [blame] | 136 | options = parser.parse_args() |
Justin Suen | f9095ee | 2021-06-25 18:25:44 +0000 | [diff] [blame] | 137 | |
Justin Suen | 84529bd | 2021-07-22 18:06:48 +0000 | [diff] [blame] | 138 | handle_config_bundle_list("hw_design/generated/configs.jsonproto", |
| 139 | options.env) |
| 140 | handle_dut_attribute_list("dut_attributes/generated/dut_attributes.jsonproto", |
| 141 | options.env) |