blob: 9b51b9f5dc75107e87b622f725483a5fede47385 [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.
7"""Marshal ConfigBundles and store them into the UFS datastore through the Google datastore API.
8
9By default, this function reads a ConfigBundleList from
10'hw_design/generated/configs.jsonproto' and parses ConfigBundles from it. Using
11the API specified, it encodes the ConfigBundle as a ConfigBundleEntity and
12stores it into the UFS datastore.
13"""
14
15import argparse
16import datetime
17import logging
18
19from google.cloud import datastore
20
21from checker import io_utils
22from common import proto_utils
23
24# type constants
25INPUT_TYPE = 'chromiumos.config.payload.ConfigBundleList'
26OUTPUT_TYPE = 'chromiumos.config.payload.ConfigBundle'
27
28# UFS services
29UFS_DEV_PROJECT = 'unified-fleet-system-dev'
30UFS_PROD_PROJECT = 'unified-fleet-system'
31
32# datastore constants
33CONFIG_BUNDLE_KIND = 'ConfigBundle'
34
35
36def 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
45def 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
51def 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
73if __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))