blob: 958c1f0557b135351727cf2cddb6f7cb93959ff0 [file] [log] [blame]
Justin Suenf9095ee2021-06-25 18:25:44 +00001#!/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 Suen84529bd2021-07-22 18:06:48 +00007"""Marshal ConfigBundles and DutAttributes. Store them into the UFS datastore
8through the Google datastore API.
Justin Suenf9095ee2021-06-25 18:25:44 +00009
Justin Suen84529bd2021-07-22 18:06:48 +000010By default, this script converts a few config-related protos into datastore
11entities:
12
131. ConfigBundleList from 'hw_design/generated/configs.jsonproto'
142. DutAttributeList from 'dut_attributes/generated/dut_attributes.jsonproto'
15
16The lists are parsed and individual entities are extracted. Using the datastore
17client specified, it encodes the protos as datastore entities and stores them
18into the UFS datastore.
Justin Suenf9095ee2021-06-25 18:25:44 +000019"""
20
21import argparse
22import datetime
23import logging
24
25from google.cloud import datastore
26
27from checker import io_utils
28from common import proto_utils
29
30# type constants
Justin Suen84529bd2021-07-22 18:06:48 +000031CB_INPUT_TYPE = 'chromiumos.config.payload.ConfigBundleList'
32CB_OUTPUT_TYPE = 'chromiumos.config.payload.ConfigBundle'
33DA_INPUT_TYPE = 'chromiumos.test.api.DutAttributeList'
34DA_OUTPUT_TYPE = 'chromiumos.test.api.DutAttribute'
Justin Suenf9095ee2021-06-25 18:25:44 +000035
36# UFS services
37UFS_DEV_PROJECT = 'unified-fleet-system-dev'
38UFS_PROD_PROJECT = 'unified-fleet-system'
39
40# datastore constants
41CONFIG_BUNDLE_KIND = 'ConfigBundle'
Justin Suen84529bd2021-07-22 18:06:48 +000042DUT_ATTRIBUTE_KIND = 'DutAttribute'
Justin Suenf9095ee2021-06-25 18:25:44 +000043
44
45def 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
54def 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 Suen84529bd2021-07-22 18:06:48 +000060def 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 Suenf9095ee2021-06-25 18:25:44 +000071def 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 Suen84529bd2021-07-22 18:06:48 +000085 logging.info('update_config_bundle: putting entity into datastore for %s',
86 eid)
87 client.put(entity)
88
89
90def 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
101def 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 Suenf9095ee2021-06-25 18:25:44 +0000118
119
120if __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 Suenf9095ee2021-06-25 18:25:44 +0000128 '--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 Suenf9095ee2021-06-25 18:25:44 +0000136 options = parser.parse_args()
Justin Suenf9095ee2021-06-25 18:25:44 +0000137
Justin Suen84529bd2021-07-22 18:06:48 +0000138 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)