Compare commits
6 commits
bda207af63
...
8e2f62d08c
Author | SHA1 | Date | |
---|---|---|---|
8e2f62d08c | |||
8130f1cef0 | |||
6262c1921c | |||
500b0d2512 | |||
|
37678c4fb5 | ||
134330d786 |
5 changed files with 106 additions and 58 deletions
|
@ -1,3 +1,8 @@
|
||||||
|
1.5.2 (2024-06-26)
|
||||||
|
------------------
|
||||||
|
|
||||||
|
- mmdebstrap-autopkgtest-build-qemu produces bit-by-bit reproducible output
|
||||||
|
|
||||||
1.5.1 (2024-06-03)
|
1.5.1 (2024-06-03)
|
||||||
------------------
|
------------------
|
||||||
|
|
||||||
|
|
|
@ -158,16 +158,19 @@ Contributors
|
||||||
|
|
||||||
- Johannes Schauer Marin Rodrigues (main author)
|
- Johannes Schauer Marin Rodrigues (main author)
|
||||||
- Helmut Grohne
|
- Helmut Grohne
|
||||||
|
- Jochen Sprickerhof
|
||||||
- Gioele Barabucci
|
- Gioele Barabucci
|
||||||
- Benjamin Drung
|
- Benjamin Drung
|
||||||
- Jochen Sprickerhof
|
|
||||||
- Josh Triplett
|
- Josh Triplett
|
||||||
- Konstantin Demin
|
- Konstantin Demin
|
||||||
|
- Chris Hofstaedtler
|
||||||
|
- Colin Watson
|
||||||
- David Kalnischkies
|
- David Kalnischkies
|
||||||
- Emilio Pozuelo Monfort
|
- Emilio Pozuelo Monfort
|
||||||
- Francesco Poli
|
- Francesco Poli
|
||||||
- Jakub Wilk
|
- Jakub Wilk
|
||||||
- Joe Groocock
|
- Joe Groocock
|
||||||
|
- Max-Julian Pogner
|
||||||
- Nicolas Vigier
|
- Nicolas Vigier
|
||||||
- Raul Tambre
|
- Raul Tambre
|
||||||
- Steve Dodd
|
- Steve Dodd
|
||||||
|
|
36
mmdebstrap
36
mmdebstrap
|
@ -23,7 +23,7 @@
|
||||||
use strict;
|
use strict;
|
||||||
use warnings;
|
use warnings;
|
||||||
|
|
||||||
our $VERSION = '1.5.1';
|
our $VERSION = '1.5.2';
|
||||||
|
|
||||||
use English;
|
use English;
|
||||||
use Getopt::Long;
|
use Getopt::Long;
|
||||||
|
@ -4293,8 +4293,8 @@ sub get_sourceslist_by_suite {
|
||||||
# the security mirror changes, starting with bullseye
|
# the security mirror changes, starting with bullseye
|
||||||
# https://lists.debian.org/87r26wqr2a.fsf@43-1.org
|
# https://lists.debian.org/87r26wqr2a.fsf@43-1.org
|
||||||
my $bullseye_or_later = 0;
|
my $bullseye_or_later = 0;
|
||||||
if (any { $_ eq $suite } ('oldstable', 'stable', 'bullseye', 'bookworm', 'trixie'))
|
if (any { $_ eq $suite }
|
||||||
{
|
('oldstable', 'stable', 'bullseye', 'bookworm', 'trixie')) {
|
||||||
$bullseye_or_later = 1;
|
$bullseye_or_later = 1;
|
||||||
}
|
}
|
||||||
my $distro_info = '/usr/share/distro-info/debian.csv';
|
my $distro_info = '/usr/share/distro-info/debian.csv';
|
||||||
|
@ -6973,13 +6973,29 @@ The above uses C<--map-auto> to map the block of user/group ids for the
|
||||||
effective user/group to a block starting at user/group ID 0. We also want to
|
effective user/group to a block starting at user/group ID 0. We also want to
|
||||||
map the current effective user/group ID into the subuid/subgid range using
|
map the current effective user/group ID into the subuid/subgid range using
|
||||||
C<--map-user> and C<--map-group>, respectively. But if that uid/gid overlaps
|
C<--map-user> and C<--map-group>, respectively. But if that uid/gid overlaps
|
||||||
with the respective range, a "hole" will be removed from the mapping and the
|
with the respective range, a "hole" will be removed from the mapping by the
|
||||||
remaining uid/gid values will get shifted. Thus, we map the current effective
|
L<unshare(1)> utility and the remaining uid/gid values will get shifted. Thus,
|
||||||
user/group ID to the highest possible uid/gid, putting them at the end. Since
|
we map the current effective user/group ID to the highest possible uid/gid,
|
||||||
that means that the user/group will be "nobody" and not "root" inside the
|
putting them at the end. Since that means that the user/group will be "nobody"
|
||||||
namespace, C<--keep-caps> propagate permitted capabilities into the ambient set
|
and not "root" inside the namespace, C<--keep-caps> propagate permitted
|
||||||
and thus give the user C<CAP_DAC_OVERRIDE> and other capabilities that it
|
capabilities into the ambient set and thus give the user C<CAP_DAC_OVERRIDE>
|
||||||
would've had.
|
and other capabilities that it would've had. The following does B<NOT> work:
|
||||||
|
|
||||||
|
$ unshare --map-root-user --map-auto ... # or equavalient:
|
||||||
|
$ unshare --map-user=0 --map-group=0 --map-users=auto --map-groups=auto ...
|
||||||
|
|
||||||
|
Using the format of L<lxc-usernsexec(1)>, these options will result in the
|
||||||
|
following mapping:
|
||||||
|
|
||||||
|
0:$UID:1 + 1:$SUBUIDBASE:65535
|
||||||
|
|
||||||
|
So a hole is punched in the automatically mapped range at the very beginning to
|
||||||
|
make space for the user id of the current user as root inside the namespace and
|
||||||
|
the remaining uids are shifted. With C<--map-user=65536> the mapping is as
|
||||||
|
follows and places the current user at the end of the range, preventing any
|
||||||
|
shifting:
|
||||||
|
|
||||||
|
0:$SUBUIDBASE:65536 + 65536:$UID:1
|
||||||
|
|
||||||
Lastly, if you don't mind using superuser privileges and have systemd-nspawn
|
Lastly, if you don't mind using superuser privileges and have systemd-nspawn
|
||||||
available and you know your subuid/subgid offset (100000 in this example):
|
available and you know your subuid/subgid offset (100000 in this example):
|
||||||
|
|
|
@ -29,10 +29,11 @@ B<mmdebstrap-autopkgtest-build-qemu> [I<OPTIONS>] B<--boot>=B<efi> I<RELEASE> I<
|
||||||
B<mmdebstrap-autopkgtest-build-qemu> is a mostly compatible drop-in replacement
|
B<mmdebstrap-autopkgtest-build-qemu> is a mostly compatible drop-in replacement
|
||||||
for L<autopkgtest-build-qemu(1)> with two main differences: Firstly, it uses
|
for L<autopkgtest-build-qemu(1)> with two main differences: Firstly, it uses
|
||||||
L<mmdebstrap(1)> instead of L<vmdb2(1)> and thus is able to create QEMU disk
|
L<mmdebstrap(1)> instead of L<vmdb2(1)> and thus is able to create QEMU disk
|
||||||
images without requiring superuser privileges. Secondly, it uses
|
images without requiring superuser privileges and with bit-by-bit reproducible
|
||||||
L<systemd-boot(7)> and thus only supports booting via EFI. For architectures
|
output. Secondly, it uses L<systemd-boot(7)> and thus only supports booting via
|
||||||
for which L<autopkgtest-virt-qemu(1)> does not default to EFI booting you must
|
EFI. For architectures for which L<autopkgtest-virt-qemu(1)> does not default
|
||||||
pass B<--boot=efi> when invoking the autopkgtest virt backend.
|
to EFI booting you must pass B<--boot=efi> when invoking the autopkgtest virt
|
||||||
|
backend.
|
||||||
|
|
||||||
=head1 POSITIONAL PARAMETERS
|
=head1 POSITIONAL PARAMETERS
|
||||||
|
|
||||||
|
@ -110,6 +111,12 @@ all path components or by creating the image in a world-readable directory like
|
||||||
Make sure to add B<--boot=efi> to both the B<mmdebstrap-autopkgtest-build-qemu>
|
Make sure to add B<--boot=efi> to both the B<mmdebstrap-autopkgtest-build-qemu>
|
||||||
as well as the B<autopkgtest-virt-qemu> invocation.
|
as well as the B<autopkgtest-virt-qemu> invocation.
|
||||||
|
|
||||||
|
Create bit-by-bit reproducible images from a given snapshot.d.o timestamp.
|
||||||
|
|
||||||
|
SOURCE_DATE_EPOCH=1612543740 mmdebstrap-autopkgtest-build-qemu --boot=efi \
|
||||||
|
--mirror=http://snapshot.debian.org/archive/debian/20210205T164900Z/ \
|
||||||
|
unstable /path/to/debian-unstable.img
|
||||||
|
|
||||||
=head1 SEE ALSO
|
=head1 SEE ALSO
|
||||||
|
|
||||||
L<autopkgtest-build-qemu(1)>, L<autopkgtest-virt-qemu(1)>, L<mmdebstrap(1)>, L<autopkgtest(1)>
|
L<autopkgtest-build-qemu(1)>, L<autopkgtest-virt-qemu(1)>, L<mmdebstrap(1)>, L<autopkgtest(1)>
|
||||||
|
@ -273,7 +280,7 @@ test_installed() {
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
for pkg in autopkgtest dosfstools e2fsprogs fdisk mount mtools passwd uidmap; do
|
for pkg in autopkgtest dosfstools e2fsprogs fdisk mount mtools passwd uidmap libarchive13; do
|
||||||
test_installed "$pkg"
|
test_installed "$pkg"
|
||||||
done
|
done
|
||||||
|
|
||||||
|
@ -320,33 +327,24 @@ FAT_SIZE_SECTORS=$((1024*254))
|
||||||
# - snapshots and overlays work just as well with raw images
|
# - snapshots and overlays work just as well with raw images
|
||||||
# - users who prefer qcow2 get to choose to run it themselves with their own
|
# - users who prefer qcow2 get to choose to run it themselves with their own
|
||||||
# custom options like compression
|
# custom options like compression
|
||||||
#
|
|
||||||
# --map-users=auto --map-user=0 => 0:$UID:1 + 1:$SUBUIDBASE:65535
|
|
||||||
# --map-users=auto --map-user=65536 => 0:$SUBUIDBASE:65536 + 65536:$UID:1
|
|
||||||
#
|
|
||||||
# Make the image writeable to the first subgid. mmdebstrap will map this gid to
|
|
||||||
# the root group. unshare instead will map the current gid to 0 and the first
|
|
||||||
# subgid to 1. Therefore mmdebstrap will be able to write to the image.
|
|
||||||
rm -f "$IMAGE"
|
|
||||||
: >"$IMAGE"
|
|
||||||
unshare --map-user=0 --map-group=0 --map-groups=auto chown 0:1 "$IMAGE"
|
|
||||||
chmod 0660 "$IMAGE"
|
|
||||||
|
|
||||||
# Make sure that the unshared user is able to access the file.
|
|
||||||
# Alternatively to using /sbin/mkfs.ext4 could use --format=ext2 which would
|
|
||||||
# add an extra copy operation and come with the limitations of ext2.
|
|
||||||
# Another solution: https://github.com/tytso/e2fsprogs/pull/118
|
|
||||||
if ! mmdebstrap --unshare-helper touch "$IMAGE"; then
|
|
||||||
die "$IMAGE cannot be accessed by the unshared user -- either make all path components up to the image itself world-executable or place the image into a world-readable path like /tmp"
|
|
||||||
fi
|
|
||||||
|
|
||||||
set -- \
|
set -- \
|
||||||
--mode=unshare \
|
--mode=unshare \
|
||||||
|
--format=tar \
|
||||||
--variant=important \
|
--variant=important \
|
||||||
--architecture="$ARCHITECTURE"
|
--architecture="$ARCHITECTURE"
|
||||||
|
|
||||||
test "$RELEASE" = jessie &&
|
case $MIRROR in http://snapshot.debian.org/archive/*|https://snapshot.debian.org/archive/*)
|
||||||
|
set -- "$@" --aptopt='Acquire::Check-Valid-Until "false"';;
|
||||||
|
esac
|
||||||
|
|
||||||
|
EXT_FEATURES=
|
||||||
|
if test "$RELEASE" = jessie; then
|
||||||
|
set -- "$@" --keyring=/usr/share/keyrings/debian-archive-removed-keys.gpg
|
||||||
|
set -- "$@" --aptopt='Apt::Key::gpgvcommand "/usr/libexec/mmdebstrap/gpgvnoexpkeysig"'
|
||||||
set -- "$@" --hook-dir=/usr/share/mmdebstrap/hooks/jessie-or-older
|
set -- "$@" --hook-dir=/usr/share/mmdebstrap/hooks/jessie-or-older
|
||||||
|
EXT_FEATURES="^metadata_csum,^metadata_csum_seed,^orphan_file"
|
||||||
|
fi
|
||||||
|
|
||||||
set -- "$@" \
|
set -- "$@" \
|
||||||
"--include=init,$LINUXIMAGE,python3" \
|
"--include=init,$LINUXIMAGE,python3" \
|
||||||
|
@ -364,30 +362,35 @@ if test -n "$SCRIPT"; then
|
||||||
'--customize-hook=rm -f "$1/userscript"'
|
'--customize-hook=rm -f "$1/userscript"'
|
||||||
fi
|
fi
|
||||||
|
|
||||||
EXT4_OFFSET_BYTES=$(( (FAT_OFFSET_SECTORS + FAT_SIZE_SECTORS) * 512))
|
|
||||||
EXT4_OPTIONS="offset=$EXT4_OFFSET_BYTES,assume_storage_prezeroed=1"
|
|
||||||
|
|
||||||
# the --no-mtab option to mount is a workaround for https://github.com/util-linux/util-linux/issues/2981
|
|
||||||
# revert 8c0ddc32660ca4e98c988966251f9c05d6bcccef once it is no longer needed
|
|
||||||
set -- "$@" \
|
set -- "$@" \
|
||||||
"--customize-hook=download vmlinuz '$WORKDIR/kernel'" \
|
"--customize-hook=download vmlinuz '$WORKDIR/kernel'" \
|
||||||
"--customize-hook=download initrd.img '$WORKDIR/initrd'" \
|
"--customize-hook=download initrd.img '$WORKDIR/initrd'" \
|
||||||
'--customize-hook=mount --no-mtab --bind "$1" "$1/mnt"' \
|
|
||||||
'--customize-hook=mount --no-mtab --bind "$1/mnt/mnt" "$1/mnt/dev"' \
|
|
||||||
'--customize-hook=/sbin/mkfs.ext4 -d "$1/mnt" -L autopkgtestvm -E '"'$EXT4_OPTIONS' '$IMAGE' '$SIZE'" \
|
|
||||||
'--customize-hook=umount --lazy --no-mtab "$1/mnt/dev"' \
|
|
||||||
'--customize-hook=umount --lazy --no-mtab "$1/mnt"' \
|
|
||||||
"$RELEASE" \
|
"$RELEASE" \
|
||||||
/dev/null
|
-
|
||||||
|
|
||||||
test -n "$MIRROR" && set -- "$@" "$MIRROR"
|
test -n "$MIRROR" && set -- "$@" "$MIRROR"
|
||||||
test -n "$KEYRING" && set -- "$@" "--keyring=$KEYRING"
|
test -n "$KEYRING" && set -- "$@" "--keyring=$KEYRING"
|
||||||
|
|
||||||
echo "mmdebstrap $*"
|
echo "+ mmdebstrap $*" >&2
|
||||||
mmdebstrap "$@" || die "mmdebstrap failed"
|
# https://github.com/koalaman/shellcheck/issues/2555
|
||||||
|
# shellcheck disable=SC3040
|
||||||
|
set -o pipefail
|
||||||
|
mmdebstrap "$@" | {
|
||||||
|
set -- -t ext4 -L autopkgtestvm -d -
|
||||||
|
if test -n "$EXT_FEATURES"; then
|
||||||
|
set -- "$@" -O "$EXT_FEATURES"
|
||||||
|
fi
|
||||||
|
EXTOPTS="offset=$(( (FAT_OFFSET_SECTORS + FAT_SIZE_SECTORS) * 512))"
|
||||||
|
if test -n "${SOURCE_DATE_EPOCH:-}"; then
|
||||||
|
uuid="$(uuidgen --sha1 --namespace="$(uuidgen --sha1 --namespace='@dns' --name mister-muffin.de)" --name "$SOURCE_DATE_EPOCH")"
|
||||||
|
set -- "$@" -U "$uuid"
|
||||||
|
EXTOPTS="$EXTOPTS,hash_seed=$uuid"
|
||||||
|
fi
|
||||||
|
set -- "$@" -E "$EXTOPTS" "$IMAGE" "$SIZE"
|
||||||
|
echo "+ mke2fs $*" >&2
|
||||||
|
/sbin/mke2fs "$@"
|
||||||
|
}
|
||||||
|
|
||||||
unshare -U -r --map-groups=auto chown 0:0 "$IMAGE"
|
|
||||||
chmod "$(printf %o "$(( 0666 & ~0$(umask) ))")" "$IMAGE"
|
|
||||||
|
|
||||||
echo "root=LABEL=autopkgtestvm rw console=ttyS0" > "$WORKDIR/cmdline"
|
echo "root=LABEL=autopkgtestvm rw console=ttyS0" > "$WORKDIR/cmdline"
|
||||||
|
|
||||||
|
@ -461,4 +464,5 @@ if test -n "$VMFPKG" && test "$(dpkg-query -f '${db:Status-Status}' -W "$VMFPKG"
|
||||||
echo "I: you might need to install $VMFPKG to use this image with autopkgtest-virt-qemu" >&2
|
echo "I: you might need to install $VMFPKG to use this image with autopkgtest-virt-qemu" >&2
|
||||||
fi
|
fi
|
||||||
|
|
||||||
echo "I: don't forget to pass --boot=efi when running autopkgtest-virt-qemu with this image" >&2
|
echo "I: SUCCESS! Your new image can be found here: $IMAGE" >&2
|
||||||
|
echo "I: Don't forget to pass --boot=efi when running autopkgtest-virt-qemu with this image" >&2
|
||||||
|
|
|
@ -157,24 +157,44 @@ if [ "{{ VARIANT }}" = "-" ] && [ "{{ DIST}}" = oldstable ]; then
|
||||||
fi
|
fi
|
||||||
|
|
||||||
for log in faillog lastlog; do
|
for log in faillog lastlog; do
|
||||||
if ! cmp /tmp/debian-{{ DIST }}-debootstrap/var/log/$log /tmp/debian-{{ DIST }}-mm/var/log/$log >&2;then
|
f1="/tmp/debian-{{ DIST }}-debootstrap/var/log/$log"
|
||||||
|
f2="/tmp/debian-{{ DIST }}-mm/var/log/$log"
|
||||||
|
# skip cmp if file is absent in both chroots
|
||||||
|
if [ ! -e "$f1" ] && [ ! -e "$f2" ]; then
|
||||||
|
continue
|
||||||
|
fi
|
||||||
|
if ! cmp "$f1" "$f2" >&2;then
|
||||||
# if the files differ, make sure they are all zeroes
|
# if the files differ, make sure they are all zeroes
|
||||||
cmp -n "$(stat -c %s "/tmp/debian-{{ DIST }}-debootstrap/var/log/$log")" "/tmp/debian-{{ DIST }}-debootstrap/var/log/$log" /dev/zero >&2
|
cmp -n "$(stat -c %s "$f1")" "$f1" /dev/zero >&2
|
||||||
cmp -n "$(stat -c %s "/tmp/debian-{{ DIST }}-mm/var/log/$log")" "/tmp/debian-{{ DIST }}-mm/var/log/$log" /dev/zero >&2
|
cmp -n "$(stat -c %s "$f2")" "$f2" /dev/zero >&2
|
||||||
# then delete them
|
# then delete them
|
||||||
rm /tmp/debian-{{ DIST }}-debootstrap/var/log/$log /tmp/debian-{{ DIST }}-mm/var/log/$log
|
rm "$f1" "$f2"
|
||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
|
|
||||||
# the order in which systemd and cron get installed differ and thus the order
|
|
||||||
# of lines in /etc/group and /etc/gshadow differs
|
|
||||||
if [ "{{ VARIANT }}" = "-" ]; then
|
if [ "{{ VARIANT }}" = "-" ]; then
|
||||||
|
# the order in which systemd and cron get installed differ and thus the order
|
||||||
|
# of lines in /etc/group and /etc/gshadow differs
|
||||||
for f in group group- gshadow gshadow-; do
|
for f in group group- gshadow gshadow-; do
|
||||||
for d in mm debootstrap; do
|
for d in mm debootstrap; do
|
||||||
sort /tmp/debian-{{ DIST }}-$d/etc/$f > /tmp/debian-{{ DIST }}-$d/etc/$f.bak
|
sort /tmp/debian-{{ DIST }}-$d/etc/$f > /tmp/debian-{{ DIST }}-$d/etc/$f.bak
|
||||||
mv /tmp/debian-{{ DIST }}-$d/etc/$f.bak /tmp/debian-{{ DIST }}-$d/etc/$f
|
mv /tmp/debian-{{ DIST }}-$d/etc/$f.bak /tmp/debian-{{ DIST }}-$d/etc/$f
|
||||||
done
|
done
|
||||||
done
|
done
|
||||||
|
# the order in which systemd and passwd get installed differ and thus
|
||||||
|
# the order of lines in /etc/shadow and /etc/shadow- differs
|
||||||
|
for f in shadow shadow-; do
|
||||||
|
for d in mm debootstrap; do
|
||||||
|
sort /tmp/debian-{{ DIST }}-$d/etc/$f > /tmp/debian-{{ DIST }}-$d/etc/$f.bak
|
||||||
|
mv /tmp/debian-{{ DIST }}-$d/etc/$f.bak /tmp/debian-{{ DIST }}-$d/etc/$f
|
||||||
|
done
|
||||||
|
done
|
||||||
|
# and since the order was different, ignore the *- files
|
||||||
|
for f in shadow- passwd-; do
|
||||||
|
for d in mm debootstrap; do
|
||||||
|
rm /tmp/debian-{{ DIST }}-$d/etc/$f
|
||||||
|
done
|
||||||
|
done
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# since debootstrap 1.0.133 there is no tzdata in the buildd variant and thus
|
# since debootstrap 1.0.133 there is no tzdata in the buildd variant and thus
|
||||||
|
|
Loading…
Reference in a new issue