Package: base-files Version: 9.6 Severity: wishlist Tags: patch User: helm...@debian.org Usertags: rebootstrap
Hi Santiago, In version 1.18.5, dpkg gained a new way for installing binary packages. It now supports executing maintainer scripts outside the system it is operating on. The feature is tracked at https://wiki.debian.org/Teams/Dpkg/Spec/InstallBootstrap. This is relevant in two ways: * When running debootstrap, ordering postinsts is tricky due to the number of dependency loops. By executing them outside the chroot, some loops can be broken as utilities of the outer system can be used. * When creating chroots for foreign architectures, the utilities inside such chroots usually cannot be executed at all. To support this, dpkg now unconditionally exports an environment variable called DPKG_ROOT. It will point to the installation root with the trailing slash stripped. That means under normal conditions, it is empty. Since scripts are normally run under chroot(2) even when passing --root to dpkg, it is empty in that case as well. Only when explicitly activating the new mode, the chroot call is skipped and DPKG_ROOT can be non-empty. It is yet unclear under what conditions this mode should be enabled, so for the time being the only way to do so is to use --force-script-chrootless and I stress that this is only meant for testing. Discussion on what maintainer scripts may assume in this mode is still ongoing, but base-files' postinst only needs a tiny fraction so it should be safe. I prepared a patch that converts all filesystem accesses to prepend DPKG_ROOT. After applying it, base-files can be installed fully unprivileged using fakeroot[1] and in foreign chroots without access to qemu. Is it acceptable for base-files? Helmut [1] fakeroot dpkg --root "$target" --log "$target/var/log/dpkg.log" --force-script-chrootless -i base-files_*.deb
diff --minimal -Nru base-files-9.6/debian/changelog base-files-9.6+nmu1/debian/changelog --- base-files-9.6/debian/changelog 2016-03-04 17:33:57.000000000 +0100 +++ base-files-9.6+nmu1/debian/changelog 2016-05-17 21:45:06.000000000 +0200 @@ -1,3 +1,10 @@ +base-files (9.6+nmu1) UNRELEASED; urgency=medium + + * Non-maintainer upload. + * Support DPKG_ROOT in postinst. Closes: #-1. + + -- Helmut Grohne <hel...@subdivi.de> Tue, 17 May 2016 21:44:49 +0200 + base-files (9.6) unstable; urgency=low * Add lintian override for /etc/os-release. diff --minimal -Nru base-files-9.6/debian/postinst.in base-files-9.6+nmu1/debian/postinst.in --- base-files-9.6/debian/postinst.in 2015-08-18 12:03:09.000000000 +0200 +++ base-files-9.6+nmu1/debian/postinst.in 2016-05-17 22:12:34.000000000 +0200 @@ -1,52 +1,75 @@ #!/bin/sh set -e +: "${DPKG_ROOT:=}" + +change_owner() { + local owner group + owner=${1%:*} + group=${1#*:} + owner=$(sed -n "s/^$owner:[^:]*:\\([0-9]*\\):.*/\\1/p" "$DPKG_ROOT/etc/passwd") + group=$(sed -n "s/^$group:[^:]*:\\([0-9]*\\):.*/\\1/p" "$DPKG_ROOT/etc/group") + chown "$owner:$group" "$DPKG_ROOT$2" +} + +change_mode() { + chmod "$1" "$DPKG_ROOT$2" +} + +ensure_file_owner_mode() { + if [ ! -f "$DPKG_ROOT$1" ]; then + : > "$DPKG_ROOT$1" + fi + change_owner "$2" "$1" + change_mode "$3" "$1" +} + install_local_dir() { - if [ ! -d $1 ]; then - mkdir -p $1 + if [ ! -d "$DPKG_ROOT$1" ]; then + mkdir -p "$DPKG_ROOT$1" fi - if [ -f /etc/staff-group-for-usr-local ]; then - chown root:staff $1 2> /dev/null || true - chmod 2775 $1 2> /dev/null || true + if [ -f "$DPKG_ROOT/etc/staff-group-for-usr-local" ]; then + change_owner root:staff "$1" 2>/dev/null || true + change_mode 2775 "$1" 2> /dev/null || true fi } install_from_default() { - if [ ! -f $2 ]; then - cp -p /usr/share/base-files/$1 $2 + if [ ! -f "$DPKG_ROOT$2" ]; then + cp -p "$DPKG_ROOT/usr/share/base-files/$1" "$DPKG_ROOT$2" fi } install_directory() { - if [ ! -d /$1 ]; then - mkdir /$1 - chown root:$3 /$1 - chmod $2 /$1 + if [ ! -d "$DPKG_ROOT/$1" ]; then + mkdir "$DPKG_ROOT/$1" + change_owner "root:$3" "/$1" + change_mode "$2" "/$1" fi } migrate_directory() { - if [ ! -L $1 ]; then - rmdir $1 - ln -s $2 $1 + if [ ! -L "$DPKG_ROOT$1" ]; then + rmdir "$DPKG_ROOT$1" + ln -s "$2" "$DPKG_ROOT$1" fi } update_to_current_default() { - if [ -f $2 ]; then - md5=`md5sum $2 | cut -f 1 -d " "` - if grep -q "$md5" /usr/share/base-files/$1.md5sums; then - if ! cmp -s /usr/share/base-files/$1 $2; then - cp -p /usr/share/base-files/$1 $2 + if [ -f "$DPKG_ROOT$2" ]; then + md5=`md5sum "$DPKG_ROOT$2" | cut -f 1 -d " "` + if grep -q "$md5" "$DPKG_ROOT/usr/share/base-files/$1.md5sums"; then + if ! cmp -s "$DPKG_ROOT/usr/share/base-files/$1" "$DPKG_ROOT$2"; then + cp -p "$DPKG_ROOT/usr/share/base-files/$1" "$DPKG_ROOT$2" echo Updating $2 to current default. fi fi fi } -if [ ! -e /etc/dpkg/origins/default ]; then - if [ -e /etc/dpkg/origins/#VENDORFILE# ]; then - ln -sf #VENDORFILE# /etc/dpkg/origins/default +if [ ! -e "$DPKG_ROOT/etc/dpkg/origins/default" ]; then + if [ -e "$DPKG_ROOT/etc/dpkg/origins/#VENDORFILE#" ]; then + ln -sf #VENDORFILE# "$DPKG_ROOT/etc/dpkg/origins/default" fi fi @@ -65,8 +88,8 @@ install_directory var/opt 755 root install_directory media 755 root install_directory var/mail 2775 mail - if [ ! -L /var/spool/mail ]; then - ln -s ../mail /var/spool/mail + if [ ! -L "$DPKG_ROOT/var/spool/mail" ]; then + ln -s ../mail "$DPKG_ROOT/var/spool/mail" fi install_directory run/lock 1777 root migrate_directory /var/run /run @@ -82,38 +105,25 @@ install_local_dir /usr/local/sbin install_local_dir /usr/local/src install_local_dir /usr/local/etc - ln -sf share/man /usr/local/man + ln -sf share/man "$DPKG_ROOT/usr/local/man" - if [ ! -f /var/log/wtmp ]; then - echo -n>/var/log/wtmp - fi - if [ ! -f /var/log/btmp ]; then - echo -n>/var/log/btmp - fi - if [ ! -f /var/log/lastlog ]; then - echo -n>/var/log/lastlog - fi - chown root:utmp /var/log/wtmp /var/log/btmp /var/log/lastlog - chmod 664 /var/log/wtmp /var/log/lastlog - chmod 660 /var/log/btmp - if [ ! -f /var/run/utmp ]; then - echo -n>/var/run/utmp - fi - chown root:utmp /var/run/utmp - chmod 664 /var/run/utmp + ensure_file_owner_mode /var/log/wtmp root:utmp 664 + ensure_file_owner_mode /var/log/btmp root:utmp 660 + ensure_file_owner_mode /var/log/lastlog root:utmp 664 + ensure_file_owner_mode /var/log/utmp root:utmp 664 fi -if [ ! -d /var/lib/dpkg ]; then - mkdir -m 755 -p /var/lib/dpkg +if [ ! -d "$DPKG_ROOT/var/lib/dpkg" ]; then + mkdir -m 755 -p "$DPKG_ROOT/var/lib/dpkg" fi -if [ ! -f /var/lib/dpkg/status ]; then - echo > /var/lib/dpkg/status - chmod 644 /var/lib/dpkg/status +if [ ! -f "$DPKG_ROOT/var/lib/dpkg/status" ]; then + echo > "$DPKG_ROOT/var/lib/dpkg/status" + change_mode 644 /var/lib/dpkg/status fi -if [ ! -f /usr/info/dir ] && [ ! -f /usr/share/info/dir ]; then +if [ ! -f "$DPKG_ROOT/usr/info/dir" ] && [ ! -f "$DPKG_ROOT/usr/share/info/dir" ]; then install_from_default info.dir /usr/share/info/dir - chmod 644 /usr/share/info/dir + change_mode 644 /usr/share/info/dir fi if [ "$1" = "configure" ] && [ "$2" != "" ]; then