Implement iso package listing into a CSV file

For IP disclosure proposes create a csv file listing the deb packages included in the ISO file.

Story: 2011336
Task: 51624

TEST PLAN

PASS: executing the script against a valid input file produces the expected CSV file
PASS: executing the script against invalid input file prints warning without producing a failure

Change-Id: Ibdda4efe1208e7145da34b468c2cc3490c05d397
This commit is contained in:
caio-volpato 2025-01-28 09:42:00 -03:00
parent 6e24ea853b
commit 79f77e0a1a
2 changed files with 137 additions and 0 deletions

View File

@ -36,3 +36,6 @@ if $SIGN_ISO_FORMAL ; then
fi
notice "building STD ISO"
stx_docker_cmd $DRY_RUN_ARG "build-image $build_img_args"
python3 $(dirname "$0")/lib/packages_parser.py --input "$BUILD_HOME"/localdisk/workdir/starlingx/packages.yaml --csv-dest "$BUILD_HOME"/localdisk/deploy/iso-packages.csv || true
# errors on the script are ignored

134
scripts/lib/packages_parser.py Executable file
View File

@ -0,0 +1,134 @@
#!/usr/bin/env python3
"""
Copyright (c) 2014-2025 Wind River Systems, Inc.
SPDX-License-Identifier: Apache-2.0
Parses the packages.yaml into a CSV file for IP disclosure proposes
The packages.yaml lists the packages present into the ISO
It was more fields that we are interested, such as the dependencies
This script only cares about the package name, the version and the filename.
The packages.yaml lives in: <build_prj>/localdisk/workdir/starlingx/packages.yaml
Usage example: packages_parser.py --input packages.yaml --csv-dest iso-packages.csv
"""
import argparse
import csv
import logging
import sys
def removeprefix(text, prefix):
"""
str.removeprefix() and str.removesuffix() was introduced on python 3.9
for older versions we need to implement it ourselfs
implementation from the PEP that introduced it
https://peps.python.org/pep-0616/#specification
"""
if text.startswith(prefix):
return text[len(prefix) :]
return text[:]
def removesuffix(text, suffix):
# suffix='' should not call self[:-0].
if suffix and text.endswith(suffix):
return text[: -len(suffix)]
return text[:]
def read_yaml(pkgs_filename):
"""parses simple key file yaml, only parsing some fields
the packages.yaml follows the following structure
acl:
arch: ''
ver: 2.2.53-10
filename: acl_2.2.53-10_amd64.deb
deps:
- libacl1
- libc6
pkgarch: ''
provs: []
[...]
we only care about the package name, version and filename
Args:
pkgs_filename packages.yaml filename
Returns:
list of the csv rows (package_name, package_version, package_filename)
"""
curr_key = ""
old_key = ""
curr_ver = ""
curr_file = ""
rows = []
with open(pkgs_filename, mode="r", encoding="utf-8") as f:
for line in f:
ls = line.rstrip() # line wo trailing spaces (to remove the newline char)
if ls.endswith(":") and not ls.startswith(" "): # parent key (pkg)
curr_key = removesuffix(ls, ":")
curr_ver = "" # found a new package, reset the other fields
curr_file = ""
elif ls.startswith(" "): # values within a pkg
if ls.strip().startswith("filename:"):
curr_file = removeprefix(ls.strip(), "filename: ")
elif ls.strip().startswith("ver:"):
curr_ver = removeprefix(ls.strip(), "ver: ")
if len(curr_ver) > 0 and len(curr_file) > 0 and old_key != curr_key:
# all the fields of a new package are field, add it results
row = [curr_key, curr_ver, curr_file]
rows.append(row)
old_key = curr_key
if len(rows) > 0:
return rows
raise ValueError(
"Parser Error! Input file is malformed, filename='%s'" % pkgs_filename
)
def write_csv(dest_filename, headers, rows):
with open(dest_filename, mode="w", encoding="utf-8") as f:
writer = csv.writer(f)
writer.writerow(headers)
writer.writerows(rows)
def main(pkgs_filename, dest_csv_filename):
logging.info(
"starting the script, input=%s, output=%s", pkgs_filename, dest_csv_filename
)
csv_headers = ["package_name", "version", "filename"]
rows = read_yaml(pkgs_filename)
logging.info("yaml parsed successfully, found %s packages", len(rows))
logging.info("writing the results into the CSV file!")
write_csv(dest_csv_filename, csv_headers, rows)
logging.info("Done!")
if __name__ == "__main__":
cliparser = argparse.ArgumentParser(
prog="PackagesDotYamlParser",
description="Convert the packages.yaml into a csv file",
)
cliparser.add_argument("--input", required=True, help="packages.yaml file location")
cliparser.add_argument("--csv-dest", required=True, help="csv output filename")
args = cliparser.parse_args()
logging.basicConfig(
format="%(asctime)s - %(levelname)s - %(message)s",
level=logging.INFO,
)
try:
main(args.input, args.csv_dest)
except Exception as e:
logging.error("Fail to execute the script, exception message:\n%s", e)
sys.exit(1)