Merge pull request #269970 from emilylange/nixos-containers-warning
nixos/containers: warn if containers are used but disabled
This commit is contained in:
commit
ecef65f019
1 changed files with 126 additions and 120 deletions
|
@ -771,141 +771,147 @@ in
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
config = mkIf (config.boot.enableContainers) (let
|
config = mkMerge [
|
||||||
|
{
|
||||||
|
warnings = optional (!config.boot.enableContainers && config.containers != {})
|
||||||
|
"containers.<name> is used, but boot.enableContainers is false. To use containers.<name>, set boot.enableContainers to true.";
|
||||||
|
}
|
||||||
|
|
||||||
unit = {
|
(mkIf (config.boot.enableContainers) (let
|
||||||
description = "Container '%i'";
|
unit = {
|
||||||
|
description = "Container '%i'";
|
||||||
|
|
||||||
unitConfig.RequiresMountsFor = "${stateDirectory}/%i";
|
unitConfig.RequiresMountsFor = "${stateDirectory}/%i";
|
||||||
|
|
||||||
path = [ pkgs.iproute2 ];
|
path = [ pkgs.iproute2 ];
|
||||||
|
|
||||||
environment = {
|
environment = {
|
||||||
root = "${stateDirectory}/%i";
|
root = "${stateDirectory}/%i";
|
||||||
INSTANCE = "%i";
|
INSTANCE = "%i";
|
||||||
|
};
|
||||||
|
|
||||||
|
preStart = preStartScript dummyConfig;
|
||||||
|
|
||||||
|
script = startScript dummyConfig;
|
||||||
|
|
||||||
|
postStart = postStartScript dummyConfig;
|
||||||
|
|
||||||
|
restartIfChanged = false;
|
||||||
|
|
||||||
|
serviceConfig = serviceDirectives dummyConfig;
|
||||||
};
|
};
|
||||||
|
in {
|
||||||
|
warnings =
|
||||||
|
(optional (config.virtualisation.containers.enable && versionOlder config.system.stateVersion "22.05") ''
|
||||||
|
Enabling both boot.enableContainers & virtualisation.containers on system.stateVersion < 22.05 is unsupported.
|
||||||
|
'');
|
||||||
|
|
||||||
preStart = preStartScript dummyConfig;
|
systemd.targets.multi-user.wants = [ "machines.target" ];
|
||||||
|
|
||||||
script = startScript dummyConfig;
|
systemd.services = listToAttrs (filter (x: x.value != null) (
|
||||||
|
# The generic container template used by imperative containers
|
||||||
|
[{ name = "container@"; value = unit; }]
|
||||||
|
# declarative containers
|
||||||
|
++ (mapAttrsToList (name: cfg: nameValuePair "container@${name}" (let
|
||||||
|
containerConfig = cfg // (
|
||||||
|
optionalAttrs cfg.enableTun
|
||||||
|
{
|
||||||
|
allowedDevices = cfg.allowedDevices
|
||||||
|
++ [ { node = "/dev/net/tun"; modifier = "rw"; } ];
|
||||||
|
additionalCapabilities = cfg.additionalCapabilities
|
||||||
|
++ [ "CAP_NET_ADMIN" ];
|
||||||
|
}
|
||||||
|
);
|
||||||
|
in
|
||||||
|
recursiveUpdate unit {
|
||||||
|
preStart = preStartScript containerConfig;
|
||||||
|
script = startScript containerConfig;
|
||||||
|
postStart = postStartScript containerConfig;
|
||||||
|
serviceConfig = serviceDirectives containerConfig;
|
||||||
|
unitConfig.RequiresMountsFor = lib.optional (!containerConfig.ephemeral) "${stateDirectory}/%i";
|
||||||
|
environment.root = if containerConfig.ephemeral then "/run/nixos-containers/%i" else "${stateDirectory}/%i";
|
||||||
|
} // (
|
||||||
|
optionalAttrs containerConfig.autoStart
|
||||||
|
{
|
||||||
|
wantedBy = [ "machines.target" ];
|
||||||
|
wants = [ "network.target" ];
|
||||||
|
after = [ "network.target" ];
|
||||||
|
restartTriggers = [
|
||||||
|
containerConfig.path
|
||||||
|
config.environment.etc."${configurationDirectoryName}/${name}.conf".source
|
||||||
|
];
|
||||||
|
restartIfChanged = containerConfig.restartIfChanged;
|
||||||
|
}
|
||||||
|
)
|
||||||
|
)) config.containers)
|
||||||
|
));
|
||||||
|
|
||||||
postStart = postStartScript dummyConfig;
|
# Generate a configuration file in /etc/nixos-containers for each
|
||||||
|
# container so that container@.target can get the container
|
||||||
restartIfChanged = false;
|
# configuration.
|
||||||
|
environment.etc =
|
||||||
serviceConfig = serviceDirectives dummyConfig;
|
let mkPortStr = p: p.protocol + ":" + (toString p.hostPort) + ":" + (if p.containerPort == null then toString p.hostPort else toString p.containerPort);
|
||||||
};
|
in mapAttrs' (name: cfg: nameValuePair "${configurationDirectoryName}/${name}.conf"
|
||||||
in {
|
{ text =
|
||||||
warnings =
|
''
|
||||||
(optional (config.virtualisation.containers.enable && versionOlder config.system.stateVersion "22.05") ''
|
SYSTEM_PATH=${cfg.path}
|
||||||
Enabling both boot.enableContainers & virtualisation.containers on system.stateVersion < 22.05 is unsupported.
|
${optionalString cfg.privateNetwork ''
|
||||||
'');
|
PRIVATE_NETWORK=1
|
||||||
|
${optionalString (cfg.hostBridge != null) ''
|
||||||
systemd.targets.multi-user.wants = [ "machines.target" ];
|
HOST_BRIDGE=${cfg.hostBridge}
|
||||||
|
''}
|
||||||
systemd.services = listToAttrs (filter (x: x.value != null) (
|
${optionalString (length cfg.forwardPorts > 0) ''
|
||||||
# The generic container template used by imperative containers
|
HOST_PORT=${concatStringsSep "," (map mkPortStr cfg.forwardPorts)}
|
||||||
[{ name = "container@"; value = unit; }]
|
''}
|
||||||
# declarative containers
|
${optionalString (cfg.hostAddress != null) ''
|
||||||
++ (mapAttrsToList (name: cfg: nameValuePair "container@${name}" (let
|
HOST_ADDRESS=${cfg.hostAddress}
|
||||||
containerConfig = cfg // (
|
''}
|
||||||
optionalAttrs cfg.enableTun
|
${optionalString (cfg.hostAddress6 != null) ''
|
||||||
{
|
HOST_ADDRESS6=${cfg.hostAddress6}
|
||||||
allowedDevices = cfg.allowedDevices
|
''}
|
||||||
++ [ { node = "/dev/net/tun"; modifier = "rw"; } ];
|
${optionalString (cfg.localAddress != null) ''
|
||||||
additionalCapabilities = cfg.additionalCapabilities
|
LOCAL_ADDRESS=${cfg.localAddress}
|
||||||
++ [ "CAP_NET_ADMIN" ];
|
''}
|
||||||
}
|
${optionalString (cfg.localAddress6 != null) ''
|
||||||
);
|
LOCAL_ADDRESS6=${cfg.localAddress6}
|
||||||
in
|
''}
|
||||||
recursiveUpdate unit {
|
|
||||||
preStart = preStartScript containerConfig;
|
|
||||||
script = startScript containerConfig;
|
|
||||||
postStart = postStartScript containerConfig;
|
|
||||||
serviceConfig = serviceDirectives containerConfig;
|
|
||||||
unitConfig.RequiresMountsFor = lib.optional (!containerConfig.ephemeral) "${stateDirectory}/%i";
|
|
||||||
environment.root = if containerConfig.ephemeral then "/run/nixos-containers/%i" else "${stateDirectory}/%i";
|
|
||||||
} // (
|
|
||||||
optionalAttrs containerConfig.autoStart
|
|
||||||
{
|
|
||||||
wantedBy = [ "machines.target" ];
|
|
||||||
wants = [ "network.target" ];
|
|
||||||
after = [ "network.target" ];
|
|
||||||
restartTriggers = [
|
|
||||||
containerConfig.path
|
|
||||||
config.environment.etc."${configurationDirectoryName}/${name}.conf".source
|
|
||||||
];
|
|
||||||
restartIfChanged = containerConfig.restartIfChanged;
|
|
||||||
}
|
|
||||||
)
|
|
||||||
)) config.containers)
|
|
||||||
));
|
|
||||||
|
|
||||||
# Generate a configuration file in /etc/nixos-containers for each
|
|
||||||
# container so that container@.target can get the container
|
|
||||||
# configuration.
|
|
||||||
environment.etc =
|
|
||||||
let mkPortStr = p: p.protocol + ":" + (toString p.hostPort) + ":" + (if p.containerPort == null then toString p.hostPort else toString p.containerPort);
|
|
||||||
in mapAttrs' (name: cfg: nameValuePair "${configurationDirectoryName}/${name}.conf"
|
|
||||||
{ text =
|
|
||||||
''
|
|
||||||
SYSTEM_PATH=${cfg.path}
|
|
||||||
${optionalString cfg.privateNetwork ''
|
|
||||||
PRIVATE_NETWORK=1
|
|
||||||
${optionalString (cfg.hostBridge != null) ''
|
|
||||||
HOST_BRIDGE=${cfg.hostBridge}
|
|
||||||
''}
|
''}
|
||||||
${optionalString (length cfg.forwardPorts > 0) ''
|
INTERFACES="${toString cfg.interfaces}"
|
||||||
HOST_PORT=${concatStringsSep "," (map mkPortStr cfg.forwardPorts)}
|
MACVLANS="${toString cfg.macvlans}"
|
||||||
|
${optionalString cfg.autoStart ''
|
||||||
|
AUTO_START=1
|
||||||
''}
|
''}
|
||||||
${optionalString (cfg.hostAddress != null) ''
|
EXTRA_NSPAWN_FLAGS="${mkBindFlags cfg.bindMounts +
|
||||||
HOST_ADDRESS=${cfg.hostAddress}
|
optionalString (cfg.extraFlags != [])
|
||||||
''}
|
(" " + concatStringsSep " " cfg.extraFlags)}"
|
||||||
${optionalString (cfg.hostAddress6 != null) ''
|
'';
|
||||||
HOST_ADDRESS6=${cfg.hostAddress6}
|
}) config.containers;
|
||||||
''}
|
|
||||||
${optionalString (cfg.localAddress != null) ''
|
|
||||||
LOCAL_ADDRESS=${cfg.localAddress}
|
|
||||||
''}
|
|
||||||
${optionalString (cfg.localAddress6 != null) ''
|
|
||||||
LOCAL_ADDRESS6=${cfg.localAddress6}
|
|
||||||
''}
|
|
||||||
''}
|
|
||||||
INTERFACES="${toString cfg.interfaces}"
|
|
||||||
MACVLANS="${toString cfg.macvlans}"
|
|
||||||
${optionalString cfg.autoStart ''
|
|
||||||
AUTO_START=1
|
|
||||||
''}
|
|
||||||
EXTRA_NSPAWN_FLAGS="${mkBindFlags cfg.bindMounts +
|
|
||||||
optionalString (cfg.extraFlags != [])
|
|
||||||
(" " + concatStringsSep " " cfg.extraFlags)}"
|
|
||||||
'';
|
|
||||||
}) config.containers;
|
|
||||||
|
|
||||||
# Generate /etc/hosts entries for the containers.
|
# Generate /etc/hosts entries for the containers.
|
||||||
networking.extraHosts = concatStrings (mapAttrsToList (name: cfg: optionalString (cfg.localAddress != null)
|
networking.extraHosts = concatStrings (mapAttrsToList (name: cfg: optionalString (cfg.localAddress != null)
|
||||||
''
|
''
|
||||||
${head (splitString "/" cfg.localAddress)} ${name}.containers
|
${head (splitString "/" cfg.localAddress)} ${name}.containers
|
||||||
'') config.containers);
|
'') config.containers);
|
||||||
|
|
||||||
networking.dhcpcd.denyInterfaces = [ "ve-*" "vb-*" ];
|
networking.dhcpcd.denyInterfaces = [ "ve-*" "vb-*" ];
|
||||||
|
|
||||||
services.udev.extraRules = optionalString config.networking.networkmanager.enable ''
|
services.udev.extraRules = optionalString config.networking.networkmanager.enable ''
|
||||||
# Don't manage interfaces created by nixos-container.
|
# Don't manage interfaces created by nixos-container.
|
||||||
ENV{INTERFACE}=="v[eb]-*", ENV{NM_UNMANAGED}="1"
|
ENV{INTERFACE}=="v[eb]-*", ENV{NM_UNMANAGED}="1"
|
||||||
'';
|
'';
|
||||||
|
|
||||||
environment.systemPackages = [
|
environment.systemPackages = [
|
||||||
nixos-container
|
nixos-container
|
||||||
];
|
];
|
||||||
|
|
||||||
boot.kernelModules = [
|
boot.kernelModules = [
|
||||||
"bridge"
|
"bridge"
|
||||||
"macvlan"
|
"macvlan"
|
||||||
"tap"
|
"tap"
|
||||||
"tun"
|
"tun"
|
||||||
];
|
];
|
||||||
});
|
}))
|
||||||
|
];
|
||||||
|
|
||||||
meta.buildDocsInSandbox = false;
|
meta.buildDocsInSandbox = false;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue