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. |
| 7 | """Marshal ConfigBundles and store them into the UFS datastore through the Google datastore API. |
| 8 | |
| 9 | By default, this function reads a ConfigBundleList from |
| 10 | 'hw_design/generated/configs.jsonproto' and parses ConfigBundles from it. Using |
| 11 | the API specified, it encodes the ConfigBundle as a ConfigBundleEntity and |
| 12 | stores it into the UFS datastore. |
| 13 | """ |
| 14 | |
| 15 | import argparse |
| 16 | import datetime |
| 17 | import logging |
| 18 | |
| 19 | from google.cloud import datastore |
| 20 | |
| 21 | from checker import io_utils |
| 22 | from common import proto_utils |
| 23 | |
| 24 | # type constants |
| 25 | INPUT_TYPE = 'chromiumos.config.payload.ConfigBundleList' |
| 26 | OUTPUT_TYPE = 'chromiumos.config.payload.ConfigBundle' |
| 27 | |
| 28 | # UFS services |
| 29 | UFS_DEV_PROJECT = 'unified-fleet-system-dev' |
| 30 | UFS_PROD_PROJECT = 'unified-fleet-system' |
| 31 | |
| 32 | # datastore constants |
| 33 | CONFIG_BUNDLE_KIND = 'ConfigBundle' |
| 34 | |
| 35 | |
| 36 | def get_ufs_project(env): |
| 37 | """Return project name based on env argument.""" |
| 38 | if env == 'dev': |
| 39 | return UFS_DEV_PROJECT |
| 40 | if env == 'prod': |
| 41 | return UFS_PROD_PROJECT |
| 42 | raise RuntimeError('get_ufs_project: environment %s not supported' % env) |
| 43 | |
| 44 | |
| 45 | def generate_entity_id(bundle): |
| 46 | """Generate ConfigBundleEntity id as ${program_id}-${design_id}.""" |
| 47 | return bundle.design_list[0].program_id.value + '-' + bundle.design_list[ |
| 48 | 0].id.value |
| 49 | |
| 50 | |
| 51 | def update_config_bundle(bundle, project): |
| 52 | """Take a ConfigBundle and store it in the UFS datastore as a ConfigBundleEntity.""" |
| 53 | eid = generate_entity_id(bundle) |
| 54 | logging.info('update_config_bundle: handling %s', eid) |
| 55 | |
| 56 | client = datastore.Client(project=project,) |
| 57 | key = client.key(CONFIG_BUNDLE_KIND, eid) |
| 58 | entity = datastore.Entity( |
| 59 | key=key, |
| 60 | exclude_from_indexes=['ConfigData'], |
| 61 | ) |
| 62 | entity['ConfigData'] = bundle.SerializeToString() |
| 63 | entity['updated'] = datetime.datetime.now() |
| 64 | |
| 65 | try: |
| 66 | logging.info('update_config_bundle: putting entity into datastore for %s', |
| 67 | eid) |
| 68 | client.put(entity) |
| 69 | except Exception as err: # pylint: disable=broad-except |
| 70 | logging.exception('update_config_bundle: %s', err) |
| 71 | |
| 72 | |
| 73 | if __name__ == '__main__': |
| 74 | logging.basicConfig(level=logging.INFO) |
| 75 | parser = argparse.ArgumentParser( |
| 76 | description=__doc__, |
| 77 | formatter_class=argparse.RawDescriptionHelpFormatter, |
| 78 | ) |
| 79 | |
| 80 | parser.add_argument( |
| 81 | 'input', |
| 82 | type=str, |
| 83 | help='message to read in jsonproto format', |
| 84 | ) |
| 85 | |
| 86 | parser.add_argument( |
| 87 | '--env', |
| 88 | type=str, |
| 89 | default='dev', |
| 90 | help='environment flag for UFS service', |
| 91 | ) |
| 92 | |
| 93 | # load database of protobuffer name -> Type |
| 94 | protodb = proto_utils.create_symbol_db() |
| 95 | |
| 96 | options = parser.parse_args() |
| 97 | output = protodb.GetSymbol(OUTPUT_TYPE)() |
| 98 | |
| 99 | # read ConfigBundleList from options.input |
| 100 | cb_list = io_utils.read_json_proto( |
| 101 | protodb.GetSymbol(INPUT_TYPE)(), options.input) |
| 102 | |
| 103 | for config_bundle in cb_list.values: |
| 104 | update_config_bundle(config_bundle, get_ufs_project(options.env)) |