Files
build/lib/tools/aggregation.py

195 lines
10 KiB
Python

#! /bin/env python3
# Disclaimer: this script was written solely using GitHub Copilot.
# I wrote "prompt" comments and the whole thing was generated by Copilot.
# Unfortunately I removed most original comments/prompts after code was generated, I should have kept them all in...
# I'm not sure if I should be proud or ashamed of this. <-- this was suggested by Copilot too.
# -- rpardini, 23/11/2022
import hashlib
import os
import common.aggregation_utils as util
# Read SRC from the environment, treat it.
armbian_build_directory = util.get_from_env_or_bomb("SRC")
if not os.path.isdir(armbian_build_directory):
raise Exception("SRC is not a directory")
# OUTPUT from the environment, treat it.
output_file = util.get_from_env_or_bomb("OUTPUT")
with open(output_file, "w") as out:
out.write("")
BUILD_DESKTOP = util.yes_or_no_or_bomb(util.get_from_env_or_bomb("BUILD_DESKTOP"))
INCLUDE_EXTERNAL_PACKAGES = True
ARCH = util.get_from_env_or_bomb("ARCH")
DESKTOP_ENVIRONMENT = util.get_from_env("DESKTOP_ENVIRONMENT")
DESKTOP_ENVIRONMENT_CONFIG_NAME = util.get_from_env("DESKTOP_ENVIRONMENT_CONFIG_NAME")
RELEASE = util.get_from_env_or_bomb("RELEASE") # "kinetic"
LINUXFAMILY = util.get_from_env_or_bomb("LINUXFAMILY")
BOARD = util.get_from_env_or_bomb("BOARD")
USERPATCHES_PATH = util.get_from_env_or_bomb("USERPATCHES_PATH")
# Show the environment
#print("Environment:")
#for k, v in os.environ.items():
# print("{}={}".format(k, v))
util.SELECTED_CONFIGURATION = util.get_from_env_or_bomb("SELECTED_CONFIGURATION") # "cli_standard"
util.DESKTOP_APPGROUPS_SELECTED = util.parse_env_for_tokens("DESKTOP_APPGROUPS_SELECTED") # ["browsers", "chat"]
util.SRC = armbian_build_directory
util.AGGREGATION_SEARCH_ROOT_ABSOLUTE_DIRS = [
f"{armbian_build_directory}/config",
f"{armbian_build_directory}/config/optional/_any_board/_config",
f"{armbian_build_directory}/config/optional/architectures/{ARCH}/_config",
f"{armbian_build_directory}/config/optional/families/{LINUXFAMILY}/_config",
f"{armbian_build_directory}/config/optional/boards/{BOARD}/_config",
f"{USERPATCHES_PATH}"
]
util.DEBOOTSTRAP_SEARCH_RELATIVE_DIRS = ["cli/_all_distributions/debootstrap", f"cli/{RELEASE}/debootstrap"]
util.CLI_SEARCH_RELATIVE_DIRS = ["cli/_all_distributions/main", f"cli/{RELEASE}/main"]
util.DESKTOP_ENVIRONMENTS_SEARCH_RELATIVE_DIRS = [
f"desktop/_all_distributions/environments/_all_environments",
f"desktop/_all_distributions/environments/{DESKTOP_ENVIRONMENT}",
f"desktop/_all_distributions/environments/{DESKTOP_ENVIRONMENT}/{DESKTOP_ENVIRONMENT_CONFIG_NAME}",
f"desktop/{RELEASE}/environments/_all_environments",
f"desktop/{RELEASE}/environments/{DESKTOP_ENVIRONMENT}",
f"desktop/{RELEASE}/environments/{DESKTOP_ENVIRONMENT}/{DESKTOP_ENVIRONMENT_CONFIG_NAME}"]
util.DESKTOP_APPGROUPS_SEARCH_RELATIVE_DIRS = [
f"desktop/_all_distributions/appgroups",
f"desktop/_all_distributions/environments/{DESKTOP_ENVIRONMENT}/appgroups",
f"desktop/{RELEASE}/appgroups",
f"desktop/{RELEASE}/environments/{DESKTOP_ENVIRONMENT}/appgroups"]
# Debootstrap.
debootstrap_packages = util.aggregate_all_debootstrap("packages")
debootstrap_packages_remove = util.aggregate_all_debootstrap("packages.remove")
# both main and additional result in the same thing, just different filenames.
rootfs_packages_main = util.aggregate_all_cli("packages")
rootfs_packages_additional = util.aggregate_all_cli("packages.additional")
rootfs_packages_external = util.aggregate_all_cli("packages.external") # @TODO: enable/disable this
rootfs_packages_all = util.merge_lists(rootfs_packages_main, rootfs_packages_additional, "add")
rootfs_packages_all = util.merge_lists(rootfs_packages_all, rootfs_packages_external, "add")
rootfs_packages_remove = util.aggregate_all_cli("packages.remove")
# Desktop environment packages; packages + packages.external
desktop_packages_main = util.aggregate_all_desktop("packages")
desktop_packages_external = util.aggregate_all_desktop("packages.external")
desktop_packages_additional = util.aggregate_all_desktop("packages.additional")
desktop_packages_all = util.merge_lists(desktop_packages_main, desktop_packages_external, "add")
desktop_packages_all = util.merge_lists(desktop_packages_all, desktop_packages_additional, "add")
desktop_packages_remove = util.aggregate_all_desktop("packages.remove")
env_list_remove = util.parse_env_for_list("REMOVE_PACKAGES")
env_list_extra_rootfs = util.parse_env_for_list("EXTRA_PACKAGES_ROOTFS")
env_list_extra_image = util.parse_env_for_list("EXTRA_PACKAGES_IMAGE")
env_package_list_board = util.parse_env_for_list(
"PACKAGE_LIST_BOARD", {"function": "board", "path": "board.conf", "line": 0})
env_package_list_family = util.parse_env_for_list(
"PACKAGE_LIST_FAMILY", {"function": "family", "path": "family.conf", "line": 0})
env_package_list_board_remove = util.parse_env_for_list(
"PACKAGE_LIST_BOARD_REMOVE", {"function": "board_remove", "path": "board.conf", "line": 0})
env_package_list_family_remove = util.parse_env_for_list(
"PACKAGE_LIST_BOARD_REMOVE", {"function": "family_remove", "path": "family.conf", "line": 0})
# Now calculate the final lists.
# debootstrap is the aggregated list, minus the packages we want to remove.
AGGREGATED_PACKAGES_DEBOOTSTRAP = util.merge_lists(debootstrap_packages, debootstrap_packages_remove, "remove")
AGGREGATED_PACKAGES_DEBOOTSTRAP = util.merge_lists(AGGREGATED_PACKAGES_DEBOOTSTRAP, env_list_remove, "remove")
# components for debootstrap is just the aggregated list; or is it?
AGGREGATED_DEBOOTSTRAP_COMPONENTS = util.aggregate_all_debootstrap("components")
AGGREGATED_DEBOOTSTRAP_COMPONENTS_COMMA = ','.join(AGGREGATED_DEBOOTSTRAP_COMPONENTS).replace(' ', ',')
# The rootfs list; add the extras, and remove the removals.
AGGREGATED_PACKAGES_ROOTFS = util.merge_lists(rootfs_packages_all, env_list_extra_rootfs, "add")
AGGREGATED_PACKAGES_ROOTFS = util.merge_lists(AGGREGATED_PACKAGES_ROOTFS, rootfs_packages_remove, "remove")
AGGREGATED_PACKAGES_ROOTFS = util.merge_lists(AGGREGATED_PACKAGES_ROOTFS, env_list_remove, "remove")
# The desktop list.
AGGREGATED_PACKAGES_DESKTOP = util.merge_lists(desktop_packages_all, desktop_packages_remove, "remove")
AGGREGATED_PACKAGES_DESKTOP = util.merge_lists(AGGREGATED_PACKAGES_DESKTOP, env_list_remove, "remove")
# the image list; this comes from env only; apply the removals.
AGGREGATED_PACKAGES_IMAGE = util.merge_lists(env_list_extra_image, env_package_list_board, "add")
AGGREGATED_PACKAGES_IMAGE = util.merge_lists(AGGREGATED_PACKAGES_IMAGE, env_package_list_family, "add")
AGGREGATED_PACKAGES_IMAGE = util.merge_lists(AGGREGATED_PACKAGES_IMAGE, env_package_list_board_remove, "remove")
AGGREGATED_PACKAGES_IMAGE = util.merge_lists(AGGREGATED_PACKAGES_IMAGE, env_package_list_family_remove, "remove")
AGGREGATED_PACKAGES_IMAGE = util.merge_lists(AGGREGATED_PACKAGES_IMAGE, env_list_remove, "remove")
# Calculate a md5 hash of the list of packages, so we can use it as a cache key.
# Attention: ROOTFS does not include DESKTOP. @TODO have 2 hashes, one for cli, one for cli+desktop.
AGGREGATED_ROOTFS_HASH = hashlib.md5(
(" ".join(AGGREGATED_PACKAGES_DEBOOTSTRAP) + " ".join(AGGREGATED_PACKAGES_ROOTFS)).encode("utf-8")).hexdigest()
# We need to aggregate some desktop stuff, which are not package lists, postinst contents and such.
# For this case just find the potentials, and for each found, take the whole contents and join via newlines.
AGGREGATED_DESKTOP_POSTINST = util.aggregate_all_desktop(
"debian/postinst", util.aggregate_simple_contents_potential)
AGGREGATED_DESKTOP_CREATE_DESKTOP_PACKAGE = util.aggregate_all_desktop(
"armbian/create_desktop_package.sh", util.aggregate_simple_contents_potential)
AGGREGATED_DESKTOP_BSP_POSTINST = util.aggregate_all_desktop(
"debian/armbian-bsp-desktop/postinst", util.aggregate_simple_contents_potential)
AGGREGATED_DESKTOP_BSP_PREPARE = util.aggregate_all_desktop(
"debian/armbian-bsp-desktop/prepare.sh", util.aggregate_simple_contents_potential)
# Aggregate the apt-sources; only done if BUILD_DESKTOP is True, otherwise empty.
AGGREGATED_APT_SOURCES = {}
if BUILD_DESKTOP:
apt_sources_debootstrap = util.aggregate_all_debootstrap("sources/apt", util.aggregate_apt_sources)
apt_sources_cli = util.aggregate_all_cli("sources/apt", util.aggregate_apt_sources)
apt_sources_desktop = util.aggregate_all_desktop("sources/apt", util.aggregate_apt_sources)
AGGREGATED_APT_SOURCES = util.merge_lists(apt_sources_debootstrap, apt_sources_cli, "add")
AGGREGATED_APT_SOURCES = util.merge_lists(AGGREGATED_APT_SOURCES, apt_sources_desktop, "add")
# ----------------------------------------------------------------------------------------------------------------------
with open(output_file, "w") as out:
# with sys.stdout as f:
out.write("#!/bin/env bash\n")
out.write(
util.prepare_bash_output_array_for_list(
"AGGREGATED_PACKAGES_DEBOOTSTRAP", AGGREGATED_PACKAGES_DEBOOTSTRAP))
out.write(util.prepare_bash_output_array_for_list(
"AGGREGATED_PACKAGES_ROOTFS", AGGREGATED_PACKAGES_ROOTFS))
out.write(util.prepare_bash_output_array_for_list(
"AGGREGATED_PACKAGES_IMAGE", AGGREGATED_PACKAGES_IMAGE))
out.write(util.prepare_bash_output_array_for_list(
"AGGREGATED_PACKAGES_DESKTOP", AGGREGATED_PACKAGES_DESKTOP))
# The rootfs hash (md5) is used as a cache key.
out.write(f"declare -g -r AGGREGATED_ROOTFS_HASH='{AGGREGATED_ROOTFS_HASH}'\n")
# Special case for components: debootstrap also wants a list of components, comma separated.
out.write(
f"declare -g -r AGGREGATED_DEBOOTSTRAP_COMPONENTS_COMMA='{AGGREGATED_DEBOOTSTRAP_COMPONENTS_COMMA}'\n")
# Single string stuff for desktop packages postinst's and preparation. @TODO use functions instead of eval.
out.write(util.prepare_bash_output_single_string(
"AGGREGATED_DESKTOP_POSTINST", AGGREGATED_DESKTOP_POSTINST))
out.write(util.prepare_bash_output_single_string(
"AGGREGATED_DESKTOP_CREATE_DESKTOP_PACKAGE", AGGREGATED_DESKTOP_CREATE_DESKTOP_PACKAGE))
out.write(util.prepare_bash_output_single_string(
"AGGREGATED_DESKTOP_BSP_POSTINST", AGGREGATED_DESKTOP_BSP_POSTINST))
out.write(util.prepare_bash_output_single_string(
"AGGREGATED_DESKTOP_BSP_PREPARE", AGGREGATED_DESKTOP_BSP_PREPARE))
# The apt sources.
out.write(util.prepare_bash_output_array_for_list(
"AGGREGATED_APT_SOURCES", AGGREGATED_APT_SOURCES, util.encode_source_base_path_extra))
# 2) @TODO: Some removals...
# aggregate_all_cli "packages.uninstall" " "
# aggregate_all_desktop "packages.uninstall" " "
# PACKAGE_LIST_UNINSTALL="$(cleanup_list aggregated_content)"
# unset aggregated_content