diff options
Diffstat (limited to 'nixos/modules/system')
27 files changed, 406 insertions, 182 deletions
diff --git a/nixos/modules/system/activation/activatable-system.nix b/nixos/modules/system/activation/activatable-system.nix index 7f6154794bd8d..3d941596747bf 100644 --- a/nixos/modules/system/activation/activatable-system.nix +++ b/nixos/modules/system/activation/activatable-system.nix @@ -1,52 +1,16 @@ -{ config, lib, pkgs, ... }: +{ options, config, lib, pkgs, ... }: let inherit (lib) mkOption - optionalString types ; - perlWrapped = pkgs.perl.withPackages (p: with p; [ ConfigIniFiles FileSlurp ]); - systemBuilderArgs = { activationScript = config.system.activationScripts.script; dryActivationScript = config.system.dryActivationScript; }; - systemBuilderCommands = '' - echo "$activationScript" > $out/activate - echo "$dryActivationScript" > $out/dry-activate - substituteInPlace $out/activate --subst-var-by out ''${!toplevelVar} - substituteInPlace $out/dry-activate --subst-var-by out ''${!toplevelVar} - chmod u+x $out/activate $out/dry-activate - unset activationScript dryActivationScript - - mkdir $out/bin - substitute ${./switch-to-configuration.pl} $out/bin/switch-to-configuration \ - --subst-var out \ - --subst-var-by toplevel ''${!toplevelVar} \ - --subst-var-by coreutils "${pkgs.coreutils}" \ - --subst-var-by distroId ${lib.escapeShellArg config.system.nixos.distroId} \ - --subst-var-by installBootLoader ${lib.escapeShellArg config.system.build.installBootLoader} \ - --subst-var-by localeArchive "${config.i18n.glibcLocales}/lib/locale/locale-archive" \ - --subst-var-by perl "${perlWrapped}" \ - --subst-var-by shell "${pkgs.bash}/bin/sh" \ - --subst-var-by su "${pkgs.shadow.su}/bin/su" \ - --subst-var-by systemd "${config.systemd.package}" \ - --subst-var-by utillinux "${pkgs.util-linux}" \ - ; - - chmod +x $out/bin/switch-to-configuration - ${optionalString (pkgs.stdenv.hostPlatform == pkgs.stdenv.buildPlatform) '' - if ! output=$(${perlWrapped}/bin/perl -c $out/bin/switch-to-configuration 2>&1); then - echo "switch-to-configuration syntax is not valid:" - echo "$output" - exit 1 - fi - ''} - ''; - in { options = { @@ -60,6 +24,18 @@ in do, but for image based systems, this may not be needed or not be desirable. ''; }; + system.activatableSystemBuilderCommands = options.system.systemBuilderCommands // { + description = lib.mdDoc '' + Like `system.systemBuilderCommands`, but only for the commands that are + needed *both* when the system is activatable and when it isn't. + + Disclaimer: This option might go away in the future. It might be + superseded by separating switch-to-configuration into a separate script + which will make this option superfluous. See + https://github.com/NixOS/nixpkgs/pull/263462#discussion_r1373104845 for + a discussion. + ''; + }; system.build.separateActivationScript = mkOption { type = types.package; description = '' @@ -71,7 +47,18 @@ in }; }; config = { - system.systemBuilderCommands = lib.mkIf config.system.activatable systemBuilderCommands; + system.activatableSystemBuilderCommands = '' + echo "$activationScript" > $out/activate + echo "$dryActivationScript" > $out/dry-activate + substituteInPlace $out/activate --subst-var-by out ''${!toplevelVar} + substituteInPlace $out/dry-activate --subst-var-by out ''${!toplevelVar} + chmod u+x $out/activate $out/dry-activate + unset activationScript dryActivationScript + ''; + + system.systemBuilderCommands = lib.mkIf + config.system.activatable + config.system.activatableSystemBuilderCommands; system.systemBuilderArgs = lib.mkIf config.system.activatable (systemBuilderArgs // { toplevelVar = "out"; @@ -86,7 +73,7 @@ in }) '' mkdir $out - ${systemBuilderCommands} + ${config.system.activatableSystemBuilderCommands} ''; }; } diff --git a/nixos/modules/system/activation/activation-script.nix b/nixos/modules/system/activation/activation-script.nix index c8407dd6779a3..bc0b7266ce959 100644 --- a/nixos/modules/system/activation/activation-script.nix +++ b/nixos/modules/system/activation/activation-script.nix @@ -55,10 +55,6 @@ let # used as a garbage collection root. ln -sfn "$(readlink -f "$systemConfig")" /run/current-system - # Prevent the current configuration from being garbage-collected. - mkdir -p /nix/var/nix/gcroots - ln -sfn /run/current-system /nix/var/nix/gcroots/current-system - exit $_status ''; @@ -233,23 +229,15 @@ in config = { system.activationScripts.stdio = ""; # obsolete + system.activationScripts.var = ""; # obsolete - system.activationScripts.var = - '' - # Various log/runtime directories. - - mkdir -p /var/tmp - chmod 1777 /var/tmp - - # Empty, immutable home directory of many system accounts. - mkdir -p /var/empty - # Make sure it's really empty - ${pkgs.e2fsprogs}/bin/chattr -f -i /var/empty || true - find /var/empty -mindepth 1 -delete - chmod 0555 /var/empty - chown root:root /var/empty - ${pkgs.e2fsprogs}/bin/chattr -f +i /var/empty || true - ''; + systemd.tmpfiles.rules = [ + # Prevent the current configuration from being garbage-collected. + "d /nix/var/nix/gcroots -" + "L+ /nix/var/nix/gcroots/current-system - - - - /run/current-system" + "D /var/empty 0555 root root -" + "h /var/empty - - - - +i" + ]; system.activationScripts.usrbinenv = if config.environment.usrbinenv != null then '' diff --git a/nixos/modules/system/activation/bootspec.nix b/nixos/modules/system/activation/bootspec.nix index 9e1fa309d5db0..98c234bc340d0 100644 --- a/nixos/modules/system/activation/bootspec.nix +++ b/nixos/modules/system/activation/bootspec.nix @@ -79,7 +79,7 @@ in // { default = true; internal = true; }; enableValidation = lib.mkEnableOption (lib.mdDoc ''the validation of bootspec documents for each build. This will introduce Go in the build-time closure as we are relying on [Cuelang](https://cuelang.org/) for schema validation. - Enable this option if you want to ascertain that your documents are correct. + Enable this option if you want to ascertain that your documents are correct '' ); diff --git a/nixos/modules/system/activation/switch-to-configuration.pl b/nixos/modules/system/activation/switch-to-configuration.pl index e05f89bb0fb4b..e2f66a287bc4f 100755 --- a/nixos/modules/system/activation/switch-to-configuration.pl +++ b/nixos/modules/system/activation/switch-to-configuration.pl @@ -22,6 +22,7 @@ use JSON::PP; use IPC::Cmd; use Sys::Syslog qw(:standard :macros); use Cwd qw(abs_path); +use Fcntl ':flock'; ## no critic(ControlStructures::ProhibitDeepNests) ## no critic(ErrorHandling::RequireCarping) @@ -91,6 +92,8 @@ if (!-f "/etc/NIXOS" && (read_file("/etc/os-release", err_mode => "quiet") // "" } make_path("/run/nixos", { mode => oct(755) }); +open(my $stc_lock, '>>', '/run/nixos/switch-to-configuration.lock') or die "Could not open lock - $!"; +flock($stc_lock, LOCK_EX) or die "Could not acquire lock - $!"; openlog("nixos", "", LOG_USER); # Install or update the bootloader. @@ -599,7 +602,9 @@ while (my ($unit, $state) = each(%{$active_cur})) { $units_to_start{$unit} = 1; record_unit($start_list_file, $unit); # Don't spam the user with target units that always get started. - $units_to_filter{$unit} = 1; + if (($ENV{"STC_DISPLAY_ALL_UNITS"} // "") ne "1") { + $units_to_filter{$unit} = 1; + } } } @@ -983,4 +988,5 @@ if ($res == 0) { syslog(LOG_ERR, "switching to system configuration $toplevel failed (status $res)"); } +close($stc_lock) or die "Could not close lock - $!"; exit($res); diff --git a/nixos/modules/system/activation/switchable-system.nix b/nixos/modules/system/activation/switchable-system.nix new file mode 100644 index 0000000000000..00bc18e48d1fb --- /dev/null +++ b/nixos/modules/system/activation/switchable-system.nix @@ -0,0 +1,55 @@ +{ config, lib, pkgs, ... }: + +let + + perlWrapped = pkgs.perl.withPackages (p: with p; [ ConfigIniFiles FileSlurp ]); + +in + +{ + + options = { + system.switch.enable = lib.mkOption { + type = lib.types.bool; + default = true; + description = lib.mdDoc '' + Whether to include the capability to switch configurations. + + Disabling this makes the system unable to be reconfigured via `nixos-rebuild`. + + This is good for image based appliances where updates are handled + outside the image. Reducing features makes the image lighter and + slightly more secure. + ''; + }; + }; + + config = lib.mkIf config.system.switch.enable { + system.activatableSystemBuilderCommands = '' + mkdir $out/bin + substitute ${./switch-to-configuration.pl} $out/bin/switch-to-configuration \ + --subst-var out \ + --subst-var-by toplevel ''${!toplevelVar} \ + --subst-var-by coreutils "${pkgs.coreutils}" \ + --subst-var-by distroId ${lib.escapeShellArg config.system.nixos.distroId} \ + --subst-var-by installBootLoader ${lib.escapeShellArg config.system.build.installBootLoader} \ + --subst-var-by localeArchive "${config.i18n.glibcLocales}/lib/locale/locale-archive" \ + --subst-var-by perl "${perlWrapped}" \ + --subst-var-by shell "${pkgs.bash}/bin/sh" \ + --subst-var-by su "${pkgs.shadow.su}/bin/su" \ + --subst-var-by systemd "${config.systemd.package}" \ + --subst-var-by utillinux "${pkgs.util-linux}" \ + ; + + chmod +x $out/bin/switch-to-configuration + ${lib.optionalString (pkgs.stdenv.hostPlatform == pkgs.stdenv.buildPlatform) '' + if ! output=$(${perlWrapped}/bin/perl -c $out/bin/switch-to-configuration 2>&1); then + echo "switch-to-configuration syntax is not valid:" + echo "$output" + exit 1 + fi + ''} + ''; + }; + +} diff --git a/nixos/modules/system/boot/binfmt.nix b/nixos/modules/system/boot/binfmt.nix index 8c9483f01c102..d16152ab9dec5 100644 --- a/nixos/modules/system/boot/binfmt.nix +++ b/nixos/modules/system/boot/binfmt.nix @@ -20,17 +20,13 @@ let optionalString fixBinary "F"; in ":${name}:${type}:${offset'}:${magicOrExtension}:${mask'}:${interpreter}:${flags}"; - activationSnippet = name: { interpreter, wrapInterpreterInShell, ... }: if wrapInterpreterInShell then '' - rm -f /run/binfmt/${name} - cat > /run/binfmt/${name} << 'EOF' - #!${pkgs.bash}/bin/sh - exec -- ${interpreter} "$@" - EOF - chmod +x /run/binfmt/${name} - '' else '' - rm -f /run/binfmt/${name} - ln -s ${interpreter} /run/binfmt/${name} - ''; + mkInterpreter = name: { interpreter, wrapInterpreterInShell, ... }: + if wrapInterpreterInShell + then pkgs.writeShellScript "${name}-interpreter" '' + #!${pkgs.bash}/bin/sh + exec -- ${interpreter} "$@" + '' + else interpreter; getEmulator = system: (lib.systems.elaborate { inherit system; }).emulator pkgs; getQemuArch = system: (lib.systems.elaborate { inherit system; }).qemuArch; @@ -318,18 +314,25 @@ in { environment.etc."binfmt.d/nixos.conf".source = builtins.toFile "binfmt_nixos.conf" (lib.concatStringsSep "\n" (lib.mapAttrsToList makeBinfmtLine config.boot.binfmt.registrations)); - system.activationScripts.binfmt = stringAfter [ "specialfs" ] '' - mkdir -p /run/binfmt - chmod 0755 /run/binfmt - ${lib.concatStringsSep "\n" (lib.mapAttrsToList activationSnippet config.boot.binfmt.registrations)} - ''; - systemd = lib.mkIf (config.boot.binfmt.registrations != {}) { - additionalUpstreamSystemUnits = [ - "proc-sys-fs-binfmt_misc.automount" - "proc-sys-fs-binfmt_misc.mount" - "systemd-binfmt.service" - ]; - services.systemd-binfmt.restartTriggers = [ (builtins.toJSON config.boot.binfmt.registrations) ]; - }; + + systemd = lib.mkMerge [ + ({ tmpfiles.rules = [ + "d /run/binfmt 0755 -" + ] ++ lib.mapAttrsToList + (name: interpreter: + "L+ /run/binfmt/${name} - - - - ${interpreter}" + ) + (lib.mapAttrs mkInterpreter config.boot.binfmt.registrations); + }) + + (lib.mkIf (config.boot.binfmt.registrations != {}) { + additionalUpstreamSystemUnits = [ + "proc-sys-fs-binfmt_misc.automount" + "proc-sys-fs-binfmt_misc.mount" + "systemd-binfmt.service" + ]; + services.systemd-binfmt.restartTriggers = [ (builtins.toJSON config.boot.binfmt.registrations) ]; + }) + ]; }; } diff --git a/nixos/modules/system/boot/grow-partition.nix b/nixos/modules/system/boot/grow-partition.nix index a2764187a5333..897602f9826ab 100644 --- a/nixos/modules/system/boot/grow-partition.nix +++ b/nixos/modules/system/boot/grow-partition.nix @@ -12,33 +12,32 @@ with lib; ]; options = { - boot.growPartition = mkEnableOption (lib.mdDoc "grow the root partition on boot"); + boot.growPartition = mkEnableOption (lib.mdDoc "growing the root partition on boot"); }; config = mkIf config.boot.growPartition { - - assertions = [{ - assertion = !config.boot.initrd.systemd.enable; - message = "systemd stage 1 does not support 'boot.growPartition' yet."; - }]; - - boot.initrd.extraUtilsCommands = '' - copy_bin_and_libs ${pkgs.gawk}/bin/gawk - copy_bin_and_libs ${pkgs.gnused}/bin/sed - copy_bin_and_libs ${pkgs.util-linux}/sbin/sfdisk - copy_bin_and_libs ${pkgs.util-linux}/sbin/lsblk - - substitute "${pkgs.cloud-utils.guest}/bin/.growpart-wrapped" "$out/bin/growpart" \ - --replace "${pkgs.bash}/bin/sh" "/bin/sh" \ - --replace "awk" "gawk" \ - --replace "sed" "gnused" - - ln -s sed $out/bin/gnused - ''; - - boot.initrd.postDeviceCommands = '' - rootDevice="${config.fileSystems."/".device}" - if waitDevice "$rootDevice"; then + assertions = [ + { + assertion = !config.boot.initrd.systemd.repart.enable && !config.systemd.repart.enable; + message = "systemd-repart already grows the root partition and thus you should not use boot.growPartition"; + } + ]; + systemd.services.growpart = { + wantedBy = [ "-.mount" ]; + after = [ "-.mount" ]; + before = [ "systemd-growfs-root.service" ]; + conflicts = [ "shutdown.target" ]; + unitConfig.DefaultDependencies = false; + serviceConfig = { + Type = "oneshot"; + RemainAfterExit = true; + TimeoutSec = "infinity"; + # growpart returns 1 if the partition is already grown + SuccessExitStatus = "0 1"; + }; + + script = '' + rootDevice="${config.fileSystems."/".device}" rootDevice="$(readlink -f "$rootDevice")" parentDevice="$rootDevice" while [ "''${parentDevice%[0-9]}" != "''${parentDevice}" ]; do @@ -48,11 +47,8 @@ with lib; if [ "''${parentDevice%[0-9]p}" != "''${parentDevice}" ] && [ -b "''${parentDevice%p}" ]; then parentDevice="''${parentDevice%p}" fi - TMPDIR=/run sh $(type -P growpart) "$parentDevice" "$partNum" - udevadm settle - fi - ''; - + "${pkgs.cloud-utils.guest}/bin/growpart" "$parentDevice" "$partNum" + ''; + }; }; - } diff --git a/nixos/modules/system/boot/initrd-network.nix b/nixos/modules/system/boot/initrd-network.nix index 1d95742face34..88ba43caf0030 100644 --- a/nixos/modules/system/boot/initrd-network.nix +++ b/nixos/modules/system/boot/initrd-network.nix @@ -80,7 +80,7 @@ in }; boot.initrd.network.udhcpc.enable = mkOption { - default = config.networking.useDHCP; + default = config.networking.useDHCP && !config.boot.initrd.systemd.enable; defaultText = "networking.useDHCP"; type = types.bool; description = lib.mdDoc '' @@ -116,11 +116,11 @@ in boot.initrd.kernelModules = [ "af_packet" ]; - boot.initrd.extraUtilsCommands = '' + boot.initrd.extraUtilsCommands = mkIf (!config.boot.initrd.systemd.enable) '' copy_bin_and_libs ${pkgs.klibc}/lib/klibc/bin.static/ipconfig ''; - boot.initrd.preLVMCommands = mkBefore ( + boot.initrd.preLVMCommands = mkIf (!config.boot.initrd.systemd.enable) (mkBefore ( # Search for interface definitions in command line. '' ifaces="" @@ -138,7 +138,7 @@ in # Bring up all interfaces. for iface in ${dhcpIfShellExpr}; do echo "bringing up network interface $iface..." - ip link set "$iface" up && ifaces="$ifaces $iface" + ip link set dev "$iface" up && ifaces="$ifaces $iface" done # Acquire DHCP leases. @@ -148,12 +148,12 @@ in done '' - + cfg.postCommands); + + cfg.postCommands)); - boot.initrd.postMountCommands = mkIf cfg.flushBeforeStage2 '' + boot.initrd.postMountCommands = mkIf (cfg.flushBeforeStage2 && !config.boot.initrd.systemd.enable) '' for iface in $ifaces; do - ip address flush "$iface" - ip link set "$iface" down + ip address flush dev "$iface" + ip link set dev "$iface" down done ''; diff --git a/nixos/modules/system/boot/initrd-ssh.nix b/nixos/modules/system/boot/initrd-ssh.nix index 60c5ff62ffff0..a8cd2e8f05fcc 100644 --- a/nixos/modules/system/boot/initrd-ssh.nix +++ b/nixos/modules/system/boot/initrd-ssh.nix @@ -164,13 +164,12 @@ in for instructions. ''; } - - { - assertion = config.boot.initrd.systemd.enable -> cfg.shell == null; - message = "systemd stage 1 does not support boot.initrd.network.ssh.shell"; - } ]; + warnings = lib.optional (config.boot.initrd.systemd.enable && cfg.shell != null) '' + Please set 'boot.initrd.systemd.users.root.shell' instead of 'boot.initrd.network.ssh.shell' + ''; + boot.initrd.extraUtilsCommands = mkIf (!config.boot.initrd.systemd.enable) '' copy_bin_and_libs ${package}/bin/sshd cp -pv ${pkgs.glibc.out}/lib/libnss_files.so.* $out/lib @@ -235,6 +234,8 @@ in users.sshd = { uid = 1; group = "sshd"; }; groups.sshd = { gid = 1; }; + users.root.shell = mkIf (config.boot.initrd.network.ssh.shell != null) config.boot.initrd.network.ssh.shell; + contents."/etc/ssh/authorized_keys.d/root".text = concatStringsSep "\n" config.boot.initrd.network.ssh.authorizedKeys; contents."/etc/ssh/sshd_config".text = sshdConfig; diff --git a/nixos/modules/system/boot/kernel.nix b/nixos/modules/system/boot/kernel.nix index 9ea6119196761..a46331ccd431d 100644 --- a/nixos/modules/system/boot/kernel.nix +++ b/nixos/modules/system/boot/kernel.nix @@ -96,8 +96,8 @@ in # (required, but can be null if only config changes # are needed) - extraStructuredConfig = { # attrset of extra configuration parameters - FOO = lib.kernel.yes; # (without the CONFIG_ prefix, optional) + extraStructuredConfig = { # attrset of extra configuration parameters without the CONFIG_ prefix + FOO = lib.kernel.yes; # (optional) }; # values should generally be lib.kernel.yes, # lib.kernel.no or lib.kernel.module @@ -105,8 +105,9 @@ in foo = true; # (may be checked by other NixOS modules, optional) }; - extraConfig = "CONFIG_FOO y"; # extra configuration options in string form - # (deprecated, use extraStructuredConfig instead, optional) + extraConfig = "FOO y"; # extra configuration options in string form without the CONFIG_ prefix + # (optional, multiple lines allowed to specify multiple options) + # (deprecated, use extraStructuredConfig instead) } ``` @@ -269,6 +270,9 @@ in "ata_piix" "pata_marvell" + # NVMe + "nvme" + # Standard SCSI stuff. "sd_mod" "sr_mod" diff --git a/nixos/modules/system/boot/loader/external/external.nix b/nixos/modules/system/boot/loader/external/external.nix index 926cbd2b4b3f3..78982356a9ea8 100644 --- a/nixos/modules/system/boot/loader/external/external.nix +++ b/nixos/modules/system/boot/loader/external/external.nix @@ -12,7 +12,7 @@ in }; options.boot.loader.external = { - enable = mkEnableOption (lib.mdDoc "use an external tool to install your bootloader"); + enable = mkEnableOption (lib.mdDoc "using an external tool to install your bootloader"); installHook = mkOption { type = with types; path; diff --git a/nixos/modules/system/boot/loader/generic-extlinux-compatible/default.nix b/nixos/modules/system/boot/loader/generic-extlinux-compatible/default.nix index 5ef3c5cd52a80..13df609071168 100644 --- a/nixos/modules/system/boot/loader/generic-extlinux-compatible/default.nix +++ b/nixos/modules/system/boot/loader/generic-extlinux-compatible/default.nix @@ -25,7 +25,7 @@ in under `/boot/extlinux.conf`. For instance, U-Boot's generic distro boot support uses this file format. - See [U-boot's documentation](http://git.denx.de/?p=u-boot.git;a=blob;f=doc/README.distro;hb=refs/heads/master) + See [U-boot's documentation](https://u-boot.readthedocs.io/en/latest/develop/distro.html) for more information. ''; }; diff --git a/nixos/modules/system/boot/loader/grub/grub.nix b/nixos/modules/system/boot/loader/grub/grub.nix index 468f701ae5bc7..7097e1d83dca9 100644 --- a/nixos/modules/system/boot/loader/grub/grub.nix +++ b/nixos/modules/system/boot/loader/grub/grub.nix @@ -339,7 +339,7 @@ in See the [ GRUB source code - ](http://git.savannah.gnu.org/cgit/grub.git/tree/grub-core/commands/nativedisk.c?h=grub-2.04#n326) + ](https://git.savannah.gnu.org/cgit/grub.git/tree/grub-core/commands/nativedisk.c?h=grub-2.04#n326) for which disk modules are available. The list elements are passed directly as `argv` diff --git a/nixos/modules/system/boot/loader/systemd-boot/systemd-boot.nix b/nixos/modules/system/boot/loader/systemd-boot/systemd-boot.nix index 6f0a62d0ea899..1086ab80b14f1 100644 --- a/nixos/modules/system/boot/loader/systemd-boot/systemd-boot.nix +++ b/nixos/modules/system/boot/loader/systemd-boot/systemd-boot.nix @@ -67,6 +67,8 @@ let ''; in { + meta.maintainers = with lib.maintainers; [ julienmalka ]; + imports = [ (mkRenamedOptionModule [ "boot" "loader" "gummiboot" "enable" ] [ "boot" "loader" "systemd-boot" "enable" ]) ]; diff --git a/nixos/modules/system/boot/luksroot.nix b/nixos/modules/system/boot/luksroot.nix index 06c329e006b84..ca560d63f3bdc 100644 --- a/nixos/modules/system/boot/luksroot.nix +++ b/nixos/modules/system/boot/luksroot.nix @@ -537,7 +537,7 @@ in description = lib.mdDoc '' Unless enabled, encryption keys can be easily recovered by an attacker with physical access to any machine with PCMCIA, ExpressCard, ThunderBolt or FireWire port. - More information is available at <http://en.wikipedia.org/wiki/DMA_attack>. + More information is available at <https://en.wikipedia.org/wiki/DMA_attack>. This option blacklists FireWire drivers, but doesn't remove them. You can manually load the drivers if you need to use a FireWire device, but don't forget to unload them! diff --git a/nixos/modules/system/boot/networkd.nix b/nixos/modules/system/boot/networkd.nix index a5084260daab9..b7ced5b0d3466 100644 --- a/nixos/modules/system/boot/networkd.nix +++ b/nixos/modules/system/boot/networkd.nix @@ -159,6 +159,7 @@ let "geneve" "l2tp" "macsec" + "wlan" "vrf" "vcan" "vxcan" @@ -468,6 +469,30 @@ let (assertMinimum "Table" 0) ]; + sectionWLAN = checkUnitConfig "WLAN" [ + (assertOnlyFields [ + "PhysicalDevice" # systemd supports both strings ("phy0") and indexes (0) here. + "Type" + "WDS" + ]) + # See https://github.com/systemd/systemd/blob/main/src/basic/linux/nl80211.h#L3382 + (assertValueOneOf "Type" [ + "ad-hoc" + "station" + "ap" + "ap-vlan" + "wds" + "monitor" + "mesh-point" + "p2p-client" + "p2p-go" + "p2p-device" + "ocb" + "nan" + ]) + (assertValueOneOf "WDS" boolValues) + ]; + sectionBatmanAdvanced = checkUnitConfig "BatmanAdvanced" [ (assertOnlyFields [ "GatewayMode" @@ -995,7 +1020,7 @@ let "MulticastToUnicast" "NeighborSuppression" "Learning" - "Hairpin" + "HairPin" "Isolated" "UseBPDU" "FastLeave" @@ -1011,7 +1036,7 @@ let (assertValueOneOf "MulticastToUnicast" boolValues) (assertValueOneOf "NeighborSuppression" boolValues) (assertValueOneOf "Learning" boolValues) - (assertValueOneOf "Hairpin" boolValues) + (assertValueOneOf "HairPin" boolValues) (assertValueOneOf "Isolated" boolValues) (assertValueOneOf "UseBPDU" boolValues) (assertValueOneOf "FastLeave" boolValues) @@ -1779,6 +1804,16 @@ let ''; }; + wlanConfig = mkOption { + default = {}; + example = { PhysicalDevice = 0; Type = "station"; }; + type = types.addCheck (types.attrsOf unitOption) check.netdev.sectionWLAN; + description = lib.mdDoc '' + Each attribute in this set specifies an option in the `[WLAN]` section of the unit. + See {manpage}`systemd.netdev(5)` for details. + ''; + }; + batmanAdvancedConfig = mkOption { default = {}; example = { @@ -2950,10 +2985,10 @@ in stage2Config (mkIf config.boot.initrd.systemd.enable { assertions = [{ - assertion = config.boot.initrd.network.udhcpc.extraArgs == []; + assertion = !config.boot.initrd.network.udhcpc.enable && config.boot.initrd.network.udhcpc.extraArgs == []; message = '' - boot.initrd.network.udhcpc.extraArgs is not supported when - boot.initrd.systemd.enable is enabled + systemd stage 1 networking does not support 'boot.initrd.network.udhcpc'. Configure + DHCP with 'networking.*' options or with 'boot.initrd.systemd.network' options. ''; }]; diff --git a/nixos/modules/system/boot/stage-1-init.sh b/nixos/modules/system/boot/stage-1-init.sh index bc2fc7f7b1083..086e5d65da2f2 100644 --- a/nixos/modules/system/boot/stage-1-init.sh +++ b/nixos/modules/system/boot/stage-1-init.sh @@ -253,9 +253,6 @@ done @setHostId@ # Load the required kernel modules. -mkdir -p /lib -ln -s @modulesClosure@/lib/modules /lib/modules -ln -s @modulesClosure@/lib/firmware /lib/firmware echo @extraUtils@/bin/modprobe > /proc/sys/kernel/modprobe for i in @kernelModules@; do info "loading module $(basename $i)..." @@ -498,6 +495,8 @@ if test -e /sys/power/resume -a -e /sys/power/disk; then fi fi +@postResumeCommands@ + # If we have a path to an iso file, find the iso and link it to /dev/root if [ -n "$isoPath" ]; then mkdir -p /findiso diff --git a/nixos/modules/system/boot/stage-1.nix b/nixos/modules/system/boot/stage-1.nix index a3551f68dbe89..13c71e1495ea9 100644 --- a/nixos/modules/system/boot/stage-1.nix +++ b/nixos/modules/system/boot/stage-1.nix @@ -284,7 +284,7 @@ let # in the NixOS installation CD, so use ID_CDROM_MEDIA in the # corresponding udev rules for now. This was the behaviour in # udev <= 154. See also - # http://www.spinics.net/lists/hotplug/msg03935.html + # https://www.spinics.net/lists/hotplug/msg03935.html substituteInPlace $out/60-persistent-storage.rules \ --replace ID_CDROM_MEDIA_TRACK_COUNT_DATA ID_CDROM_MEDIA ''; # */ @@ -307,7 +307,7 @@ let ${pkgs.buildPackages.busybox}/bin/ash -n $target ''; - inherit linkUnits udevRules extraUtils modulesClosure; + inherit linkUnits udevRules extraUtils; inherit (config.boot) resumeDevice; @@ -316,7 +316,7 @@ let inherit (config.system.build) earlyMountScript; inherit (config.boot.initrd) checkJournalingFS verbose - preLVMCommands preDeviceCommands postDeviceCommands postMountCommands preFailCommands kernelModules; + preLVMCommands preDeviceCommands postDeviceCommands postResumeCommands postMountCommands preFailCommands kernelModules; resumeDevices = map (sd: if sd ? device then sd.device else "/dev/disk/by-label/${sd.label}") (filter (sd: hasPrefix "/dev/" sd.device && !sd.randomEncryption.enable @@ -349,6 +349,9 @@ let [ { object = bootStage1; symlink = "/init"; } + { object = "${modulesClosure}/lib"; + symlink = "/lib"; + } { object = pkgs.runCommand "initrd-kmod-blacklist-ubuntu" { src = "${pkgs.kmod-blacklist-ubuntu}/modprobe.conf"; preferLocalBuild = true; @@ -524,6 +527,14 @@ in ''; }; + boot.initrd.postResumeCommands = mkOption { + default = ""; + type = types.lines; + description = lib.mdDoc '' + Shell commands to be executed immediately after attempting to resume. + ''; + }; + boot.initrd.postMountCommands = mkOption { default = ""; type = types.lines; diff --git a/nixos/modules/system/boot/stage-2-init.sh b/nixos/modules/system/boot/stage-2-init.sh index 5a2133f960e2b..a89e3d8176374 100755 --- a/nixos/modules/system/boot/stage-2-init.sh +++ b/nixos/modules/system/boot/stage-2-init.sh @@ -54,7 +54,7 @@ if [ ! -e /proc/1 ]; then fi -if [ "${IN_NIXOS_SYSTEMD_STAGE1:-}" = true ]; then +if [ "${IN_NIXOS_SYSTEMD_STAGE1:-}" = true ] || [ ! -c /dev/kmsg ] ; then echo "booting system configuration ${systemConfig}" else echo "booting system configuration $systemConfig" > /dev/kmsg diff --git a/nixos/modules/system/boot/systemd.nix b/nixos/modules/system/boot/systemd.nix index 8e38072b4c6db..68a8c1f37ed5a 100644 --- a/nixos/modules/system/boot/systemd.nix +++ b/nixos/modules/system/boot/systemd.nix @@ -575,7 +575,7 @@ in system.requiredKernelConfig = map config.lib.kernelConfig.isEnabled [ "DEVTMPFS" "CGROUPS" "INOTIFY_USER" "SIGNALFD" "TIMERFD" "EPOLL" "NET" "SYSFS" "PROC_FS" "FHANDLE" "CRYPTO_USER_API_HASH" "CRYPTO_HMAC" - "CRYPTO_SHA256" "DMIID" "AUTOFS4_FS" "TMPFS_POSIX_ACL" + "CRYPTO_SHA256" "DMIID" "AUTOFS_FS" "TMPFS_POSIX_ACL" "TMPFS_XATTR" "SECCOMP" ]; diff --git a/nixos/modules/system/boot/systemd/homed.nix b/nixos/modules/system/boot/systemd/homed.nix index 403d1690124db..b216820c0c0cd 100644 --- a/nixos/modules/system/boot/systemd/homed.nix +++ b/nixos/modules/system/boot/systemd/homed.nix @@ -5,7 +5,7 @@ let in { options.services.homed.enable = lib.mkEnableOption (lib.mdDoc '' - Enable systemd home area/user account manager + systemd home area/user account manager ''); config = lib.mkIf cfg.enable { diff --git a/nixos/modules/system/boot/systemd/initrd.nix b/nixos/modules/system/boot/systemd/initrd.nix index 61af2768e2959..0e7d59b32075b 100644 --- a/nixos/modules/system/boot/systemd/initrd.nix +++ b/nixos/modules/system/boot/systemd/initrd.nix @@ -128,10 +128,6 @@ in { stage 2 counterparts such as {option}`systemd.services`, except that `restartTriggers` and `reloadTriggers` are not supported. - - Note: This is experimental. Some of the `boot.initrd` options - are not supported when this is enabled, and the options under - `boot.initrd.systemd` are subject to change. ''; }; @@ -348,17 +344,39 @@ in { }; config = mkIf (config.boot.initrd.enable && cfg.enable) { + assertions = map (name: { + assertion = lib.attrByPath name (throw "impossible") config.boot.initrd == ""; + message = '' + systemd stage 1 does not support 'boot.initrd.${lib.concatStringsSep "." name}'. Please + convert it to analogous systemd units in 'boot.initrd.systemd'. + + Definitions: + ${lib.concatMapStringsSep "\n" ({ file, ... }: " - ${file}") (lib.attrByPath name (throw "impossible") options.boot.initrd).definitionsWithLocations} + ''; + }) [ + [ "preFailCommands" ] + [ "preDeviceCommands" ] + [ "preLVMCommands" ] + [ "postDeviceCommands" ] + [ "postResumeCommands" ] + [ "postMountCommands" ] + [ "extraUdevRulesCommands" ] + [ "extraUtilsCommands" ] + [ "extraUtilsCommandsTest" ] + [ "network" "postCommands" ] + ]; + system.build = { inherit initialRamdisk; }; boot.initrd.availableKernelModules = [ # systemd needs this for some features - "autofs4" + "autofs" # systemd-cryptenroll ] ++ lib.optional cfg.enableTpm2 "tpm-tis" ++ lib.optional (cfg.enableTpm2 && !(pkgs.stdenv.hostPlatform.isRiscV64 || pkgs.stdenv.hostPlatform.isArmv7)) "tpm-crb"; boot.initrd.systemd = { - initrdBin = [pkgs.bash pkgs.coreutils cfg.package.kmod cfg.package] ++ config.system.fsPackages; + initrdBin = [pkgs.bash pkgs.coreutils cfg.package.kmod cfg.package]; extraBin = { less = "${pkgs.less}/bin/less"; mount = "${cfg.package.util-linux}/bin/mount"; diff --git a/nixos/modules/system/boot/systemd/journald.nix b/nixos/modules/system/boot/systemd/journald.nix index 773163bbcb811..7e62a4c9bfedf 100644 --- a/nixos/modules/system/boot/systemd/journald.nix +++ b/nixos/modules/system/boot/systemd/journald.nix @@ -28,6 +28,15 @@ in { ''; }; + services.journald.storage = mkOption { + default = "persistent"; + type = types.enum [ "persistent" "volatile" "auto" "none" ]; + description = mdDoc '' + Controls where to store journal data. See + {manpage}`journald.conf(5)` for further information. + ''; + }; + services.journald.rateLimitBurst = mkOption { default = 10000; type = types.int; @@ -100,7 +109,7 @@ in { environment.etc = { "systemd/journald.conf".text = '' [Journal] - Storage=persistent + Storage=${cfg.storage} RateLimitInterval=${cfg.rateLimitInterval} RateLimitBurst=${toString cfg.rateLimitBurst} ${optionalString (cfg.console != "") '' diff --git a/nixos/modules/system/boot/systemd/repart.nix b/nixos/modules/system/boot/systemd/repart.nix index 2431c68ea17b8..5ac2ace56ba02 100644 --- a/nixos/modules/system/boot/systemd/repart.nix +++ b/nixos/modules/system/boot/systemd/repart.nix @@ -74,6 +74,15 @@ in }; config = lib.mkIf (cfg.enable || initrdCfg.enable) { + assertions = [ + { + assertion = initrdCfg.enable -> config.boot.initrd.systemd.enable; + message = '' + 'boot.initrd.systemd.repart.enable' requires 'boot.initrd.systemd.enable' to be enabled. + ''; + } + ]; + boot.initrd.systemd = lib.mkIf initrdCfg.enable { additionalUpstreamUnits = [ "systemd-repart.service" diff --git a/nixos/modules/system/boot/systemd/tmpfiles.nix b/nixos/modules/system/boot/systemd/tmpfiles.nix index 32b9b275d3587..183e2033ecb01 100644 --- a/nixos/modules/system/boot/systemd/tmpfiles.nix +++ b/nixos/modules/system/boot/systemd/tmpfiles.nix @@ -20,6 +20,102 @@ in ''; }; + systemd.tmpfiles.settings = mkOption { + description = lib.mdDoc '' + Declare systemd-tmpfiles rules to create, delete, and clean up volatile + and temporary files and directories. + + Even though the service is called `*tmp*files` you can also create + persistent files. + ''; + example = { + "10-mypackage" = { + "/var/lib/my-service/statefolder".d = { + mode = "0755"; + user = "root"; + group = "root"; + }; + }; + }; + default = {}; + type = types.attrsOf (types.attrsOf (types.attrsOf (types.submodule ({ name, config, ... }: { + options.type = mkOption { + type = types.str; + default = name; + example = "d"; + description = lib.mdDoc '' + The type of operation to perform on the file. + + The type consists of a single letter and optionally one or more + modifier characters. + + Please see the upstream documentation for the available types and + more details: + <https://www.freedesktop.org/software/systemd/man/tmpfiles.d> + ''; + }; + options.mode = mkOption { + type = types.str; + default = "-"; + example = "0755"; + description = lib.mdDoc '' + The file access mode to use when creating this file or directory. + ''; + }; + options.user = mkOption { + type = types.str; + default = "-"; + example = "root"; + description = lib.mdDoc '' + The user of the file. + + This may either be a numeric ID or a user/group name. + + If omitted or when set to `"-"`, the user and group of the user who + invokes systemd-tmpfiles is used. + ''; + }; + options.group = mkOption { + type = types.str; + default = "-"; + example = "root"; + description = lib.mdDoc '' + The group of the file. + + This may either be a numeric ID or a user/group name. + + If omitted or when set to `"-"`, the user and group of the user who + invokes systemd-tmpfiles is used. + ''; + }; + options.age = mkOption { + type = types.str; + default = "-"; + example = "10d"; + description = lib.mdDoc '' + Delete a file when it reaches a certain age. + + If a file or directory is older than the current time minus the age + field, it is deleted. + + If set to `"-"` no automatic clean-up is done. + ''; + }; + options.argument = mkOption { + type = types.str; + default = ""; + example = ""; + description = lib.mdDoc '' + An argument whose meaning depends on the type of operation. + + Please see the upstream documentation for the meaning of this + parameter in different situations: + <https://www.freedesktop.org/software/systemd/man/tmpfiles.d> + ''; + }; + })))); + }; + systemd.tmpfiles.packages = mkOption { type = types.listOf types.package; default = []; @@ -100,7 +196,13 @@ in ${concatStringsSep "\n" cfg.rules} ''; }) - ]; + ] ++ (mapAttrsToList (name: paths: + pkgs.writeTextDir "lib/tmpfiles.d/${name}.conf" (concatStrings (mapAttrsToList (path: types: + concatStrings (mapAttrsToList (_type: entry: '' + '${entry.type}' '${path}' '${entry.mode}' '${entry.user}' '${entry.group}' '${entry.age}' ${entry.argument} + '') types) + ) paths )) + ) cfg.settings); systemd.tmpfiles.rules = [ "d /nix/var 0755 root root - -" diff --git a/nixos/modules/system/boot/systemd/userdbd.nix b/nixos/modules/system/boot/systemd/userdbd.nix index 994aa3ca3b8c1..e7f6d42341c4e 100644 --- a/nixos/modules/system/boot/systemd/userdbd.nix +++ b/nixos/modules/system/boot/systemd/userdbd.nix @@ -5,7 +5,7 @@ let in { options.services.userdbd.enable = lib.mkEnableOption (lib.mdDoc '' - Enables the systemd JSON user/group record lookup service + the systemd JSON user/group record lookup service ''); config = lib.mkIf cfg.enable { systemd.additionalUpstreamSystemUnits = [ diff --git a/nixos/modules/system/boot/timesyncd.nix b/nixos/modules/system/boot/timesyncd.nix index a6604802c38ca..7487cf97fe531 100644 --- a/nixos/modules/system/boot/timesyncd.nix +++ b/nixos/modules/system/boot/timesyncd.nix @@ -46,6 +46,28 @@ with lib; wantedBy = [ "sysinit.target" ]; aliases = [ "dbus-org.freedesktop.timesync1.service" ]; restartTriggers = [ config.environment.etc."systemd/timesyncd.conf".source ]; + + preStart = ( + # Ensure that we have some stored time to prevent + # systemd-timesyncd to resort back to the fallback time. If + # the file doesn't exist we assume that our current system + # clock is good enough to provide an initial value. + '' + if ! [ -f /var/lib/systemd/timesync/clock ]; then + test -d /var/lib/systemd/timesync || mkdir -p /var/lib/systemd/timesync + touch /var/lib/systemd/timesync/clock + fi + '' + + # workaround an issue of systemd-timesyncd not starting due to upstream systemd reverting their dynamic users changes + # - https://github.com/NixOS/nixpkgs/pull/61321#issuecomment-492423742 + # - https://github.com/systemd/systemd/issues/12131 + (lib.optionalString (versionOlder config.system.stateVersion "19.09") '' + if [ -L /var/lib/systemd/timesync ]; then + rm /var/lib/systemd/timesync + mv /var/lib/private/systemd/timesync /var/lib/systemd/timesync + fi + '') + ); }; environment.etc."systemd/timesyncd.conf".text = '' @@ -59,28 +81,5 @@ with lib; group = "systemd-timesync"; }; users.groups.systemd-timesync.gid = config.ids.gids.systemd-timesync; - - system.activationScripts.systemd-timesyncd-migration = - # workaround an issue of systemd-timesyncd not starting due to upstream systemd reverting their dynamic users changes - # - https://github.com/NixOS/nixpkgs/pull/61321#issuecomment-492423742 - # - https://github.com/systemd/systemd/issues/12131 - mkIf (versionOlder config.system.stateVersion "19.09") '' - if [ -L /var/lib/systemd/timesync ]; then - rm /var/lib/systemd/timesync - mv /var/lib/private/systemd/timesync /var/lib/systemd/timesync - fi - ''; - system.activationScripts.systemd-timesyncd-init-clock = - # Ensure that we have some stored time to prevent systemd-timesyncd to - # resort back to the fallback time. - # If the file doesn't exist we assume that our current system clock is - # good enough to provide an initial value. - '' - if ! [ -f /var/lib/systemd/timesync/clock ]; then - test -d /var/lib/systemd/timesync || mkdir -p /var/lib/systemd/timesync - touch /var/lib/systemd/timesync/clock - fi - ''; }; - } |