armbian-build/lib/functions/main/default-build.sh
Ricardo Pardini 76e276c6a9
armbian-next: Python patching delusion, pt1 & pt2 & pt3
- WiP: Python patching delusion, pt 1: finding & parsing patches; apply & git commit with pygit2; Markdown summaries (also for aggregation); git-to-patches tool
  - Python: Markdown aggregation and patching summaries; collapsible; SummarizedMarkdownWriter
  - Python: Markdown aggregation and patching summaries
  - Python: reorg a bit into common/armbian_utils; define the `ASSET_LOG_BASE` in preparation for Markdown delusion
  - Python patching: initial apply patches & initial commit patches to git (using pygit2)
  - Python patching: add basic `series.conf` support
  - Python patching: force use of utf-8; better error handling; use realpath of dirs
  - Python patching: `git-to-patches` initial hack. not proud. half-reused some of the patches-to-git
  - Python patching: "tag" the git commits with info for extracting later; introduce REWRITE_PATCHES/rewrite_patches_in_place
  - Python patching: commented-out, recover-bad-patches hacks
  - Python patching: shorten the signature
  - Python patching: allow BASE_GIT_TAG as well as BASE_GIT_REVISION
  - Python patching: git-archeology for patches missing descriptions; avoid UTF-8 in header/desc (not diff)
  - Python patching: use modern-er email.utils.parsedate_to_datetime to parse commit date
  - Python patching: unify PatchInPatchFile; better git-commiting; re-exporting patches from Git (directly)
  - Python patching: switch to GitPython
    - GitPython is like 100x slower than pygit2, but actually allows for date & committer
    - also allows to remove untracked files before starting
  - Python aggregation: fix missing `AGGREGATED_APT_SOURCES_DICT`
  - Python patching: add `unidecode` dependency to pip3 install
  - Python patching: don't try archeology if SRC is not a Git Repo (eg, in Docker)
  - Python patching: don't try archeology if not applying patches to git
- WiP: Python patching delusion, pt2: actually use for u-boot & kernel patching
  - Python patching: much better problem handling/logging; lenient with recreations (kernel)
  - Python patching: don't force SHOW_LOG for u-boot patching
  - Python patching: don't bomb for no reason when there are no patches to apply
  - Python patching: fully (?) switch kernel patching to Python
  - Python patching: more logging fixups
  - Python patching: capture `kernel_git_revision` from `fetch_from_repo()`'s `checked_out_revision`
  - Python patching: fully switch u-boot patching to Python
  - Python aggregation/patching: colored logging; patching: always reset to git revision
  - Python aggregation/patching: better logging; introduce u-boot Python patching
- Python patching pt3: recovers and better Markdown
  - Python patching: detect, and rescue, `wrong_strip_level` problem; don't try to export patches that didn't apply, bitch instead
  - Python patching: Markdown patching summary table, complete with emoji
  - Python patching: include the problem breakdown in Markdown summary
  - Python patching: sanity check against half-bare, half-mbox patches
  - Python patching: try to recover from 1) bad utf-8 encoded patches; 2) bad unidiff patches; add a few sanity checks
  - Python patching: try, and fail, to apply badly utf-8 encoded patches directly as bytes [reverted]
  - Python patching: try to recover from patch *parse* failures; show summary; better logging
      - set `GIT_ARCHEOLOGY=yes` to do archeology, default not

- armbian-next: Python `pip` dependencies handling, similar to `hostdeps`
  - same scheme for Dockerfile caching
  - @TODO: still using global/shared environment; should move to a dir under `cache` or some kinda venv
- WiP: add `python3-pip` to hostdeps; remove `python-setuptools`
  - remove `python-setuptools` (Python2, no longer exists in Sid) from hostdeps
  - add `python3-pip` to hostdeps; part of virtualenv saga
- WiP: split `kernel.sh` a bit, into `kernel-patching.sh`, `kernel-config.sh` and `kernel-make.sh`
  - `advanced_patch()`: rename vars for clarity; no real changes
- Python patching: introduce FAST_ARCHEOLOGY; still trying for Markdown links
2023-02-18 07:40:52 -03:00

252 lines
12 KiB
Bash

# This does NOT run under the logging manager. We should invoke the do_with_logging wrapper for
# strategic parts of this. Attention: rootfs does it's own logging, so just let that be.
function main_default_build_single() {
# Check that WORKDIR_BASE_TMP exists; if not, create it.
if [[ ! -d "${WORKDIR_BASE_TMP}" ]]; then
mkdir -p "${WORKDIR_BASE_TMP}"
fi
# Check the sanity of WORKDIR_BASE_TMP regarding mount options.
check_dir_for_mount_options "${WORKDIR_BASE_TMP}" "main temporary dir"
# Starting work. Export TMPDIR, which will be picked up by all `mktemp` invocations hopefully.
# Runner functions in logging/runners.sh will explicitly unset TMPDIR before invoking chroot.
# Invoking chroot directly will fail in subtle ways, so, please use the runner.sh functions.
display_alert "Starting single build, exporting TMPDIR" "${WORKDIR}" "debug"
mkdir -p "${WORKDIR}"
add_cleanup_handler trap_handler_cleanup_workdir
export TMPDIR="${WORKDIR}"
start=$(date +%s)
### Write config summary
LOG_SECTION="config_summary" do_with_logging write_config_summary_output_file
# Check and install dependencies, directory structure and settings
LOG_SECTION="prepare_host" do_with_logging prepare_host
# Create a directory inside WORKDIR with a "python" symlink to "/usr/bin/python2"; add it to PATH first.
BIN_WORK_DIR="${WORKDIR}/bin"
# No cleanup of this is necessary, since it's inside WORKDIR.
mkdir -p "${BIN_WORK_DIR}"
ln -s "/usr/bin/python2" "${BIN_WORK_DIR}/python"
export PATH="${BIN_WORK_DIR}:${PATH}"
if [[ "${JUST_INIT}" == "yes" ]]; then
exit 0
fi
if [[ $CLEAN_LEVEL == *sources* ]]; then
general_cleaning "sources"
fi
# Too many things being done. Allow doing only one thing. For core development, mostly.
# Also because "KERNEL_ONLY=yes" should really be spelled "PACKAGES_ONLY=yes"
local do_build_uboot="yes" do_build_kernel="yes" exit_after_kernel_build="no" exit_after_uboot_build="no" do_host_tools="yes"
if [[ "${JUST_UBOOT}" == "yes" && "${JUST_KERNEL}" == "yes" ]]; then
exit_with_error "User of build system" "can't make up his mind about JUST_KERNEL or JUST_UBOOT"
elif [[ "${JUST_UBOOT}" == "yes" ]]; then
display_alert "JUST_KERNEL set to yes" "Building only kernel and exiting after that" "debug"
do_build_uboot="yes"
do_host_tools="${INSTALL_HOST_TOOLS:-yes}" # rkbin, fips, etc.
exit_after_uboot_build="yes"
elif [[ "${JUST_KERNEL}" == "yes" ]]; then
display_alert "JUST_KERNEL set to yes" "Building only kernel and exiting after that" "debug"
do_build_uboot="no"
exit_after_kernel_build="yes"
do_host_tools="no"
fi
# ignore updates help on building all images - for internal purposes
if [[ $IGNORE_UPDATES != yes ]]; then
# Fetch and build the host tools (via extensions)
if [[ "${do_host_tools}" == "yes" ]]; then
LOG_SECTION="fetch_and_build_host_tools" do_with_logging fetch_and_build_host_tools
fi
# Cleaning of old, deprecated mountpoints; only done if not running under Docker.
# mountpoints under Docker manifest as volumes, and as such can't be cleaned this way.
if [[ "${ARMBIAN_RUNNING_IN_CONTAINER}" != "yes" ]]; then
prepare_armbian_mountpoints_description_dict
local mountpoint=""
for mountpoint in "${ARMBIAN_MOUNTPOINTS_DEPRECATED[@]}"; do
local mountpoint_dir="${SRC}/${mountpoint}"
display_alert "Considering cleaning deprecated mountpoint" "${mountpoint_dir}" "debug"
if [[ -d "${mountpoint_dir}" ]]; then
display_alert "Cleaning deprecated mountpoint" "${mountpoint_dir}" "info"
run_host_command_logged rm -rf "${mountpoint_dir}"
fi
done
fi
for cleaning_fragment in $(tr ',' ' ' <<< "${CLEAN_LEVEL}"); do
if [[ $cleaning_fragment != sources ]] && [[ $cleaning_fragment != none ]] && [[ $cleaning_fragment != make* ]]; then
LOG_SECTION="cleaning_${cleaning_fragment}" do_with_logging general_cleaning "${cleaning_fragment}"
fi
done
fi
if [[ "${do_build_uboot}" == "yes" ]]; then
# Don't build u-boot at all if the BOOTCONFIG is 'none'.
if [[ "${BOOTCONFIG}" != "none" ]]; then
# @TODO: refactor this. we use it very often
# Compile u-boot if packed .deb does not exist or use the one from repository
if [[ ! -f "${DEB_STORAGE}"/${CHOSEN_UBOOT}_${REVISION}_${ARCH}.deb ]]; then
if [[ -n "${ATFSOURCE}" && "${ATFSOURCE}" != "none" && "${REPOSITORY_INSTALL}" != *u-boot* ]]; then
LOG_SECTION="compile_atf" do_with_logging compile_atf
fi
# @TODO: refactor this construct. we use it too many times.
if [[ "${REPOSITORY_INSTALL}" != *u-boot* ]]; then
declare uboot_git_revision="not_determined_yet"
LOG_SECTION="uboot_prepare_git" do_with_logging_unless_user_terminal uboot_prepare_git
LOG_SECTION="compile_uboot" do_with_logging compile_uboot
fi
fi
fi
if [[ "${exit_after_uboot_build}" == "yes" ]]; then
display_alert "Exiting after u-boot build" "JUST_UBOOT=yes" "info"
exit 0
fi
fi
# Compile kernel if packed .deb does not exist or use the one from repository
if [[ "${do_build_kernel}" == "yes" ]]; then
if [[ ! -f ${DEB_STORAGE}/${CHOSEN_KERNEL}_${REVISION}_${ARCH}.deb ]]; then
export KDEB_CHANGELOG_DIST=$RELEASE
if [[ -n $KERNELSOURCE ]] && [[ "${REPOSITORY_INSTALL}" != *kernel* ]]; then
compile_kernel # This handles its own logging sections.
fi
fi
if [[ "${exit_after_kernel_build}" == "yes" ]]; then
display_alert "Only building kernel and exiting" "JUST_KERNEL=yes" "debug"
exit 0
fi
fi
# Compile armbian-config if packed .deb does not exist or use the one from repository
if [[ ! -f ${DEB_STORAGE}/armbian-config_${REVISION}_all.deb ]]; then
if [[ "${REPOSITORY_INSTALL}" != *armbian-config* ]]; then
LOG_SECTION="compile_armbian-config" do_with_logging compile_armbian-config
fi
fi
# Compile armbian-zsh if packed .deb does not exist or use the one from repository
if [[ ! -f ${DEB_STORAGE}/armbian-zsh_${REVISION}_all.deb ]]; then
if [[ "${REPOSITORY_INSTALL}" != *armbian-zsh* ]]; then
LOG_SECTION="compile_armbian-zsh" do_with_logging compile_armbian-zsh
fi
fi
# Compile plymouth-theme-armbian if packed .deb does not exist or use the one from repository
if [[ ! -f ${DEB_STORAGE}/plymouth-theme-armbian_${REVISION}_all.deb ]]; then
if [[ "${REPOSITORY_INSTALL}" != *plymouth-theme-armbian* ]]; then
compile_plymouth_theme_armbian
fi
fi
# Compile armbian-firmware if packed .deb does not exist or use the one from repository
if ! ls "${DEB_STORAGE}/armbian-firmware_${REVISION}_all.deb" 1> /dev/null 2>&1 || ! ls "${DEB_STORAGE}/armbian-firmware-full_${REVISION}_all.deb" 1> /dev/null 2>&1; then
if [[ "${REPOSITORY_INSTALL}" != *armbian-firmware* ]]; then
if [[ "${INSTALL_ARMBIAN_FIRMWARE:-yes}" == "yes" ]]; then # Build firmware by default.
# Build the light version of firmware package
FULL="" REPLACE="-full" LOG_SECTION="compile_firmware" do_with_logging compile_firmware
# Build the full version of firmware package
FULL="-full" REPLACE="" LOG_SECTION="compile_firmware_full" do_with_logging compile_firmware
fi
fi
fi
overlayfs_wrapper "cleanup"
# create board support package
if [[ -n "${RELEASE}" && ! -f "${DEB_STORAGE}/${BSP_CLI_PACKAGE_FULLNAME}.deb" && "${REPOSITORY_INSTALL}" != *armbian-bsp-cli* ]]; then
LOG_SECTION="create_board_package" do_with_logging create_board_package
fi
# create desktop package
if [[ -n "${RELEASE}" && "${DESKTOP_ENVIRONMENT}" && ! -f "${DEB_STORAGE}/$RELEASE/${CHOSEN_DESKTOP}_${REVISION}_all.deb" && "${REPOSITORY_INSTALL}" != *armbian-desktop* ]]; then
LOG_SECTION="create_desktop_package" do_with_logging create_desktop_package
fi
if [[ -n "${RELEASE}" && "${DESKTOP_ENVIRONMENT}" && ! -f "${DEB_STORAGE}/${RELEASE}/${BSP_DESKTOP_PACKAGE_FULLNAME}.deb" && "${REPOSITORY_INSTALL}" != *armbian-bsp-desktop* ]]; then
LOG_SECTION="create_bsp_desktop_package" do_with_logging create_bsp_desktop_package
fi
# skip image creation if exists. useful for CI when making a lot of images
if [ "$IMAGE_PRESENT" == yes ] && ls "${FINALDEST}/${VENDOR}_${REVISION}_${BOARD^}_${RELEASE}_${BRANCH}_${VER/-$LINUXFAMILY/}${DESKTOP_ENVIRONMENT:+_$DESKTOP_ENVIRONMENT}"*.xz 1> /dev/null 2>&1; then
display_alert "Skipping image creation" "image already made - IMAGE_PRESENT is set" "wrn"
exit
fi
# build additional packages
if [[ $EXTERNAL_NEW == compile ]]; then
display_alert "Building external packages" "$EXTERNAL - WARNING: this has not been armbian-nextifed yet and will fail." "warn"
exit_with_error "buildpkg chroot_build_packages() nas not been ported to armbian-next yet, rpardini is a bum"
LOG_SECTION="chroot_build_packages" do_with_logging chroot_build_packages
fi
# Reset owner of DEB_STORAGE, if needed. Might be a lot of packages there, but such is life.
# @TODO: might be needed also during 'cleanup': if some package fails, the previous package might be left owned by root.
reset_uid_owner "${DEB_STORAGE}"
# end of kernel-only, so display what was built.
if [[ $KERNEL_ONLY != yes ]]; then
display_alert "Kernel build done" "@host" "target-reached"
display_alert "Target directory" "${DEB_STORAGE}/" "info"
display_alert "File name" "${CHOSEN_KERNEL}_${REVISION}_${ARCH}.deb" "info"
fi
# build rootfs, if not only kernel.
if [[ $KERNEL_ONLY != yes ]]; then
display_alert "Building image" "${BOARD}" "target-started"
[[ $BSP_BUILD != yes ]] && build_rootfs_and_image # old debootstrap-ng. !!!LOGGING!!! handled inside, there are many sub-parts.
display_alert "Done building image" "${BOARD}" "target-reached"
fi
call_extension_method "run_after_build" <<- 'RUN_AFTER_BUILD'
*hook for function to run after build, i.e. to change owner of `$SRC`*
Really one of the last hooks ever called. The build has ended. Congratulations.
- *NOTE:* this will run only if there were no errors during build process.
RUN_AFTER_BUILD
end=$(date +%s)
runtime=$(((end - start) / 60))
display_alert "Runtime" "$runtime min" "info"
if armbian_is_running_in_container; then
BUILD_CONFIG='docker' # @TODO: this is not true, depends on how we end up launching this.
fi
# Make it easy to repeat build by displaying build options used. Prepare array.
local -a repeat_args=("./compile.sh" "${BUILD_CONFIG}" " BRANCH=${BRANCH}")
[[ -n ${RELEASE} ]] && repeat_args+=("RELEASE=${RELEASE}")
[[ -n ${BUILD_MINIMAL} ]] && repeat_args+=("BUILD_MINIMAL=${BUILD_MINIMAL}")
[[ -n ${BUILD_DESKTOP} ]] && repeat_args+=("BUILD_DESKTOP=${BUILD_DESKTOP}")
[[ -n ${KERNEL_ONLY} ]] && repeat_args+=("KERNEL_ONLY=${KERNEL_ONLY}")
[[ -n ${KERNEL_CONFIGURE} ]] && repeat_args+=("KERNEL_CONFIGURE=${KERNEL_CONFIGURE}")
[[ -n ${DESKTOP_ENVIRONMENT} ]] && repeat_args+=("DESKTOP_ENVIRONMENT=${DESKTOP_ENVIRONMENT}")
[[ -n ${DESKTOP_ENVIRONMENT_CONFIG_NAME} ]] && repeat_args+=("DESKTOP_ENVIRONMENT_CONFIG_NAME=${DESKTOP_ENVIRONMENT_CONFIG_NAME}")
[[ -n ${DESKTOP_APPGROUPS_SELECTED} ]] && repeat_args+=("DESKTOP_APPGROUPS_SELECTED=\"${DESKTOP_APPGROUPS_SELECTED}\"")
[[ -n ${DESKTOP_APT_FLAGS_SELECTED} ]] && repeat_args+=("DESKTOP_APT_FLAGS_SELECTED=\"${DESKTOP_APT_FLAGS_SELECTED}\"")
[[ -n ${COMPRESS_OUTPUTIMAGE} ]] && repeat_args+=("COMPRESS_OUTPUTIMAGE=${COMPRESS_OUTPUTIMAGE}")
display_alert "Repeat Build Options" "${repeat_args[*]}" "ext" # * = expand array, space delimited, single-word.
}
function trap_handler_cleanup_workdir() {
display_alert "Cleanup WORKDIR: $WORKDIR" "trap_handler_cleanup_workdir" "cleanup"
unset TMPDIR
if [[ -d "${WORKDIR}" ]]; then
if [[ "${PRESERVE_WORKDIR}" != "yes" ]]; then
display_alert "Cleaning up WORKDIR" "$(du -h -s "$WORKDIR")" "debug"
rm -rf "${WORKDIR}"
else
display_alert "Preserving WORKDIR due to PRESERVE_WORKDIR=yes" "$(du -h -s "$WORKDIR")" "warn"
fi
fi
}