#!/usr/bin/env bash
function create_new_rootfs_cache_tarball() {
[[ -n "${cache_fname}" ]] || exit_with_error "create_new_rootfs_cache_tarball: cache_fname is not set"
[[ -n "${SDCARD}" ]] || exit_with_error "create_new_rootfs_cache_tarball: SDCARD is not set"
[[ -n "${cache_name}" ]] || exit_with_error "create_new_rootfs_cache_tarball: cache_name is not set"
display_alert "Disk space usage of rootfs" "${RELEASE}:: ${cache_name}" "info"
run_host_command_logged "cd ${SDCARD} && " du -h -d 4 -x "." "| sort -h | tail -20"
wait_for_disk_sync "after disk-space usage report of rootfs"
declare compression_ratio_rootfs="${ROOTFS_COMPRESSION_RATIO:-"5"}"
display_alert "zstd tarball of rootfs" "${RELEASE}:: ${cache_name} :: compression ${compression_ratio_rootfs}" "info"
tar cp --xattrs --directory="$SDCARD"/ --exclude='./dev/*' --exclude='./proc/*' --exclude='./run/*' \
--exclude='./tmp/*' --exclude='./sys/*' --exclude='./home/*' --exclude='./root/*' . |
pv -p -b -r -s "$(du -sb "$SDCARD"/ | cut -f1)" -N "$(logging_echo_prefix_for_pv "store_rootfs") $cache_name" |
zstdmt "-${compression_ratio_rootfs}" -c > "${cache_fname}"
declare -a pv_tar_zstdmt_pipe_status=("${PIPESTATUS[@]}")
declare one_pipe_status
for one_pipe_status in "${pv_tar_zstdmt_pipe_status[@]}"; do
if [[ "$one_pipe_status" != "0" ]]; then
exit_with_error "create_new_rootfs_cache_tarball: compress: ${cache_fname} failed (${pv_tar_zstdmt_pipe_status[*]}) - out of disk space?"
fi
done
wait_for_disk_sync "after zstd tarball rootfs"
local cache_size
cache_size=$(du -sh "${cache_fname}" | cut -f1)
display_alert "rootfs cache created" "${cache_fname} [${cache_size}]" "info"
}
function create_new_rootfs_cache_via_debootstrap() {
declare mmdebstrap_branch="branch:main"
[[ ! -d "${SDCARD:?}" ]] && exit_with_error "create_new_rootfs_cache_via_debootstrap: ${SDCARD} is not a directory"
declare debootstrap_apt_mirror="http://${APT_MIRROR}"
case "${MANAGE_ACNG}" in
yes)
local debootstrap_apt_mirror="http://localhost:3142/${APT_MIRROR}"
acng_check_status_or_restart
;;
no) ;&
"")
:
;;
*)
if [[ ! "${MANAGE_ACNG}" =~ ^https?:// ]]; then
exit_with_error "MANAGE_ACNG must be yes/no OR be a full URL with http/https" "${MANAGE_ACNG}"
else
local debootstrap_apt_mirror="${MANAGE_ACNG}/${APT_MIRROR}"
fi
;;
esac
declare debootstrap_bin="" debootstrap_version="" debootstrap_wanted_dir="" debootstrap_default_script=""
display_alert "Preparing mmdebstrap" "for ${DISTRIBUTION}'s ${RELEASE}" "info"
declare debootstrap_name="mmdebstrap-debian-devel"
GIT_FIXED_WORKDIR="${debootstrap_name}" \
fetch_from_repo "https://gitlab.mister-muffin.de/josch/mmdebstrap" "${debootstrap_name}" "${mmdebstrap_branch}"
debootstrap_wanted_dir="${SRC}/cache/sources/${debootstrap_name}"
debootstrap_version="$(sed 's/^## \[\([^]]*\)\].*/\1/; q' "${debootstrap_wanted_dir}/CHANGELOG.md")"
debootstrap_bin="${debootstrap_wanted_dir}/mmdebstrap"
run_host_command_logged chmod a+x "${debootstrap_bin}"
display_alert "mmdebstrap version" "'${debootstrap_version}' for ${debootstrap_bin}" "info"
display_alert "Installing base system with ${#AGGREGATED_PACKAGES_DEBOOTSTRAP[@]} packages" "Stage 1/1" "info"
cd "${SDCARD}" || exit_with_error "cray-cray about SDCARD" "${SDCARD}"
declare -ga debootstrap_arguments=(
"--variant=minbase"
"--arch=${ARCH}"
"'--include=${AGGREGATED_PACKAGES_DEBOOTSTRAP_COMMA}'"
"'--components=${AGGREGATED_DEBOOTSTRAP_COMPONENTS_COMMA}'"
"'--skip=check/empty'"
)
[[ "${DEBUG}" == "yes" ]] && debootstrap_arguments+=("--verbose")
fetch_distro_keyring "$RELEASE"
local_apt_deb_cache_prepare "before mmdebstrap"
if [[ "${LOCAL_APT_CACHE_INFO[USE]}" == "yes" ]]; then
debootstrap_arguments+=("--setup-hook='mkdir -p ${LOCAL_APT_CACHE_INFO[HOST_DEBOOTSTRAP_CACHE_DIR]} \"\$1\"/var/cache/apt/archives/'")
debootstrap_arguments+=("--setup-hook='sync-in ${LOCAL_APT_CACHE_INFO[HOST_DEBOOTSTRAP_CACHE_DIR]} /var/cache/apt/archives/'")
debootstrap_arguments+=("--customize-hook='sync-out /var/cache/apt/archives/ ${LOCAL_APT_CACHE_INFO[HOST_DEBOOTSTRAP_CACHE_DIR]}'")
fi
if [[ -n "${APT_PROXY_ADDR}" && ("${MANAGE_ACNG}" == "no" || -z "${MANAGE_ACNG}") ]]; then
display_alert "Routing mmdebstrap through apt proxy" "http://${APT_PROXY_ADDR##*@}" "info"
debootstrap_arguments+=("'--aptopt=Acquire::http::Proxy \"http://${APT_PROXY_ADDR}\"'")
fi
debootstrap_arguments+=("${RELEASE}" "${SDCARD}/" "${debootstrap_apt_mirror}")
mkdir -p "${SDCARD}/usr/bin"
mkdir -p "${SDCARD}/etc/apt/apt.conf.d"
echo 'APT::Sandbox::User "root";' > "${SDCARD}/etc/apt/apt.conf.d/99-armbian-sandbox"
deploy_qemu_binary_to_chroot "${SDCARD}" "rootfs"
run_host_command_logged "${debootstrap_bin}" "${debootstrap_arguments[@]}" || {
exit_with_error "mmdebstrap failed" "${debootstrap_bin} ${RELEASE} ${DESKTOP_ENVIRONMENT:-cli} ${DESKTOP_TIER:-none} ${BUILD_MINIMAL}"
}
skip_target_check="yes" local_apt_deb_cache_prepare "for mmdebstrap"
[[ ! -f "${SDCARD}/bin/bash" ]] && exit_with_error "mmdebstrap did not produce /bin/bash"
display_alert "Cleaning up after mmdebstrap" "mmdebstrap cleanup" "info"
run_host_command_logged rm -rf "${SDCARD}/var/cache/apt" "${SDCARD}/var/lib/apt/lists"
rm -f "${SDCARD}/etc/apt/apt.conf.d/99-armbian-sandbox"
rm -f "${SDCARD}/etc/apt/apt.conf.d/99mmdebstrap"
local_apt_deb_cache_prepare "after mmdebstrap cleanup"
mount_chroot "${SDCARD}"
display_alert "Diverting" "initctl/start-stop-daemon" "info"
printf '#!/bin/sh\nexit 101' > $SDCARD/usr/sbin/policy-rc.d
chroot_sdcard LC_ALL=C LANG=C dpkg-divert --quiet --local --rename --add /sbin/initctl
chroot_sdcard LC_ALL=C LANG=C dpkg-divert --quiet --local --rename --add /sbin/start-stop-daemon
printf '#!/bin/sh\necho "Warning: Fake start-stop-daemon called, doing nothing"' > "$SDCARD/sbin/start-stop-daemon"
printf '#!/bin/sh\necho "Warning: Fake initctl called, doing nothing"' > "$SDCARD/sbin/initctl"
chmod 755 "${SDCARD}/usr/sbin/policy-rc.d"
chmod 755 "${SDCARD}/sbin/initctl"
chmod 755 "${SDCARD}/sbin/start-stop-daemon"
display_alert "Configuring locales" "DEST_LANG: ${DEST_LANG}" "info"
[[ "x${DEST_LANG}x" == "xx" ]] && exit_with_error "Bug: got to config locales without DEST_LANG set"
[[ -f $SDCARD/etc/locale.gen ]] && sed -i "s/^# ${DEST_LANG}/${DEST_LANG}/" $SDCARD/etc/locale.gen
chroot_sdcard LC_ALL=C LANG=C locale-gen "${DEST_LANG}"
chroot_sdcard LC_ALL=C LANG=C update-locale "LANG=${DEST_LANG}" "LANGUAGE=${DEST_LANG}" "LC_MESSAGES=${DEST_LANG}"
if [[ -f $SDCARD/etc/default/console-setup ]]; then
sed -e 's/CHARMAP=.*/CHARMAP="UTF-8"/' -e 's/FONTSIZE=.*/FONTSIZE="8x16"/' \
-e 's/CODESET=.*/CODESET="guess"/' -i "$SDCARD/etc/default/console-setup"
chroot_sdcard "LC_ALL=C LANG=C setupcon --save --force 2>/dev/null || true"
fi
create_sources_list_and_deploy_repo_key "root" "$RELEASE" "$SDCARD/"
if [[ "a${ARMHF_ARCH}" == "ayes" ]]; then
[[ $ARCH == arm64 ]] && chroot_sdcard LC_ALL=C LANG=C dpkg --add-architecture armhf
fi
chroot_sdcard 'echo "resolvconf resolvconf/linkify-resolvconf boolean false" | debconf-set-selections'
add_apt_sources
run_host_command_logged ls -l "${SDCARD}/usr/share/keyrings"
run_host_command_logged ls -l "${SDCARD}/etc/apt/sources.list.d"
run_host_command_logged cat "${SDCARD}/etc/apt/sources.list.d/${DISTRIBUTION,,}.sources"
display_alert "Updating package list" "$RELEASE" "info"
do_with_retries 3 chroot_sdcard_apt_get_update
display_alert "Upgrading base packages" "Armbian" "info"
do_with_retries 3 chroot_sdcard_apt_get upgrade
display_alert "Installing the main packages for" "Armbian" "info"
declare -g if_error_detail_message="Installation of Armbian main packages for ${RELEASE} ${DESKTOP_ENVIRONMENT:-cli} ${DESKTOP_TIER:-none} ${BUILD_MINIMAL} failed"
chroot_sdcard_apt_get_install_dry_run "${AGGREGATED_PACKAGES_ROOTFS[@]}"
do_with_retries 3 chroot_sdcard_apt_get_install_download_only "${AGGREGATED_PACKAGES_ROOTFS[@]}"
chroot_sdcard_apt_get_install "${AGGREGATED_PACKAGES_ROOTFS[@]}"
write_build_resolv_conf "${SDCARD}"
if [[ $BUILD_DESKTOP == "yes" ]]; then
display_alert "Installing desktop via armbian-config" "${DESKTOP_ENVIRONMENT} tier=${DESKTOP_TIER:-mid}" "info"
chroot_sdcard_apt_get_install armbian-config
chroot_sdcard "SUDO_USER= DEBIAN_FRONTEND=noninteractive DIALOG=read armbian-config --api module_desktops install de=${DESKTOP_ENVIRONMENT} tier=${DESKTOP_TIER:-mid} mode=build"
fi
if [[ "${DISTRIBUTION_STATUS}" == "supported" && "${FORCE_CHECK_MD5_PACKAGES:-"no"}" == "yes" ]]; then
display_alert "Checking MD5 sum of installed packages" "debsums" "info"
declare -g if_error_detail_message="Check MD5 sum of installed packages failed"
chroot_sdcard debsums --silent
fi
DONT_MAINTAIN_APT_CACHE="yes" chroot_sdcard_apt_get autoremove
apt_purge_unneeded_packages_and_clean_apt_caches
local free_space
free_space=$(LC_ALL=C df -h)
display_alert "Free disk space on rootfs" "SDCARD: $(echo -e "${free_space}" | awk -v mp="${SDCARD}" '$6==mp {print $5}')" "info"
write_build_resolv_conf "${SDCARD}"
run_host_command_logged echo -n ">" "${SDCARD}/etc/machine-id"
run_host_command_logged rm -fv "${SDCARD}/var/lib/dbus/machine-id"
chroot_sdcard systemctl mask systemd-firstboot.service
undeploy_qemu_binary_from_chroot "${SDCARD}" "rootfs"
display_alert "Ending mmdebstrap process and preparing cache" "$RELEASE" "info"
wait_for_disk_sync "before tar rootfs"
umount_chroot "${SDCARD}"
wait_for_disk_sync "after unmounting chroot used for rootfs build"
return 0
}