nixos/filesystems: fix special file-systems for systemd-nspawn (#345899)
This commit is contained in:
@@ -295,6 +295,15 @@
|
|||||||
- `services.nextcloud.configureRedis` now defaults to `true` in accordance with upstream recommendations to have caching for file locking. See the [upstream doc](https://docs.nextcloud.com/server/31/admin_manual/configuration_files/files_locking_transactional.html) for further details.
|
- `services.nextcloud.configureRedis` now defaults to `true` in accordance with upstream recommendations to have caching for file locking. See the [upstream doc](https://docs.nextcloud.com/server/31/admin_manual/configuration_files/files_locking_transactional.html) for further details.
|
||||||
|
|
||||||
- mate-wayland-session 1.28.4 is now using the default wayfire decorator instead of firedecor, thus `services.xserver.desktopManager.mate.enableWaylandSession` is no longer shipping firedecor. If you are experiencing broken window decorations after upgrade, backup and remove `~/.config/mate/wayfire.ini` and re-login.
|
- mate-wayland-session 1.28.4 is now using the default wayfire decorator instead of firedecor, thus `services.xserver.desktopManager.mate.enableWaylandSession` is no longer shipping firedecor. If you are experiencing broken window decorations after upgrade, backup and remove `~/.config/mate/wayfire.ini` and re-login.
|
||||||
|
-
|
||||||
|
- A new option [](#opt-boot.isNspawnContainer) has been added. This option will be used to guard nspawn-specific configuration in NixOS since [](#opt-boot.isContainer) is also used for different container-runtimes such as LXC.
|
||||||
|
- The new option is automatically set to `true` by the declarative container module and `nixos-container` when not using flakes.
|
||||||
|
- Existing setups can be migrated by running either
|
||||||
|
- `nixos-container update <container-name> --config-file /path/to/the/config-file-in-use.nix`
|
||||||
|
- `nixos-container update <container-name> --config '/* config code */'`
|
||||||
|
- Setting the option by hand in your configuration when using flakes.
|
||||||
|
- In all other cases, you'll need to set this option to `true` yourself.
|
||||||
|
- `boot.isNspawnContainer` being `true` implies [](#opt-boot.isContainer) being `true`.
|
||||||
|
|
||||||
- Due to [deprecation of gnome-session X11 support](https://blogs.gnome.org/alatiera/2025/06/08/the-x11-session-removal/), `services.desktopManager.pantheon` now defaults to pantheon-wayland session. The X11 session has been removed, see [this issue](https://github.com/elementary/session-settings/issues/91) for details.
|
- Due to [deprecation of gnome-session X11 support](https://blogs.gnome.org/alatiera/2025/06/08/the-x11-session-removal/), `services.desktopManager.pantheon` now defaults to pantheon-wayland session. The X11 session has been removed, see [this issue](https://github.com/elementary/session-settings/issues/91) for details.
|
||||||
|
|
||||||
|
|||||||
@@ -306,7 +306,7 @@ if ($virt eq "microsoft") {
|
|||||||
|
|
||||||
# Pull in NixOS configuration for containers.
|
# Pull in NixOS configuration for containers.
|
||||||
if ($virt eq "systemd-nspawn") {
|
if ($virt eq "systemd-nspawn") {
|
||||||
push @attrs, "boot.isContainer = true;";
|
push @attrs, "boot.isNspawnContainer = true;";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -40,6 +40,10 @@ in
|
|||||||
default = false;
|
default = false;
|
||||||
internal = true;
|
internal = true;
|
||||||
};
|
};
|
||||||
|
options.boot.isNspawnContainer = lib.mkOption {
|
||||||
|
default = false;
|
||||||
|
internal = true;
|
||||||
|
};
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
|
|||||||
@@ -545,6 +545,30 @@ in
|
|||||||
|
|
||||||
# Sync mount options with systemd's src/core/mount-setup.c: mount_table.
|
# Sync mount options with systemd's src/core/mount-setup.c: mount_table.
|
||||||
boot.specialFileSystems = {
|
boot.specialFileSystems = {
|
||||||
|
# To hold secrets that shouldn't be written to disk
|
||||||
|
"/run/keys" = {
|
||||||
|
fsType = "ramfs";
|
||||||
|
options = [
|
||||||
|
"nosuid"
|
||||||
|
"nodev"
|
||||||
|
"mode=750"
|
||||||
|
];
|
||||||
|
};
|
||||||
|
}
|
||||||
|
// optionalAttrs (!config.boot.isContainer) {
|
||||||
|
# systemd-nspawn populates /sys by itself, and remounting it causes all
|
||||||
|
# kinds of weird issues (most noticeably, waiting for host disk device
|
||||||
|
# nodes).
|
||||||
|
"/sys" = {
|
||||||
|
fsType = "sysfs";
|
||||||
|
options = [
|
||||||
|
"nosuid"
|
||||||
|
"noexec"
|
||||||
|
"nodev"
|
||||||
|
];
|
||||||
|
};
|
||||||
|
}
|
||||||
|
// optionalAttrs (!config.boot.isNspawnContainer) {
|
||||||
"/proc" = {
|
"/proc" = {
|
||||||
fsType = "proc";
|
fsType = "proc";
|
||||||
options = [
|
options = [
|
||||||
@@ -592,29 +616,6 @@ in
|
|||||||
"gid=${toString config.ids.gids.tty}"
|
"gid=${toString config.ids.gids.tty}"
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
|
|
||||||
# To hold secrets that shouldn't be written to disk
|
|
||||||
"/run/keys" = {
|
|
||||||
fsType = "ramfs";
|
|
||||||
options = [
|
|
||||||
"nosuid"
|
|
||||||
"nodev"
|
|
||||||
"mode=750"
|
|
||||||
];
|
|
||||||
};
|
|
||||||
}
|
|
||||||
// optionalAttrs (!config.boot.isContainer) {
|
|
||||||
# systemd-nspawn populates /sys by itself, and remounting it causes all
|
|
||||||
# kinds of weird issues (most noticeably, waiting for host disk device
|
|
||||||
# nodes).
|
|
||||||
"/sys" = {
|
|
||||||
fsType = "sysfs";
|
|
||||||
options = [
|
|
||||||
"nosuid"
|
|
||||||
"noexec"
|
|
||||||
"nodev"
|
|
||||||
];
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -509,13 +509,25 @@ in
|
|||||||
|
|
||||||
boot.isContainer = mkOption {
|
boot.isContainer = mkOption {
|
||||||
type = types.bool;
|
type = types.bool;
|
||||||
default = false;
|
default = config.boot.isNspawnContainer;
|
||||||
|
defaultText = "config.boot.isNspawnContainer";
|
||||||
description = ''
|
description = ''
|
||||||
Whether this NixOS machine is a lightweight container running
|
Whether this NixOS machine is a lightweight container running
|
||||||
in another NixOS system.
|
in another NixOS system.
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
|
|
||||||
|
boot.isNspawnContainer = mkOption {
|
||||||
|
type = types.bool;
|
||||||
|
default = false;
|
||||||
|
description = ''
|
||||||
|
Whether the machine is running in an nspawn container. This
|
||||||
|
option is added because [](#opt-boot.isContainer) is heavily used
|
||||||
|
for non-nspawn environments as well, hence nspawn-specific settings
|
||||||
|
are guarded by this option.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
boot.enableContainers = mkOption {
|
boot.enableContainers = mkOption {
|
||||||
type = types.bool;
|
type = types.bool;
|
||||||
default = config.containers != { };
|
default = config.containers != { };
|
||||||
@@ -558,7 +570,7 @@ in
|
|||||||
{ inherit (host.pkgs.stdenv) hostPlatform; }
|
{ inherit (host.pkgs.stdenv) hostPlatform; }
|
||||||
else
|
else
|
||||||
{ localSystem = host.pkgs.stdenv.hostPlatform; };
|
{ localSystem = host.pkgs.stdenv.hostPlatform; };
|
||||||
boot.isContainer = true;
|
boot.isNspawnContainer = true;
|
||||||
networking.hostName = mkDefault name;
|
networking.hostName = mkDefault name;
|
||||||
networking.useDHCP = false;
|
networking.useDHCP = false;
|
||||||
assertions = [
|
assertions = [
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ let
|
|||||||
{ config, ... }:
|
{ config, ... }:
|
||||||
{
|
{
|
||||||
# We re-use the NixOS container option ...
|
# We re-use the NixOS container option ...
|
||||||
boot.isContainer = true;
|
boot.isNspawnContainer = true;
|
||||||
# ... and revert unwanted defaults
|
# ... and revert unwanted defaults
|
||||||
networking.useHostResolvConf = false;
|
networking.useHostResolvConf = false;
|
||||||
|
|
||||||
@@ -98,11 +98,6 @@ in
|
|||||||
serviceConfig.Environment = [
|
serviceConfig.Environment = [
|
||||||
# Disable tmpfs for /tmp
|
# Disable tmpfs for /tmp
|
||||||
"SYSTEMD_NSPAWN_TMPFS_TMP=0"
|
"SYSTEMD_NSPAWN_TMPFS_TMP=0"
|
||||||
|
|
||||||
# force unified cgroup delegation, which would be the default
|
|
||||||
# if systemd could check the capabilities of the installed systemd.
|
|
||||||
# see also: https://github.com/NixOS/nixpkgs/pull/198526
|
|
||||||
"SYSTEMD_NSPAWN_UNIFIED_HIERARCHY=1"
|
|
||||||
];
|
];
|
||||||
overrideStrategy = "asDropin";
|
overrideStrategy = "asDropin";
|
||||||
};
|
};
|
||||||
@@ -152,7 +147,7 @@ in
|
|||||||
|
|
||||||
# Test if systemd-nspawn provides a working environment for nix to build derivations
|
# Test if systemd-nspawn provides a working environment for nix to build derivations
|
||||||
# https://nixos.org/guides/nix-pills/07-working-derivation
|
# https://nixos.org/guides/nix-pills/07-working-derivation
|
||||||
machine.succeed('systemd-run --pty --wait -M ${containerName} /run/current-system/sw/bin/nix-instantiate --expr \'derivation { name = "myname"; builder = "/bin/sh"; args = [ "-c" "echo foo > $out" ]; system = "${pkgs.system}"; }\' --add-root /tmp/drv')
|
machine.succeed('systemd-run --pty --wait -M ${containerName} /run/current-system/sw/bin/nix-instantiate --expr \'derivation { name = "myname"; builder = "/bin/sh"; args = [ "-c" "echo foo > $out" ]; system = "${pkgs.stdenv.hostPlatform.system}"; }\' --add-root /tmp/drv')
|
||||||
machine.succeed('systemd-run --pty --wait -M ${containerName} /run/current-system/sw/bin/nix-store --option substitute false --realize /tmp/drv')
|
machine.succeed('systemd-run --pty --wait -M ${containerName} /run/current-system/sw/bin/nix-store --option substitute false --realize /tmp/drv')
|
||||||
|
|
||||||
# Test nss_mymachines without nscd
|
# Test nss_mymachines without nscd
|
||||||
|
|||||||
@@ -8,6 +8,11 @@ use Fcntl ':flock';
|
|||||||
use Getopt::Long qw(:config gnu_getopt no_bundling);
|
use Getopt::Long qw(:config gnu_getopt no_bundling);
|
||||||
use Cwd 'abs_path';
|
use Cwd 'abs_path';
|
||||||
use Time::HiRes;
|
use Time::HiRes;
|
||||||
|
use IPC::Run 'run';
|
||||||
|
|
||||||
|
# Version::Compare et al. don't work because they do the wrong thing on e.g.
|
||||||
|
# 25.11pre-git.
|
||||||
|
my $nixpkgsLib = "@lib@";
|
||||||
|
|
||||||
my $nsenter = "@util-linux@/bin/nsenter";
|
my $nsenter = "@util-linux@/bin/nsenter";
|
||||||
my $su = "@su@";
|
my $su = "@su@";
|
||||||
@@ -171,7 +176,7 @@ sub writeNixOSConfig {
|
|||||||
my $nixosConfig = <<EOF;
|
my $nixosConfig = <<EOF;
|
||||||
{ config, lib, pkgs, ... }:
|
{ config, lib, pkgs, ... }:
|
||||||
|
|
||||||
{ boot.isContainer = true;
|
{ boot.isNspawnContainer = true;
|
||||||
networking.hostName = lib.mkDefault "$containerName";
|
networking.hostName = lib.mkDefault "$containerName";
|
||||||
networking.useDHCP = false;
|
networking.useDHCP = false;
|
||||||
$localExtraConfig
|
$localExtraConfig
|
||||||
@@ -368,6 +373,35 @@ sub runInContainer {
|
|||||||
die "cannot run ‘nsenter’: $!\n";
|
die "cannot run ‘nsenter’: $!\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sub evalAttribute {
|
||||||
|
my ($attribute, $nixosF, $nixosConfigF, $extraArgs) = @_;
|
||||||
|
run [
|
||||||
|
"nix-instantiate", $nixosF, "-I", "nixos-config=$nixosConfigF", "-A", $attribute, "--eval"
|
||||||
|
], ">", \my $result;
|
||||||
|
chomp $result;
|
||||||
|
$result =~ s/^"([^"]+)"$/$1/g;
|
||||||
|
return $result;
|
||||||
|
}
|
||||||
|
|
||||||
|
sub evalAttributeFlake {
|
||||||
|
my ($attribute) = @_;
|
||||||
|
run [
|
||||||
|
"nix", "eval", "$flake#nixosConfigurations.\"$flakeAttr\".$attribute"
|
||||||
|
], ">", \my $result;
|
||||||
|
chomp $result;
|
||||||
|
$result =~ s/^"([^"]+)"$/$1/g;
|
||||||
|
return $result;
|
||||||
|
}
|
||||||
|
|
||||||
|
sub isAtLeast2511 {
|
||||||
|
my ($version) = @_;
|
||||||
|
run [
|
||||||
|
"nix-instantiate", "--eval", "-E", "with import $nixpkgsLib; versionAtLeast \"$version\" \"25.11pre-git\""
|
||||||
|
], ">", \my $result;
|
||||||
|
chomp $result;
|
||||||
|
return $result eq "true";
|
||||||
|
}
|
||||||
|
|
||||||
# Remove a directory while recursively unmounting all mounted filesystems within
|
# Remove a directory while recursively unmounting all mounted filesystems within
|
||||||
# that directory and unmounting/removing that directory afterwards as well.
|
# that directory and unmounting/removing that directory afterwards as well.
|
||||||
#
|
#
|
||||||
@@ -426,6 +460,10 @@ elsif ($action eq "update") {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (defined $flake) {
|
if (defined $flake) {
|
||||||
|
my $nixpkgsVersion = evalAttributeFlake "lib.version";
|
||||||
|
if (isAtLeast2511($nixpkgsVersion) && evalAttributeFlake("config.boot.isNspawnContainer") ne "true") {
|
||||||
|
die "$0: on 25.11 and newer, containers require boot.isNspawnContainer=true. Please set this in $flake";
|
||||||
|
}
|
||||||
buildFlake();
|
buildFlake();
|
||||||
system("nix-env", "-p", "$profileDir/system", "--set", $systemPath) == 0
|
system("nix-env", "-p", "$profileDir/system", "--set", $systemPath) == 0
|
||||||
or die "$0: failed to set container configuration\n";
|
or die "$0: failed to set container configuration\n";
|
||||||
@@ -441,6 +479,14 @@ elsif ($action eq "update") {
|
|||||||
}
|
}
|
||||||
|
|
||||||
my $nixenvF = $nixosPath // "<nixpkgs/nixos>";
|
my $nixenvF = $nixosPath // "<nixpkgs/nixos>";
|
||||||
|
|
||||||
|
my $nixpkgsVersion = evalAttribute "pkgs.lib.version", $nixenvF, $nixosConfigFile;
|
||||||
|
if (isAtLeast2511($nixpkgsVersion)
|
||||||
|
&& evalAttribute("config.boot.isNspawnContainer", $nixenvF, $nixosConfigFile) ne "true"
|
||||||
|
) {
|
||||||
|
die "$0: on 25.11 and newer, containers require boot.isNspawnContainer=true. Refresh your configuration (or check the 25.11 release notes on how to correctly do that)";
|
||||||
|
}
|
||||||
|
|
||||||
system("nix-env", "-p", "$profileDir/system",
|
system("nix-env", "-p", "$profileDir/system",
|
||||||
"-I", "nixos-config=$nixosConfigFile", "-f", $nixenvF,
|
"-I", "nixos-config=$nixosConfigFile", "-f", $nixenvF,
|
||||||
"--set", "-A", "system", @nixFlags) == 0
|
"--set", "-A", "system", @nixFlags) == 0
|
||||||
|
|||||||
@@ -7,6 +7,7 @@
|
|||||||
configurationDirectory ? "/etc/nixos-containers",
|
configurationDirectory ? "/etc/nixos-containers",
|
||||||
stateDirectory ? "/var/lib/nixos-containers",
|
stateDirectory ? "/var/lib/nixos-containers",
|
||||||
nixosTests,
|
nixosTests,
|
||||||
|
path,
|
||||||
}:
|
}:
|
||||||
replaceVarsWith {
|
replaceVarsWith {
|
||||||
name = "nixos-container";
|
name = "nixos-container";
|
||||||
@@ -15,8 +16,12 @@ replaceVarsWith {
|
|||||||
src = ./nixos-container.pl;
|
src = ./nixos-container.pl;
|
||||||
|
|
||||||
replacements = {
|
replacements = {
|
||||||
perl = perl.withPackages (p: [ p.FileSlurp ]);
|
perl = perl.withPackages (p: [
|
||||||
|
p.FileSlurp
|
||||||
|
p.IPCRun
|
||||||
|
]);
|
||||||
su = "${shadow.su}/bin/su";
|
su = "${shadow.su}/bin/su";
|
||||||
|
lib = "${path + "/lib"}";
|
||||||
|
|
||||||
inherit configurationDirectory stateDirectory util-linux;
|
inherit configurationDirectory stateDirectory util-linux;
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user