@@ -962,3 +962,19 @@ INSTALLER_UNATTENDED_ABORT_ENABLE = "1"
# Optional: set countdown timeout in seconds (default 5)
INSTALLER_UNATTENDED_ABORT_TIMEOUT = "5"
```
+
+### Execution of privileged commands
+
+When operations require higher privileges than those available to the build user,
+the following helper functions shall be used:
+
+**run_privileged**: Run a command as root while preserving the environment.
+
+**run_privileged_here**: Execute commands provided via stdin in a root shell.
+
+**run_in_chroot**: Run a command within a chroot environment. The first argument
+specifies the rootfs path.
+
+Using these helpers instead of direct `sudo` invocations centralizes platform-specific
+privileged execution logic in `base.bbclass`. Direct use of `sudo` is discouraged
+in downstream layers.
@@ -384,3 +384,33 @@ python deprecation_checking() {
deprecation_checking[vardepsexclude] += "MACHINE"
do_unpack[prefuncs] += "deprecation_checking"
+
+# Helpers for privileged execution. Only the non-underscore functions
+# shall be used outside of this class.
+
+def run_privileged_cmd(d):
+ cmd = 'sudo -E'
+ bb.debug(1, "privileged cmd: %s" % cmd)
+ return cmd
+
+RUN_PRIVILEGED_CMD := "${@run_privileged_cmd(d)}"
+
+run_privileged() {
+ ${RUN_PRIVILEGED_CMD} "$@"
+}
+
+run_privileged_here() {
+ ${RUN_PRIVILEGED_CMD} /bin/bash -s "$@"
+}
+
+# create a directory that is suitable to be the
+# parent of a rootfs
+create_chroot_parent_dir() {
+ mkdir -p "$@"
+}
+
+run_in_chroot() {
+ rootfs="$1"
+ shift
+ ${RUN_PRIVILEGED_CMD} chroot "$rootfs" "$@"
+}
@@ -110,7 +110,7 @@ dbg_pkgs_download() {
| grep "${DISTRO_ARCH}" \
| awk '!/Binary:/ {print $1}' \
| sort -u
- done | xargs -r sudo -E chroot ${rootfs} sh -c '/usr/bin/apt-get -y --download-only install "$@"' --
+ done | xargs -r run_in_chroot ${rootfs} sh -c '/usr/bin/apt-get -y --download-only install "$@"' --
}
deb_dl_dir_import() {
@@ -120,7 +120,7 @@ deb_dl_dir_import() {
export gid=$(id -g)
# let our unprivileged user place downloaded packages in /var/cache/apt/archives/
- sudo -Es << ' EOSUDO'
+ run_privileged_here << ' EOSUDO'
mkdir -p "${rootfs}"/var/cache/apt/archives/partial/
chown -R ${uid}:${gid} "${rootfs}"/var/cache/apt/archives/
EOSUDO
@@ -161,7 +161,7 @@ def isar_export_build_settings(d):
dpkg_schroot_create_configs() {
schroot_create_configs
- sudo -s <<'EOSUDO'
+ run_privileged_here <<'EOSUDO'
sbuild_fstab="${SBUILD_CONF_DIR}/fstab"
fstab_isarapt="${WORKDIR}/isar-apt/${DISTRO}-${DISTRO_ARCH}/apt/${DISTRO} /isar-apt none rw,bind 0 0"
grep -qxF "${fstab_isarapt}" ${sbuild_fstab} || echo "${fstab_isarapt}" >> ${sbuild_fstab}
@@ -129,5 +129,5 @@ dpkg_runbuild() {
deb_dl_dir_export "${WORKDIR}/rootfs" "${distro}"
# Cleanup apt artifacts
- sudo rm -rf ${WORKDIR}/rootfs
+ run_privileged rm -rf ${WORKDIR}/rootfs
}
@@ -34,7 +34,7 @@ def image_create_groups(d: "DataSmart") -> None:
"""
entries = (d.getVar("GROUPS") or "").split()
rootfsdir = d.getVar("ROOTFSDIR")
- chroot = ["sudo", "-E", "chroot", rootfsdir]
+ chroot = run_privileged_cmd(d).split() + ["chroot", rootfsdir]
for entry in entries:
args = []
@@ -72,7 +72,7 @@ def image_create_users(d: "DataSmart") -> None:
entries = (d.getVar("USERS") or "").split()
rootfsdir = d.getVar("ROOTFSDIR")
- chroot = ["sudo", "-E", "chroot", rootfsdir]
+ chroot = run_privileged_cmd(d).split() + ["chroot", rootfsdir]
for entry in entries:
args = []
@@ -29,7 +29,7 @@ ROOTFS_INSTALL_COMMAND_BEFORE_EXPORT += "image_install_localepurge_download"
image_install_localepurge_download[weight] = "40"
image_install_localepurge_download[network] = "${TASK_USE_NETWORK_AND_SUDO}"
image_install_localepurge_download() {
- sudo -E chroot '${ROOTFSDIR}' \
+ run_in_chroot '${ROOTFSDIR}' \
/usr/bin/apt-get ${ROOTFS_APT_ARGS} -oDebug::NoLocking=1 --download-only localepurge
}
@@ -60,7 +60,7 @@ ${@get_nopurge(d)}
__EOF__
# Install configuration into image:
- sudo -E -s <<'EOSUDO'
+ run_privileged_here <<'EOSUDO'
set -e
localepurge_state='i'
if chroot '${ROOTFSDIR}' dpkg -s localepurge 2>/dev/null >&2
@@ -17,19 +17,19 @@ update_etc_os_release() {
done
if [ -n "${OS_RELEASE_BUILD_ID}" ]; then
- sudo sed -i '/^BUILD_ID=.*/d' '${IMAGE_ROOTFS}/etc/os-release'
+ run_privileged sed -i '/^BUILD_ID=.*/d' '${IMAGE_ROOTFS}/etc/os-release'
echo "BUILD_ID=\"${OS_RELEASE_BUILD_ID}\"" | \
- sudo tee -a '${IMAGE_ROOTFS}/etc/os-release'
+ run_privileged tee -a '${IMAGE_ROOTFS}/etc/os-release'
fi
if [ -n "${OS_RELEASE_VARIANT}" ]; then
- sudo sed -i '/^VARIANT=.*/d' '${IMAGE_ROOTFS}/etc/os-release'
+ run_privileged sed -i '/^VARIANT=.*/d' '${IMAGE_ROOTFS}/etc/os-release'
echo "VARIANT=\"${OS_RELEASE_VARIANT}\"" | \
- sudo tee -a '${IMAGE_ROOTFS}/etc/os-release'
+ run_privileged tee -a '${IMAGE_ROOTFS}/etc/os-release'
fi
if [ -n "${OS_RELEASE_VARIANT_VERSION}" ]; then
- sudo sed -i '/^VARIANT_VERSION=.*/d' '${IMAGE_ROOTFS}/etc/os-release'
+ run_privileged sed -i '/^VARIANT_VERSION=.*/d' '${IMAGE_ROOTFS}/etc/os-release'
echo "VARIANT_VERSION=\"${OS_RELEASE_VARIANT_VERSION}\"" | \
- sudo tee -a '${IMAGE_ROOTFS}/etc/os-release'
+ run_privileged tee -a '${IMAGE_ROOTFS}/etc/os-release'
fi
}
@@ -37,11 +37,11 @@ ROOTFS_POSTPROCESS_COMMAND =+ "image_postprocess_configure"
image_postprocess_configure() {
# Configure root filesystem
if [ -n "${DISTRO_CONFIG_SCRIPT}" ]; then
- sudo install -m 755 "${WORKDIR}/${DISTRO_CONFIG_SCRIPT}" "${IMAGE_ROOTFS}"
+ run_privileged install -m 755 "${WORKDIR}/${DISTRO_CONFIG_SCRIPT}" "${IMAGE_ROOTFS}"
TARGET_DISTRO_CONFIG_SCRIPT="$(basename ${DISTRO_CONFIG_SCRIPT})"
- sudo chroot ${IMAGE_ROOTFS} "/$TARGET_DISTRO_CONFIG_SCRIPT" \
+ run_in_chroot ${IMAGE_ROOTFS} "/$TARGET_DISTRO_CONFIG_SCRIPT" \
"${MACHINE_SERIAL}" "${BAUDRATE_TTY}"
- sudo rm "${IMAGE_ROOTFS}/$TARGET_DISTRO_CONFIG_SCRIPT"
+ run_privileged rm "${IMAGE_ROOTFS}/$TARGET_DISTRO_CONFIG_SCRIPT"
fi
}
@@ -58,13 +58,13 @@ image_postprocess_machine_id() {
# systemd(1) takes care of recreating the machine-id on first boot
# for systemd < v247, set to empty string, else set to uninitialized
# (required if initramfs with ro root is used)
- SYSTEMD_VERSION=$( sudo chroot ${IMAGE_ROOTFS} dpkg-query --showformat='${source:Upstream-Version}' --show systemd || echo "0" )
+ SYSTEMD_VERSION=$( run_in_chroot ${IMAGE_ROOTFS} dpkg-query --showformat='${source:Upstream-Version}' --show systemd || echo "0" )
MACHINE_ID="uninitialized"
if dpkg --compare-versions "$SYSTEMD_VERSION" "lt" "247"; then
MACHINE_ID=""
fi
- echo "$MACHINE_ID" | sudo chroot ${IMAGE_ROOTFS} tee /etc/machine-id
- sudo rm -f '${IMAGE_ROOTFS}/var/lib/dbus/machine-id'
+ echo "$MACHINE_ID" | run_in_chroot ${IMAGE_ROOTFS} tee /etc/machine-id
+ run_privileged rm -f '${IMAGE_ROOTFS}/var/lib/dbus/machine-id'
}
ROOTFS_POSTPROCESS_COMMAND =+ "image_postprocess_sshd_key_regen"
@@ -82,13 +82,13 @@ image_postprocess_sshd_key_regen() {
ROOTFS_POSTPROCESS_COMMAND =+ "image_postprocess_disable_systemd_firstboot"
image_postprocess_disable_systemd_firstboot() {
- SYSTEMD_VERSION=$(sudo chroot '${ROOTFSDIR}' dpkg-query \
+ SYSTEMD_VERSION=$(run_in_chroot '${ROOTFSDIR}' dpkg-query \
--showformat='${source:Upstream-Version}' \
--show systemd || echo "0" )
if dpkg --compare-versions "$SYSTEMD_VERSION" "ge" "251"; then
- sudo chroot '${ROOTFSDIR}' systemctl mask systemd-firstboot
- if ! cmd_output=$(sudo chroot '${ROOTFSDIR}' systemd-firstboot \
+ run_in_chroot '${ROOTFSDIR}' systemctl mask systemd-firstboot
+ if ! cmd_output=$(run_in_chroot '${ROOTFSDIR}' systemd-firstboot \
--prompt --welcome=false </dev/null 2>/dev/null); then
bbwarn "Your image is not configured completely according to systemd-firstboot."
bbwarn "It prompted: \"${cmd_output}\""
@@ -363,7 +363,7 @@ get_build_id() {
ROOTFS_CONFIGURE_COMMAND += "image_configure_fstab"
image_configure_fstab[weight] = "2"
image_configure_fstab() {
- sudo tee '${IMAGE_ROOTFS}/etc/fstab' << EOF
+ run_privileged tee '${IMAGE_ROOTFS}/etc/fstab' << EOF
# Begin /etc/fstab
proc /proc proc nosuid,noexec,nodev 0 0
sysfs /sys sysfs nosuid,noexec,nodev 0 0
@@ -391,7 +391,7 @@ do_copy_boot_files() {
kernel="$(realpath -q '${IMAGE_ROOTFS}'/boot/vmlinu[xz])"
fi
if [ -f "$kernel" ]; then
- sudo cat "$kernel" > "${DEPLOYDIR}/${KERNEL_IMAGE}"
+ run_privileged cat "$kernel" > "${DEPLOYDIR}/${KERNEL_IMAGE}"
fi
for file in ${DTB_FILES}; do
@@ -447,7 +447,7 @@ def apt_list_files(d):
IMAGE_LISTS = "${@ ' '.join(apt_list_files(d)) }"
do_rootfs_finalize() {
- sudo -s <<'EOSUDO'
+ run_privileged_here <<'EOSUDO'
set -e
if [ -e "${ROOTFSDIR}/chroot-setup.sh" ]; then
@@ -473,14 +473,14 @@ EOSUDO
# Sometimes qemu-user-static generates coredumps in chroot, move them
# to work temporary directory and inform user about it.
- for f in $(sudo find ${ROOTFSDIR} -type f -name *.core -exec file --mime-type {} \; | grep 'application/x-coredump' | cut -d: -f1); do
- sudo mv "${f}" "${WORKDIR}/temp/"
+ for f in $(run_privileged find ${ROOTFSDIR} -type f -name *.core -exec file --mime-type {} \; | grep 'application/x-coredump' | cut -d: -f1); do
+ run_privileged mv "${f}" "${WORKDIR}/temp/"
bbwarn "found core dump in rootfs, check it in ${WORKDIR}/temp/${f##*/}"
done
# Set same time-stamps to the newly generated file/folders in the
# rootfs image for the purpose of reproducible builds.
- sudo find ${ROOTFSDIR} -newermt "$(date -d@${SOURCE_DATE_EPOCH} '+%Y-%m-%d %H:%M:%S')" \
+ run_privileged find ${ROOTFSDIR} -newermt "$(date -d@${SOURCE_DATE_EPOCH} '+%Y-%m-%d %H:%M:%S')" \
-exec touch '{}' -h -d@${SOURCE_DATE_EPOCH} ';'
}
do_rootfs_finalize[network] = "${TASK_USE_SUDO}"
@@ -517,7 +517,7 @@ do_rootfs_quality_check() {
;;
esac
done
- found=$( sudo find ${ROOTFSDIR} -type f -newer $rootfs_install_stamp $args )
+ found=$( run_privileged find ${ROOTFSDIR} -type f -newer $rootfs_install_stamp $args )
if [ -n "$found" ]; then
bbwarn "Files changed after package install. The following files seem"
bbwarn "to have changed where they probably should not have."
@@ -37,38 +37,38 @@ do_containerize() {
# prepare OCI container image skeleton
bbdebug 1 "prepare OCI container image skeleton"
- sudo rm -rf "${oci_img_dir}" "${oci_img_dir}_unpacked"
- sudo umoci init --layout "${oci_img_dir}"
- sudo umoci new --image "${oci_img_dir}:${empty_tag}"
+ run_privileged rm -rf "${oci_img_dir}" "${oci_img_dir}_unpacked"
+ run_privileged umoci init --layout "${oci_img_dir}"
+ run_privileged umoci new --image "${oci_img_dir}:${empty_tag}"
if [ -n "${cmd}" ]; then
- sudo umoci config --image "${oci_img_dir}:${empty_tag}" \
+ run_privileged umoci config --image "${oci_img_dir}:${empty_tag}" \
--config.cmd="${cmd}"
fi
if [ -n "${entrypoint}" ]; then
- sudo umoci config --image "${oci_img_dir}:${empty_tag}" \
+ run_privileged umoci config --image "${oci_img_dir}:${empty_tag}" \
--config.entrypoint="${entrypoint}"
fi
if [ -n "${path}" ]; then
- sudo umoci config --image "${oci_img_dir}:${empty_tag}" \
+ run_privileged umoci config --image "${oci_img_dir}:${empty_tag}" \
--config.env="PATH=${path}"
fi
- sudo umoci unpack --image "${oci_img_dir}:${empty_tag}" \
+ run_privileged umoci unpack --image "${oci_img_dir}:${empty_tag}" \
"${oci_img_dir}_unpacked"
# add root filesystem as the flesh of the skeleton
- sudo cp --reflink=auto -a "${rootfs}"/* "${oci_img_dir}_unpacked/rootfs/"
+ run_privileged cp --reflink=auto -a "${rootfs}"/* "${oci_img_dir}_unpacked/rootfs/"
# clean-up temporary files
- sudo find "${oci_img_dir}_unpacked/rootfs/tmp" -mindepth 1 -delete
+ run_privileged find "${oci_img_dir}_unpacked/rootfs/tmp" -mindepth 1 -delete
# pack container image
bbdebug 1 "pack container image"
- sudo umoci repack --image "${oci_img_dir}:${tag}" \
+ run_privileged umoci repack --image "${oci_img_dir}:${tag}" \
"${oci_img_dir}_unpacked"
- sudo umoci remove --image "${oci_img_dir}:${empty_tag}"
- sudo rm -rf "${oci_img_dir}_unpacked"
+ run_privileged umoci remove --image "${oci_img_dir}:${empty_tag}"
+ run_privileged rm -rf "${oci_img_dir}_unpacked"
# no root needed anymore
- sudo chown --recursive $(id -u):$(id -g) "${oci_img_dir}"
+ run_privileged chown --recursive $(id -u):$(id -g) "${oci_img_dir}"
}
convert_container() {
@@ -193,8 +193,8 @@ generate_wic_image() {
fi
EOIMAGER
- sudo chown -R $(stat -c "%U" ${LAYERDIR_core}) ${LAYERDIR_core} ${LAYERDIR_isar} ${SCRIPTSDIR} || true
- sudo chown -R $(id -u):$(id -g) "${DEPLOY_DIR_IMAGE}/${IMAGE_FULLNAME}.wic"*
+ run_privileged chown -R $(stat -c "%U" ${LAYERDIR_core}) ${LAYERDIR_core} ${LAYERDIR_isar} ${SCRIPTSDIR} || true
+ run_privileged chown -R $(id -u):$(id -g) "${DEPLOY_DIR_IMAGE}/${IMAGE_FULLNAME}.wic"*
rm -rf ${IMAGE_ROOTFS}/../pseudo
cat ${DEPLOY_DIR_IMAGE}/${IMAGE_FULLNAME}.manifest \
@@ -136,7 +136,7 @@ rootfs_cmd() {
rootfs_do_mounts[weight] = "3"
rootfs_do_mounts() {
- sudo -s <<'EOSUDO'
+ run_privileged_here <<'EOSUDO'
set -e
mountpoint -q '${ROOTFSDIR}/dev' || \
( mount -o bind,private /dev '${ROOTFSDIR}/dev' &&
@@ -182,7 +182,7 @@ EOSUDO
}
rootfs_do_umounts() {
- sudo -s <<'EOSUDO'
+ run_privileged_here <<'EOSUDO'
set -e
if mountpoint -q '${ROOTFSDIR}/isar-apt'; then
umount '${ROOTFSDIR}/isar-apt'
@@ -225,7 +225,7 @@ rootfs_do_qemu() {
if [ '${@repr(d.getVar('ROOTFS_ARCH') == d.getVar('HOST_ARCH'))}' = 'False' ]
then
test -e '${ROOTFSDIR}/usr/bin/qemu-${QEMU_ARCH}-static' || \
- sudo cp '/usr/bin/qemu-${QEMU_ARCH}-static' '${ROOTFSDIR}/usr/bin/qemu-${QEMU_ARCH}-static'
+ run_privileged cp '/usr/bin/qemu-${QEMU_ARCH}-static' '${ROOTFSDIR}/usr/bin/qemu-${QEMU_ARCH}-static'
fi
}
@@ -240,16 +240,16 @@ ROOTFS_EXTRA_IMPORTED := "${@rootfs_extra_import(d)}"
rootfs_prepare[weight] = "25"
rootfs_prepare(){
- sudo tar -xf "${BOOTSTRAP_SRC}" -C "${ROOTFSDIR}" --exclude="./dev/console"
+ run_privileged tar -xf "${BOOTSTRAP_SRC}" -C "${ROOTFSDIR}" --exclude="./dev/console"
# setup chroot
- sudo "${ROOTFSDIR}/chroot-setup.sh" "setup" "${ROOTFSDIR}"
+ run_privileged "${ROOTFSDIR}/chroot-setup.sh" "setup" "${ROOTFSDIR}"
}
ROOTFS_CONFIGURE_COMMAND += "rootfs_configure_isar_apt"
rootfs_configure_isar_apt[weight] = "2"
rootfs_configure_isar_apt() {
- sudo -s <<'EOSUDO'
+ run_privileged_here <<'EOSUDO'
set -e
mkdir -p '${ROOTFSDIR}/etc/apt/sources.list.d'
@@ -270,7 +270,7 @@ EOSUDO
ROOTFS_CONFIGURE_COMMAND += "rootfs_configure_apt"
rootfs_configure_apt[weight] = "2"
rootfs_configure_apt() {
- sudo -s <<'EOSUDO'
+ run_privileged_here <<'EOSUDO'
set -e
mkdir -p '${ROOTFSDIR}/etc/apt/apt.conf.d'
@@ -293,7 +293,7 @@ ROOTFS_CONFIGURE_COMMAND += "rootfs_disable_initrd_generation"
rootfs_disable_initrd_generation[weight] = "1"
rootfs_disable_initrd_generation() {
# fully disable initrd generation
- sudo -s <<'EOSUDO'
+ run_privileged_here <<'EOSUDO'
set -e
mkdir -p "${ROOTFSDIR}${ROOTFS_STUBS_DIR}"
@@ -310,7 +310,7 @@ rootfs_install_pkgs_update[weight] = "5"
rootfs_install_pkgs_update[isar-apt-lock] = "acquire-before"
rootfs_install_pkgs_update[network] = "${TASK_USE_NETWORK_AND_SUDO}"
rootfs_install_pkgs_update() {
- sudo -E chroot '${ROOTFSDIR}' /usr/bin/apt-get update \
+ run_in_chroot '${ROOTFSDIR}' /usr/bin/apt-get update \
-o Dir::Etc::SourceList="sources.list.d/isar-apt.list" \
-o Dir::Etc::SourceParts="-" \
-o APT::Get::List-Cleanup="0"
@@ -322,9 +322,9 @@ rootfs_install_resolvconf() {
if [ "${@repr(bb.utils.to_boolean(d.getVar('BB_NO_NETWORK')))}" != "True" ]
then
if [ -L "${ROOTFSDIR}/etc/resolv.conf" ]; then
- sudo unlink "${ROOTFSDIR}/etc/resolv.conf"
+ run_privileged unlink "${ROOTFSDIR}/etc/resolv.conf"
fi
- sudo cp -rL /etc/resolv.conf '${ROOTFSDIR}/etc'
+ run_privileged cp -rL /etc/resolv.conf '${ROOTFSDIR}/etc'
fi
}
@@ -358,7 +358,7 @@ rootfs_export_package_cache() {
ROOTFS_INSTALL_COMMAND += "${@ 'rootfs_install_clean_files' if (d.getVar('ROOTFS_CLEAN_FILES') or '').strip() else ''}"
rootfs_install_clean_files[weight] = "2"
rootfs_install_clean_files() {
- sudo -s <<'EOSUDO'
+ run_privileged_here <<'EOSUDO'
for clean_file in ${ROOTFS_CLEAN_FILES}; do
rm -f "${ROOTFSDIR}/$clean_file"
done
@@ -370,14 +370,14 @@ rootfs_install_pkgs_install[weight] = "8000"
rootfs_install_pkgs_install[progress] = "custom:rootfs_progress.PkgsInstallProgressHandler"
rootfs_install_pkgs_install[network] = "${TASK_USE_SUDO}"
rootfs_install_pkgs_install() {
- sudo -E chroot "${ROOTFSDIR}" \
+ run_in_chroot "${ROOTFSDIR}" \
/usr/bin/apt-get ${ROOTFS_APT_ARGS} ${ROOTFS_PACKAGES}
}
ROOTFS_INSTALL_COMMAND += "rootfs_restore_initrd_tooling"
rootfs_restore_initrd_tooling[weight] = "1"
rootfs_restore_initrd_tooling() {
- sudo -s <<'EOSUDO'
+ run_privileged_here <<'EOSUDO'
set -e
rm -f "${ROOTFSDIR}/etc/apt/apt.conf.d/50isar-stubs"
rm -rf "${ROOTFSDIR}${ROOTFS_STUBS_DIR}"
@@ -386,8 +386,8 @@ EOSUDO
ROOTFS_INSTALL_COMMAND += "${@bb.utils.contains('ROOTFS_FEATURES', 'generate-initrd', '', 'rootfs_clear_initrd_symlinks', d)}"
rootfs_clear_initrd_symlinks() {
- sudo rm -f ${ROOTFSDIR}/initrd.img
- sudo rm -f ${ROOTFSDIR}/initrd.img.old
+ run_privileged rm -f ${ROOTFSDIR}/initrd.img
+ run_privileged rm -f ${ROOTFSDIR}/initrd.img.old
}
do_rootfs_install[root_cleandirs] = "${ROOTFSDIR}"
@@ -437,21 +437,21 @@ do_cache_deb_src[network] = "${TASK_USE_SUDO}"
do_cache_deb_src() {
if [ -e "${ROOTFSDIR}"/etc/resolv.conf ] ||
[ -h "${ROOTFSDIR}"/etc/resolv.conf ]; then
- sudo mv "${ROOTFSDIR}"/etc/resolv.conf "${ROOTFSDIR}"/etc/resolv.conf.isar
+ run_privileged mv "${ROOTFSDIR}"/etc/resolv.conf "${ROOTFSDIR}"/etc/resolv.conf.isar
fi
rootfs_install_resolvconf
# Note: ISAR updates the apt state information(apt-get update) only once during bootstrap and
# relies on that through out the build. Copy that state information instead of apt-get update
# which generates a new state from upstream.
- sudo tar -xf "${BOOTSTRAP_SRC}" ./var/lib/apt/lists --one-top-level="${ROOTFSDIR}"
+ run_privileged tar -xf "${BOOTSTRAP_SRC}" ./var/lib/apt/lists --one-top-level="${ROOTFSDIR}"
deb_dl_dir_import ${ROOTFSDIR} ${ROOTFS_BASE_DISTRO}-${BASE_DISTRO_CODENAME}
debsrc_download ${ROOTFSDIR} ${ROOTFS_BASE_DISTRO}-${BASE_DISTRO_CODENAME}
- sudo rm -f "${ROOTFSDIR}"/etc/resolv.conf
+ run_privileged rm -f "${ROOTFSDIR}"/etc/resolv.conf
if [ -e "${ROOTFSDIR}"/etc/resolv.conf.isar ] ||
[ -h "${ROOTFSDIR}"/etc/resolv.conf.isar ]; then
- sudo mv "${ROOTFSDIR}"/etc/resolv.conf.isar "${ROOTFSDIR}"/etc/resolv.conf
+ run_privileged mv "${ROOTFSDIR}"/etc/resolv.conf.isar "${ROOTFSDIR}"/etc/resolv.conf
fi
}
@@ -459,21 +459,21 @@ ROOTFS_POSTPROCESS_COMMAND += "${@bb.utils.contains('BASE_REPO_FEATURES', 'cache
cache_dbg_pkgs() {
if [ -e "${ROOTFSDIR}"/etc/resolv.conf ] ||
[ -h "${ROOTFSDIR}"/etc/resolv.conf ]; then
- sudo mv "${ROOTFSDIR}"/etc/resolv.conf "${ROOTFSDIR}"/etc/resolv.conf.isar
+ run_privileged mv "${ROOTFSDIR}"/etc/resolv.conf "${ROOTFSDIR}"/etc/resolv.conf.isar
fi
rootfs_install_resolvconf
# Note: ISAR updates the apt state information(apt-get update) only once during bootstrap and
# relies on that through out the build. Copy that state information instead of apt-get update
# which generates a new state from upstream.
- sudo tar -xf "${BOOTSTRAP_SRC}" ./var/lib/apt/lists --one-top-level="${ROOTFSDIR}"
+ run_privileged tar -xf "${BOOTSTRAP_SRC}" ./var/lib/apt/lists --one-top-level="${ROOTFSDIR}"
deb_dl_dir_import ${ROOTFSDIR} ${ROOTFS_BASE_DISTRO}-${BASE_DISTRO_CODENAME}
dbg_pkgs_download ${ROOTFSDIR}
- sudo rm -f "${ROOTFSDIR}"/etc/resolv.conf
+ run_privileged rm -f "${ROOTFSDIR}"/etc/resolv.conf
if [ -e "${ROOTFSDIR}"/etc/resolv.conf.isar ] ||
[ -h "${ROOTFSDIR}"/etc/resolv.conf.isar ]; then
- sudo mv "${ROOTFSDIR}"/etc/resolv.conf.isar "${ROOTFSDIR}"/etc/resolv.conf
+ run_privileged mv "${ROOTFSDIR}"/etc/resolv.conf.isar "${ROOTFSDIR}"/etc/resolv.conf
fi
}
@@ -482,17 +482,17 @@ ROOTFS_POSTPROCESS_COMMAND += "${@bb.utils.contains('ROOTFS_FEATURES', 'generate
ROOTFS_POSTPROCESS_COMMAND += "${@bb.utils.contains('ROOTFS_FEATURES', 'clean-package-cache', 'rootfs_postprocess_clean_package_cache', '', d)}"
rootfs_postprocess_clean_package_cache() {
- sudo -E chroot '${ROOTFSDIR}' \
+ run_in_chroot '${ROOTFSDIR}' \
/usr/bin/apt-get clean
- sudo rm -rf "${ROOTFSDIR}/var/lib/apt/lists/"*
+ run_privileged rm -rf "${ROOTFSDIR}/var/lib/apt/lists/"*
# remove apt-cache folder itself (required in case rootfs is provided by sstate cache)
- sudo rm -rf "${ROOTFSDIR}/var/cache/apt/archives"
+ run_privileged rm -rf "${ROOTFSDIR}/var/cache/apt/archives"
}
ROOTFS_POSTPROCESS_COMMAND += "${@bb.utils.contains('ROOTFS_FEATURES', 'clean-log-files', 'rootfs_postprocess_clean_log_files', '', d)}"
rootfs_postprocess_clean_log_files() {
# Delete log files that are not owned by packages
- sudo -E chroot '${ROOTFSDIR}' \
+ run_in_chroot '${ROOTFSDIR}' \
/usr/bin/find /var/log/ -type f \
-exec sh -c '! dpkg -S {} > /dev/null 2>&1' ';' \
-exec rm -f {} ';'
@@ -501,32 +501,32 @@ rootfs_postprocess_clean_log_files() {
ROOTFS_POSTPROCESS_COMMAND += "${@bb.utils.contains('ROOTFS_FEATURES', 'clean-debconf-cache', 'rootfs_postprocess_clean_debconf_cache', '', d)}"
rootfs_postprocess_clean_debconf_cache() {
# Delete debconf cache files
- sudo rm -rf "${ROOTFSDIR}/var/cache/debconf/"*
+ run_privileged rm -rf "${ROOTFSDIR}/var/cache/debconf/"*
}
ROOTFS_POSTPROCESS_COMMAND += "${@bb.utils.contains('ROOTFS_FEATURES', 'clean-pycache', 'rootfs_postprocess_clean_pycache', '', d)}"
rootfs_postprocess_clean_pycache() {
- sudo find ${ROOTFSDIR}/usr -type f -name '*.pyc' -delete -print
- sudo find ${ROOTFSDIR}/usr -type d -name '__pycache__' -delete -print
+ run_privileged find ${ROOTFSDIR}/usr -type f -name '*.pyc' -delete -print
+ run_privileged find ${ROOTFSDIR}/usr -type d -name '__pycache__' -delete -print
}
ROOTFS_POSTPROCESS_COMMAND += "rootfs_postprocess_clean_ldconfig_cache"
rootfs_postprocess_clean_ldconfig_cache() {
# the ldconfig aux-cache is not portable and breaks reproducability
# https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=845034#49
- sudo rm -f ${ROOTFSDIR}/var/cache/ldconfig/aux-cache
+ run_privileged rm -f ${ROOTFSDIR}/var/cache/ldconfig/aux-cache
}
ROOTFS_POSTPROCESS_COMMAND += "rootfs_postprocess_clean_tmp"
rootfs_postprocess_clean_tmp() {
# /tmp is by definition non persistent across boots
- sudo rm -rf "${ROOTFSDIR}/tmp/"*
+ run_privileged rm -rf "${ROOTFSDIR}/tmp/"*
}
ROOTFS_POSTPROCESS_COMMAND += "${@bb.utils.contains('ROOTFS_FEATURES', 'generate-manifest', 'rootfs_generate_manifest', '', d)}"
rootfs_generate_manifest () {
mkdir -p ${ROOTFS_MANIFEST_DEPLOY_DIR}
- sudo -E chroot --userspec=$(id -u):$(id -g) '${ROOTFSDIR}' \
+ run_in_chroot '${ROOTFSDIR}' \
dpkg-query -W -f \
'${source:Package}|${source:Version}|${Package}:${Architecture}|${Version}\n' > \
'${ROOTFS_MANIFEST_DEPLOY_DIR}'/'${ROOTFS_PACKAGE_SUFFIX}'.manifest
@@ -542,7 +542,7 @@ rootfs_export_dpkg_status() {
ROOTFS_POSTPROCESS_COMMAND += "rootfs_cleanup_isar_apt"
rootfs_cleanup_isar_apt[weight] = "2"
rootfs_cleanup_isar_apt() {
- sudo -s <<'EOSUDO'
+ run_privileged_here <<'EOSUDO'
set -e
rm -f "${ROOTFSDIR}/etc/apt/sources.list.d/isar-apt.list"
rm -f "${ROOTFSDIR}/etc/apt/preferences.d/isar-apt"
@@ -553,7 +553,7 @@ EOSUDO
ROOTFS_POSTPROCESS_COMMAND += "${@'rootfs_cleanup_base_apt' if bb.utils.to_boolean(d.getVar('ISAR_USE_CACHED_BASE_REPO')) else ''}"
rootfs_cleanup_base_apt[weight] = "2"
rootfs_cleanup_base_apt() {
- sudo -s <<'EOSUDO'
+ run_privileged_here <<'EOSUDO'
set -e
rm -f "${ROOTFSDIR}/etc/apt/sources.list.d/"*base-apt.list
EOSUDO
@@ -561,12 +561,12 @@ EOSUDO
ROOTFS_POSTPROCESS_COMMAND += "${@bb.utils.contains('ROOTFS_FEATURES', 'populate-systemd-preset', 'image_postprocess_populate_systemd_preset', '', d)}"
image_postprocess_populate_systemd_preset() {
- SYSTEMD_INSTALLED=$(sudo chroot '${ROOTFSDIR}' dpkg-query \
+ SYSTEMD_INSTALLED=$(run_in_chroot '${ROOTFSDIR}' dpkg-query \
--showformat='${db:Status-Status}' \
--show systemd || echo "" )
if (test "$SYSTEMD_INSTALLED" = "installed"); then
- sudo chroot '${ROOTFSDIR}' systemctl preset-all --preset-mode="enable-only"
+ run_in_chroot '${ROOTFSDIR}' systemctl preset-all --preset-mode="enable-only"
fi
}
@@ -626,7 +626,7 @@ rootfs_generate_initramfs() {
mods_total="$(find ${ROOTFSDIR}/usr/lib/modules/$kernel_version -type f -name '*.ko*' | wc -l)"
echo "Total number of modules: $mods_total"
echo "Generating initrd for kernel version: $kernel_version"
- sudo -E chroot "${ROOTFSDIR}" sh -ec ' \
+ run_in_chroot "${ROOTFSDIR}" sh -ec ' \
${ROOTFS_INITRAMFS_GENERATOR_CMDLINE}; \
find /boot -name "initrd.img-$kernel_version*" -exec install --mode 0644 {} /isar-work/initrd.img \; \
'
@@ -663,11 +663,11 @@ rootfs_install_sstate_prepare() {
# tar --one-file-system will cross bind-mounts to the same filesystem,
# so we use some mount magic to prevent that
mkdir -p ${WORKDIR}/mnt/rootfs
- sudo mount -o bind,private '${WORKDIR}/rootfs' '${WORKDIR}/mnt/rootfs' -o ro
+ run_privileged mount -o bind,private '${WORKDIR}/rootfs' '${WORKDIR}/mnt/rootfs' -o ro
lopts="--one-file-system --exclude=var/cache/apt/archives"
- sudo tar -C ${WORKDIR}/mnt -cpSf rootfs.tar $lopts ${SSTATE_TAR_ATTR_FLAGS} rootfs
- sudo umount ${WORKDIR}/mnt/rootfs
- sudo chown $(id -u):$(id -g) rootfs.tar
+ run_privileged tar -C ${WORKDIR}/mnt -cpSf rootfs.tar $lopts ${SSTATE_TAR_ATTR_FLAGS} rootfs
+ run_privileged umount ${WORKDIR}/mnt/rootfs
+ run_privileged chown $(id -u):$(id -g) rootfs.tar
}
do_rootfs_install_sstate_prepare[lockfiles] = "${REPO_ISAR_DIR}/isar.lock"
@@ -676,7 +676,7 @@ rootfs_install_sstate_finalize() {
# - after building the rootfs, the tar won't be there, but we also don't need to unpack
# - after restoring from cache, there will be a tar which we unpack and then delete
if [ -f rootfs.tar ]; then
- sudo tar -C ${WORKDIR} -xpf rootfs.tar ${SSTATE_TAR_ATTR_FLAGS}
+ run_privileged tar -C ${WORKDIR} -xpf rootfs.tar ${SSTATE_TAR_ATTR_FLAGS}
rm rootfs.tar
fi
}
@@ -20,7 +20,7 @@ SCHROOT_LOCKFILE = "/tmp/schroot.lock"
schroot_create_configs() {
mkdir -p "${TMPDIR}/schroot-overlay"
echo "Creating ${SCHROOT_CONF_FILE}"
- sudo -s <<'EOSUDO'
+ run_privileged_here <<'EOSUDO'
set -e
cat << EOF > "${SCHROOT_CONF_FILE}"
@@ -59,7 +59,7 @@ EOSUDO
schroot_delete_configs() {
(flock -x 9
set -e
- sudo -s <<'EOSUDO'
+ run_privileged_here <<'EOSUDO'
set -e
if [ -d "${SBUILD_CONF_DIR}" ]; then
echo "Removing ${SBUILD_CONF_DIR}"
@@ -101,7 +101,7 @@ sbuild_export() {
}
insert_mounts() {
- sudo -s <<'EOSUDO'
+ run_privileged_here <<'EOSUDO'
set -e
for mp in ${SCHROOT_MOUNTS}; do
FSTAB_LINE="${mp%%:*} ${mp#*:} none rw,bind,private 0 0"
@@ -112,7 +112,7 @@ EOSUDO
}
remove_mounts() {
- sudo -s <<'EOSUDO'
+ run_privileged_here <<'EOSUDO'
set -e
for mp in ${SCHROOT_MOUNTS}; do
FSTAB_LINE="${mp%%:*} ${mp#*:} none rw,bind,private 0 0"
@@ -123,7 +123,7 @@ EOSUDO
schroot_configure_ccache() {
mkdir -p "${CCACHE_DIR}"
- sudo -s <<'EOSUDO'
+ run_privileged_here <<'EOSUDO'
set -e
sbuild_fstab="${SBUILD_CONF_DIR}/fstab"
@@ -69,12 +69,12 @@ ROOTFS_POSTPROCESS_COMMAND:remove = "${@'rootfs_cleanup_isar_apt' if bb.utils.to
ROOTFS_CONFIGURE_COMMAND:append:class-sdk = " ${@'rootfs_configure_isar_apt_dir' if bb.utils.to_boolean(d.getVar('SDK_INCLUDE_ISAR_APT')) else ''}"
rootfs_configure_isar_apt_dir() {
# Copy isar-apt instead of mounting:
- sudo cp -Trpfx --reflink=auto ${REPO_ISAR_DIR}/${DISTRO} ${ROOTFSDIR}/isar-apt
+ run_privileged cp -Trpfx --reflink=auto ${REPO_ISAR_DIR}/${DISTRO} ${ROOTFSDIR}/isar-apt
}
ROOTFS_POSTPROCESS_COMMAND:prepend:class-sdk = "sdkchroot_configscript "
sdkchroot_configscript () {
- sudo chroot ${ROOTFSDIR} /configscript.sh ${DISTRO_ARCH}
+ run_in_chroot ${ROOTFSDIR} /configscript.sh ${DISTRO_ARCH}
}
ROOTFS_POSTPROCESS_COMMAND:append:class-sdk = " sdkchroot_finalize"
@@ -83,7 +83,7 @@ sdkchroot_finalize() {
rootfs_do_umounts
# Remove setup scripts
- sudo rm -f ${ROOTFSDIR}/chroot-setup.sh ${ROOTFSDIR}/configscript.sh
+ run_privileged rm -f ${ROOTFSDIR}/chroot-setup.sh ${ROOTFSDIR}/configscript.sh
# Make all links relative
for link in $(find ${ROOTFSDIR}/ -type l); do
@@ -95,16 +95,16 @@ sdkchroot_finalize() {
new_target=$(realpath --no-symlinks -m --relative-to=$basedir ${ROOTFSDIR}${target})
# remove first to allow rewriting directory links
- sudo rm $link
- sudo ln -s $new_target $link
+ run_privileged rm $link
+ run_privileged ln -s $new_target $link
fi
done
# Set up sysroot wrapper
for tool_pattern in "gcc-[0-9]*" "g++-[0-9]*" "cpp-[0-9]*" "ld.bfd" "ld.gold"; do
for tool in $(find ${ROOTFSDIR}/usr/bin -type f -name "*-linux-gnu*-${tool_pattern}"); do
- sudo mv "${tool}" "${tool}.bin"
- sudo ln -sf gcc-sysroot-wrapper.sh ${tool}
+ run_privileged mv "${tool}" "${tool}.bin"
+ run_privileged ln -sf gcc-sysroot-wrapper.sh ${tool}
done
done
}
@@ -41,7 +41,7 @@ def sbom_doc_uuid(d):
d.setVar("SBOM_DOCUMENT_UUID", generate_document_uuid(d))
generate_sbom() {
- sudo mkdir -p ${SBOM_CHROOT}/mnt/rootfs ${SBOM_CHROOT}/mnt/deploy-dir
+ run_privileged mkdir -p ${SBOM_CHROOT}/mnt/rootfs ${SBOM_CHROOT}/mnt/deploy-dir
TIMESTAMP=$(date --iso-8601=s -d @${SOURCE_DATE_EPOCH})
bwrap \
@@ -204,19 +204,19 @@ do_bootstrap() {
trap '[ -r "${WORKDIR}/mmtmpdir" ] && tmpdir=$(cat "${WORKDIR}/mmtmpdir") \
&& rm "${WORKDIR}/mmtmpdir"; \
[ -d "$tmpdir" ] && mountpoint -q $tmpdir/$base_apt_tmp \
- && sudo umount $tmpdir/$base_apt_tmp; \
+ && run_privileged umount $tmpdir/$base_apt_tmp; \
[ -d "$tmpdir" ] && mountpoint -q $tmpdir/base-apt \
- && sudo umount $tmpdir/base-apt; \
- [ -d "$tmpdir" ] && sudo rm -rf --one-file-system $tmpdir; \
+ && run_privileged umount $tmpdir/base-apt; \
+ [ -d "$tmpdir" ] && run_privileged rm -rf --one-file-system $tmpdir; \
[ -n "$base_apt_tmp" ] && mountpoint -q $base_apt_tmp \
- && sudo umount $base_apt_tmp \
+ && run_privileged umount $base_apt_tmp \
&& rm -rf --one-file-system $base_apt_tmp' EXIT
# Create lock file so that it is owned by the user running the build (not root)
mkdir -p ${DEBDIR}
touch ${DEB_DL_LOCK}
- sudo TMPDIR="${BOOTSTRAP_TMPDIR}" mmdebstrap $bootstrap_args \
+ run_privileged TMPDIR="${BOOTSTRAP_TMPDIR}" mmdebstrap $bootstrap_args \
$arch_param \
--mode=unshare \
${MMHOOKS} \
@@ -248,7 +248,7 @@ do_bootstrap() {
if [ "${ISAR_USE_CACHED_BASE_REPO}" != "1" ]; then
deb_dl_dir_export "${WORKDIR}/dl_dir" "${BOOTSTRAP_BASE_DISTRO}-${BASE_DISTRO_CODENAME}"
- sudo rm -rf --one-file-system "${WORKDIR}/dl_dir"
+ run_privileged rm -rf --one-file-system "${WORKDIR}/dl_dir"
fi
}
addtask bootstrap before do_build after do_generate_keyrings
@@ -54,9 +54,8 @@ class TestImageAccountExtensionImageCreateUsers(
image_create_users(d)
run_mock.assert_called_once_with(
+ run_privileged_cmd(d).split() +
[
- 'sudo',
- '-E',
'chroot',
rootfs.path(),
'/usr/sbin/useradd',
@@ -136,9 +135,8 @@ class TestImageAccountExtensionImageCreateGroups(
image_create_groups(d)
run_mock.assert_called_once_with(
+ run_privileged_cmd(d).split() +
[
- 'sudo',
- '-E',
'chroot',
rootfs.path(),
'/usr/sbin/groupadd',
@@ -164,9 +162,8 @@ class TestImageAccountExtensionImageCreateGroups(
image_create_groups(d)
run_mock.assert_called_once_with(
+ run_privileged_cmd(d).split() +
[
- 'sudo',
- '-E',
'chroot',
rootfs.path(),
'/usr/sbin/groupmod',
As a preparation to enable rootless builds, we introduce wrappers for common cases of privileged command execution. The wrappers are defined in the base class where later on the executor dispatching will be implemented as well. The wrappers are introduced throughout the whole codebase and downstream layers are also encouraged to use them to increase compatibility with upcoming API changes. Signed-off-by: Felix Moessbauer <felix.moessbauer@siemens.com> --- RECIPE-API-CHANGELOG.md | 16 ++++ meta/classes-global/base.bbclass | 30 +++++++ meta/classes-recipe/deb-dl-dir.bbclass | 4 +- meta/classes-recipe/dpkg-base.bbclass | 2 +- meta/classes-recipe/dpkg.bbclass | 2 +- .../image-account-extension.bbclass | 4 +- .../image-locales-extension.bbclass | 4 +- .../image-postproc-extension.bbclass | 30 +++---- meta/classes-recipe/image.bbclass | 14 +-- .../imagetypes_container.bbclass | 26 +++--- meta/classes-recipe/imagetypes_wic.bbclass | 4 +- meta/classes-recipe/rootfs.bbclass | 88 +++++++++---------- meta/classes-recipe/sbuild.bbclass | 10 +-- meta/classes-recipe/sdk.bbclass | 14 +-- meta/classes/sbom.bbclass | 2 +- .../isar-mmdebstrap/isar-mmdebstrap.inc | 12 +-- .../unittests/test_image_account_extension.py | 9 +- 17 files changed, 157 insertions(+), 114 deletions(-)