@@ -20,6 +20,8 @@ DISTRO_MM_OPTS += "${MMAPTOPT_NOEXPKEYSIGN}"
DISTRO_BOOTSTRAP_KEYS = "http://raspbian.raspberrypi.org/raspbian.public.key;sha256sum=ca59cd4f2bcbc3a1d41ba6815a02a8dc5c175467a59bd87edeac458f4a5345de"
DISTRO_BOOTSTRAP_KEYS:arm64 = ""
DISTRO_BOOTSTRAP_BASE_PACKAGES:append = " usrmerge"
+# workaround for missing depends to apt in raspbian-archive-keyring
+DISTRO_BOOTSTRAP_BASE_PACKAGES:append = " apt"
DISTRO_KERNELS ?= "kernel kernel7 kernel7l kernel8"
@@ -12,3 +12,6 @@ DISTRO_GCC = "9"
DEBIAN_COMPAT = "12"
DEBIAN_STANDARDS_VERSION ?= "4.5.0"
+
+# workaround for missing depends in /usr/share/initramfs-tools/hooks/fixrtc
+IMAGE_PREINSTALL:append = " e2fsprogs"
@@ -178,3 +178,37 @@ deb_dl_dir_export() {
done
EOF
}
+
+# Point isar-apt at its real build-path location so host apt can access it.
+# The reproducible 'file:///isar-apt' encodes to the apt list prefix '_isar-apt',
+# the real repo path encodes to the same path with '/' replaced by '_'.
+deb_dl_dir_isar_apt_to_host() {
+ export rootfs="${1}"
+ export host_prefix="$(printf '%s' '${REPO_ISAR_DIR}/${DISTRO}' | tr '/' '_')"
+ run_privileged_heredoc << ' EOSUDO'
+ set -e
+ sed -i 's|file:///isar-apt|file://${REPO_ISAR_DIR}/${DISTRO}|g' \
+ "${rootfs}/etc/apt/sources.list.d/isar-apt.list"
+ for f in "${rootfs}/var/lib/apt/lists/"_isar-apt*; do
+ [ -e "$f" ] || continue
+ suffix="$(basename "$f" | sed 's|^_isar-apt||')"
+ mv "$f" "${rootfs}/var/lib/apt/lists/${host_prefix}${suffix}"
+ done
+ EOSUDO
+}
+
+# Revert the deb_dl_dir_isar_apt_to_host changes.
+deb_dl_dir_isar_apt_to_target() {
+ export rootfs="${1}"
+ export host_prefix="$(printf '%s' '${REPO_ISAR_DIR}/${DISTRO}' | tr '/' '_')"
+ run_privileged_heredoc << ' EOSUDO'
+ set -e
+ sed -i 's|file://${REPO_ISAR_DIR}/${DISTRO}|file:///isar-apt|g' \
+ "${rootfs}/etc/apt/sources.list.d/isar-apt.list"
+ for f in "${rootfs}/var/lib/apt/lists/${host_prefix}"*; do
+ [ -e "$f" ] || continue
+ suffix="$(basename "$f" | sed "s|^${host_prefix}||")"
+ mv "$f" "${rootfs}/var/lib/apt/lists/_isar-apt${suffix}"
+ done
+ EOSUDO
+}
@@ -104,20 +104,26 @@ fetch_common_source_unshare() {
set -e
mkdir -p ${UNSHARE_DPKG_SOURCE_CHROOT}
tar -xf "${SBUILD_CHROOT}" -C ${UNSHARE_DPKG_SOURCE_CHROOT}
+EOF
- ${@insert_isar_mounts(d, d.getVar('UNSHARE_DPKG_SOURCE_CHROOT'), d.getVar('SCHROOT_MOUNTS'))}
- chroot ${UNSHARE_DPKG_SOURCE_CHROOT} /bin/bash -s <<'EOAPT'
- set -e
- apt-get update \
- -o Dir::Etc::SourceList="sources.list.d/isar-apt.list" \
- -o Dir::Etc::SourceParts="-" \
- -o APT::Get::List-Cleanup="0"
+ deb_dl_dir_isar_apt_to_host ${UNSHARE_DPKG_SOURCE_CHROOT}
- cd /work
- apt-get -y --download-only --only-source \
- -o Debug::NoLocking=1 -o Acquire::Source-Symlinks="false" \
- source ${DEBIAN_SOURCE}
-EOAPT
+ run_privileged_heredoc <<'EOF'
+ ${@insert_isar_mounts(d, d.getVar('UNSHARE_DPKG_SOURCE_CHROOT'), d.getVar('SCHROOT_MOUNTS'))}
+ apt-get update \
+ -o Dir="${UNSHARE_DPKG_SOURCE_CHROOT}" \
+ -o APT::Architecture="${HOST_ARCH}" \
+ -o Dir::Etc::SourceList="sources.list.d/isar-apt.list" \
+ -o Dir::Etc::SourceParts="-" \
+ -o APT::Get::List-Cleanup="0"
+
+ cd /work
+ apt-get \
+ -o Dir="${UNSHARE_DPKG_SOURCE_CHROOT}" \
+ -o APT::Architecture="${HOST_ARCH}" \
+ -y --download-only --only-source \
+ -o Debug::NoLocking=1 -o Acquire::Source-Symlinks="false" \
+ source ${DEBIAN_SOURCE}
EOF
# run cleanup in separate session to ensure nothing is mounted
@@ -140,6 +140,7 @@ def image_create_users(d: "DataSmart") -> None:
bb.process.run([*chroot, "/usr/bin/passwd", "--expire", entry])
+ROOTFS_PACKAGES += "passwd"
ROOTFS_POSTPROCESS_COMMAND += "image_postprocess_accounts"
image_postprocess_accounts[vardeps] += "USERS GROUPS"
python image_postprocess_accounts() {
@@ -32,8 +32,10 @@ image_install_localepurge_download() {
run_privileged_heredoc <<'EOF'
set -e
${@insert_isar_mounts(d, d.getVar('ROOTFSDIR'), d.getVar('ROOTFS_MOUNTS') if d.getVar('ISAR_CHROOT_MODE') == 'unshare' else '')}
- chroot ${ROOTFSDIR} \
- /usr/bin/apt-get ${ROOTFS_APT_ARGS} -o Debug::NoLocking=1 --download-only localepurge
+ /usr/bin/apt-get ${ROOTFS_APT_ARGS} \
+ -o Dir="${ROOTFSDIR}" \
+ -o APT::Architecture="${ROOTFS_ARCH}" \
+ -o Debug::NoLocking=1 --download-only localepurge
EOF
}
@@ -78,8 +80,9 @@ __EOF__
echo 'localepurge was not installed (removing it later)'
# track additional packages that will be installed, as these packages might be
# in the suggested set of other packages and by that need to be explicitly removed
- localepurge_pkgs=$(chroot '${ROOTFSDIR}' apt-get ${ROOTFS_APT_ARGS} -s localepurge 2>&1 | sed -n 's/^Inst \([^ ]*\) .*/\1/p')
- chroot '${ROOTFSDIR}' apt-get ${ROOTFS_APT_ARGS} localepurge
+ localepurge_pkgs=$(/usr/bin/apt-get \
+ ${ROOTFS_HOST_APT_OPTS} ${ROOTFS_APT_ARGS} -s localepurge 2>&1 | sed -n 's/^Inst \([^ ]*\) .*/\1/p')
+ /usr/bin/apt-get ${ROOTFS_HOST_APT_OPTS} ${ROOTFS_APT_ARGS} localepurge
fi
cat '${WORKDIR}/locale.gen' >> '${ROOTFSDIR}/etc/locale.gen'
@@ -115,7 +118,7 @@ EOSH
if [ "$localepurge_state" = 'p' ]
then
echo removing localepurge...
- chroot '${ROOTFSDIR}' apt-get purge --yes $localepurge_pkgs
+ /usr/bin/apt-get ${ROOTFS_HOST_APT_OPTS} purge --yes $localepurge_pkgs
fi
EOSUDO
}
@@ -59,6 +59,16 @@ ROOTFS_FEATURES:remove:focal = "generate-sbom"
# Capture all information needed for sbom generation
ROOTFS_APT_STATE = "apt-state.tar.zst"
ROOTFS_APT_ARGS="install --yes -o Debug::pkgProblemResolver=yes"
+ROOTFS_HOST_APT_OPTS = "-o Dir=${ROOTFSDIR} -o APT::Architecture=${ROOTFS_ARCH} -o DPkg::Chroot-Directory=${ROOTFSDIR}"
+
+# The host apt-get used to populate the rootfs must honor the rootfs' own apt
+# configuration fragments instead of the host's /etc/apt. A command-line '-o' is
+# applied too late (after apt has already read its config parts), so point apt at
+# the chroot via APT_CONFIG, which is parsed during apt initialization - before
+# the config parts directory is read. No host file is touched.
+ROOTFS_HOST_APT_CONFIG = "${WORKDIR}/isar-host-apt.conf"
+# Wrapper to run the host apt-get with that configuration.
+HOST_APT_CMD = "env APT_CONFIG=${ROOTFS_HOST_APT_CONFIG} /usr/bin/apt-get ${ROOTFS_HOST_APT_OPTS}"
ROOTFS_CLEAN_FILES="/etc/hostname /etc/resolv.conf"
@@ -68,7 +78,7 @@ ROOTFS_PACKAGE_SUFFIX ?= "${PN}-${DISTRO}-${DISTRO_ARCH}"
ROOTFS_STUBS_DIR = "/usr/local/isar-sbin"
# list of <outer>:<inner> or <outer> mount entries
-ROOTFS_MOUNTS ??= "${REPO_ISAR_DIR}/${DISTRO}:/isar-apt ${WORKDIR}:/isar-work"
+ROOTFS_MOUNTS ??= "${WORKDIR}:/isar-work"
python () {
mounts = d.getVar('ROOTFS_MOUNTS', False)
@@ -95,75 +105,6 @@ export LANG = "${LOCALE_DEFAULT}"
export LANGUAGE = "${LOCALE_DEFAULT}"
export LC_ALL = "${LOCALE_DEFAULT}"
-# Execute a command against a rootfs and with isar-apt bind-mounted.
-# Additional mounts may be specified using --bind <source> <target> and a
-# custom directory for the command to be executed with --chdir <dir>. The
-# command is assumed to follow the special "--" argument. This would replace
-# "sudo chroot" calls especially when a native command may be used instead of
-# chroot'ed command and without elevated privileges (the command will likely
-# take the rootfs as argument; e.g. apt-get -o Dir=${ROOTFSDIR}). If the
-# optional rootfs argument is omitted, the host rootfs will be used (e.g. to
-# run native commands): this should be used with care.
-#
-# Usage: rootfs_cmd [options] [rootfs] -- command
-#
-rootfs_cmd() {
- set -- "$@"
- bwrap_args="--bind ${REPO_ISAR_DIR}/${DISTRO} /isar-apt"
- bwrap_binds=""
- bwrap_rootfs=""
-
- while [ "${#}" -gt "0" ] && [ "${1}" != "--" ]; do
- case "${1}" in
- --bind)
- if [ "${#}" -lt "3" ]; then
- bbfatal "--bind requires two arguments"
- fi
- bwrap_binds="${bwrap_binds} --bind ${2} ${3}"
- shift 3
- ;;
- --chdir)
- if [ "${#}" -lt "2" ]; then
- bbfatal "${1} requires an argument"
- fi
- bwrap_args="${bwrap_args} ${1} ${2}"
- shift 2
- ;;
- -*)
- bbfatal "${1} is not a supported option!"
- ;;
- *)
- if [ -z "${bwrap_rootfs}" ]; then
- bwrap_rootfs="${1}"
- shift
- else
- bbfatal "unexpected argument '${1}'"
- fi
- ;;
- esac
- done
-
- if [ -n "${bwrap_rootfs}" ]; then
- bwrap_args="${bwrap_args} --bind ${bwrap_rootfs} /"
- fi
-
- if [ "${#}" -le "1" ] || [ "${1}" != "--" ]; then
- bbfatal "no command specified (missing --)"
- fi
- shift # remove "--", command and its arguments follows
-
- # bin, lib and lib64 are only real directories on unmerged-usr rootfs
- for ro_d in bin etc lib lib64 sys usr var; do
- [ -d ${bwrap_rootfs}/${ro_d} ] && [ ! -L ${bwrap_rootfs}/${ro_d} ] || continue
- bwrap_args="${bwrap_args} --ro-bind ${bwrap_rootfs}/${ro_d} /${ro_d}"
- done
-
- bwrap --unshare-user --unshare-pid ${bwrap_args} \
- --dev-bind /dev /dev --proc /proc --tmpfs /tmp \
- ${@'--bind "${REPO_ISAR_DIR}/${DISTRO}" /isar-apt' if d.getVar('ISAR_CHROOT_MODE') == 'unshare' else ''} \
- ${bwrap_binds} -- "${@}"
-}
-
rootfs_do_mounts[weight] = "3"
python rootfs_do_mounts() {
if d.getVar('ISAR_CHROOT_MODE') == 'schroot':
@@ -277,6 +218,20 @@ EOF
EOSUDO
}
+ROOTFS_CONFIGURE_COMMAND += "rootfs_redirect_isar_apt_to_host"
+rootfs_redirect_isar_apt_to_host() {
+ if [ -f "${ROOTFSDIR}/etc/apt/sources.list.d/isar-apt.list" ]; then
+ deb_dl_dir_isar_apt_to_host "${ROOTFSDIR}"
+ fi
+}
+
+# restore by latest before capturing the apt state and before sstate caching
+rootfs_redirect_isar_apt_to_target() {
+ if [ -f "${ROOTFSDIR}/etc/apt/sources.list.d/isar-apt.list" ]; then
+ deb_dl_dir_isar_apt_to_target "${ROOTFSDIR}"
+ fi
+}
+
ROOTFS_CONFIGURE_COMMAND += "rootfs_configure_apt"
rootfs_configure_apt[weight] = "2"
rootfs_configure_apt() {
@@ -299,6 +254,14 @@ rootfs_configure_apt() {
EOSUDO
}
+# Point the host apt-get at the rootfs' apt.conf.d (see ROOTFS_HOST_APT_CONFIG).
+ROOTFS_CONFIGURE_COMMAND =+ "rootfs_configure_host_apt_config"
+rootfs_configure_host_apt_config[weight] = "1"
+rootfs_configure_host_apt_config() {
+ echo 'Dir::Etc::parts "${ROOTFSDIR}/etc/apt/apt.conf.d";' \
+ > '${ROOTFS_HOST_APT_CONFIG}'
+}
+
ROOTFS_CONFIGURE_COMMAND += "rootfs_disable_initrd_generation"
rootfs_disable_initrd_generation[weight] = "1"
rootfs_disable_initrd_generation() {
@@ -323,7 +286,7 @@ rootfs_install_pkgs_update() {
run_privileged_heredoc <<'EOF'
set -e
${@insert_isar_mounts(d, d.getVar('ROOTFSDIR'), d.getVar('ROOTFS_MOUNTS')) if d.getVar('ISAR_CHROOT_MODE') == 'unshare' else ''}
- chroot '${ROOTFSDIR}' /usr/bin/apt-get update \
+ ${HOST_APT_CMD} update \
-o Dir::Etc::SourceList="sources.list.d/isar-apt.list" \
-o Dir::Etc::SourceParts="-" \
-o APT::Get::List-Cleanup="0"
@@ -354,10 +317,14 @@ rootfs_install_pkgs_download[progress] = "custom:rootfs_progress.PkgsDownloadPro
rootfs_install_pkgs_download[isar-apt-lock] = "release-after"
rootfs_install_pkgs_download[network] = "${TASK_USE_NETWORK}"
rootfs_install_pkgs_download() {
- # download packages using apt in a non-privileged namespace
- rootfs_cmd --bind "${ROOTFSDIR}/var/cache/apt/archives" /var/cache/apt/archives \
- ${ROOTFSDIR} \
- -- /usr/bin/apt-get ${ROOTFS_APT_ARGS} -o Debug::NoLocking=1 --download-only ${ROOTFS_PACKAGES}
+ run_privileged_heredoc <<'EOF'
+ set -e
+ ${@insert_isar_mounts(d, d.getVar('ROOTFSDIR'), d.getVar('ROOTFS_MOUNTS')) if d.getVar('ISAR_CHROOT_MODE') == 'unshare' else ''}
+ ${HOST_APT_CMD} \
+ ${ROOTFS_APT_ARGS} \
+ -o Debug::NoLocking=1 \
+ --download-only ${ROOTFS_PACKAGES}
+EOF
}
ROOTFS_INSTALL_COMMAND_BEFORE_EXPORT ??= ""
@@ -373,16 +340,15 @@ ROOTFS_INSTALL_COMMAND += "rootfs_install_pkgs_isar_download"
rootfs_install_pkgs_isar_download[weight] = "50"
rootfs_install_pkgs_isar_download[isar-apt-lock] = "acquire-before release-after"
rootfs_install_pkgs_isar_download() {
- # Command apt-get install do not cache packages from local repos
- # We can obtain non cached package URIs by recalling install command here
- # No need to export those files to dl_dir, so we can run it right after
- rootfs_cmd --bind "${ROOTFSDIR}/var/cache/apt/archives" /var/cache/apt/archives \
- --chdir "/var/cache/apt/archives" \
- ${ROOTFSDIR} \
- -- /usr/bin/sh -c 'apt-get ${ROOTFS_APT_ARGS} --print-uris ${ROOTFS_PACKAGES} | \
- sed -n "s|^.file:\(/[^'\'']*\.deb\). \([^ ]*\.deb\).*|\1 \2|p" | \
- sed ":a; s|^\([^ ]*\)%|\1\\\\x|; ta" | \
- while read -r path name; do cp -n "$(/usr/bin/printf "%b" "$path")" "$name" ; done'
+ run_privileged_heredoc <<'EOF'
+ set -e
+ ${@insert_isar_mounts(d, d.getVar('ROOTFSDIR'), d.getVar('ROOTFS_MOUNTS')) if d.getVar('ISAR_CHROOT_MODE') == 'unshare' else ''}
+ ${HOST_APT_CMD} \
+ ${ROOTFS_APT_ARGS} --print-uris ${ROOTFS_PACKAGES} | \
+ sed -n "s|^.file:\(/[^'\'']*\.deb\). \([^ ]*\.deb\).*|\1 \2|p" | \
+ sed ":a; s|^\([^ ]*\)%|\1\\\\x|; ta" | \
+ while read -r path name; do cp -n "$(/usr/bin/printf "%b" "$path")" "${ROOTFSDIR}/var/cache/apt/archives/$name" ; done
+EOF
}
ROOTFS_INSTALL_COMMAND += "${@ 'rootfs_install_clean_files' if (d.getVar('ROOTFS_CLEAN_FILES') or '').strip() else ''}"
@@ -403,8 +369,7 @@ rootfs_install_pkgs_install() {
run_privileged_heredoc <<'EOF'
set -e
${@insert_isar_mounts(d, d.getVar('ROOTFSDIR'), d.getVar('ROOTFS_MOUNTS')) if d.getVar('ISAR_CHROOT_MODE') == 'unshare' else ''}
- chroot "${ROOTFSDIR}" \
- /usr/bin/apt-get ${ROOTFS_APT_ARGS} --no-download ${ROOTFS_PACKAGES}
+ ${HOST_APT_CMD} ${ROOTFS_APT_ARGS} --no-download ${ROOTFS_PACKAGES}
EOF
}
@@ -424,7 +389,7 @@ rootfs_clear_initrd_symlinks() {
run_privileged rm -f ${ROOTFSDIR}/initrd.img.old
}
-ROOTFS_INSTALL_COMMAND += "${@bb.utils.contains('ROOTFS_FEATURES', 'generate-sbom', 'rootfs_capture_apt_state', '', d)}"
+ROOTFS_POSTPROCESS_COMMAND:prepend = "${@bb.utils.contains('ROOTFS_FEATURES', 'generate-sbom', 'rootfs_capture_apt_state', '', d)} "
rootfs_capture_apt_state() {
( cd ${ROOTFSDIR} && find usr/share/doc -name copyright -print0 ) | \
tar -cf ${WORKDIR}/${ROOTFS_APT_STATE} --zstd --sort=name \
@@ -437,6 +402,7 @@ rootfs_capture_apt_state() {
var/lib/apt/extended_states \
var/lib/dpkg/status
}
+ROOTFS_POSTPROCESS_COMMAND:prepend = "rootfs_redirect_isar_apt_to_target "
do_rootfs_install[root_cleandirs] = "${ROOTFSDIR}"
do_rootfs_install[cleandirs] += "${DEPLOYDIR}"
@@ -533,8 +499,7 @@ cache_dbg_pkgs() {
ROOTFS_POSTPROCESS_COMMAND += "${@bb.utils.contains('ROOTFS_FEATURES', 'clean-package-cache', 'rootfs_postprocess_clean_package_cache', '', d)}"
rootfs_postprocess_clean_package_cache() {
- run_in_chroot '${ROOTFSDIR}' \
- /usr/bin/apt-get clean
+ run_privileged ${HOST_APT_CMD} clean
# remove apt-cache folder itself (required in case rootfs is provided by sstate cache)
run_privileged find "${ROOTFSDIR}/var/cache/apt" -type f \
\( -name '*.deb' -o -name '*.bin' \) -delete
@@ -42,7 +42,10 @@ SDK_PREINSTALL += " \
apt \
automake \
devscripts \
- equivs"
+ equivs \
+ apt \
+ passwd \
+"
# rootfs/image overrides for the SDK
ROOTFS_ARCH:class-sdk = "${HOST_ARCH}"
@@ -9,7 +9,7 @@ inherit bootstrap
inherit compat
inherit deb-dl-dir
-DISTRO_BOOTSTRAP_BASE_PACKAGES += "locales apt"
+DISTRO_BOOTSTRAP_BASE_PACKAGES += "locales"
DISTRO_BOOTSTRAP_BASE_PACKAGES:append:https-support = " ca-certificates"
BOOTSTRAP_TMPDIR = "${WORKDIR}/tempdir"
@@ -146,7 +146,7 @@ do_bootstrap() {
bbfatal "${DISTRO_ARCH} does not have a compat arch"
fi
fi
- bootstrap_args="--verbose --variant=minbase --include=${@','.join(d.getVar('DISTRO_BOOTSTRAP_BASE_PACKAGES').split())}"
+ bootstrap_args="--verbose --variant=essential --include=${@','.join(d.getVar('DISTRO_BOOTSTRAP_BASE_PACKAGES').split())}"
if [ -f "${DISTRO_BOOTSTRAP_KEYRING}" ]; then
bootstrap_args="$bootstrap_args --keyring=${DISTRO_BOOTSTRAP_KEYRING}"
cp "${DISTRO_BOOTSTRAP_KEYRING}" "${WORKDIR}/trusted.gpg.d/"
@@ -174,10 +174,6 @@ do_bootstrap() {
syncout='echo skip sync-out'
extra_setup="mount --bind '${REPO_BASE_DIR}' $base_apt_tmp"
extra_extract="$syncout"
- # save mmdebstrap tempdir for cleanup
- extra_essential="mkdir -p \$1/$base_apt_tmp && \
- echo \$1 > ${WORKDIR}/mmtmpdir && \
- mount -o bind,private '${REPO_BASE_DIR}' \$1/$base_apt_tmp"
# replace base-apt mount in tmp with /base-apt mount
extra_customize="sed -i \"s|copy://$base_apt_tmp|file:///base-apt|g\" \
\$1/etc/apt/sources.list.d/*.list && \
@@ -206,15 +202,6 @@ do_bootstrap() {
"${WORKDIR}/dl_dir/var/cache/apt/archives/"'
extra_setup="$syncin"
extra_extract="$syncout"
- # prefetch apt debs because mmdebstrap will clean them on next stage
- extra_essential='apt-get install apt -y -d \
- -o Dir::State="$1/var/lib/apt" \
- -o Dir::Etc="$1/etc/apt" \
- -o Dir::Cache="$1/var/cache/apt" \
- ${@'-o APT::Sandbox::User=root' if d.getVar('ISAR_CHROOT_MODE') == 'unshare' else ''} \
- -o Apt::Architecture="${BOOTSTRAP_DISTRO_ARCH}" \
- ${@get_apt_opts(d, '-o')}'
- extra_essential="$extra_essential && $syncout"
extra_customize="$syncout"
fi
@@ -250,11 +237,9 @@ do_bootstrap() {
--setup-hook='chown -R root:root "$1/etc/apt/trusted.gpg.d"' \
--setup-hook='install -v -m755 "${WORKDIR}/chroot-setup.sh" "$1/chroot-setup.sh"' \
--extract-hook="$extra_extract" \
- --essential-hook="$extra_essential" \
--customize-hook="$extra_customize" \
--customize-hook='sed -i "/en_US.UTF-8 UTF-8/s/^#//g" "$1/etc/locale.gen"' \
--customize-hook='chroot "$1" /usr/sbin/locale-gen' \
- --customize-hook='chroot "$1" /usr/bin/apt-get -y clean' \
--customize-hook='echo nameserver 127.0.0.1 > "$1"/etc/resolv.conf' \
--customize-hook='echo isar > "$1"/etc/hostname' \
${@'--skip=output/dev' if d.getVar('ISAR_CHROOT_MODE') == 'unshare' else ''} \
@@ -21,7 +21,7 @@ DEPENDS:append:bookworm = " python3-cyclonedx-lib"
DEPENDS:append:noble = " python3-cyclonedx-lib"
DEPENDS += "python3-debsbom python3-spdx-tools"
-SBOM_IMAGE_INSTALL = "python3-debsbom python3-spdx-tools python3-cyclonedx-lib"
+SBOM_IMAGE_INSTALL = "python3-debsbom python3-spdx-tools python3-cyclonedx-lib lz4"
ROOTFSDIR = "${WORKDIR}/rootfs"
ROOTFS_PACKAGES = "${SBOM_IMAGE_INSTALL}"
@@ -54,6 +54,7 @@ SBUILD_CHROOT_PREINSTALL_COMMON = " \
${@ 'ccache' if bb.utils.to_boolean(d.getVar('USE_CCACHE')) else ''} \
devscripts \
equivs \
+ apt \
"
SBUILD_CHROOT_DIR = "${WORKDIR}/rootfs"
We currently use the apt inside the rootfs to operate on the rootfs. This has two major disadvantages: 1. on non-native, the apt invocations are emulated (including the extraction of the packages and downloading) 2. apt must be installed in the rootfs (which makes the rootfs larger and pulls in a lot of static-build-using dependencies related to the rust parts, which is relevant for license clearing) We change that similar to how mmdebstrap is doing it: Use the host apt to operate on the chroot, whereby dpkg itself runs inside the chroot to have proper support for the maintainer scripts. By that, apt is not emulated and the generated chroots can be much smaller. Not having apt inside the chroot exposes packaging bugs that assume that it (or any of its dependencies) is available. To work around these, we explicitly install the needed packages on a case-by-case decision. As of now, this series is only CI tested for rootless and also does not support the base-apt case. Signed-off-by: Felix Moessbauer <felix.moessbauer@siemens.com> --- meta-isar/conf/distro/raspios-bullseye.conf | 2 + meta-isar/conf/distro/ubuntu-focal.conf | 3 + meta/classes-recipe/deb-dl-dir.bbclass | 34 ++++ meta/classes-recipe/dpkg-source.bbclass | 30 ++-- .../image-account-extension.bbclass | 1 + .../image-locales-extension.bbclass | 13 +- meta/classes-recipe/rootfs.bbclass | 145 +++++++----------- meta/classes-recipe/sdk.bbclass | 5 +- .../isar-mmdebstrap/isar-mmdebstrap.inc | 19 +-- .../sbom-chroot/sbom-chroot.bb | 2 +- .../sbuild-chroot/sbuild-chroot.inc | 1 + 11 files changed, 129 insertions(+), 126 deletions(-)