make back /etc/static absolute symlink

This commit is contained in:
danbst 2019-01-23 22:19:50 +02:00
parent fc8e1745c0
commit f47bfce584
2 changed files with 27 additions and 14 deletions

View File

@ -459,10 +459,16 @@
</listitem> </listitem>
<listitem> <listitem>
<para> <para>
Symlinks in <filename>/etc</filename> are now relative instead of absolute, Symlinks in <filename>/etc</filename> (except <filename>/etc/static</filename>)
so that the links can be followed if the NixOS installation is not mounted as filesystem root. are now relative instead of absolute. This makes possible to examine
In particular, this makes <filename>/etc/os-release</filename> adhere to NixOS container's <filename>/etc</filename> directory from host system
<link xlink:href="https://www.freedesktop.org/software/systemd/man/os-release.html">the standard</link>. (previously it pointed to host <filename>/etc</filename> when viewed from host,
and to container <filename>/etc</filename> when viewed from container chroot).
</para>
<para>
This also makes <filename>/etc/os-release</filename> adhere to
<link xlink:href="https://www.freedesktop.org/software/systemd/man/os-release.html">the standard</link>
for NixOS containers.
</para> </para>
</listitem> </listitem>
<listitem> <listitem>

View File

@ -13,18 +13,26 @@ sub atomicSymlink {
my ($source, $target) = @_; my ($source, $target) = @_;
my $tmp = "$target.tmp"; my $tmp = "$target.tmp";
unlink $tmp; unlink $tmp;
symlink $source, $tmp or return 0;
rename $tmp, $target or return 0;
return 1;
}
# Create relative symlinks, so that the links can be followed if # Create relative symlinks, so that the links can be followed if
# the NixOS installation is not mounted as filesystem root. # the NixOS installation is not mounted as filesystem root.
# Absolute symlinks violate the os-release format # Absolute symlinks violate the os-release format
# at https://www.freedesktop.org/software/systemd/man/os-release.html # at https://www.freedesktop.org/software/systemd/man/os-release.html
# and break e.g. systemd-nspawn and os-prober. # and break e.g. systemd-nspawn and os-prober.
sub atomicRelativeSymlink {
my ($source, $target) = @_;
my $tmp = "$target.tmp";
unlink $tmp;
my $rel = File::Spec->abs2rel($source, dirname $target); my $rel = File::Spec->abs2rel($source, dirname $target);
symlink $rel, $tmp or return 0; symlink $rel, $tmp or return 0;
rename $tmp, $target or return 0; rename $tmp, $target or return 0;
return 1; return 1;
} }
# Atomically update /etc/static to point at the etc files of the # Atomically update /etc/static to point at the etc files of the
# current configuration. # current configuration.
atomicSymlink $etc, $static or die; atomicSymlink $etc, $static or die;
@ -37,8 +45,7 @@ sub isStatic {
if (-l $path) { if (-l $path) {
my $target = readlink $path; my $target = readlink $path;
my $rel = File::Spec->abs2rel("/etc/static", dirname $path); return substr($target, 0, length "/etc/static/") eq "/etc/static/";
return substr($target, 0, length $rel) eq $rel;
} }
if (-d $path) { if (-d $path) {
@ -111,7 +118,7 @@ sub link {
if (-e "$_.mode") { if (-e "$_.mode") {
my $mode = read_file("$_.mode"); chomp $mode; my $mode = read_file("$_.mode"); chomp $mode;
if ($mode eq "direct-symlink") { if ($mode eq "direct-symlink") {
atomicSymlink readlink("$static/$fn"), $target or warn; atomicRelativeSymlink readlink("$static/$fn"), $target or warn;
} else { } else {
my $uid = read_file("$_.uid"); chomp $uid; my $uid = read_file("$_.uid"); chomp $uid;
my $gid = read_file("$_.gid"); chomp $gid; my $gid = read_file("$_.gid"); chomp $gid;
@ -125,7 +132,7 @@ sub link {
push @copied, $fn; push @copied, $fn;
print CLEAN "$fn\n"; print CLEAN "$fn\n";
} elsif (-l "$_") { } elsif (-l "$_") {
atomicSymlink "$static/$fn", $target or warn; atomicRelativeSymlink "$static/$fn", $target or warn;
} }
} }