diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-13 14:14:39 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-13 14:14:39 +0000 |
commit | ee17e45964b786b48b455959dfe68715971893fb (patch) | |
tree | 118f40aa65dc838499053413b05adfd00f839c62 /hooks/merged-usr | |
parent | Initial commit. (diff) | |
download | mmdebstrap-ee17e45964b786b48b455959dfe68715971893fb.tar.xz mmdebstrap-ee17e45964b786b48b455959dfe68715971893fb.zip |
Adding upstream version 1.4.3.upstream/1.4.3
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'hooks/merged-usr')
-rwxr-xr-x | hooks/merged-usr/essential00.sh | 28 | ||||
-rwxr-xr-x | hooks/merged-usr/extract00.sh | 85 | ||||
-rwxr-xr-x | hooks/merged-usr/setup00.sh | 79 |
3 files changed, 192 insertions, 0 deletions
diff --git a/hooks/merged-usr/essential00.sh b/hooks/merged-usr/essential00.sh new file mode 100755 index 0000000..d9a8130 --- /dev/null +++ b/hooks/merged-usr/essential00.sh @@ -0,0 +1,28 @@ +#!/bin/sh + +set -eu + +if [ "${MMDEBSTRAP_VERBOSITY:-1}" -ge 3 ]; then + set -x +fi + +TARGET="$1" + +if [ "${MMDEBSTRAP_MODE:-}" = "chrootless" ]; then + APT_CONFIG=$MMDEBSTRAP_APT_CONFIG apt-get --yes install \ + -oDPkg::Chroot-Directory= \ + -oDPkg::Options::=--force-not-root \ + -oDPkg::Options::=--force-script-chrootless \ + -oDPkg::Options::=--root="$TARGET" \ + -oDPkg::Options::=--log="$TARGET/var/log/dpkg.log" \ + usr-is-merged + export DPKG_ROOT="$TARGET" + dpkg-query --showformat '${db:Status-Status}\n' --show usr-is-merged | grep -q '^installed$' + dpkg-query --showformat '${Source}\n' --show usr-is-merged | grep -q '^usrmerge$' + dpkg --compare-versions "1" "lt" "$(dpkg-query --showformat '${Version}\n' --show usr-is-merged)" +else + APT_CONFIG=$MMDEBSTRAP_APT_CONFIG apt-get --yes install usr-is-merged + chroot "$TARGET" dpkg-query --showformat '${db:Status-Status}\n' --show usr-is-merged | grep -q '^installed$' + chroot "$TARGET" dpkg-query --showformat '${Source}\n' --show usr-is-merged | grep -q '^usrmerge$' + dpkg --compare-versions "1" "lt" "$(chroot "$TARGET" dpkg-query --showformat '${Version}\n' --show usr-is-merged)" +fi diff --git a/hooks/merged-usr/extract00.sh b/hooks/merged-usr/extract00.sh new file mode 100755 index 0000000..7334191 --- /dev/null +++ b/hooks/merged-usr/extract00.sh @@ -0,0 +1,85 @@ +#!/bin/sh + +set -eu + +if [ "${MMDEBSTRAP_VERBOSITY:-1}" -ge 3 ]; then + set -x +fi + +TARGET="$1" + +# can_usrmerge_symlink() and can_usrmerge_symlink() are +# Copyright 2023 Helmut Grohne <helmut@subdivi.de> +# and part of the debootstrap source in /usr/share/debootstrap/functions +# https://salsa.debian.org/installer-team/debootstrap/-/merge_requests/96 +# https://bugs.debian.org/104989 +can_usrmerge_symlink() { + # Absolute symlinks can be relocated without problems. + test "${2#/}" = "$2" || return 0 + while :; do + if test "${2#/}" != "$2"; then + # Handle double-slashes. + set -- "$1" "${2#/}" + elif test "${2#./}" != "$2"; then + # Handle ./ inside a link target. + set -- "$1" "${2#./}" + elif test "$2" = ..; then + # A parent directory symlink is ok if it does not + # cross the top level directory. + test "${1%/*/*}" != "$1" -a -n "${1%/*/*}" + return $? + elif test "${2#../}" != "$2"; then + # Symbolic link crossing / cannot be moved safely. + # This is prohibited by Debian Policy 10.5. + test "${1%/*/*}" = "$1" -o -z "${1%/*/*}" && return 1 + set -- "${1%/*}" "${2#../}" + else + # Consider the symlink ok if its target does not + # contain a parent directory. When we fail here, + # the link target is non-minimal and doesn't happen + # in the archive. + test "${2#*/../}" = "$2" + return $? + fi + done +} + +merge_usr_entry() { + # shellcheck disable=SC3043 + local entry canon + canon="$TARGET/usr/${1#"$TARGET/"}" + test -h "$canon" && + error 1 USRMERGEFAIL "cannot move %s as its destination exists as a symlink" "${1#"$TARGET"}" + if ! test -e "$canon"; then + mv "$1" "$canon" + return 0 + fi + test -d "$1" || + error 1 USRMERGEFAIL "cannot move non-directory %s as its destination exists" "${1#"$TARGET"}" + test -d "$canon" || + error 1 USRMERGEFAIL "cannot move directory %s as its destination is not a directory" "${1#"$TARGET"}" + for entry in "$1/"* "$1/."*; do + # Some shells return . and .. on dot globs. + test "${entry%/.}" != "${entry%/..}" && continue + if test -h "$entry" && ! can_usrmerge_symlink "${entry#"$TARGET"}" "$(readlink "$entry")"; then + error 1 USRMERGEFAIL "cannot move relative symlink crossing top-level directory" "${entry#"$TARGET"}" + fi + # Ignore glob match failures + if test "${entry%'/*'}" != "${entry%'/.*'}" && ! test -e "$entry"; then + continue + fi + merge_usr_entry "$entry" + done + rmdir "$1" +} + +# This is list includes all possible multilib directories. It must be +# updated when new multilib directories are being added. Hopefully, +# all new architectures use multiarch instead, so we never get to +# update this. +for dir in bin lib lib32 lib64 libo32 libx32 sbin; do + test -h "$TARGET/$dir" && continue + test -e "$TARGET/$dir" || continue + merge_usr_entry "$TARGET/$dir" + ln -s "usr/$dir" "$TARGET/$dir" +done diff --git a/hooks/merged-usr/setup00.sh b/hooks/merged-usr/setup00.sh new file mode 100755 index 0000000..a6b08d2 --- /dev/null +++ b/hooks/merged-usr/setup00.sh @@ -0,0 +1,79 @@ +#!/bin/sh +# +# mmdebstrap does have a --merged-usr option but only as a no-op for +# debootstrap compatibility +# +# Using this hook script, you can emulate what debootstrap does to set up +# merged /usr via directory symlinks, even using the exact same shell function +# that debootstrap uses by running mmdebstrap with: +# +# --setup-hook=/usr/share/mmdebstrap/hooks/merged-usr/setup00.sh +# +# Alternatively, you can setup merged-/usr by installing the usrmerge package: +# +# --include=usrmerge +# +# mmdebstrap will not include this functionality via a --merged-usr option +# because there are many reasons against implementing merged-/usr that way: +# +# https://wiki.debian.org/Teams/Dpkg/MergedUsr +# https://wiki.debian.org/Teams/Dpkg/FAQ#Q:_Does_dpkg_support_merged-.2Fusr-via-aliased-dirs.3F +# https://lists.debian.org/20190219044924.GB21901@gaara.hadrons.org +# https://lists.debian.org/YAkLOMIocggdprSQ@thunder.hadrons.org +# https://lists.debian.org/20181223030614.GA8788@gaara.hadrons.org +# +# In addition, the merged-/usr-via-aliased-dirs approach violates an important +# principle of component based software engineering one of the core design +# ideas/goals of mmdebstrap: All the information to create a chroot of a Debian +# based distribution should be included in its packages and their metadata. +# Using directory symlinks as used by debootstrap contradicts this principle. +# The information whether a distribution uses this approach to merged-/usr or +# not is not anymore contained in its packages but in a tool from the outside. +# +# Example real world problem: I'm using debbisect to bisect Debian unstable +# between 2015 and today. For which snapshot.d.o timestamp should a merged-/usr +# chroot be created and for which ones not? +# +# The problem is not the idea of merged-/usr but the problem is the way how it +# got implemented in debootstrap via directory symlinks. That way of rolling +# out merged-/usr is bad from the dpkg point-of-view and completely opposite of +# the vision with which in mind I wrote mmdebstrap. + +set -eu + +if [ "${MMDEBSTRAP_VERBOSITY:-1}" -ge 3 ]; then + set -x +fi + +TARGET="$1" + +# now install an empty "usr-is-merged" package to avoid installing the +# usrmerge package on this system even after init-system-helpers starts +# depending on "usrmerge | usr-is-merged". +# +# This package will not end up in the final chroot because the essential +# hook replaces it with the actual usr-is-merged package from src:usrmerge. + +tmpdir=$(mktemp --directory --tmpdir="$TARGET/tmp") +mkdir -p "$tmpdir/usr-is-merged/DEBIAN" + +cat << END > "$tmpdir/usr-is-merged/DEBIAN/control" +Package: usr-is-merged +Priority: optional +Section: oldlibs +Maintainer: Johannes Schauer Marin Rodrigues <josch@debian.org> +Architecture: all +Multi-Arch: foreign +Source: mmdebstrap-dummy-usr-is-merged +Version: 1 +Description: dummy package created by mmdebstrap merged-usr setup hook + This package was generated and installed by the mmdebstrap merged-usr + setup hook at /usr/share/mmdebstrap/hooks/merged-usr. + . + If this package is installed in the final chroot, then this is a bug + in mmdebstrap. Please report: https://gitlab.mister-muffin.de/josch/mmdebstrap +END +dpkg-deb --build "$tmpdir/usr-is-merged" "$tmpdir/usr-is-merged.deb" +dpkg --root="$TARGET" --log="$TARGET/var/log/dpkg.log" --install "$tmpdir/usr-is-merged.deb" +rm "$tmpdir/usr-is-merged.deb" "$tmpdir/usr-is-merged/DEBIAN/control" +rmdir "$tmpdir/usr-is-merged/DEBIAN" "$tmpdir/usr-is-merged" "$tmpdir" |