diff --git a/checks/flake-module.nix b/checks/flake-module.nix index 8cb587f45..a6f4a0eff 100644 --- a/checks/flake-module.nix +++ b/checks/flake-module.nix @@ -22,7 +22,6 @@ in imports = filter pathExists [ ./backups/flake-module.nix ../nixosModules/clanCore/machine-id/tests/flake-module.nix - ../nixosModules/clanCore/state-version/tests/flake-module.nix ./devshell/flake-module.nix ./flash/flake-module.nix ./impure/flake-module.nix diff --git a/clanModules/flake-module.nix b/clanModules/flake-module.nix index 2cbdd6744..54bcfc4d1 100644 --- a/clanModules/flake-module.nix +++ b/clanModules/flake-module.nix @@ -33,6 +33,7 @@ in root-password = ./root-password; single-disk = ./single-disk; sshd = ./sshd; + state-version = ./state-version; static-hosts = ./static-hosts; sunshine = ./sunshine; syncthing = ./syncthing; diff --git a/clanModules/state-version/README.md b/clanModules/state-version/README.md new file mode 100644 index 000000000..f8544f0de --- /dev/null +++ b/clanModules/state-version/README.md @@ -0,0 +1,18 @@ +--- +description = "Automatically generate the state version of the nixos installation." +features = [ "inventory", "deprecated" ] +--- + +This module generates the `system.stateVersion` of the nixos installation automatically. + +Options: [system.stateVersion](https://search.nixos.org/options?channel=unstable&show=system.stateVersion&from=0&size=50&sort=relevance&type=packages&query=stateVersion) + +Migration: +If you are already setting `system.stateVersion`, then import the module and then either let the automatic generation happen, or trigger the generation manually for the machine. The module will take the specified version, if one is already supplied through the config. +To manually generate the version for a specified machine run: + +``` +clan vars generate [MACHINE] +``` + +If the setting was already set you can then remove `system.stateVersion` from your machine configuration. For new machines, just import the module. diff --git a/clanModules/state-version/default.nix b/clanModules/state-version/default.nix new file mode 100644 index 000000000..ed6af3368 --- /dev/null +++ b/clanModules/state-version/default.nix @@ -0,0 +1,6 @@ +# Dont import this file +# It is only here for backwards compatibility. +# Dont author new modules with this file. +{ + imports = [ ./roles/default.nix ]; +} diff --git a/clanModules/state-version/roles/default.nix b/clanModules/state-version/roles/default.nix new file mode 100644 index 000000000..a136e8432 --- /dev/null +++ b/clanModules/state-version/roles/default.nix @@ -0,0 +1,25 @@ +{ config, lib, ... }: +let + var = config.clan.core.vars.generators.state-version.files.version or { }; +in +{ + + warnings = [ + "The clan.state-version module is deprecated and will be removed on 2025-07-15. + Please migrate to user-maintained configuration or the new equivalent clan services + (https://docs.clan.lol/reference/clanServices)." + ]; + + system.stateVersion = lib.mkDefault (lib.removeSuffix "\n" var.value); + + clan.core.vars.generators.state-version = { + files.version = { + secret = false; + value = lib.mkDefault config.system.nixos.release; + }; + runtimeInputs = [ ]; + script = '' + echo -n ${config.system.stateVersion} > "$out"/version + ''; + }; +} diff --git a/clanServices/state-version/README.md b/clanServices/state-version/README.md new file mode 100644 index 000000000..c55063b66 --- /dev/null +++ b/clanServices/state-version/README.md @@ -0,0 +1,37 @@ +This service generates the `system.stateVersion` of the nixos installation +automatically. + +Possible values: +[system.stateVersion](https://search.nixos.org/options?channel=unstable&show=system.stateVersion&from=0&size=50&sort=relevance&type=packages&query=stateVersion) + +## Usage + +The following configuration will set `stateVersion` for all machines: + +``` +inventory.instances = { + state-version = { + module = { + name = "state-version"; + input = "clan"; + }; + roles.default.tags.all = { }; + }; +``` + +## Migration + +If you are already setting `system.stateVersion`, either let the automatic +generation happen, or trigger the generation manually for the machine. The +service will take the specified version, if one is already supplied through the +config. + +To manually generate the version for a specified machine run: + +``` +clan vars generate [MACHINE] +``` + +If the setting was already set, you can then remove `system.stateVersion` from +your machine configuration. For new machines, just import the service as shown +above. diff --git a/clanServices/state-version/default.nix b/clanServices/state-version/default.nix new file mode 100644 index 000000000..34a0575e8 --- /dev/null +++ b/clanServices/state-version/default.nix @@ -0,0 +1,39 @@ +{ ... }: +{ + _class = "clan.service"; + manifest.name = "clan-core/state-version"; + manifest.description = "Automatically generate the state version of the nixos installation."; + manifest.categories = [ "System" ]; + + roles.default = { + + perInstance = + { ... }: + { + nixosModule = + { + config, + lib, + ... + }: + let + var = config.clan.core.vars.generators.state-version.files.version or { }; + in + { + system.stateVersion = lib.mkDefault (lib.removeSuffix "\n" var.value); + + clan.core.vars.generators.state-version = { + files.version = { + secret = false; + value = lib.mkDefault config.system.nixos.release; + }; + runtimeInputs = [ ]; + script = '' + echo -n ${config.system.stateVersion} > "$out"/version + ''; + }; + }; + }; + }; + +} diff --git a/clanServices/state-version/flake-module.nix b/clanServices/state-version/flake-module.nix new file mode 100644 index 000000000..c4ff9d633 --- /dev/null +++ b/clanServices/state-version/flake-module.nix @@ -0,0 +1,16 @@ +{ lib, ... }: +let + module = lib.modules.importApply ./default.nix { }; +in +{ + clan.modules.state-version = module; + perSystem = + { ... }: + { + clan.nixosTests.state-version = { + imports = [ ./tests/vm/default.nix ]; + + clan.modules."@clan/state-version" = module; + }; + }; +} diff --git a/clanServices/state-version/tests/vm/default.nix b/clanServices/state-version/tests/vm/default.nix new file mode 100644 index 000000000..efd4a6f14 --- /dev/null +++ b/clanServices/state-version/tests/vm/default.nix @@ -0,0 +1,21 @@ +{ + name = "state-version"; + + clan = { + directory = ./.; + inventory = { + machines.server = { }; + instances.default = { + module.name = "@clan/state-version"; + module.input = "self"; + roles.default.machines."server" = { }; + }; + }; + }; + + nodes.server = { }; + + testScript = '' + start_all() + ''; +} diff --git a/nixosModules/clanCore/state-version/tests/sops/users/admin/key.json b/clanServices/state-version/tests/vm/sops/users/admin/key.json similarity index 100% rename from nixosModules/clanCore/state-version/tests/sops/users/admin/key.json rename to clanServices/state-version/tests/vm/sops/users/admin/key.json diff --git a/nixosModules/clanCore/state-version/tests/vars/per-machine/server/state-version/version/value b/clanServices/state-version/tests/vm/vars/per-machine/server/state-version/version/value similarity index 100% rename from nixosModules/clanCore/state-version/tests/vars/per-machine/server/state-version/version/value rename to clanServices/state-version/tests/vm/vars/per-machine/server/state-version/version/value diff --git a/docs/mkdocs.yml b/docs/mkdocs.yml index 27fb6bbb6..c40d39159 100644 --- a/docs/mkdocs.yml +++ b/docs/mkdocs.yml @@ -92,6 +92,7 @@ nav: - reference/clanServices/mycelium.md - reference/clanServices/packages.md - reference/clanServices/sshd.md + - reference/clanServices/state-version.md - reference/clanServices/trusted-nix-caches.md - reference/clanServices/users.md - reference/clanServices/wifi.md @@ -126,6 +127,7 @@ nav: - reference/clanModules/root-password.md - reference/clanModules/single-disk.md - reference/clanModules/sshd.md + - reference/clanModules/state-version.md - reference/clanModules/static-hosts.md - reference/clanModules/sunshine.md - reference/clanModules/syncthing-static-peers.md diff --git a/nixosModules/clanCore/default.nix b/nixosModules/clanCore/default.nix index 891b7cec5..2b2c3990b 100644 --- a/nixosModules/clanCore/default.nix +++ b/nixosModules/clanCore/default.nix @@ -19,7 +19,6 @@ ./nixos-facter.nix ./vm.nix ./machine-id - ./state-version ./wayland-proxy-virtwl.nix ./zerotier ./zfs.nix diff --git a/pkgs/clan-cli/clan_cli/tests/sshd.py b/pkgs/clan-cli/clan_cli/tests/sshd.py index d40b06568..edd84d0c5 100644 --- a/pkgs/clan-cli/clan_cli/tests/sshd.py +++ b/pkgs/clan-cli/clan_cli/tests/sshd.py @@ -42,7 +42,7 @@ class SshdConfig: def sshd_config(test_root: Path) -> Iterator[SshdConfig]: # FIXME, if any parent of the sshd directory is world-writable then sshd will refuse it. # we use .direnv instead since it's already in .gitignore - with TemporaryDirectory(prefix="sshd-") as _dir: + with TemporaryDirectory(prefix="sshd-", ignore_cleanup_errors=True) as _dir: tmpdir = Path(_dir) host_key = test_root / "data" / "ssh_host_ed25519_key" host_key.chmod(0o600) diff --git a/pkgs/clan-cli/clan_lib/tests/test_create.py b/pkgs/clan-cli/clan_lib/tests/test_create.py index 40e476912..940469291 100644 --- a/pkgs/clan-cli/clan_lib/tests/test_create.py +++ b/pkgs/clan-cli/clan_lib/tests/test_create.py @@ -63,7 +63,17 @@ def create_base_inventory(ssh_keys_pairs: list[SSHKeyPair]) -> InventoryWrapper: ssh_keys.append(InvSSHKeyEntry(f"user_{num}", ssh_key.public.read_text())) """Create the base inventory structure.""" - legacy_services: dict[str, Any] = {} + legacy_services: dict[str, Any] = { + "state-version": { + "someid": { + "roles": { + "default": { + "tags": ["all"], + } + } + } + }, + } instances = InventoryInstancesType( { diff --git a/templates/clan/new-clan/modules/shared.nix b/templates/clan/new-clan/modules/shared.nix index d6dc92a85..23f8a3fb3 100644 --- a/templates/clan/new-clan/modules/shared.nix +++ b/templates/clan/new-clan/modules/shared.nix @@ -12,6 +12,7 @@ # Set a root password clan-core.clanModules.root-password clan-core.clanModules.user-password + clan-core.clanModules.state-version # You can access other flakes imported in your flake via `self` like this: # self.inputs.nix-index-database.nixosModules.nix-index