armbian-next: artifacts: firmware/rootfs and actual usage of artifacts during image build

- artifacts: introduce `ARTIFACT_IGNORE_CACHE=yes`
- artifacts: introduce `DONT_BUILD_ARTIFACTS`, list of artifacts that if not found cached, fail the build
- kernel_package_source() is no more
- a long dissertation about kernels, families, and the universe
- artifacts: actually use rootfs artifact for image build
- artifacts: detangle via artifact_base_dir
- artifacts: rootfs: use folders in artifact_name; include cache_type
- artifacts: some cleanups / validations
- rootfs artifact; drop old rootfs cli
- artifacts: new CLI shortcuts; remove old firmware CLI
- artifacts: full firmware & usage
- use firmware artifacts in image build and install its debs
- kernel artifact sans legacy; use tmpdir for .deb target for all packages
- legacy artifact versions is no more; pack/unpack now in common obtain;
- artifacts: uboot: cleanup legacy renaming, use artifact version directly
- artifacts: add firmware (small) artifact
- deploy uboot to loop from artifact; allow tty to artifact; todos for cleaning
- fixes, kernel dtb/headers conditional; remove `.git` from Makefile url; use mapfile for finding files to hash
  - completely remove KERNEL_HAS_WORKING_HEADERS_FULL_SOURCE and `kernel_package_callback_linux_headers_full_source()`
  - don't use realpath for artifact_file_relative
  - curb some warnings
  - fix: only install headers & dtbs if such exist
- kernel .config hook modification hash versioning
- OCI_TARGET_BASE vs per-artifact defaults; only deploy to remote from CLI with OTB
- artifact revolver & installing into image
  - add artifact_map_packages and artifact_map_debs dicts
  - revolver accumulates all info
  - REPOSITORY_INSTALL is no more (for uboot/kernel, later others)
  - rename `VER` to `IMAGE_INSTALLED_KERNEL_VERSION`
This commit is contained in:
Ricardo Pardini
2023-02-03 15:36:28 +01:00
parent 8900eea0af
commit 9bffa5e749
41 changed files with 1267 additions and 1079 deletions

View File

@@ -1,109 +1,49 @@
function cli_artifact_pre_run() {
initialize_artifact "${WHAT:-"kernel"}"
initialize_artifact "${WHAT}"
# Run the pre run adapter
artifact_cli_adapter_pre_run
}
function cli_artifact_run() {
display_alert "artifact" "${chosen_artifact}" "warn"
display_alert "artifact" "${chosen_artifact} :: ${chosen_artifact_impl}()" "warn"
: "${chosen_artifact:?chosen_artifact is not set}"
: "${chosen_artifact_impl:?chosen_artifact_impl is not set}"
display_alert "artifact" "${chosen_artifact}" "debug"
display_alert "artifact" "${chosen_artifact} :: ${chosen_artifact_impl}()" "debug"
artifact_cli_adapter_config_prep # only if in cli.
# only if in cli, if not just run it bare, since we'd be already inside do_with_default_build
do_with_default_build obtain_complete_artifact < /dev/null
}
# When run in GHA, assume we're checking/updating the remote cache only.
# Local cache is ignored, and if found, it's not unpacked, either from local or remote.
# If remote cache is found, does nothing.
declare default_update_remote_only="no"
if [[ "${CI}" == "true" ]] && [[ "${GITHUB_ACTIONS}" == "true" ]]; then
display_alert "Running in GitHub Actions, assuming we're updating remote cache only" "GHA remote-only" "info"
default_update_remote_only="yes"
fi
function create_artifact_functions() {
declare -a funcs=(
"cli_adapter_pre_run" "cli_adapter_config_prep"
"prepare_version"
"is_available_in_local_cache" "is_available_in_remote_cache" "obtain_from_remote_cache"
"deploy_to_remote_cache"
"build_from_sources"
)
for func in "${funcs[@]}"; do
declare impl_func="artifact_${chosen_artifact_impl}_${func}"
if [[ $(type -t "${impl_func}") == function ]]; then
declare cmd
cmd="$(
cat <<- ARTIFACT_DEFINITION
function artifact_${func}() {
display_alert "Calling artifact function" "${impl_func}() \$*" "warn"
${impl_func} "\$@"
}
ARTIFACT_DEFINITION
)"
eval "${cmd}"
else
exit_with_error "Missing artifact implementation function '${impl_func}'"
declare skip_unpack_if_found_in_caches="${skip_unpack_if_found_in_caches:-"${default_update_remote_only}"}"
declare ignore_local_cache="${ignore_local_cache:-"${default_update_remote_only}"}"
declare deploy_to_remote="${deploy_to_remote:-"${default_update_remote_only}"}"
# If OCI_TARGET_BASE is explicitly set, ignore local, skip if found in remote, and deploy to remote after build.
if [[ -n "${OCI_TARGET_BASE}" ]]; then
skip_unpack_if_found_in_caches="yes"
ignore_local_cache="yes"
deploy_to_remote="yes"
# Pass ARTIFACT_USE_CACHE=yes to actually use the cache versions, but don't deploy to remote.
# @TODO this is confusing. each op should be individually controlled...
# what we want is:
# 1: - check remote, if not found, check local, if not found, build, then deploy to remote
# - if remote found, do nothing.
# - if local found, deploy it to remote (for switching targets)
# 2: - get from remote -> get local -> build, then DON'T deploy to remote
if [[ "${ARTIFACT_USE_CACHE}" == "yes" ]]; then
skip_unpack_if_found_in_caches="no"
ignore_local_cache="no"
deploy_to_remote="no"
fi
done
}
function initialize_artifact() {
declare -g chosen_artifact="${1}"
armbian_register_artifacts
declare -g chosen_artifact_impl="${ARMBIAN_ARTIFACTS_TO_HANDLERS_DICT["${chosen_artifact}"]}"
[[ "x${chosen_artifact_impl}x" == "xx" ]] && exit_with_error "Unknown artifact '${chosen_artifact}'"
display_alert "artifact" "${chosen_artifact} :: ${chosen_artifact_impl}()" "info"
create_artifact_functions
}
function obtain_complete_artifact() {
declare -g artifact_version="undetermined"
declare -g artifact_version_reason="undetermined"
declare -A -g artifact_map_versions=()
declare -A -g artifact_map_versions_legacy=()
# Check if REVISION is set, otherwise exit_with_error
[[ "x${REVISION}x" == "xx" ]] && exit_with_error "REVISION is not set"
artifact_prepare_version
debug_var artifact_version
debug_var artifact_version_reason
debug_dict artifact_map_versions_legacy
debug_dict artifact_map_versions
# @TODO the whole artifact upload/download dance
artifact_is_available_in_local_cache
artifact_is_available_in_remote_cache
artifact_obtain_from_remote_cache
artifact_build_from_sources
artifact_deploy_to_remote_cache
}
# This is meant to be run after config, inside default build.
function build_artifact() {
initialize_artifact "${WHAT:-"kernel"}"
obtain_complete_artifact
}
function capture_rename_legacy_debs_into_artifacts() {
LOG_SECTION="capture_rename_legacy_debs_into_artifacts" do_with_logging capture_rename_legacy_debs_into_artifacts_logged
}
function capture_rename_legacy_debs_into_artifacts_logged() {
# So the deb-building code will consider the artifact_version in it's "Version: " field in the .debs.
# But it will produce .deb's with the legacy name. We gotta find and rename them.
# Loop over the artifact_map_versions, and rename the .debs.
debug_dict artifact_map_versions_legacy
debug_dict artifact_map_versions
declare deb_name_base deb_name_full new_name_full legacy_version legacy_base_version
for deb_name_base in "${!artifact_map_versions[@]}"; do
legacy_base_version="${artifact_map_versions_legacy[${deb_name_base}]}"
if [[ -z "${legacy_base_version}" ]]; then
exit_with_error "Legacy base version not found for artifact '${deb_name_base}'"
fi
display_alert "Legacy base version" "${legacy_base_version}" "info"
legacy_version="${legacy_base_version}_${ARCH}" # Arch-specific package; has ARCH at the end.
deb_name_full="${DEST}/debs/${deb_name_base}_${legacy_version}.deb"
new_name_full="${DEST}/debs/${deb_name_base}_${artifact_map_versions[${deb_name_base}]}_${ARCH}.deb"
display_alert "Full legacy deb name" "${deb_name_full}" "info"
display_alert "New artifact deb name" "${new_name_full}" "info"
run_host_command_logged mv -v "${deb_name_full}" "${new_name_full}"
done
fi
do_with_default_build obtain_complete_artifact # @TODO: < /dev/null -- but what about kernel configure?
}