Skip to content

Commit

Permalink
Dev 202111 build metadata (sonic-net#11)
Browse files Browse the repository at this point in the history
* Added build metadata:
	- versions info (software versions, date, commit)
	- build configuration (config and config.user files)
	- features status
sonic_features.yaml - file with features and dependencies description
build_img_metadata.py - parsing configuration and features file into metadata file

* Add build metadata file to the artifacts and image

* Update build_img_metadata.py
  • Loading branch information
nazar-garmadiy authored and Maksym Hedeon committed Feb 1, 2023
1 parent 513eb15 commit ecca7e6
Show file tree
Hide file tree
Showing 4 changed files with 736 additions and 0 deletions.
6 changes: 6 additions & 0 deletions build_debian.sh
Original file line number Diff line number Diff line change
Expand Up @@ -593,6 +593,12 @@ export build_number="${BUILD_NUMBER:-0}"
export built_by="$USER@$BUILD_HOSTNAME"
j2 files/build_templates/sonic_version.yml.j2 | sudo tee $FILESYSTEM_ROOT/etc/sonic/sonic_version.yml

## Metadata file
./build_img_metadata.py
if [ -f ./img_metadata.yaml ]; then
sudo cp ./img_metadata.yaml $FILESYSTEM_ROOT/etc/sonic/
fi

## Copy over clean-up script
sudo cp ./files/scripts/core_cleanup.py $FILESYSTEM_ROOT/usr/bin/core_cleanup.py

Expand Down
134 changes: 134 additions & 0 deletions build_img_metadata.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
#!/usr/bin/python3

import os
import os.path
import yaml
import re

RULES_CFG_PATH = 'rules/config'
RULES_CFG_USER_PATH = 'rules/config.user'
IMG_METADATA_FILE = 'img_metadata.yaml'
FEATURES_LIST_YML_FILE = 'sonic_features.yaml'

DEFAULT_ENABLE_OPTION = 'y'
DEFAULT_NOT_APPLICABLE_OPTION = 'N/A'
FEATURE_ENABLED_OPTION = 'Enabled'
FEATURE_DISABLED_OPTION = 'Disabled'
FEATURE_NOT_APPLICABLE_OPTION = DEFAULT_NOT_APPLICABLE_OPTION

#
# Helper functions
#

# Get header info (version, date/time, commit/branch, kernel/distro)

def get_header_info():
hdr_data = {}
hdr_data ['SONiC Software Version'] = os.environ.get('build_version')
hdr_data['Distribution'] = os.environ.get('debian_version')
hdr_data['Kernel'] = os.environ.get('kernel_version')
hdr_data['Build branch'] = os.environ.get('branch')
hdr_data['Build commit'] = os.environ.get('commit_id')
hdr_data['Build date'] = os.environ.get('build_date')

return hdr_data

# Read config file by a given path, create dictionary

def read_cfg_file(cfg_path:str, cfg_dict:dict):
if os.path.exists(cfg_path) is False:
return

#read config file
with open(cfg_path) as cfg_fp:
cfg_lines = cfg_fp.readlines()
for line in cfg_lines:
line = line.strip()
if line.startswith('#') or re.search("^\s*$", line):
#skip comments or empty lines
continue
else:
#strip spaces, for pairs with ?= remove '?'
key = line.split('=')[0].rstrip('?').strip()
value = line.split('=')[1].strip()
cfg_dict[key] = value

# Get build configuration
# read build configuration from config and config.user files
# config.user overwrites options from config, see slave.mk

def get_bld_config():
bld_config = {}

read_cfg_file(RULES_CFG_PATH, bld_config)
read_cfg_file(RULES_CFG_USER_PATH, bld_config)

return bld_config

# Get features list
# get features list and status according to build configuration

def get_features_list(features_list_path:str):
feature_list = {}

if os.path.exists(features_list_path) is False:
return

with open(features_list_path) as feature_yaml:
feature_list = yaml.safe_load(feature_yaml)

return feature_list

# Get feature status from build onfig

def get_feature_status(feature: dict, build_cfg: dict):
status = FEATURE_ENABLED_OPTION

for option in feature['options']:
if option == DEFAULT_NOT_APPLICABLE_OPTION:
status = FEATURE_NOT_APPLICABLE_OPTION
break
cfg_val = build_cfg.get(option)
if cfg_val is None:
#if option was not found - silently continue
continue
elif cfg_val != DEFAULT_ENABLE_OPTION:
status = FEATURE_DISABLED_OPTION
break

return status

# Get features configuration according to build configuration

def get_features_config():
feature_list = get_features_list(FEATURES_LIST_YML_FILE)
cfg_feature_arr = []
build_cfg = get_bld_config()

for feature_item in feature_list:
feature_data = {}
feature_data['name'] = feature_item['feature']['name']
feature_data['group'] = feature_item['feature']['group']
feature_data['description'] = feature_item['feature']['description']
feature_data['status'] = get_feature_status(feature_item['feature'], build_cfg)
cfg_feature_arr.append(feature_data)

return cfg_feature_arr

# Write build metadata into yaml file

def write_matadata(path:str):
bld_metadata = {}

bld_metadata['Version'] = get_header_info()
bld_metadata['Configuration'] = get_bld_config()
bld_metadata['Features'] = get_features_config()

with open(path, 'w') as file:
yaml.dump(bld_metadata, file)

def build_metadata():
write_matadata(IMG_METADATA_FILE)

if __name__ == '__main__':
build_metadata()
5 changes: 5 additions & 0 deletions scripts/collect_build_version_files.sh
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,11 @@ mkdir -p $VERSION_SLAVE_PATH

scripts/versions_manager.py merge -t $VERSION_SLAVE_PATH -b $LOG_VERSION_PATH -e $POST_VERSION_PATH

## Metadata file
if [ -f ./img_metadata.yaml ]; then
sudo cp ./img_metadata.yaml $VERSION_SLAVE_PATH
fi

rm -rf $BUILD_VERSION_PATH/*

exit $RET
Loading

0 comments on commit ecca7e6

Please sign in to comment.