diff --git a/maintainers/maintainer-list.nix b/maintainers/maintainer-list.nix index 098715d34561..0132b970b988 100644 --- a/maintainers/maintainer-list.nix +++ b/maintainers/maintainer-list.nix @@ -13604,6 +13604,11 @@ githubId = 15645854; name = "Brad Christensen"; }; + paumr = { + github = "paumr"; + name = "Michael Bergmeister"; + githubId = 53442728; + }; paveloom = { email = "paveloom@riseup.net"; github = "paveloom"; diff --git a/nixos/lib/test-driver/default.nix b/nixos/lib/test-driver/default.nix index 6e01e00b4355..09d80deb8546 100644 --- a/nixos/lib/test-driver/default.nix +++ b/nixos/lib/test-driver/default.nix @@ -11,6 +11,7 @@ , tesseract4 , vde2 , extraPythonPackages ? (_ : []) +, nixosTests }: python3Packages.buildPythonApplication { @@ -31,6 +32,10 @@ python3Packages.buildPythonApplication { ++ (lib.optionals enableOCR [ imagemagick_light tesseract4 ]) ++ extraPythonPackages python3Packages; + passthru.tests = { + inherit (nixosTests.nixos-test-driver) driver-timeout; + }; + doCheck = true; nativeCheckInputs = with python3Packages; [ mypy ruff black ]; checkPhase = '' diff --git a/nixos/lib/test-driver/test_driver/__init__.py b/nixos/lib/test-driver/test_driver/__init__.py index 371719d7a988..9daae1e941a6 100755 --- a/nixos/lib/test-driver/test_driver/__init__.py +++ b/nixos/lib/test-driver/test_driver/__init__.py @@ -76,6 +76,14 @@ def main() -> None: nargs="*", help="vlans to span by the driver", ) + arg_parser.add_argument( + "--global-timeout", + type=int, + metavar="GLOBAL_TIMEOUT", + action=EnvDefault, + envvar="globalTimeout", + help="Timeout in seconds for the whole test", + ) arg_parser.add_argument( "-o", "--output_directory", @@ -103,6 +111,7 @@ def main() -> None: args.testscript.read_text(), args.output_directory.resolve(), args.keep_vm_state, + args.global_timeout, ) as driver: if args.interactive: history_dir = os.getcwd() diff --git a/nixos/lib/test-driver/test_driver/driver.py b/nixos/lib/test-driver/test_driver/driver.py index 723c80717860..786821b0cc0d 100644 --- a/nixos/lib/test-driver/test_driver/driver.py +++ b/nixos/lib/test-driver/test_driver/driver.py @@ -1,6 +1,8 @@ import os import re +import signal import tempfile +import threading from contextlib import contextmanager from pathlib import Path from typing import Any, Callable, ContextManager, Dict, Iterator, List, Optional, Union @@ -41,6 +43,8 @@ class Driver: vlans: List[VLan] machines: List[Machine] polling_conditions: List[PollingCondition] + global_timeout: int + race_timer: threading.Timer def __init__( self, @@ -49,9 +53,12 @@ class Driver: tests: str, out_dir: Path, keep_vm_state: bool = False, + global_timeout: int = 24 * 60 * 60 * 7, ): self.tests = tests self.out_dir = out_dir + self.global_timeout = global_timeout + self.race_timer = threading.Timer(global_timeout, self.terminate_test) tmp_dir = get_tmp_dir() @@ -82,6 +89,7 @@ class Driver: def __exit__(self, *_: Any) -> None: with rootlog.nested("cleanup"): + self.race_timer.cancel() for machine in self.machines: machine.release() @@ -144,6 +152,10 @@ class Driver: def run_tests(self) -> None: """Run the test script (for non-interactive test runs)""" + rootlog.info( + f"Test will time out and terminate in {self.global_timeout} seconds" + ) + self.race_timer.start() self.test_script() # TODO: Collect coverage data for machine in self.machines: @@ -161,6 +173,19 @@ class Driver: with rootlog.nested("wait for all VMs to finish"): for machine in self.machines: machine.wait_for_shutdown() + self.race_timer.cancel() + + def terminate_test(self) -> None: + # This will be usually running in another thread than + # the thread actually executing the test script. + with rootlog.nested("timeout reached; test terminating..."): + for machine in self.machines: + machine.release() + # As we cannot `sys.exit` from another thread + # We can at least force the main thread to get SIGTERM'ed. + # This will prevent any user who caught all the exceptions + # to swallow them and prevent itself from terminating. + os.kill(os.getpid(), signal.SIGTERM) def create_machine(self, args: Dict[str, Any]) -> Machine: tmp_dir = get_tmp_dir() diff --git a/nixos/lib/testing-python.nix b/nixos/lib/testing-python.nix index 4904ad6e3591..f5222351518b 100644 --- a/nixos/lib/testing-python.nix +++ b/nixos/lib/testing-python.nix @@ -42,6 +42,7 @@ rec { , nodes ? {} , testScript , enableOCR ? false + , globalTimeout ? (60 * 60) , name ? "unnamed" , skipTypeCheck ? false # Skip linting (mainly intended for faster dev cycles) diff --git a/nixos/lib/testing/driver.nix b/nixos/lib/testing/driver.nix index cc97ca72083f..b6f01c38191d 100644 --- a/nixos/lib/testing/driver.nix +++ b/nixos/lib/testing/driver.nix @@ -94,6 +94,7 @@ let wrapProgram $out/bin/nixos-test-driver \ --set startScripts "''${vmStartScripts[*]}" \ --set testScript "$out/test-script" \ + --set globalTimeout "${toString config.globalTimeout}" \ --set vlans '${toString vlans}' \ ${lib.escapeShellArgs (lib.concatMap (arg: ["--add-flags" arg]) config.extraDriverArgs)} ''; @@ -123,6 +124,18 @@ in defaultText = "hostPkgs.qemu_test"; }; + globalTimeout = mkOption { + description = mdDoc '' + A global timeout for the complete test, expressed in seconds. + Beyond that timeout, every resource will be killed and released and the test will fail. + + By default, we use a 1 hour timeout. + ''; + type = types.int; + default = 60 * 60; + example = 10 * 60; + }; + enableOCR = mkOption { description = mdDoc '' Whether to enable Optical Character Recognition functionality for diff --git a/nixos/lib/testing/run.nix b/nixos/lib/testing/run.nix index 0cd07d8afd21..9440c1acdfd8 100644 --- a/nixos/lib/testing/run.nix +++ b/nixos/lib/testing/run.nix @@ -16,6 +16,15 @@ in ''; }; + rawTestDerivation = mkOption { + type = types.package; + description = mdDoc '' + Unfiltered version of `test`, for troubleshooting the test framework and `testBuildFailure` in the test framework's test suite. + This is not intended for general use. Use `test` instead. + ''; + internal = true; + }; + test = mkOption { type = types.package; # TODO: can the interactive driver be configured to access the network? @@ -29,25 +38,26 @@ in }; config = { + rawTestDerivation = hostPkgs.stdenv.mkDerivation { + name = "vm-test-run-${config.name}"; + + requiredSystemFeatures = [ "kvm" "nixos-test" ]; + + buildCommand = '' + mkdir -p $out + + # effectively mute the XMLLogger + export LOGFILE=/dev/null + + ${config.driver}/bin/nixos-test-driver -o $out + ''; + + passthru = config.passthru; + + meta = config.meta; + }; test = lib.lazyDerivation { # lazyDerivation improves performance when only passthru items and/or meta are used. - derivation = hostPkgs.stdenv.mkDerivation { - name = "vm-test-run-${config.name}"; - - requiredSystemFeatures = [ "kvm" "nixos-test" ]; - - buildCommand = '' - mkdir -p $out - - # effectively mute the XMLLogger - export LOGFILE=/dev/null - - ${config.driver}/bin/nixos-test-driver -o $out - ''; - - passthru = config.passthru; - - meta = config.meta; - }; + derivation = config.rawTestDerivation; inherit (config) passthru meta; }; diff --git a/nixos/maintainers/scripts/azure-new/examples/basic/system.nix b/nixos/maintainers/scripts/azure-new/examples/basic/system.nix index d283742701d1..d1044802e1f0 100644 --- a/nixos/maintainers/scripts/azure-new/examples/basic/system.nix +++ b/nixos/maintainers/scripts/azure-new/examples/basic/system.nix @@ -21,7 +21,6 @@ in virtualisation.azureImage.diskSize = 2500; - system.stateVersion = "20.03"; boot.kernelPackages = pkgs.linuxPackages_latest; # test user doesn't have a password diff --git a/nixos/maintainers/scripts/lxd/lxd-container-image-inner.nix b/nixos/maintainers/scripts/lxd/lxd-container-image-inner.nix index 7b743d170bc6..62a6e1f9aa3a 100644 --- a/nixos/maintainers/scripts/lxd/lxd-container-image-inner.nix +++ b/nixos/maintainers/scripts/lxd/lxd-container-image-inner.nix @@ -2,13 +2,13 @@ # your system. Help is available in the configuration.nix(5) man page # and in the NixOS manual (accessible by running ‘nixos-help’). -{ config, pkgs, lib, ... }: +{ config, pkgs, lib, modulesPath, ... }: { imports = [ # Include the default lxd configuration. - ../../../modules/virtualisation/lxc-container.nix + "${modulesPath}/modules/virtualisation/lxc-container.nix" # Include the container-specific autogenerated configuration. ./lxd.nix ]; @@ -16,5 +16,5 @@ networking.useDHCP = false; networking.interfaces.eth0.useDHCP = true; - system.stateVersion = "21.05"; # Did you read the comment? + system.stateVersion = "@stateVersion@"; # Did you read the comment? } diff --git a/nixos/maintainers/scripts/lxd/lxd-container-image.nix b/nixos/maintainers/scripts/lxd/lxd-container-image.nix index 3bd1320b2b68..b77f9f5aabe0 100644 --- a/nixos/maintainers/scripts/lxd/lxd-container-image.nix +++ b/nixos/maintainers/scripts/lxd/lxd-container-image.nix @@ -13,11 +13,15 @@ }; # copy the config for nixos-rebuild - system.activationScripts.config = '' + system.activationScripts.config = let + config = pkgs.substituteAll { + src = ./lxd-container-image-inner.nix; + stateVersion = lib.trivial.release; + }; + in '' if [ ! -e /etc/nixos/configuration.nix ]; then mkdir -p /etc/nixos - cat ${./lxd-container-image-inner.nix} > /etc/nixos/configuration.nix - ${lib.getExe pkgs.gnused} 's|../../../modules/virtualisation/lxc-container.nix||g' -i /etc/nixos/configuration.nix + cp ${config} /etc/nixos/configuration.nix fi ''; diff --git a/nixos/maintainers/scripts/lxd/lxd-virtual-machine-image-inner.nix b/nixos/maintainers/scripts/lxd/lxd-virtual-machine-image-inner.nix index a8f2c63ac5c6..c1c50b32ff5b 100644 --- a/nixos/maintainers/scripts/lxd/lxd-virtual-machine-image-inner.nix +++ b/nixos/maintainers/scripts/lxd/lxd-virtual-machine-image-inner.nix @@ -2,13 +2,13 @@ # your system. Help is available in the configuration.nix(5) man page # and in the NixOS manual (accessible by running ‘nixos-help’). -{ config, pkgs, lib, ... }: +{ config, pkgs, lib, modulesPath, ... }: { imports = [ # Include the default lxd configuration. - ../../../modules/virtualisation/lxd-virtual-machine.nix + "${modulesPath}/virtualisation/lxd-virtual-machine.nix" # Include the container-specific autogenerated configuration. ./lxd.nix ]; @@ -16,5 +16,5 @@ networking.useDHCP = false; networking.interfaces.eth0.useDHCP = true; - system.stateVersion = "23.05"; # Did you read the comment? + system.stateVersion = "@stateVersion@"; # Did you read the comment? } diff --git a/nixos/maintainers/scripts/lxd/lxd-virtual-machine-image.nix b/nixos/maintainers/scripts/lxd/lxd-virtual-machine-image.nix index eb0d9217d402..0d96eea0e2d2 100644 --- a/nixos/maintainers/scripts/lxd/lxd-virtual-machine-image.nix +++ b/nixos/maintainers/scripts/lxd/lxd-virtual-machine-image.nix @@ -13,11 +13,15 @@ }; # copy the config for nixos-rebuild - system.activationScripts.config = '' + system.activationScripts.config = let + config = pkgs.substituteAll { + src = ./lxd-virtual-machine-image-inner.nix; + stateVersion = lib.trivial.release; + }; + in '' if [ ! -e /etc/nixos/configuration.nix ]; then mkdir -p /etc/nixos - cat ${./lxd-virtual-machine-image-inner.nix} > /etc/nixos/configuration.nix - ${lib.getExe pkgs.gnused} 's|../../../modules/virtualisation/lxd-virtual-machine.nix||g' -i /etc/nixos/configuration.nix + cp ${config} /etc/nixos/configuration.nix fi ''; diff --git a/nixos/modules/config/users-groups.nix b/nixos/modules/config/users-groups.nix index 97268a8d83ef..b4251214876e 100644 --- a/nixos/modules/config/users-groups.nix +++ b/nixos/modules/config/users-groups.nix @@ -606,6 +606,14 @@ in { defaultText = literalExpression "config.users.users.\${name}.group"; default = cfg.users.${name}.group; }; + options.shell = mkOption { + type = types.passwdEntry types.path; + description = '' + The path to the user's shell in initrd. + ''; + default = "${pkgs.shadow}/bin/nologin"; + defaultText = literalExpression "\${pkgs.shadow}/bin/nologin"; + }; })); }; @@ -750,17 +758,20 @@ in { boot.initrd.systemd = lib.mkIf config.boot.initrd.systemd.enable { contents = { "/etc/passwd".text = '' - ${lib.concatStringsSep "\n" (lib.mapAttrsToList (n: { uid, group }: let + ${lib.concatStringsSep "\n" (lib.mapAttrsToList (n: { uid, group, shell }: let g = config.boot.initrd.systemd.groups.${group}; - in "${n}:x:${toString uid}:${toString g.gid}::/var/empty:") config.boot.initrd.systemd.users)} + in "${n}:x:${toString uid}:${toString g.gid}::/var/empty:${shell}") config.boot.initrd.systemd.users)} ''; "/etc/group".text = '' ${lib.concatStringsSep "\n" (lib.mapAttrsToList (n: { gid }: "${n}:x:${toString gid}:") config.boot.initrd.systemd.groups)} ''; + "/etc/shells".text = lib.concatStringsSep "\n" (lib.unique (lib.mapAttrsToList (_: u: u.shell) config.boot.initrd.systemd.users)) + "\n"; }; + storePaths = [ "${pkgs.shadow}/bin/nologin" ]; + users = { - root = {}; + root = { shell = lib.mkDefault "/bin/bash"; }; nobody = {}; }; diff --git a/nixos/modules/installer/tools/tools.nix b/nixos/modules/installer/tools/tools.nix index d385e4a6b1c8..15e10128ac9a 100644 --- a/nixos/modules/installer/tools/tools.nix +++ b/nixos/modules/installer/tools/tools.nix @@ -224,12 +224,22 @@ in # accidentally delete configuration.nix. # system.copySystemConfiguration = true; - # This value determines the NixOS release from which the default - # settings for stateful data, like file locations and database versions - # on your system were taken. It's perfectly fine and recommended to leave - # this value at the release version of the first install of this system. - # Before changing this value read the documentation for this option - # (e.g. man configuration.nix or on https://nixos.org/nixos/options.html). + # This option defines the first version of NixOS you have installed on this particular machine, + # and is used to maintain compatibility with application data (e.g. databases) created on older NixOS versions. + # + # Most users should NEVER change this value after the initial install, for any reason, + # even if you've upgraded your system to a new NixOS release. + # + # This value does NOT affect the Nixpkgs version your packages and OS are pulled from, + # so changing it will NOT upgrade your system. + # + # This value being lower than the current NixOS release does NOT mean your system is + # out of date, out of support, or vulnerable. + # + # Do NOT change this value unless you have manually inspected all the changes it would make to your configuration, + # and migrated your data accordingly. + # + # For more information, see `man configuration.nix` or https://nixos.org/manual/nixos/stable/options#opt-system.stateVersion . system.stateVersion = "${config.system.nixos.release}"; # Did you read the comment? } diff --git a/nixos/modules/installer/virtualbox-demo.nix b/nixos/modules/installer/virtualbox-demo.nix index 27a7651382b2..01931b2acfca 100644 --- a/nixos/modules/installer/virtualbox-demo.nix +++ b/nixos/modules/installer/virtualbox-demo.nix @@ -21,7 +21,7 @@ with lib; services.xserver.videoDrivers = mkOverride 40 [ "virtualbox" "vmware" "cirrus" "vesa" "modesetting" ]; powerManagement.enable = false; - system.stateVersion = mkDefault "18.03"; + system.stateVersion = lib.mkDefault lib.trivial.release; installer.cloneConfigExtra = '' # Let demo build as a trusted user. diff --git a/nixos/modules/misc/version.nix b/nixos/modules/misc/version.nix index 0a66eafe933e..45dbf45b3ae7 100644 --- a/nixos/modules/misc/version.nix +++ b/nixos/modules/misc/version.nix @@ -121,22 +121,32 @@ in default = cfg.release; defaultText = literalExpression "config.${opt.release}"; description = lib.mdDoc '' - Every once in a while, a new NixOS release may change - configuration defaults in a way incompatible with stateful - data. For instance, if the default version of PostgreSQL - changes, the new version will probably be unable to read your - existing databases. To prevent such breakage, you should set the - value of this option to the NixOS release with which you want - to be compatible. The effect is that NixOS will use - defaults corresponding to the specified release (such as using - an older version of PostgreSQL). - It’s perfectly fine and recommended to leave this value at the - release version of the first install of this system. - Changing this option will not upgrade your system. In fact it - is meant to stay constant exactly when you upgrade your system. - You should only bump this option, if you are sure that you can - or have migrated all state on your system which is affected - by this option. + This option defines the first version of NixOS you have installed on this particular machine, + and is used to maintain compatibility with application data (e.g. databases) created on older NixOS versions. + + For example, if NixOS version XX.YY ships with AwesomeDB version N by default, and is then + upgraded to version XX.YY+1, which ships AwesomeDB version N+1, the existing databases + may no longer be compatible, causing applications to fail, or even leading to data loss. + + The `stateVersion` mechanism avoids this situation by making the default version of such packages + conditional on the first version of NixOS you've installed (encoded in `stateVersion`), instead of + simply always using the latest one. + + Note that this generally only affects applications that can't upgrade their data automatically - + applications and services supporting automatic migrations will remain on latest versions when + you upgrade. + + Most users should **never** change this value after the initial install, for any reason, + even if you've upgraded your system to a new NixOS release. + + This value does **not** affect the Nixpkgs version your packages and OS are pulled from, + so changing it will **not** upgrade your system. + + This value being lower than the current NixOS release does **not** mean your system is + out of date, out of support, or vulnerable. + + Do **not** change this value unless you have manually inspected all the changes it would + make to your configuration, and migrated your data accordingly. ''; }; diff --git a/nixos/modules/services/networking/gvpe.nix b/nixos/modules/services/networking/gvpe.nix index 2279ceee2f58..558f499022c8 100644 --- a/nixos/modules/services/networking/gvpe.nix +++ b/nixos/modules/services/networking/gvpe.nix @@ -29,7 +29,7 @@ let export PATH=$PATH:${pkgs.iproute2}/sbin - ip link set $IFNAME up + ip link set dev $IFNAME up ip address add ${cfg.ipAddress} dev $IFNAME ip route add ${cfg.subnet} dev $IFNAME diff --git a/nixos/modules/services/networking/ssh/sshd.nix b/nixos/modules/services/networking/ssh/sshd.nix index daa30fe09b89..f54ce5917438 100644 --- a/nixos/modules/services/networking/ssh/sshd.nix +++ b/nixos/modules/services/networking/ssh/sshd.nix @@ -12,22 +12,44 @@ let then cfgc.package else pkgs.buildPackages.openssh; - # reports boolean as yes / no - mkValueStringSshd = with lib; v: - if isInt v then toString v - else if isString v then v - else if true == v then "yes" - else if false == v then "no" - else if isList v then concatStringsSep "," v - else throw "unsupported type ${builtins.typeOf v}: ${(lib.generators.toPretty {}) v}"; - # dont use the "=" operator - settingsFormat = (pkgs.formats.keyValue { - mkKeyValue = lib.generators.mkKeyValueDefault { - mkValueString = mkValueStringSshd; - } " ";}); + settingsFormat = + let + # reports boolean as yes / no + mkValueString = with lib; v: + if isInt v then toString v + else if isString v then v + else if true == v then "yes" + else if false == v then "no" + else throw "unsupported type ${builtins.typeOf v}: ${(lib.generators.toPretty {}) v}"; - configFile = settingsFormat.generate "sshd.conf-settings" cfg.settings; + base = pkgs.formats.keyValue { + mkKeyValue = lib.generators.mkKeyValueDefault { inherit mkValueString; } " "; + }; + # OpenSSH is very inconsistent with options that can take multiple values. + # For some of them, they can simply appear multiple times and are appended, for others the + # values must be separated by whitespace or even commas. + # Consult either sshd_config(5) or, as last resort, the OpehSSH source for parsing + # the options at servconf.c:process_server_config_line_depth() to determine the right "mode" + # for each. But fortunaly this fact is documented for most of them in the manpage. + commaSeparated = [ "Ciphers" "KexAlgorithms" "Macs" ]; + spaceSeparated = [ "AuthorizedKeysFile" "AllowGroups" "AllowUsers" "DenyGroups" "DenyUsers" ]; + in { + inherit (base) type; + generate = name: value: + let transformedValue = mapAttrs (key: val: + if isList val then + if elem key commaSeparated then concatStringsSep "," val + else if elem key spaceSeparated then concatStringsSep " " val + else throw "list value for unknown key ${key}: ${(lib.generators.toPretty {}) val}" + else + val + ) value; + in + base.generate name transformedValue; + }; + + configFile = settingsFormat.generate "sshd.conf-settings" (filterAttrs (n: v: v != null) cfg.settings); sshconf = pkgs.runCommand "sshd.conf-final" { } '' cat ${configFile} - >$out < ''; }; + AllowUsers = mkOption { + type = with types; nullOr (listOf str); + default = null; + description = lib.mdDoc '' + If specified, login is allowed only for the listed users. + See {manpage}`sshd_config(5)` for details. + ''; + }; + DenyUsers = mkOption { + type = with types; nullOr (listOf str); + default = null; + description = lib.mdDoc '' + If specified, login is denied for all listed users. Takes + precedence over [](#opt-services.openssh.settings.AllowUsers). + See {manpage}`sshd_config(5)` for details. + ''; + }; + AllowGroups = mkOption { + type = with types; nullOr (listOf str); + default = null; + description = lib.mdDoc '' + If specified, login is allowed only for users part of the + listed groups. + See {manpage}`sshd_config(5)` for details. + ''; + }; + DenyGroups = mkOption { + type = with types; nullOr (listOf str); + default = null; + description = lib.mdDoc '' + If specified, login is denied for all users part of the listed + groups. Takes precedence over + [](#opt-services.openssh.settings.AllowGroups). See + {manpage}`sshd_config(5)` for details. + ''; + }; }; }); }; diff --git a/nixos/modules/system/activation/activation-script.nix b/nixos/modules/system/activation/activation-script.nix index 95b0c7bbd681..bc0b7266ce95 100644 --- a/nixos/modules/system/activation/activation-script.nix +++ b/nixos/modules/system/activation/activation-script.nix @@ -230,7 +230,6 @@ in system.activationScripts.stdio = ""; # obsolete system.activationScripts.var = ""; # obsolete - system.activationScripts.specialfs = ""; # obsolete systemd.tmpfiles.rules = [ # Prevent the current configuration from being garbage-collected. @@ -252,6 +251,25 @@ in rmdir --ignore-fail-on-non-empty /usr/bin /usr ''; + system.activationScripts.specialfs = + '' + specialMount() { + local device="$1" + local mountPoint="$2" + local options="$3" + local fsType="$4" + + if mountpoint -q "$mountPoint"; then + local options="remount,$options" + else + mkdir -p "$mountPoint" + chmod 0755 "$mountPoint" + fi + mount -t "$fsType" -o "$options" "$device" "$mountPoint" + } + source ${config.system.build.earlyMountScript} + ''; + systemd.user = { services.nixos-activation = { description = "Run user-specific NixOS activation"; diff --git a/nixos/modules/system/boot/initrd-network.nix b/nixos/modules/system/boot/initrd-network.nix index 5bf38b6fa200..5696cae8e65b 100644 --- a/nixos/modules/system/boot/initrd-network.nix +++ b/nixos/modules/system/boot/initrd-network.nix @@ -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. @@ -152,8 +152,8 @@ in boot.initrd.postMountCommands = mkIf cfg.flushBeforeStage2 '' 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 60c5ff62ffff..3df14030ab68 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/tasks/network-interfaces-scripted.nix b/nixos/modules/tasks/network-interfaces-scripted.nix index da4aa916d655..e1ac7f24cb32 100644 --- a/nixos/modules/tasks/network-interfaces-scripted.nix +++ b/nixos/modules/tasks/network-interfaces-scripted.nix @@ -28,12 +28,12 @@ let SLAVES=$(ip link | grep 'master ${i}' | awk -F: '{print $2}') for I in $SLAVES; do UPDATED=0 - ip link set "$I" nomaster + ip link set dev "$I" nomaster done [ "$UPDATED" -eq "1" ] && break done - ip link set "${i}" down 2>/dev/null || true - ip link del "${i}" 2>/dev/null || true + ip link set dev "${i}" down 2>/dev/null || true + ip link del dev "${i}" 2>/dev/null || true ''; # warn that these attributes are deprecated (2017-2-2) @@ -193,7 +193,7 @@ let state="/run/nixos/network/addresses/${i.name}" mkdir -p $(dirname "$state") - ip link set "${i.name}" up + ip link set dev "${i.name}" up ${flip concatMapStrings ips (ip: let @@ -270,7 +270,7 @@ let ip tuntap add dev "${i.name}" mode "${i.virtualType}" user "${i.virtualOwner}" ''; postStop = '' - ip link del ${i.name} || true + ip link del dev ${i.name} || true ''; }; @@ -291,15 +291,15 @@ let script = '' # Remove Dead Interfaces echo "Removing old bridge ${n}..." - ip link show dev "${n}" >/dev/null 2>&1 && ip link del "${n}" + ip link show dev "${n}" >/dev/null 2>&1 && ip link del dev "${n}" echo "Adding bridge ${n}..." ip link add name "${n}" type bridge # Enslave child interfaces ${flip concatMapStrings v.interfaces (i: '' - ip link set "${i}" master "${n}" - ip link set "${i}" up + ip link set dev "${i}" master "${n}" + ip link set dev "${i}" up '')} # Save list of enslaved interfaces echo "${flip concatMapStrings v.interfaces (i: '' @@ -316,7 +316,7 @@ let for uri in qemu:///system lxc:///; do for dom in $(${pkgs.libvirt}/bin/virsh -c $uri list --name); do ${pkgs.libvirt}/bin/virsh -c $uri dumpxml "$dom" | \ - ${pkgs.xmlstarlet}/bin/xmlstarlet sel -t -m "//domain/devices/interface[@type='bridge'][source/@bridge='${n}'][target/@dev]" -v "concat('ip link set ',target/@dev,' master ',source/@bridge,';')" | \ + ${pkgs.xmlstarlet}/bin/xmlstarlet sel -t -m "//domain/devices/interface[@type='bridge'][source/@bridge='${n}'][target/@dev]" -v "concat('ip link set dev ',target/@dev,' master ',source/@bridge,';')" | \ ${pkgs.bash}/bin/bash done done @@ -328,23 +328,23 @@ let echo 2 >/sys/class/net/${n}/bridge/stp_state ''} - ip link set "${n}" up + ip link set dev "${n}" up ''; postStop = '' - ip link set "${n}" down || true - ip link del "${n}" || true + ip link set dev "${n}" down || true + ip link del dev "${n}" || true rm -f /run/${n}.interfaces ''; reload = '' # Un-enslave child interfaces (old list of interfaces) for interface in `cat /run/${n}.interfaces`; do - ip link set "$interface" nomaster up + ip link set dev "$interface" nomaster up done # Enslave child interfaces (new list of interfaces) ${flip concatMapStrings v.interfaces (i: '' - ip link set "${i}" master "${n}" - ip link set "${i}" up + ip link set dev "${i}" master "${n}" + ip link set dev "${i}" up '')} # Save list of enslaved interfaces echo "${flip concatMapStrings v.interfaces (i: '' @@ -395,7 +395,7 @@ let postStop = '' echo "Cleaning Open vSwitch ${n}" echo "Shutting down internal ${n} interface" - ip link set ${n} down || true + ip link set dev ${n} down || true echo "Deleting flows for ${n}" ovs-ofctl --protocols=${v.openFlowVersion} del-flows ${n} || true echo "Deleting Open vSwitch ${n}" @@ -433,10 +433,10 @@ let while [ ! -d "/sys/class/net/${n}" ]; do sleep 0.1; done; # Bring up the bond and enslave the specified interfaces - ip link set "${n}" up + ip link set dev "${n}" up ${flip concatMapStrings v.interfaces (i: '' - ip link set "${i}" down - ip link set "${i}" master "${n}" + ip link set dev "${i}" down + ip link set dev "${i}" master "${n}" '')} ''; postStop = destroyBond n; @@ -457,13 +457,13 @@ let path = [ pkgs.iproute2 ]; script = '' # Remove Dead Interfaces - ip link show dev "${n}" >/dev/null 2>&1 && ip link delete "${n}" + ip link show dev "${n}" >/dev/null 2>&1 && ip link delete dev "${n}" ip link add link "${v.interface}" name "${n}" type macvlan \ ${optionalString (v.mode != null) "mode ${v.mode}"} - ip link set "${n}" up + ip link set dev "${n}" up ''; postStop = '' - ip link delete "${n}" || true + ip link delete dev "${n}" || true ''; }); @@ -515,7 +515,7 @@ let path = [ pkgs.iproute2 ]; script = '' # Remove Dead Interfaces - ip link show dev "${n}" >/dev/null 2>&1 && ip link delete "${n}" + ip link show dev "${n}" >/dev/null 2>&1 && ip link delete dev "${n}" ip link add name "${n}" type sit \ ${optionalString (v.remote != null) "remote \"${v.remote}\""} \ ${optionalString (v.local != null) "local \"${v.local}\""} \ @@ -526,10 +526,10 @@ let optionalString (v.encapsulation.sourcePort != null) "encap-sport ${toString v.encapsulation.sourcePort}" }"} - ip link set "${n}" up + ip link set dev "${n}" up ''; postStop = '' - ip link delete "${n}" || true + ip link delete dev "${n}" || true ''; }); @@ -549,16 +549,16 @@ let path = [ pkgs.iproute2 ]; script = '' # Remove Dead Interfaces - ip link show dev "${n}" >/dev/null 2>&1 && ip link delete "${n}" + ip link show dev "${n}" >/dev/null 2>&1 && ip link delete dev "${n}" ip link add name "${n}" type ${v.type} \ ${optionalString (v.remote != null) "remote \"${v.remote}\""} \ ${optionalString (v.local != null) "local \"${v.local}\""} \ ${optionalString (v.ttl != null) "${ttlarg} ${toString v.ttl}"} \ ${optionalString (v.dev != null) "dev \"${v.dev}\""} - ip link set "${n}" up + ip link set dev "${n}" up ''; postStop = '' - ip link delete "${n}" || true + ip link delete dev "${n}" || true ''; }); @@ -577,17 +577,17 @@ let path = [ pkgs.iproute2 ]; script = '' # Remove Dead Interfaces - ip link show dev "${n}" >/dev/null 2>&1 && ip link delete "${n}" + ip link show dev "${n}" >/dev/null 2>&1 && ip link delete dev "${n}" ip link add link "${v.interface}" name "${n}" type vlan id "${toString v.id}" # We try to bring up the logical VLAN interface. If the master # interface the logical interface is dependent upon is not up yet we will # fail to immediately bring up the logical interface. The resulting logical # interface will brought up later when the master interface is up. - ip link set "${n}" up || true + ip link set dev "${n}" up || true ''; postStop = '' - ip link delete "${n}" || true + ip link delete dev "${n}" || true ''; }); diff --git a/nixos/modules/tasks/network-interfaces-systemd.nix b/nixos/modules/tasks/network-interfaces-systemd.nix index cee23eb24406..2009c9a7e6e2 100644 --- a/nixos/modules/tasks/network-interfaces-systemd.nix +++ b/nixos/modules/tasks/network-interfaces-systemd.nix @@ -442,7 +442,7 @@ in postStop = '' echo "Cleaning Open vSwitch ${n}" echo "Shutting down internal ${n} interface" - ip link set ${n} down || true + ip link set dev ${n} down || true echo "Deleting flows for ${n}" ovs-ofctl --protocols=${v.openFlowVersion} del-flows ${n} || true echo "Deleting Open vSwitch ${n}" diff --git a/nixos/modules/virtualisation/nixos-containers.nix b/nixos/modules/virtualisation/nixos-containers.nix index aa85665af695..6fdb177b968b 100644 --- a/nixos/modules/virtualisation/nixos-containers.nix +++ b/nixos/modules/virtualisation/nixos-containers.nix @@ -754,7 +754,7 @@ in { services.postgresql.enable = true; services.postgresql.package = pkgs.postgresql_14; - system.stateVersion = "21.05"; + system.stateVersion = "${lib.trivial.release}"; }; }; } @@ -906,4 +906,6 @@ in "tun" ]; }); + + meta.buildDocsInSandbox = false; } diff --git a/nixos/release.nix b/nixos/release.nix index a5909fa7bbdd..2acc5ade7848 100644 --- a/nixos/release.nix +++ b/nixos/release.nix @@ -398,7 +398,7 @@ in rec { modules = singleton ({ ... }: { fileSystems."/".device = mkDefault "/dev/sda1"; boot.loader.grub.device = mkDefault "/dev/sda"; - system.stateVersion = mkDefault "18.03"; + system.stateVersion = mkDefault lib.trivial.release; }); }).config.system.build.toplevel; preferLocalBuild = true; diff --git a/nixos/tests/all-tests.nix b/nixos/tests/all-tests.nix index 9109ab3e2482..2f6d5a8dae88 100644 --- a/nixos/tests/all-tests.nix +++ b/nixos/tests/all-tests.nix @@ -90,6 +90,14 @@ in { lib-extend = handleTestOn [ "x86_64-linux" "aarch64-linux" ] ./nixos-test-driver/lib-extend.nix {}; node-name = runTest ./nixos-test-driver/node-name.nix; busybox = runTest ./nixos-test-driver/busybox.nix; + driver-timeout = pkgs.runCommand "ensure-timeout-induced-failure" { + failed = pkgs.testers.testBuildFailure ((runTest ./nixos-test-driver/timeout.nix).config.rawTestDerivation); + } '' + grep -F "timeout reached; test terminating" $failed/testBuildFailure.log + # The program will always be terminated by SIGTERM (143) if it waits for the deadline thread. + [[ 143 = $(cat $failed/testBuildFailure.exit) ]] + touch $out + ''; }; # NixOS vm tests and non-vm unit tests diff --git a/nixos/tests/containers-imperative.nix b/nixos/tests/containers-imperative.nix index 22b664a90e17..18bec1db78e8 100644 --- a/nixos/tests/containers-imperative.nix +++ b/nixos/tests/containers-imperative.nix @@ -21,9 +21,7 @@ import ./make-test-python.nix ({ pkgs, lib, ... }: { modules = lib.singleton { nixpkgs = { inherit (config.nixpkgs) localSystem; }; - containers.foo.config = { - system.stateVersion = "18.03"; - }; + containers.foo.config = {}; }; # The system is inherited from the host above. diff --git a/nixos/tests/nextcloud/basic.nix b/nixos/tests/nextcloud/basic.nix index b7af6d6d7364..ab1d8353dba0 100644 --- a/nixos/tests/nextcloud/basic.nix +++ b/nixos/tests/nextcloud/basic.nix @@ -37,8 +37,6 @@ in { "d /var/lib/nextcloud-data 0750 nextcloud nginx - -" ]; - system.stateVersion = "22.11"; # stateVersion >=21.11 to make sure that we use OpenSSL3 - services.nextcloud = { enable = true; datadir = "/var/lib/nextcloud-data"; diff --git a/nixos/tests/nixos-test-driver/timeout.nix b/nixos/tests/nixos-test-driver/timeout.nix new file mode 100644 index 000000000000..29bd85d2498e --- /dev/null +++ b/nixos/tests/nixos-test-driver/timeout.nix @@ -0,0 +1,15 @@ +{ + name = "Test that sleep of 6 seconds fails a timeout of 5 seconds"; + globalTimeout = 5; + + nodes = { + machine = ({ pkgs, ... }: { + }); + }; + + testScript = '' + start_all() + machine.wait_for_unit("multi-user.target") + machine.succeed("sleep 6") + ''; +} diff --git a/nixos/tests/openssh.nix b/nixos/tests/openssh.nix index 88d3e54ee76c..881eb9d7d91c 100644 --- a/nixos/tests/openssh.nix +++ b/nixos/tests/openssh.nix @@ -82,6 +82,19 @@ in { }; }; + server_allowedusers = + { ... }: + + { + services.openssh = { enable = true; settings.AllowUsers = [ "alice" "bob" ]; }; + users.groups = { alice = { }; bob = { }; carol = { }; }; + users.users = { + alice = { isNormalUser = true; group = "alice"; openssh.authorizedKeys.keys = [ snakeOilPublicKey ]; }; + bob = { isNormalUser = true; group = "bob"; openssh.authorizedKeys.keys = [ snakeOilPublicKey ]; }; + carol = { isNormalUser = true; group = "carol"; openssh.authorizedKeys.keys = [ snakeOilPublicKey ]; }; + }; + }; + client = { ... }: { }; @@ -147,5 +160,23 @@ in { with subtest("match-rules"): server_match_rule.succeed("ss -nlt | grep '127.0.0.1:22'") + + with subtest("allowed-users"): + client.succeed( + "cat ${snakeOilPrivateKey} > privkey.snakeoil" + ) + client.succeed("chmod 600 privkey.snakeoil") + client.succeed( + "ssh -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -i privkey.snakeoil alice@server_allowedusers true", + timeout=30 + ) + client.succeed( + "ssh -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -i privkey.snakeoil bob@server_allowedusers true", + timeout=30 + ) + client.fail( + "ssh -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -i privkey.snakeoil carol@server_allowedusers true", + timeout=30 + ) ''; }) diff --git a/pkgs/applications/audio/vgmstream/default.nix b/pkgs/applications/audio/vgmstream/default.nix index f696c5061864..6b5e6460172d 100644 --- a/pkgs/applications/audio/vgmstream/default.nix +++ b/pkgs/applications/audio/vgmstream/default.nix @@ -1,21 +1,23 @@ { stdenv, lib, fetchFromGitHub, cmake, pkg-config , mpg123, ffmpeg, libvorbis, libao, jansson, speex +, nix-update-script }: -let - vgmstreamVersion = "r1702-5596-00bdb165b"; -in + stdenv.mkDerivation rec { pname = "vgmstream"; - version = "unstable-2022-02-21"; + version = "1879"; src = fetchFromGitHub { owner = "vgmstream"; repo = "vgmstream"; - rev = "00bdb165ba6b55420bbd5b21f54c4f7a825d15a0"; - sha256 = "18g1yqlnf48hi2xn2z2wajnjljpdbfdqmcmi7y8hi1r964ypmfcr"; + rev = "refs/tags/r${version}"; + sha256 = "sha256-m7M9oIEym/jzuw2HAbjdF6fZsfTew1KK0g1D4SePiiE="; }; - passthru.updateScript = ./update.sh; + passthru.updateScript = nix-update-script { + attrPath = "vgmstream"; + extraArgs = [ "--version-regex" "r(.*)" ]; + }; nativeBuildInputs = [ cmake pkg-config ]; @@ -28,10 +30,6 @@ stdenv.mkDerivation rec { "-DUSE_CELT=OFF" ]; - postConfigure = '' - echo "#define VGMSTREAM_VERSION \"${vgmstreamVersion}\"" > ../version.h - ''; - meta = with lib; { description = "A library for playback of various streamed audio formats used in video games"; homepage = "https://vgmstream.org"; diff --git a/pkgs/applications/audio/vgmstream/update.sh b/pkgs/applications/audio/vgmstream/update.sh deleted file mode 100755 index 5353480dd335..000000000000 --- a/pkgs/applications/audio/vgmstream/update.sh +++ /dev/null @@ -1,77 +0,0 @@ -#!/usr/bin/env nix-shell -#!nix-shell -i bash --pure --keep GITHUB_TOKEN -p gnused jq nix-prefetch-git curl cacert - -set -euo pipefail - -ROOT="$(dirname "$(readlink -f "$0")")" -if [[ ! "$(basename $ROOT)" == "vgmstream" || ! -f "$ROOT/default.nix" ]]; then - echo "ERROR: Not in the vgmstream folder" - exit 1 -fi - -if [[ ! -v GITHUB_TOKEN ]]; then - echo "ERROR: \$GITHUB_TOKEN not set" - exit 1 -fi - - -payload=$(jq -cn --rawfile query /dev/stdin '{"query": $query}' <