diff options
Diffstat (limited to 'nixpkgs/nixos/modules/tasks')
-rw-r--r-- | nixpkgs/nixos/modules/tasks/auto-upgrade.nix | 98 | ||||
-rw-r--r-- | nixpkgs/nixos/modules/tasks/bcache.nix | 2 | ||||
-rw-r--r-- | nixpkgs/nixos/modules/tasks/encrypted-devices.nix | 21 | ||||
-rw-r--r-- | nixpkgs/nixos/modules/tasks/filesystems.nix | 4 | ||||
-rw-r--r-- | nixpkgs/nixos/modules/tasks/filesystems/btrfs.nix | 5 | ||||
-rw-r--r-- | nixpkgs/nixos/modules/tasks/filesystems/zfs.nix | 51 | ||||
-rw-r--r-- | nixpkgs/nixos/modules/tasks/lvm.nix | 67 | ||||
-rw-r--r-- | nixpkgs/nixos/modules/tasks/network-interfaces-scripted.nix | 28 | ||||
-rw-r--r-- | nixpkgs/nixos/modules/tasks/network-interfaces.nix | 10 |
9 files changed, 213 insertions, 73 deletions
diff --git a/nixpkgs/nixos/modules/tasks/auto-upgrade.nix b/nixpkgs/nixos/modules/tasks/auto-upgrade.nix index e70004e643e..69385e5f2fe 100644 --- a/nixpkgs/nixos/modules/tasks/auto-upgrade.nix +++ b/nixpkgs/nixos/modules/tasks/auto-upgrade.nix @@ -2,9 +2,9 @@ with lib; -let cfg = config.system.autoUpgrade; in +let cfg = config.system.autoUpgrade; -{ +in { options = { @@ -21,6 +21,16 @@ let cfg = config.system.autoUpgrade; in ''; }; + flake = mkOption { + type = types.nullOr types.str; + default = null; + example = "github:kloenk/nix"; + description = '' + The Flake URI of the NixOS configuration to build. + Disables the option <option>system.autoUpgrade.channel</option>. + ''; + }; + channel = mkOption { type = types.nullOr types.str; default = null; @@ -35,10 +45,20 @@ let cfg = config.system.autoUpgrade; in flags = mkOption { type = types.listOf types.str; - default = []; - example = [ "-I" "stuff=/home/alice/nixos-stuff" "--option" "extra-binary-caches" "http://my-cache.example.org/" ]; + default = [ ]; + example = [ + "-I" + "stuff=/home/alice/nixos-stuff" + "--option" + "extra-binary-caches" + "http://my-cache.example.org/" + ]; description = '' Any additional flags passed to <command>nixos-rebuild</command>. + + If you are using flakes and use a local repo you can add + <command>[ "--update-input" "nixpkgs" "--commit-lock-file" ]</command> + to update nixpkgs. ''; }; @@ -82,11 +102,23 @@ let cfg = config.system.autoUpgrade; in config = lib.mkIf cfg.enable { - system.autoUpgrade.flags = - [ "--no-build-output" ] - ++ (if cfg.channel == null - then [ "--upgrade" ] - else [ "-I" "nixpkgs=${cfg.channel}/nixexprs.tar.xz" ]); + assertions = [{ + assertion = !((cfg.channel != null) && (cfg.flake != null)); + message = '' + The options 'system.autoUpgrade.channels' and 'system.autoUpgrade.flake' cannot both be set. + ''; + }]; + + system.autoUpgrade.flags = [ "--no-build-output" ] + ++ (if cfg.flake == null then + (if cfg.channel == null then + [ "--upgrade" ] + else [ + "-I" + "nixpkgs=${cfg.channel}/nixexprs.tar.xz" + ]) + else + [ "--flake ${cfg.flake}" ]); systemd.services.nixos-upgrade = { description = "NixOS Upgrade"; @@ -96,33 +128,41 @@ let cfg = config.system.autoUpgrade; in serviceConfig.Type = "oneshot"; - environment = config.nix.envVars // - { inherit (config.environment.sessionVariables) NIX_PATH; - HOME = "/root"; - } // config.networking.proxy.envVars; + environment = config.nix.envVars // { + inherit (config.environment.sessionVariables) NIX_PATH; + HOME = "/root"; + } // config.networking.proxy.envVars; - path = with pkgs; [ coreutils gnutar xz.bin gzip gitMinimal config.nix.package.out ]; + path = with pkgs; [ + coreutils + gnutar + xz.bin + gzip + gitMinimal + config.nix.package.out + ]; script = let - nixos-rebuild = "${config.system.build.nixos-rebuild}/bin/nixos-rebuild"; - in - if cfg.allowReboot then '' - ${nixos-rebuild} boot ${toString cfg.flags} - booted="$(readlink /run/booted-system/{initrd,kernel,kernel-modules})" - built="$(readlink /nix/var/nix/profiles/system/{initrd,kernel,kernel-modules})" - if [ "$booted" = "$built" ]; then - ${nixos-rebuild} switch ${toString cfg.flags} - else - /run/current-system/sw/bin/shutdown -r +1 - fi - '' else '' - ${nixos-rebuild} switch ${toString cfg.flags} - ''; + nixos-rebuild = + "${config.system.build.nixos-rebuild}/bin/nixos-rebuild"; + in if cfg.allowReboot then '' + ${nixos-rebuild} boot ${toString cfg.flags} + booted="$(readlink /run/booted-system/{initrd,kernel,kernel-modules})" + built="$(readlink /nix/var/nix/profiles/system/{initrd,kernel,kernel-modules})" + if [ "$booted" = "$built" ]; then + ${nixos-rebuild} switch ${toString cfg.flags} + else + /run/current-system/sw/bin/shutdown -r +1 + fi + '' else '' + ${nixos-rebuild} switch ${toString cfg.flags} + ''; startAt = cfg.dates; }; - systemd.timers.nixos-upgrade.timerConfig.RandomizedDelaySec = cfg.randomizedDelaySec; + systemd.timers.nixos-upgrade.timerConfig.RandomizedDelaySec = + cfg.randomizedDelaySec; }; diff --git a/nixpkgs/nixos/modules/tasks/bcache.nix b/nixpkgs/nixos/modules/tasks/bcache.nix index 8bab91c721f..41fb7664f3d 100644 --- a/nixpkgs/nixos/modules/tasks/bcache.nix +++ b/nixpkgs/nixos/modules/tasks/bcache.nix @@ -8,6 +8,6 @@ boot.initrd.extraUdevRulesCommands = '' cp -v ${pkgs.bcache-tools}/lib/udev/rules.d/*.rules $out/ - ''; + ''; } diff --git a/nixpkgs/nixos/modules/tasks/encrypted-devices.nix b/nixpkgs/nixos/modules/tasks/encrypted-devices.nix index bc0933f16fe..dd337de9869 100644 --- a/nixpkgs/nixos/modules/tasks/encrypted-devices.nix +++ b/nixpkgs/nixos/modules/tasks/encrypted-devices.nix @@ -37,7 +37,14 @@ let default = null; example = "/mnt-root/root/.swapkey"; type = types.nullOr types.str; - description = "File system location of keyfile. This unlocks the drive after the root has been mounted to <literal>/mnt-root</literal>."; + description = '' + Path to a keyfile used to unlock the backing encrypted + device. At the time this keyfile is accessed, the + <literal>neededForBoot</literal> filesystems (see + <literal>fileSystems.<name?>.neededForBoot</literal>) + will have been mounted under <literal>/mnt-root</literal>, + so the keyfile path should usually start with "/mnt-root/". + ''; }; }; }; @@ -47,7 +54,7 @@ in options = { fileSystems = mkOption { - type = with lib.types; loaOf (submodule encryptedFSOptions); + type = with lib.types; attrsOf (submodule encryptedFSOptions); }; swapDevices = mkOption { type = with lib.types; listOf (submodule encryptedFSOptions); @@ -65,12 +72,16 @@ in boot.initrd = { luks = { devices = - builtins.listToAttrs (map (dev: { name = dev.encrypted.label; value = { device = dev.encrypted.blkDev; }; }) keylessEncDevs); + builtins.listToAttrs (map (dev: { + name = dev.encrypted.label; + value = { device = dev.encrypted.blkDev; }; + }) keylessEncDevs); forceLuksSupportInInitrd = true; }; postMountCommands = - concatMapStrings (dev: "cryptsetup luksOpen --key-file ${dev.encrypted.keyFile} ${dev.encrypted.blkDev} ${dev.encrypted.label};\n") keyedEncDevs; + concatMapStrings (dev: + "cryptsetup luksOpen --key-file ${dev.encrypted.keyFile} ${dev.encrypted.blkDev} ${dev.encrypted.label};\n" + ) keyedEncDevs; }; }; } - diff --git a/nixpkgs/nixos/modules/tasks/filesystems.nix b/nixpkgs/nixos/modules/tasks/filesystems.nix index 0ade74b957a..3ea67dac714 100644 --- a/nixpkgs/nixos/modules/tasks/filesystems.nix +++ b/nixpkgs/nixos/modules/tasks/filesystems.nix @@ -159,7 +159,7 @@ in "/bigdisk".label = "bigdisk"; } ''; - type = types.loaOf (types.submodule [coreFileSystemOpts fileSystemOpts]); + type = types.attrsOf (types.submodule [coreFileSystemOpts fileSystemOpts]); description = '' The file systems to be mounted. It must include an entry for the root directory (<literal>mountPoint = "/"</literal>). Each @@ -193,7 +193,7 @@ in boot.specialFileSystems = mkOption { default = {}; - type = types.loaOf (types.submodule coreFileSystemOpts); + type = types.attrsOf (types.submodule coreFileSystemOpts); internal = true; description = '' Special filesystems that are mounted very early during boot. diff --git a/nixpkgs/nixos/modules/tasks/filesystems/btrfs.nix b/nixpkgs/nixos/modules/tasks/filesystems/btrfs.nix index f64493e1a3c..c0ff28039b1 100644 --- a/nixpkgs/nixos/modules/tasks/filesystems/btrfs.nix +++ b/nixpkgs/nixos/modules/tasks/filesystems/btrfs.nix @@ -128,7 +128,10 @@ in Nice = 19; IOSchedulingClass = "idle"; ExecStart = "${pkgs.btrfs-progs}/bin/btrfs scrub start -B ${fs}"; - ExecStop = "${pkgs.btrfs-progs}/bin/btrfs scrub cancel ${fs}"; + # if the service is stopped before scrub end, cancel it + ExecStop = pkgs.writeShellScript "btrfs-scrub-maybe-cancel" '' + (${pkgs.btrfs-progs}/bin/btrfs scrub status ${fs} | ${pkgs.gnugrep}/bin/grep finished) || ${pkgs.btrfs-progs}/bin/btrfs scrub cancel ${fs} + ''; }; }; in listToAttrs (map scrubService cfgScrub.fileSystems); diff --git a/nixpkgs/nixos/modules/tasks/filesystems/zfs.nix b/nixpkgs/nixos/modules/tasks/filesystems/zfs.nix index 71eed4d6f1a..9ca7c6fb343 100644 --- a/nixpkgs/nixos/modules/tasks/filesystems/zfs.nix +++ b/nixpkgs/nixos/modules/tasks/filesystems/zfs.nix @@ -191,15 +191,14 @@ in }; requestEncryptionCredentials = mkOption { - type = types.bool; + type = types.either types.bool (types.listOf types.str); default = true; + example = [ "tank" "data" ]; description = '' - Request encryption keys or passwords for all encrypted datasets on import. - For root pools the encryption key can be supplied via both an - interactive prompt (keylocation=prompt) and from a file - (keylocation=file://). Note that for data pools the encryption key can - be only loaded from a file and not via interactive prompt since the - import is processed in a background systemd service. + If true on import encryption keys or passwords for all encrypted datasets + are requested. To only decrypt selected datasets supply a list of dataset + names instead. For root pools the encryption key can be supplied via both + an interactive prompt (keylocation=prompt) and from a file (keylocation=file://). ''; }; @@ -421,9 +420,13 @@ in fi poolImported "${pool}" || poolImport "${pool}" # Try one last time, e.g. to import a degraded pool. fi - ${lib.optionalString cfgZfs.requestEncryptionCredentials '' - zfs load-key -a - ''} + ${if isBool cfgZfs.requestEncryptionCredentials + then optionalString cfgZfs.requestEncryptionCredentials '' + zfs load-key -a + '' + else concatMapStrings (fs: '' + zfs load-key ${fs} + '') cfgZfs.requestEncryptionCredentials} '') rootPools)); }; @@ -490,7 +493,11 @@ in description = "Import ZFS pool \"${pool}\""; # we need systemd-udev-settle until https://github.com/zfsonlinux/zfs/pull/4943 is merged requires = [ "systemd-udev-settle.service" ]; - after = [ "systemd-udev-settle.service" "systemd-modules-load.service" ]; + after = [ + "systemd-udev-settle.service" + "systemd-modules-load.service" + "systemd-ask-password-console.service" + ]; wantedBy = (getPoolMounts pool) ++ [ "local-fs.target" ]; before = (getPoolMounts pool) ++ [ "local-fs.target" ]; unitConfig = { @@ -515,7 +522,27 @@ in done poolImported "${pool}" || poolImport "${pool}" # Try one last time, e.g. to import a degraded pool. if poolImported "${pool}"; then - ${optionalString cfgZfs.requestEncryptionCredentials "\"${packages.zfsUser}/sbin/zfs\" load-key -r \"${pool}\""} + ${optionalString (if isBool cfgZfs.requestEncryptionCredentials + then cfgZfs.requestEncryptionCredentials + else cfgZfs.requestEncryptionCredentials != []) '' + ${packages.zfsUser}/sbin/zfs list -rHo name,keylocation ${pool} | while IFS=$'\t' read ds kl; do + (${optionalString (!isBool cfgZfs.requestEncryptionCredentials) '' + if ! echo '${concatStringsSep "\n" cfgZfs.requestEncryptionCredentials}' | grep -qFx "$ds"; then + continue + fi + ''} + case "$kl" in + none ) + ;; + prompt ) + ${config.systemd.package}/bin/systemd-ask-password "Enter key for $ds:" | ${packages.zfsUser}/sbin/zfs load-key "$ds" + ;; + * ) + ${packages.zfsUser}/sbin/zfs load-key "$ds" + ;; + esac) < /dev/null # To protect while read ds kl in case anything reads stdin + done + ''} echo "Successfully imported ${pool}" else exit 1 diff --git a/nixpkgs/nixos/modules/tasks/lvm.nix b/nixpkgs/nixos/modules/tasks/lvm.nix index d56a8a2f63a..2c3cc4c5467 100644 --- a/nixpkgs/nixos/modules/tasks/lvm.nix +++ b/nixpkgs/nixos/modules/tasks/lvm.nix @@ -1,17 +1,70 @@ { config, lib, pkgs, ... }: with lib; +let + cfg = config.services.lvm; +in { + options.services.lvm = { + package = mkOption { + type = types.package; + default = if cfg.dmeventd.enable then pkgs.lvm2_dmeventd else pkgs.lvm2; + internal = true; + defaultText = "pkgs.lvm2"; + description = '' + This option allows you to override the LVM package that's used on the system + (udev rules, tmpfiles, systemd services). + Defaults to pkgs.lvm2, or pkgs.lvm2_dmeventd if dmeventd is enabled. + ''; + }; + dmeventd.enable = mkEnableOption "the LVM dmevent daemon"; + boot.thin.enable = mkEnableOption "support for booting from ThinLVs"; + }; -{ - - ###### implementation + config = mkMerge [ + (mkIf (!config.boot.isContainer) { + systemd.tmpfiles.packages = [ cfg.package.out ]; + environment.systemPackages = [ cfg.package ]; + systemd.packages = [ cfg.package ]; - config = mkIf (!config.boot.isContainer) { + # TODO: update once https://github.com/NixOS/nixpkgs/pull/93006 was merged + services.udev.packages = [ cfg.package.out ]; + }) + (mkIf cfg.dmeventd.enable { + systemd.sockets."dm-event".wantedBy = [ "sockets.target" ]; + systemd.services."lvm2-monitor".wantedBy = [ "sysinit.target" ]; - environment.systemPackages = [ pkgs.lvm2 ]; + environment.etc."lvm/lvm.conf".text = '' + dmeventd/executable = "${cfg.package}/bin/dmeventd" + ''; + }) + (mkIf cfg.boot.thin.enable { + boot.initrd = { + kernelModules = [ "dm-snapshot" "dm-thin-pool" ]; - services.udev.packages = [ pkgs.lvm2 ]; + extraUtilsCommands = '' + copy_bin_and_libs ${pkgs.thin-provisioning-tools}/bin/pdata_tools + copy_bin_and_libs ${pkgs.thin-provisioning-tools}/bin/thin_check + ''; + }; - }; + environment.etc."lvm/lvm.conf".text = '' + global/thin_check_executable = "${pkgs.thin-provisioning-tools}/bin/thin_check" + ''; + }) + (mkIf (cfg.dmeventd.enable || cfg.boot.thin.enable) { + boot.initrd.preLVMCommands = '' + mkdir -p /etc/lvm + cat << EOF >> /etc/lvm/lvm.conf + ${optionalString cfg.boot.thin.enable '' + global/thin_check_executable = "$(command -v thin_check)" + ''} + ${optionalString cfg.dmeventd.enable '' + dmeventd/executable = "$(command -v false)" + activation/monitoring = 0 + ''} + EOF + ''; + }) + ]; } diff --git a/nixpkgs/nixos/modules/tasks/network-interfaces-scripted.nix b/nixpkgs/nixos/modules/tasks/network-interfaces-scripted.nix index d895c58bab0..9ba6ccfbe71 100644 --- a/nixpkgs/nixos/modules/tasks/network-interfaces-scripted.nix +++ b/nixpkgs/nixos/modules/tasks/network-interfaces-scripted.nix @@ -232,25 +232,29 @@ let ''; preStop = '' state="/run/nixos/network/routes/${i.name}" - while read cidr; do - echo -n "deleting route $cidr... " - ip route del "$cidr" dev "${i.name}" >/dev/null 2>&1 && echo "done" || echo "failed" - done < "$state" - rm -f "$state" + if [ -e "$state" ]; then + while read cidr; do + echo -n "deleting route $cidr... " + ip route del "$cidr" dev "${i.name}" >/dev/null 2>&1 && echo "done" || echo "failed" + done < "$state" + rm -f "$state" + fi state="/run/nixos/network/addresses/${i.name}" - while read cidr; do - echo -n "deleting address $cidr... " - ip addr del "$cidr" dev "${i.name}" >/dev/null 2>&1 && echo "done" || echo "failed" - done < "$state" - rm -f "$state" + if [ -e "$state" ]; then + while read cidr; do + echo -n "deleting address $cidr... " + ip addr del "$cidr" dev "${i.name}" >/dev/null 2>&1 && echo "done" || echo "failed" + done < "$state" + rm -f "$state" + fi ''; }; createTunDevice = i: nameValuePair "${i.name}-netdev" { description = "Virtual Network Interface ${i.name}"; - bindsTo = [ "dev-net-tun.device" ]; - after = [ "dev-net-tun.device" "network-pre.target" ]; + bindsTo = optional (!config.boot.isContainer) "dev-net-tun.device"; + after = optional (!config.boot.isContainer) "dev-net-tun.device" ++ [ "network-pre.target" ]; wantedBy = [ "network-setup.service" (subsystemDevice i.name) ]; partOf = [ "network-setup.service" ]; before = [ "network-setup.service" ]; diff --git a/nixpkgs/nixos/modules/tasks/network-interfaces.nix b/nixpkgs/nixos/modules/tasks/network-interfaces.nix index a2811104944..c0e4d3979fd 100644 --- a/nixpkgs/nixos/modules/tasks/network-interfaces.nix +++ b/nixpkgs/nixos/modules/tasks/network-interfaces.nix @@ -381,7 +381,7 @@ in # syntax). Note: We also allow underscores for compatibility/legacy # reasons (as undocumented feature): type = types.strMatching - "^[[:alpha:]]([[:alnum:]_-]{0,61}[[:alnum:]])?$"; + "^$|^[[:alpha:]]([[:alnum:]_-]{0,61}[[:alnum:]])?$"; description = '' The name of the machine. Leave it empty if you want to obtain it from a DHCP server (if using DHCP). The hostname must be a valid DNS label (see @@ -408,6 +408,9 @@ in (this derives it from the machine-id that systemd generates) or <literal>head -c4 /dev/urandom | od -A none -t x4</literal> + + The primary use case is to ensure when using ZFS that a pool isn't imported + accidentally on a wrong machine. ''; }; @@ -516,7 +519,7 @@ in <option>networking.useDHCP</option> is true, then every interface not listed here will be configured using DHCP. ''; - type = with types; loaOf (submodule interfaceOpts); + type = with types; attrsOf (submodule interfaceOpts); }; networking.vswitches = mkOption { @@ -541,7 +544,7 @@ in interfaces = mkOption { example = [ "eth0" "eth1" ]; description = "The physical network interfaces connected by the vSwitch."; - type = with types; loaOf (submodule vswitchInterfaceOpts); + type = with types; attrsOf (submodule vswitchInterfaceOpts); }; controllers = mkOption { @@ -1126,7 +1129,6 @@ in ++ optionals config.networking.wireless.enable [ pkgs.wirelesstools # FIXME: obsolete? pkgs.iw - pkgs.rfkill ] ++ bridgeStp; |