New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
nixos: make systemd-nspawn work out of the box on a NixOS root filesystem #35364
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good if this fixes the issue. :)
@palmeida confirmed this works for os-prober, but for nspawn, this is only enough for filesystems that were already booted once. The containerTarball generation code needs to copy /etc/os-release as well. The easiest way to achieve that would be to add something like:
in the code for the docker container at Not sure what makes more sense, though, especially I have no idea whether you want |
1f23793
to
d477f65
Compare
As docker is not really about starting OSes but more like start anything and just give me the right executable, in contrast to lxc, I now think putting this in lxc is the right way. I added a commit which should copy |
943ff33
to
6a6847f
Compare
Found out the reason for why nix-build did just return nothing was actually in my code! I fixed that now! 🎉 for which I had to put The minimal commands to test this:
Finally, just works, with no container tarball modifications necessary! As soon as hydra builds this thing, a machinectl pull-tar will suffice, without any image modifications! 😅 |
@rhendric reported problems with the a) make docker use b) make c) split the config for docker and lxc, and fix this TODO while we are at it. I don't know what @edolstra had in mind there, though - move Just discovered this, might be relevant as well: https://github.com/florianjacob/nixpkgs/blob/6a6847f15486eeba8e2b54d2710f0f61836b8cfe/nixos/modules/system/boot/loader/init-script/init-script.nix |
I think making |
@dezgeg oh that is good to know, from a quick glance I thought lxc had no default places where it automatically checks for an init script, and only nspawn would profit. 👍 |
(triage) @florianjacob, are you still working on this? |
76bd765
to
ca28a30
Compare
@Ekleog Thanks, I forgot about this. It is essentially finished, I'm rebasing stuff now and applying the |
ca28a30
to
6c9126c
Compare
I now introduced the As far as I know, this only is a breaking change for docker for people using docker to boot a full-blown NixOS instead of directly specifying the process they want to run. |
Not really in favor of replacing /etc symlinks by copies since it reduces the atomicity of the upgrade process. Maybe symlinks in /etc could be made relative (e.g. to |
I'd prefer relative symlinks as well, and tried that route first, even without realizing the implications for the upgrade process. I found no way to create relative symlinks though within NixOS, and therefore used the existing ways to get a copy. @edolstra you're suggesting to make all symlinks in /etc relative, if I understand you correctly? |
@florianjacob Yes, sounds good! |
b2c5bfe
to
d18d332
Compare
d18d332
to
fb00a87
Compare
so that the links can be followed if the NixOS installation is not mounted as filesystem root. In particular, this makes /etc/os-release adhere to the standard: https://www.freedesktop.org/software/systemd/man/os-release.html Fixes NixOS#28833.
out of the box by adding /etc/os-release to the image and putting init at the /sbin/init standard location.
fb00a87
to
ba45d51
Compare
I now switched everything to relative symlinks, mainly by using the This is now ready again for review and intensive testing - is there something like |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've rebased this PR on master and built on my system. So far so good. Then I checked for my main usecase, running nixos containers on non-nixos, and it failed. Left a comment. Here is patch:
From 9c0f4945fc96a14fe5ca4cc18bdbcb0b2a4d2b3e Mon Sep 17 00:00:00 2001
From: danbst <abcz2.uprola@gmail.com>
Date: Wed, 23 Jan 2019 22:19:50 +0200
Subject: [PATCH] make back /etc/static absolute symlink
---
nixos/modules/system/etc/setup-etc.pl | 27 +++++++++++++++++----------
1 file changed, 17 insertions(+), 10 deletions(-)
diff --git a/nixos/modules/system/etc/setup-etc.pl b/nixos/modules/system/etc/setup-etc.pl
index 6cbf0e17793..82ef49a2a27 100644
--- a/nixos/modules/system/etc/setup-etc.pl
+++ b/nixos/modules/system/etc/setup-etc.pl
@@ -13,18 +13,26 @@ sub atomicSymlink {
my ($source, $target) = @_;
my $tmp = "$target.tmp";
unlink $tmp;
- # Create relative symlinks, so that the links can be followed if
- # the NixOS installation is not mounted as filesystem root.
- # Absolute symlinks violate the os-release format
- # at https://www.freedesktop.org/software/systemd/man/os-release.html
- # and break e.g. systemd-nspawn and os-prober.
+ 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
+# the NixOS installation is not mounted as filesystem root.
+# Absolute symlinks violate the os-release format
+# at https://www.freedesktop.org/software/systemd/man/os-release.html
+# 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);
symlink $rel, $tmp or return 0;
rename $tmp, $target or return 0;
return 1;
}
-
# Atomically update /etc/static to point at the etc files of the
# current configuration.
atomicSymlink $etc, $static or die;
@@ -37,8 +45,7 @@ sub isStatic {
if (-l $path) {
my $target = readlink $path;
- my $rel = File::Spec->abs2rel("/etc/static", dirname $path);
- return substr($target, 0, length $rel) eq $rel;
+ return substr($target, 0, length "/etc/static/") eq "/etc/static/";
}
if (-d $path) {
@@ -111,7 +118,7 @@ sub link {
if (-e "$_.mode") {
my $mode = read_file("$_.mode"); chomp $mode;
if ($mode eq "direct-symlink") {
- atomicSymlink readlink("$static/$fn"), $target or warn;
+ atomicRelativeSymlink readlink("$static/$fn"), $target or warn;
} else {
my $uid = read_file("$_.uid"); chomp $uid;
my $gid = read_file("$_.gid"); chomp $gid;
@@ -125,7 +132,7 @@ sub link {
push @copied, $fn;
print CLEAN "$fn\n";
} elsif (-l "$_") {
- atomicSymlink "$static/$fn", $target or warn;
+ atomicRelativeSymlink "$static/$fn", $target or warn;
}
}
--
2.19.2
Let me know if you'd like to polish this PR further, otherwise I'll grab your commit (that which doesn't touch docker) as a separate PR.
# at https://www.freedesktop.org/software/systemd/man/os-release.html | ||
# and break e.g. systemd-nspawn and os-prober. | ||
my $rel = File::Spec->abs2rel($source, dirname $target); | ||
symlink $rel, $tmp or return 0; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is wrong. This works for system
$ ls -ld /etc/static
lrwxrwxrwx 1 root root 53 січ 23 21:27 /etc/static -> ../nix/store/23r7mdcbqh5h7rfvdzifcygjfp9f5kyd-etc/etc
But fails for container:
# ls -ld /var/lib/containers/db2/etc/static
lrwxrwxrwx 1 root root 53 Jan 23 15:07 /var/lib/containers/db2/etc/static -> ../nix/store/c7xn0a16907d2mi3kyidina9hg3r9nh4-etc/etc
That symlink doesn't resolve for container, when viewed from host
With my patch applied on top of this, I get following for containers:
Last one looks strange, but actually all good, it is a relative |
That is really strange, as this is/was my main use case as well and I'm quite sure I tested that, as host acces to /etc/os-release is the main thing this PR is about 🤔
If that's copied correctly then I'd argue that the first one looks odd, as it seems absolute. Will that really go to the container's nix store and not the host's nix store?
Feel free to extract and handle that part if you're not using LXC for whatever you're doing. 👍 |
very strange.
How can |
@danbst the main question is, what happens when you do |
@florianjacob oh I see now. So in your case you distribute /nix/store with container, in my case I reuse /nix/store from the host. Have to think about what is best solution for both cases |
I'm happy I was able to bring my point across. 👍 |
Update: relative symlinks turned out to be bad idea, because it is not easy to verify that relative symlink is actually a symlink to |
As I understand this PR, the functionality will be properly implemented by #67232. This closing for now. Feel free to reopen if you disagree. |
@fpletz Thanks, was not aware of that new effort. |
@fpletz @florianjacob #67232 was reverted |
instead of creating an absolute symlink, which violates the os-release format
at https://www.freedesktop.org/software/systemd/man/os-release.html and
breaks systemd-nspawn and os-prober.
Motivation for this change
Fixes #28833, related to #9884.
Things done
build-use-sandbox
innix.conf
on non-NixOS)nix-shell -p nox --run "nox-review wip"
./result/bin/
)