kernel/redhat/scripts/uki_addons/uki_create_json.py

105 lines
3.7 KiB
Python
Executable File

#!/usr/bin/env python3
#
# This script recursively inspects the 'redhat/uki_addons' directory,
# and creates a json file containing name and description of each addon found.
#
# Usage: python uki_create_json.py output_file
#
# Addon file
#-----------
# The addon files are contained into the 'redhat/uki_addons' folder.
# Each addon terminates with .addon.
# Each addon contains only two types of lines:
# Lines beginning with '#' are description and thus ignored
# All other lines are command line to be added.
# This script just parses the folder structure and creates a json reflecting
# all addons and their line found.
# For example, if we define test.addon (text: 'test1\n') in
# redhat/uki_addons/virt/rhel/x86_64, the resulting output_file will contain
# { 'virt' : { 'rhel' : { 'x86_64' : { 'test.addon' : ['test1\n'] }}}}
#
# The name of the end resulting addon is taken from the folder hierarchy, but this
# is handled by uki_create_addons.py when building the rpm. This script only
# prepares the json file to be added in the srpm. For more information about
# the folder hierarchy, what the 'common' and 'sbat' folder are, look at
# uki_create_addons.py.
#
# The common folder, present in any folder under redhat/uki_addons
# (except the leaf folders) is used as place for default addons when the same
# addon is not defined deep in the hierarchy.
#
# How to extend the script and kernel.spec with a new arch or uki or distro
#--------------------------------------------------------------------------
# A new distro has to be added by creating the folder in redhat/uki_addons.
# See uki_create_addons.py to how the directory hierarchy in redhat/uki_addons
# is expected to be.
# After that, if the distro is a different arch from the one already supported,
# one needs to extend the %define with_efiuki in kernel.spec.template.
# If a new UKI has to be created with a different name from the existing ones,
# the logic to create the addons and call this script has to be implemented too
# in kernel.spec.template. As an example, see how the 'virt' UKI addons are
# created.
import os
import sys
import json
import subprocess
def usage(err):
print(f'Usage: {os.path.basename(__file__)} dest_file')
print(f'Error:{err}')
sys.exit(1)
def find_addons():
cmd = ['/usr/bin/find', 'uki_addons', "(", '-name', '*.addon', '-o', '-name', 'sbat.conf', ")"]
proc_out = subprocess.run(cmd, check=True, capture_output=True, text=True)
if proc_out.returncode == 0:
return proc_out.stdout
return None
def add_keys_to_obj(ret_data, keys, value):
if len(keys) == 0:
return
key = keys[0]
val = {}
if len(keys) == 1:
val = value
if not key in ret_data:
ret_data[key] = val
ret_data = ret_data[key]
add_keys_to_obj(ret_data, keys[1:], value)
def create_json(addons):
obj = {}
for el in addons:
print(f'Processing {el} ...')
with open(el, 'r') as f:
lines = f.readlines()
dirs, name = os.path.split(el)
keys = dirs.split('/')
if keys[0] == 'uki_addons':
keys = keys[1:]
keys.append(name)
add_keys_to_obj(obj, keys, lines)
print(f'Processing {el} completed')
return obj
def write_json(obj, dest_file):
with open(dest_file, 'w') as f:
json.dump(obj , f, indent=4)
print(f'Processed addons files are in {dest_file}')
if __name__ == "__main__":
argc = len(sys.argv) - 1
if argc != 1:
usage('too few or too many parameters!')
dest = sys.argv[1]
output = find_addons()
if output is None:
usage('error finding the addons')
addons_list = output.split()
obj = create_json(addons_list)
write_json(obj, dest)