diff --git a/nixos/modules/system/activation/specialisation.nix b/nixos/modules/system/activation/specialisation.nix index fdab287802fa5..fc348ad94c03a 100644 --- a/nixos/modules/system/activation/specialisation.nix +++ b/nixos/modules/system/activation/specialisation.nix @@ -1,10 +1,14 @@ -{ config, lib, pkgs, extendModules, noUserModules, ... }: +{ config, lib, extendModules, noUserModules, ... }: let inherit (lib) + attrNames concatStringsSep + filter + length mapAttrs mapAttrsToList + match mkOption types ; @@ -73,6 +77,19 @@ in }; config = { + assertions = [( + let + invalidNames = filter (name: match "[[:alnum:]_]+" name == null) (attrNames config.specialisation); + in + { + assertion = length invalidNames == 0; + message = '' + Specialisation names can only contain alphanumeric characters and underscores + Invalid specialisation names: ${concatStringsSep ", " invalidNames} + ''; + } + )]; + system.systemBuilderCommands = '' mkdir $out/specialisation ${concatStringsSep "\n" diff --git a/nixos/modules/system/boot/loader/systemd-boot/systemd-boot-builder.py b/nixos/modules/system/boot/loader/systemd-boot/systemd-boot-builder.py index 846787985ceab..c4324a8eae5bc 100644 --- a/nixos/modules/system/boot/loader/systemd-boot/systemd-boot-builder.py +++ b/nixos/modules/system/boot/loader/systemd-boot/systemd-boot-builder.py @@ -65,7 +65,7 @@ def from_path(cls: Type["Entry"], path: Path) -> "Entry": # Matching nixos*-generation-$number*.conf rex_generation = re.compile(r"^nixos.*-generation-([0-9]+).*\.conf$") # Matching nixos*-generation-$number-specialisation-$specialisation_name*.conf - rex_specialisation = re.compile(r"^nixos.*-generation-([0-9]+)-specialisation-([a-zA-Z0-9]+).*\.conf$") + rex_specialisation = re.compile(r"^nixos.*-generation-([0-9]+)-specialisation-([a-zA-Z0-9_]+).*\.conf$") profile = rex_profile.sub(r"\1", filename) if rex_profile.match(filename) else None specialisation = rex_specialisation.sub(r"\2", filename) if rex_specialisation.match(filename) else None try: diff --git a/nixos/tests/nixos-rebuild-specialisations.nix b/nixos/tests/nixos-rebuild-specialisations.nix index 9192b8a8a030b..a5b916f7d7e90 100644 --- a/nixos/tests/nixos-rebuild-specialisations.nix +++ b/nixos/tests/nixos-rebuild-specialisations.nix @@ -71,6 +71,32 @@ import ./make-test-python.nix ({ pkgs, ... }: { } ''; + wrongConfigFile = pkgs.writeText "configuration.nix" '' + { lib, pkgs, ... }: { + imports = [ + ./hardware-configuration.nix + + ]; + + boot.loader.grub = { + enable = true; + device = "/dev/vda"; + forceInstall = true; + }; + + documentation.enable = false; + + environment.systemPackages = [ + (pkgs.writeShellScriptBin "parent" "") + ]; + + specialisation.foo-bar = { + inheritParentConfig = true; + + configuration = { ... }: { }; + }; + } + ''; in '' machine.start() @@ -116,5 +142,12 @@ import ./make-test-python.nix ({ pkgs, ... }: { with subtest("Make sure nonsense command combinations are forbidden"): machine.fail("nixos-rebuild boot --specialisation foo") machine.fail("nixos-rebuild boot -c foo") + + machine.copy_from_host( + "${wrongConfigFile}", + "/etc/nixos/configuration.nix", + ) + with subtest("Make sure that invalid specialisation names are rejected"): + machine.fail("nixos-rebuild switch") ''; })