Restore deterministic tar with pax and xattr support
- all creating and extraction of tarballs respects extended attributes - extended attributes require pax format, so explicitly request the format - to make pax bit-by-bit reproducible, ctime, atime and PID have to be removed from the headers with: --pax-option=exthdr.name=%d/PaxHeaders/%f,delete=atime,delete=ctime - always pass --numeric-owner to tar - always pass --xattrs when creating a tar - always pass --xattrs --xattrs-include=* when extracting a tar
This commit is contained in:
parent
a1df1a9730
commit
64fedc530e
2 changed files with 30 additions and 14 deletions
|
@ -1585,9 +1585,9 @@ echo copy-in-customize > /tmp/copy-in-customize
|
||||||
echo tar-in-setup > /tmp/tar-in-setup
|
echo tar-in-setup > /tmp/tar-in-setup
|
||||||
echo tar-in-essential > /tmp/tar-in-essential
|
echo tar-in-essential > /tmp/tar-in-essential
|
||||||
echo tar-in-customize > /tmp/tar-in-customize
|
echo tar-in-customize > /tmp/tar-in-customize
|
||||||
tar -C /tmp -cf /tmp/tar-in-setup.tar tar-in-setup
|
tar --numeric-owner --format=pax --pax-option=exthdr.name=%d/PaxHeaders/%f,delete=atime,delete=ctime -C /tmp -cf /tmp/tar-in-setup.tar tar-in-setup
|
||||||
tar -C /tmp -cf /tmp/tar-in-essential.tar tar-in-essential
|
tar --numeric-owner --format=pax --pax-option=exthdr.name=%d/PaxHeaders/%f,delete=atime,delete=ctime -C /tmp -cf /tmp/tar-in-essential.tar tar-in-essential
|
||||||
tar -C /tmp -cf /tmp/tar-in-customize.tar tar-in-customize
|
tar --numeric-owner --format=pax --pax-option=exthdr.name=%d/PaxHeaders/%f,delete=atime,delete=ctime -C /tmp -cf /tmp/tar-in-customize.tar tar-in-customize
|
||||||
rm /tmp/tar-in-setup
|
rm /tmp/tar-in-setup
|
||||||
rm /tmp/tar-in-essential
|
rm /tmp/tar-in-essential
|
||||||
rm /tmp/tar-in-customize
|
rm /tmp/tar-in-customize
|
||||||
|
|
38
mmdebstrap
38
mmdebstrap
|
@ -2369,7 +2369,11 @@ sub hookhelper {
|
||||||
# path that is valid on the outside -- fakechroot and proot have their
|
# path that is valid on the outside -- fakechroot and proot have their
|
||||||
# own reasons, see below
|
# own reasons, see below
|
||||||
my @cmdprefix = ();
|
my @cmdprefix = ();
|
||||||
my @tarcmd = ('tar');
|
my @tarcmd = (
|
||||||
|
'tar', '--numeric-owner', '--xattrs', '--format=pax',
|
||||||
|
'--pax-option=exthdr.name=%d/PaxHeaders/%f,'
|
||||||
|
. 'delete=atime,delete=ctime'
|
||||||
|
);
|
||||||
if ($hook eq 'setup') {
|
if ($hook eq 'setup') {
|
||||||
if ($mode eq 'proot') {
|
if ($mode eq 'proot') {
|
||||||
# since we cannot run tar inside the chroot under proot during
|
# since we cannot run tar inside the chroot under proot during
|
||||||
|
@ -2378,7 +2382,7 @@ sub hookhelper {
|
||||||
# by the user running mmdebstrap. To let the ownership
|
# by the user running mmdebstrap. To let the ownership
|
||||||
# information not be completely off, we force all files be
|
# information not be completely off, we force all files be
|
||||||
# owned by the root user.
|
# owned by the root user.
|
||||||
push @tarcmd, '--owner=root', '--group=root';
|
push @tarcmd, '--owner=0', '--group=0';
|
||||||
}
|
}
|
||||||
} elsif (any { $_ eq $hook } ('essential', 'customize')) {
|
} elsif (any { $_ eq $hook } ('essential', 'customize')) {
|
||||||
if ($mode eq 'fakechroot') {
|
if ($mode eq 'fakechroot') {
|
||||||
|
@ -2440,8 +2444,8 @@ sub hookhelper {
|
||||||
# open a tar process that extracts the tarfile that we
|
# open a tar process that extracts the tarfile that we
|
||||||
# supply it with on stdin to the output directory inside
|
# supply it with on stdin to the output directory inside
|
||||||
# the chroot
|
# the chroot
|
||||||
open $fh, '|-', @cmdprefix, @tarcmd, '--directory',
|
open $fh, '|-', @cmdprefix, @tarcmd, '--xattrs-include=*',
|
||||||
$directory, '--extract', '--file',
|
'--directory', $directory, '--extract', '--file',
|
||||||
'-' // error "failed to fork(): $!";
|
'-' // error "failed to fork(): $!";
|
||||||
} else {
|
} else {
|
||||||
error "unknown command: $command";
|
error "unknown command: $command";
|
||||||
|
@ -3571,10 +3575,16 @@ sub main() {
|
||||||
|
|
||||||
my $exitstatus = 0;
|
my $exitstatus = 0;
|
||||||
my @taropts = (
|
my @taropts = (
|
||||||
'--sort=name', "--mtime=\@$mtime",
|
'--sort=name',
|
||||||
'--clamp-mtime', '--numeric-owner',
|
"--mtime=\@$mtime",
|
||||||
'--one-file-system', '--xattrs',
|
'--clamp-mtime',
|
||||||
'-c', '--exclude=./dev'
|
'--numeric-owner',
|
||||||
|
'--one-file-system',
|
||||||
|
'--xattrs',
|
||||||
|
'--format=pax',
|
||||||
|
'--pax-option=exthdr.name=%d/PaxHeaders/%f,delete=atime,delete=ctime',
|
||||||
|
'-c',
|
||||||
|
'--exclude=./dev'
|
||||||
);
|
);
|
||||||
|
|
||||||
# disable signals so that we can fork and change behaviour of the signal
|
# disable signals so that we can fork and change behaviour of the signal
|
||||||
|
@ -3925,7 +3935,11 @@ sub main() {
|
||||||
# Open a tar process creating a tarfile of the instructed
|
# Open a tar process creating a tarfile of the instructed
|
||||||
# path. To emulate the behaviour of cp, change to the
|
# path. To emulate the behaviour of cp, change to the
|
||||||
# dirname of the requested path first.
|
# dirname of the requested path first.
|
||||||
open my $fh, '-|', 'tar', '--directory',
|
open my $fh, '-|', 'tar', '--numeric-owner', '--xattrs',
|
||||||
|
'--format=pax',
|
||||||
|
'--pax-option=exthdr.name=%d/PaxHeaders/%f,'
|
||||||
|
. 'delete=atime,delete=ctime',
|
||||||
|
'--directory',
|
||||||
$msg eq 'mktar' ? dirname($indir) : $indir,
|
$msg eq 'mktar' ? dirname($indir) : $indir,
|
||||||
'--create', '--file', '-',
|
'--create', '--file', '-',
|
||||||
$msg eq 'mktar' ? basename($indir) : '.'
|
$msg eq 'mktar' ? basename($indir) : '.'
|
||||||
|
@ -3994,8 +4008,10 @@ sub main() {
|
||||||
|
|
||||||
# now we expect one or more "write" messages containing the
|
# now we expect one or more "write" messages containing the
|
||||||
# tarball to unpack
|
# tarball to unpack
|
||||||
open my $fh, '|-', 'tar', '--directory', $outdir, '--extract',
|
open my $fh, '|-', 'tar', '--numeric-owner', '--xattrs',
|
||||||
'--file', '-' // error "failed to fork(): $!";
|
'--xattrs-include=*', '--directory', $outdir,
|
||||||
|
'--extract', '--file',
|
||||||
|
'-' // error "failed to fork(): $!";
|
||||||
|
|
||||||
# handle "write" messages from the child process and feed
|
# handle "write" messages from the child process and feed
|
||||||
# their payload into the tar process until a "close" message
|
# their payload into the tar process until a "close" message
|
||||||
|
|
Loading…
Reference in a new issue