Package: debootstrap Version: 1.0.75 Severity: wishlist Tags: patch Hi,
please consider the following two patches that allow smaller systems to be installed by debootstrap. The first patch, "add exclude-stage1-path option" adds an option to debootstrap which can exclude certain paths (a comma-delimited list that is converted to --exclude options for the tar calls) in stage1. This can, for example, be used to exclude /usr/share from the stage 1 unpack process. This is currently only supported by scripts/sid, which is used for all current Debian releases. The second patch, "add --copy-stage1-path functionality and docs" allows a path from the host system or a prepared tarball (uncompressed or compressed by gzip and xz) to be copied/unpacked in the target directory before stage 2 debootstrap is invoked. This allows, for example, appropriate /etc/dpkg/dpkg.conf.d/exclude-foo files to be placed there so that stage 2 dpkg can already honor them. Currently, until #811267 is fixed in dpkg, the same mechanism can be used to poke empty directories into the chroot that dpkg needs to successfully unpack package contents into excluded paths. Both patches together allow to bring a --variant=minbase sid install down from 199 MB to 147 MB, which is a rather impressive result. Please consider applying them in debootstrap. Thank you very much. Greetings Marc
>From 644753cd1a0556291dcbfd21cd881ec075de23c9 Mon Sep 17 00:00:00 2001 From: Marc Haber <mh+debian-packa...@zugschlus.de> Date: Sat, 9 Jan 2016 17:01:11 +0100 Subject: [PATCH 1/2] add exclude-stage1-path option --- debootstrap | 15 +++++++++++++++ debootstrap.8 | 4 ++++ functions | 2 +- scripts/sid | 4 ++++ 4 files changed, 24 insertions(+), 1 deletion(-) diff --git a/debootstrap b/debootstrap index 2a959bb..fe4de7b 100755 --- a/debootstrap +++ b/debootstrap @@ -46,6 +46,7 @@ VERBOSE="" CERTIFICATE="" CHECKCERTIF="" PRIVATEKEY="" +EXCLUDE_STAGE1_PATH="" DEF_MIRROR="http://httpredir.debian.org/debian" DEF_HTTPS_MIRROR="https://mirrors.kernel.org/debian" @@ -121,6 +122,9 @@ usage() --private-key=file read the private key from file --certificate=file use the client certificate stored in file (PEM) --no-check-certificate do not check certificate against certificate authorities + + --exclude-stage1-path=PATH,PATH do not install anything to PATH and PATH in + stage 1 EOF } @@ -352,6 +356,17 @@ if [ $# != 0 ] ; then CHECKCERTIF="--no-check-certificate" shift ;; + --exclude-stage1-path|--exclude-stage1-path=?*) + if [ "$1" = "--exclude-stage1-path" -a -n "$2" ]; then + EXCLUDE_STAGE1_PATH="$2" + shift 2 + elif [ "$1" != "${1#--exclude-stage1-path=}" ]; then + EXCLUDE_STAGE1_PATH="${1#--exclude-stage1-path=}" + shift 1 + else + error 1 NEEDARG "option requires an argument %s" "$1" + fi + ;; --*) error 1 BADARG "unrecognized or invalid option %s" "$1" ;; diff --git a/debootstrap.8 b/debootstrap.8 index 5864148..c8f0722 100644 --- a/debootstrap.8 +++ b/debootstrap.8 @@ -156,6 +156,10 @@ Use the client certificate stored in file (PEM) .IP .IP "\fB\-\-private\-key=FILE\fP" Read the private key from file +.IP +.IP "\fB\-\-exclude\-stage1\-path=PATH,PATH\fP" +Exclude the paths listed in the comma separated from being unpacked +during stage 1. .SH EXAMPLES . diff --git a/functions b/functions index 8bef5e6..76c1eae 100644 --- a/functions +++ b/functions @@ -807,7 +807,7 @@ extract_dpkg_deb_field () { extract_dpkg_deb_data () { local pkg="$1" - dpkg-deb --fsys-tarfile "$pkg" | tar -xf - + dpkg-deb --fsys-tarfile "$pkg" | tar --extract $TAR_OPTS --file - } # Raw .deb extractors diff --git a/scripts/sid b/scripts/sid index bf3404f..fd0666a 100644 --- a/scripts/sid +++ b/scripts/sid @@ -4,6 +4,10 @@ finddebs_style from-indices variants - buildd fakechroot minbase scratchbox keyring /usr/share/keyrings/debian-archive-keyring.gpg +if [ -n "$EXCLUDE_STAGE1_PATH" ]; then + TAR_OPTS="$TAR_OPTS --exclude=.$(echo $EXCLUDE_STAGE1_PATH | sed 's|,| --exclude=.|g')" +fi + if doing_variant fakechroot; then test "$FAKECHROOT" = "true" || error 1 FAKECHROOTREQ "This variant requires fakechroot environment to be started" fi -- 2.7.0.rc3
>From 9054d421d5f483a616adc9bf3d39f23750da528f Mon Sep 17 00:00:00 2001 From: Marc Haber <mh+debian-packa...@zugschlus.de> Date: Sat, 16 Jan 2016 22:40:40 +0100 Subject: [PATCH 2/2] add --copy-stage1-path functionality and docs --- debootstrap | 32 ++++++++++++++++++++++++++++++-- debootstrap.8 | 7 +++++++ 2 files changed, 37 insertions(+), 2 deletions(-) diff --git a/debootstrap b/debootstrap index fe4de7b..d5ebfbb 100755 --- a/debootstrap +++ b/debootstrap @@ -47,6 +47,7 @@ CERTIFICATE="" CHECKCERTIF="" PRIVATEKEY="" EXCLUDE_STAGE1_PATH="" +COPY_STAGE1_PATH="" DEF_MIRROR="http://httpredir.debian.org/debian" DEF_HTTPS_MIRROR="https://mirrors.kernel.org/debian" @@ -125,6 +126,7 @@ usage() --exclude-stage1-path=PATH,PATH do not install anything to PATH and PATH in stage 1 + --copy-stage1-path=PATH tarball or tree to copy into chroot after stage 1 EOF } @@ -361,7 +363,18 @@ if [ $# != 0 ] ; then EXCLUDE_STAGE1_PATH="$2" shift 2 elif [ "$1" != "${1#--exclude-stage1-path=}" ]; then - EXCLUDE_STAGE1_PATH="${1#--exclude-stage1-path=}" + EXCLUDE_STAGE1_PATH="${1#--exclude-stage1-path=}" + shift 1 + else + error 1 NEEDARG "option requires an argument %s" "$1" + fi + ;; + --copy-stage1-path|--copy-stage1-path=?*) + if [ "$1" = "--copy-stage1-path" -a -n "$2" ]; then + COPY_STAGE1_PATH="$2" + shift 2 + elif [ "$1" != "${1#--copy-stage1-path=}" ]; then + COPY_STAGE1_PATH="${1#--copy-stage1-path=}" shift 1 else error 1 NEEDARG "option requires an argument %s" "$1" @@ -658,7 +671,6 @@ if am_doing_phase first_stage; then echo "$VARIANT" >"$TARGET/debootstrap/variant" echo "$required" >"$TARGET/debootstrap/required" echo "$base" >"$TARGET/debootstrap/base" - chmod 755 "$TARGET/debootstrap/debootstrap" fi fi @@ -670,6 +682,22 @@ if am_doing_phase second_stage; then all_debs="$required $base" fi + if [ -n "$COPY_STAGE1_PATH" ]; then + if [ -d "$COPY_STAGE1_PATH" ]; then + info COPYPATH "Copying files from %s..." "${COPY_STAGE1_PATH}" + tar -cf - -C "${COPY_STAGE1_PATH}" . | tar -xf - -C "$TARGET" + elif [ -e "$COPY_STAGE1_PATH" ]; then + info UNTARPATH "Untarring files from %s..." "${COPY_STAGE1_PATH}" + case "$COPY_STAGE1_PATH" in + *.tar.gz) cat_cmd=zcat ;; + *.tar.xz) cat_cmd=xzcat ;; + *.tar) cat_cmd=cat ;; + *) error 1 UNKNOWNCONTROLCOMP "Unknown compression type for %s" "$COPY_STAGE1_PATH" + esac + $cat_cmd "$COPY_STAGE1_PATH" | tar -xf - -C "$TARGET" + fi + fi + # second stage uses the chroot to clean itself up -- has to be able to # work from entirely within the chroot (in case we've booted into it, # possibly over NFS eg) diff --git a/debootstrap.8 b/debootstrap.8 index c8f0722..b1e6270 100644 --- a/debootstrap.8 +++ b/debootstrap.8 @@ -160,6 +160,13 @@ Read the private key from file .IP "\fB\-\-exclude\-stage1\-path=PATH,PATH\fP" Exclude the paths listed in the comma separated from being unpacked during stage 1. +.IP +.IP "\fB\-\-copy\-stage1\-path=PATH,PATH\fP" +If PARM points to a directory, copy the tree below this directory to +the chroot after stage 1. If PARM points to a tar.{gz,bz2,xz}, unpack +this tar in the chroot after stage 1. This can, for example be used to +plant pre-configuration in the chroot that is already used by package +configuration in stage 2. .SH EXAMPLES . -- 2.7.0.rc3