blob: b0336a15668ebfe8f3ad1236cbd06db056770575 [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 Suen0d7a9092021-09-07 17:41:38 +00007"""Marshal various scheduling configs. Store them into the UFS datastore
Justin Suen84529bd2021-07-22 18:06:48 +00008through 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'
Justin Suen5aaa7cd2021-09-01 08:55:53 +0000153. FlatConfigList from 'hw_design/generated/flattened.jsonproto'
Justin Suen0d7a9092021-09-07 17:41:38 +0000164. DeviceStabilityList from
17 '.../chromiumos/infra/config/testingconfig/generated/device_stability.cfg'
Justin Suen84529bd2021-07-22 18:06:48 +000018
19The lists are parsed and individual entities are extracted. Using the datastore
20client specified, it encodes the protos as datastore entities and stores them
21into the UFS datastore.
Justin Suenf9095ee2021-06-25 18:25:44 +000022"""
23
24import argparse
25import datetime
26import logging
Justin Suen0d7a9092021-09-07 17:41:38 +000027import os
Justin Suenf9095ee2021-06-25 18:25:44 +000028
29from google.cloud import datastore
30
31from checker import io_utils
32from common import proto_utils
33
34# type constants
Justin Suen84529bd2021-07-22 18:06:48 +000035CB_INPUT_TYPE = 'chromiumos.config.payload.ConfigBundleList'
36CB_OUTPUT_TYPE = 'chromiumos.config.payload.ConfigBundle'
37DA_INPUT_TYPE = 'chromiumos.test.api.DutAttributeList'
38DA_OUTPUT_TYPE = 'chromiumos.test.api.DutAttribute'
Justin Suen5aaa7cd2021-09-01 08:55:53 +000039FC_INPUT_TYPE = 'chromiumos.config.payload.FlatConfigList'
40FC_OUTPUT_TYPE = 'chromiumos.config.payload.FlatConfig'
Justin Suen0d7a9092021-09-07 17:41:38 +000041DEV_STAB_INPUT_TYPE = 'chromiumos.test.dut.DeviceStabilityList'
42DEV_STAB_OUTPUT_TYPE = 'chromiumos.test.dut.DeviceStability'
Justin Suenf9095ee2021-06-25 18:25:44 +000043
44# UFS services
45UFS_DEV_PROJECT = 'unified-fleet-system-dev'
46UFS_PROD_PROJECT = 'unified-fleet-system'
47
48# datastore constants
49CONFIG_BUNDLE_KIND = 'ConfigBundle'
Justin Suen84529bd2021-07-22 18:06:48 +000050DUT_ATTRIBUTE_KIND = 'DutAttribute'
Justin Suen5aaa7cd2021-09-01 08:55:53 +000051FLAT_CONFIG_KIND = 'FlatConfig'
Justin Suen0d7a9092021-09-07 17:41:38 +000052DEVICE_STABILITY_KIND = 'DeviceStability'
Justin Suenf9095ee2021-06-25 18:25:44 +000053
54
55def 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 Suen5aaa7cd2021-09-01 08:55:53 +000064def generate_config_bundle_id(bundle):
Justin Suenf9095ee2021-06-25 18:25:44 +000065 """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 Suen0d7a9092021-09-07 17:41:38 +000070def handle_config_bundle_list(cb_list_path, client):
Justin Suen84529bd2021-07-22 18:06:48 +000071 """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 Suen0d7a9092021-09-07 17:41:38 +000078 update_config(config_bundle, client, flat=False)
Justin Suen84529bd2021-07-22 18:06:48 +000079
80
Justin Suen5aaa7cd2021-09-01 08:55:53 +000081def 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 Suen0d7a9092021-09-07 17:41:38 +000090def handle_flat_config_list(fc_list_path, client):
Justin Suen5aaa7cd2021-09-01 08:55:53 +000091 """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 Suen0d7a9092021-09-07 17:41:38 +000098 update_config(flat_config, client, flat=True)
Justin Suen5aaa7cd2021-09-01 08:55:53 +000099
100
Justin Suen0d7a9092021-09-07 17:41:38 +0000101def update_config(config, client, flat=False):
Justin Suen5aaa7cd2021-09-01 08:55:53 +0000102 """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 Suenf9095ee2021-06-25 18:25:44 +0000110
Justin Suen5aaa7cd2021-09-01 08:55:53 +0000111 key = client.key(kind, eid)
Justin Suenf9095ee2021-06-25 18:25:44 +0000112 entity = datastore.Entity(
113 key=key,
114 exclude_from_indexes=['ConfigData'],
115 )
Justin Suen5aaa7cd2021-09-01 08:55:53 +0000116 entity['ConfigData'] = config.SerializeToString()
Justin Suenf9095ee2021-06-25 18:25:44 +0000117 entity['updated'] = datetime.datetime.now()
118
Justin Suen5aaa7cd2021-09-01 08:55:53 +0000119 logging.info('update_config: putting entity into datastore for %s', eid)
Justin Suen84529bd2021-07-22 18:06:48 +0000120 client.put(entity)
121
122
Justin Suen0d7a9092021-09-07 17:41:38 +0000123def handle_dut_attribute_list(dut_attr_list_path, client):
Justin Suen84529bd2021-07-22 18:06:48 +0000124 """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 Suen0d7a9092021-09-07 17:41:38 +0000131 update_dut_attribute(dut_attribute, client)
Justin Suen84529bd2021-07-22 18:06:48 +0000132
133
Justin Suen0d7a9092021-09-07 17:41:38 +0000134def update_dut_attribute(attr, client):
Justin Suen84529bd2021-07-22 18:06:48 +0000135 """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 Suen84529bd2021-07-22 18:06:48 +0000139 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 Suenf9095ee2021-06-25 18:25:44 +0000150
151
Justin Suen0d7a9092021-09-07 17:41:38 +0000152def 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
163def 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 Suenf9095ee2021-06-25 18:25:44 +0000187if __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 Suenf9095ee2021-06-25 18:25:44 +0000195 '--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 Suenf9095ee2021-06-25 18:25:44 +0000203 options = parser.parse_args()
Justin Suen0d7a9092021-09-07 17:41:38 +0000204 ufs_ds_client = datastore.Client(project=get_ufs_project(options.env),)
205 script_dir = os.path.dirname(os.path.realpath(__file__))
Justin Suenf9095ee2021-06-25 18:25:44 +0000206
Justin Suen84529bd2021-07-22 18:06:48 +0000207 handle_config_bundle_list("hw_design/generated/configs.jsonproto",
Justin Suen0d7a9092021-09-07 17:41:38 +0000208 ufs_ds_client)
Sean McAllistercf0db3a2021-09-14 17:03:47 -0600209 handle_dut_attribute_list(
210 os.path.realpath(
211 os.path.join(
212 script_dir,
213 "../generated/dut_attributes.jsonproto",
214 )), ufs_ds_client)
Justin Suen5aaa7cd2021-09-01 08:55:53 +0000215 handle_flat_config_list("hw_design/generated/flattened.jsonproto",
Justin Suen0d7a9092021-09-07 17:41:38 +0000216 ufs_ds_client)
217 handle_device_stability_list(
218 os.path.realpath(
219 os.path.join(
220 script_dir,
Justin Suen7c6674c2021-09-07 20:00:50 +0000221 "../../../infra/config/testingconfig/generated/device_stability.cfg"
Justin Suen0d7a9092021-09-07 17:41:38 +0000222 )), ufs_ds_client)