From 94c7834ac7104b2fa037096ea18a6c771cc393b6 Mon Sep 17 00:00:00 2001 From: Michael Hoang Date: Tue, 25 Mar 2025 13:45:51 +0900 Subject: [PATCH 1/5] flake: add `nix-darwin` --- flake.lock | 21 +++++++++++++++++++++ flake.nix | 3 +++ 2 files changed, 24 insertions(+) diff --git a/flake.lock b/flake.lock index 567efea86..ed3a52c45 100644 --- a/flake.lock +++ b/flake.lock @@ -69,6 +69,26 @@ "type": "github" } }, + "nix-darwin": { + "inputs": { + "nixpkgs": [ + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1743496612, + "narHash": "sha256-emPWa5lmKbnyuj8c1mSJUkzJNT+iJoU9GMcXwjp2oVM=", + "owner": "LnL7", + "repo": "nix-darwin", + "rev": "73d59580d01e9b9f957ba749f336a272869c42dd", + "type": "github" + }, + "original": { + "owner": "LnL7", + "repo": "nix-darwin", + "type": "github" + } + }, "nixos-facter-modules": { "locked": { "lastModified": 1743671943, @@ -102,6 +122,7 @@ "data-mesher": "data-mesher", "disko": "disko", "flake-parts": "flake-parts", + "nix-darwin": "nix-darwin", "nixos-facter-modules": "nixos-facter-modules", "nixpkgs": "nixpkgs", "sops-nix": "sops-nix", diff --git a/flake.nix b/flake.nix index 9eb051808..cac1a192a 100644 --- a/flake.nix +++ b/flake.nix @@ -4,6 +4,9 @@ inputs = { nixpkgs.url = "https://nixos.org/channels/nixpkgs-unstable/nixexprs.tar.xz"; + nix-darwin.url = "github:LnL7/nix-darwin"; + nix-darwin.inputs.nixpkgs.follows = "nixpkgs"; + flake-parts.url = "github:hercules-ci/flake-parts"; flake-parts.inputs.nixpkgs-lib.follows = "nixpkgs"; From 66e4c41142db01ab5808d41f4fd2af473f376744 Mon Sep 17 00:00:00 2001 From: Michael Hoang Date: Sun, 6 Apr 2025 20:48:25 +0200 Subject: [PATCH 2/5] lib/jsonschema: fix `enum` support --- lib/jsonschema/default.nix | 8 +++- lib/jsonschema/example-interface.nix | 10 ++++ lib/jsonschema/example-schema.json | 6 +++ lib/jsonschema/options.json | 69 +++++++++++++++++++++++++--- lib/jsonschema/test.nix | 2 +- 5 files changed, 86 insertions(+), 9 deletions(-) diff --git a/lib/jsonschema/default.nix b/lib/jsonschema/default.nix index 8dfddde94..177fef8d5 100644 --- a/lib/jsonschema/default.nix +++ b/lib/jsonschema/default.nix @@ -309,7 +309,13 @@ rec { option.type.name == "enum" # return jsonschema property definition for enum then - exposedModuleInfo // default // example // description // { enum = option.type.functor.payload; } + exposedModuleInfo + // default + // example + // description + // { + enum = option.type.functor.payload.values; + } # parse listOf submodule else if option.type.name == "listOf" && option.type.nestedTypes.elemType.name == "submodule" diff --git a/lib/jsonschema/example-interface.nix b/lib/jsonschema/example-interface.nix index 0ba650183..9b7c1b9e8 100644 --- a/lib/jsonschema/example-interface.nix +++ b/lib/jsonschema/example-interface.nix @@ -50,6 +50,16 @@ ]; description = "A list of enabled kernel modules"; }; + # enum + colour = lib.mkOption { + type = lib.types.enum [ + "red" + "blue" + "green" + ]; + default = "red"; + description = "The colour of the user"; + }; destinations = lib.mkOption { type = lib.types.attrsOf ( lib.types.submodule ( diff --git a/lib/jsonschema/example-schema.json b/lib/jsonschema/example-schema.json index 487e29085..3944cca62 100644 --- a/lib/jsonschema/example-schema.json +++ b/lib/jsonschema/example-schema.json @@ -46,6 +46,12 @@ }, "description": "Some attributes" }, + "colour": { + "$exportedModuleInfo": { "path": ["colour"] }, + "default": "red", + "description": "The colour of the user", + "enum": ["red", "blue", "green"] + }, "services": { "$exportedModuleInfo": { "path": ["services"] }, "type": "object", diff --git a/lib/jsonschema/options.json b/lib/jsonschema/options.json index 4ba1ddb86..cc2ae27b9 100644 --- a/lib/jsonschema/options.json +++ b/lib/jsonschema/options.json @@ -1,7 +1,14 @@ { + "_module.args": { + "declarations": ["lib/modules.nix"], + "description": "Additional arguments passed to each module in addition to ones\nlike `lib`, `config`,\nand `pkgs`, `modulesPath`.\n\nThis option is also available to all submodules. Submodules do not\ninherit args from their parent module, nor do they provide args to\ntheir parent module or sibling submodules. The sole exception to\nthis is the argument `name` which is provided by\nparent modules to a submodule and contains the attribute name\nthe submodule is bound to, or a unique generated name if it is\nnot bound to an attribute.\n\nSome arguments are already passed by default, of which the\nfollowing *cannot* be changed with this option:\n- {var}`lib`: The nixpkgs library.\n- {var}`config`: The results of all options after merging the values from all modules together.\n- {var}`options`: The options declared in all modules.\n- {var}`specialArgs`: The `specialArgs` argument passed to `evalModules`.\n- All attributes of {var}`specialArgs`\n\n Whereas option values can generally depend on other option values\n thanks to laziness, this does not apply to `imports`, which\n must be computed statically before anything else.\n\n For this reason, callers of the module system can provide `specialArgs`\n which are available during import resolution.\n\n For NixOS, `specialArgs` includes\n {var}`modulesPath`, which allows you to import\n extra modules from the nixpkgs package tree without having to\n somehow make the module aware of the location of the\n `nixpkgs` or NixOS directories.\n ```\n { modulesPath, ... }: {\n imports = [\n (modulesPath + \"/profiles/minimal.nix\")\n ];\n }\n ```\n\nFor NixOS, the default value for this option includes at least this argument:\n- {var}`pkgs`: The nixpkgs package set according to\n the {option}`nixpkgs.pkgs` option.\n", + "loc": ["_module", "args"], + "readOnly": false, + "type": "lazy attribute set of raw value" + }, "age": { "declarations": [ - "/home/grmpf/synced/projects/clan/clan-core/lib/jsonschema/example-interface.nix" + "/Users/enzime/Work/clan/clan-core/lib/jsonschema/example-interface.nix" ], "default": { "_type": "literalExpression", @@ -12,9 +19,57 @@ "readOnly": false, "type": "signed integer" }, + "colour": { + "declarations": [ + "/Users/enzime/Work/clan/clan-core/lib/jsonschema/example-interface.nix" + ], + "default": { + "_type": "literalExpression", + "text": "\"red\"" + }, + "description": "The colour of the user", + "loc": ["colour"], + "readOnly": false, + "type": "one of \"red\", \"blue\", \"green\"" + }, + "destinations": { + "declarations": [ + "/Users/enzime/Work/clan/clan-core/lib/jsonschema/example-interface.nix" + ], + "default": { + "_type": "literalExpression", + "text": "{ }" + }, + "description": null, + "loc": ["destinations"], + "readOnly": false, + "type": "attribute set of (submodule)" + }, + "destinations..name": { + "declarations": [ + "/Users/enzime/Work/clan/clan-core/lib/jsonschema/example-interface.nix" + ], + "default": { + "_type": "literalExpression", + "text": "\"‹name›\"" + }, + "description": "the name of the backup job", + "loc": ["destinations", "", "name"], + "readOnly": false, + "type": "string matching the pattern ^[a-zA-Z0-9._-]+$" + }, + "destinations..repo": { + "declarations": [ + "/Users/enzime/Work/clan/clan-core/lib/jsonschema/example-interface.nix" + ], + "description": "the borgbackup repository to backup to", + "loc": ["destinations", "", "repo"], + "readOnly": false, + "type": "string" + }, "isAdmin": { "declarations": [ - "/home/grmpf/synced/projects/clan/clan-core/lib/jsonschema/example-interface.nix" + "/Users/enzime/Work/clan/clan-core/lib/jsonschema/example-interface.nix" ], "default": { "_type": "literalExpression", @@ -27,7 +82,7 @@ }, "kernelModules": { "declarations": [ - "/home/grmpf/synced/projects/clan/clan-core/lib/jsonschema/example-interface.nix" + "/Users/enzime/Work/clan/clan-core/lib/jsonschema/example-interface.nix" ], "default": { "_type": "literalExpression", @@ -40,7 +95,7 @@ }, "name": { "declarations": [ - "/home/grmpf/synced/projects/clan/clan-core/lib/jsonschema/example-interface.nix" + "/Users/enzime/Work/clan/clan-core/lib/jsonschema/example-interface.nix" ], "default": { "_type": "literalExpression", @@ -53,7 +108,7 @@ }, "services": { "declarations": [ - "/home/grmpf/synced/projects/clan/clan-core/lib/jsonschema/example-interface.nix" + "/Users/enzime/Work/clan/clan-core/lib/jsonschema/example-interface.nix" ], "description": null, "loc": ["services"], @@ -62,7 +117,7 @@ }, "services.opt": { "declarations": [ - "/home/grmpf/synced/projects/clan/clan-core/lib/jsonschema/example-interface.nix" + "/Users/enzime/Work/clan/clan-core/lib/jsonschema/example-interface.nix" ], "default": { "_type": "literalExpression", @@ -75,7 +130,7 @@ }, "userIds": { "declarations": [ - "/home/grmpf/synced/projects/clan/clan-core/lib/jsonschema/example-interface.nix" + "/Users/enzime/Work/clan/clan-core/lib/jsonschema/example-interface.nix" ], "default": { "_type": "literalExpression", diff --git a/lib/jsonschema/test.nix b/lib/jsonschema/test.nix index e4f53e74d..56e69d6ac 100644 --- a/lib/jsonschema/test.nix +++ b/lib/jsonschema/test.nix @@ -4,6 +4,6 @@ slib ? (import ./. { inherit lib; } { }), }: { - # parseOption = import ./test_parseOption.nix { inherit lib slib; }; + parseOption = import ./test_parseOption.nix { inherit lib slib; }; parseOptions = import ./test_parseOptions.nix { inherit lib slib; }; } From 6de4735c816bd9637878567d4d84ad6b881591d6 Mon Sep 17 00:00:00 2001 From: Michael Hoang Date: Tue, 25 Mar 2025 13:39:04 +0900 Subject: [PATCH 3/5] build-clan: support constructing `darwinConfigurations` --- flakeModules/clan.nix | 2 +- lib/build-clan/default.nix | 2 + lib/build-clan/function-adapter.nix | 8 +- lib/build-clan/interface.nix | 9 ++ lib/build-clan/module.nix | 164 ++++++++++++++------ lib/build-clan/public.nix | 1 + lib/build-clan/tests.nix | 56 ++++++- lib/default.nix | 3 +- lib/flake-module.nix | 2 +- lib/inventory/build-inventory/interface.nix | 16 ++ pkgs/clan-cli/clan_cli/inventory/classes.py | 1 + 11 files changed, 207 insertions(+), 57 deletions(-) diff --git a/flakeModules/clan.nix b/flakeModules/clan.nix index ae960793c..a78ac5aad 100644 --- a/flakeModules/clan.nix +++ b/flakeModules/clan.nix @@ -34,7 +34,7 @@ in type = types.submoduleWith { specialArgs = { inherit clan-core self; - inherit (inputs) nixpkgs; + inherit (inputs) nixpkgs nix-darwin; # TODO: inject the inventory interface # inventoryInterface = {}; }; diff --git a/lib/build-clan/default.nix b/lib/build-clan/default.nix index 466368484..baa43bbd9 100644 --- a/lib/build-clan/default.nix +++ b/lib/build-clan/default.nix @@ -4,6 +4,7 @@ { lib, nixpkgs, + nix-darwin ? null, ... }: { @@ -54,6 +55,7 @@ inherit lib nixpkgs + nix-darwin clan-core self ; diff --git a/lib/build-clan/function-adapter.nix b/lib/build-clan/function-adapter.nix index 4a11fd1e0..aa8b1a601 100644 --- a/lib/build-clan/function-adapter.nix +++ b/lib/build-clan/function-adapter.nix @@ -1,6 +1,7 @@ { lib, nixpkgs, + nix-darwin ? null, clan-core, self, specialArgs ? { }, @@ -9,7 +10,12 @@ module: (lib.evalModules { specialArgs = { - inherit self clan-core nixpkgs; + inherit + self + clan-core + nixpkgs + nix-darwin + ; }; modules = [ ./interface.nix diff --git a/lib/build-clan/interface.nix b/lib/build-clan/interface.nix index 2f92275c0..c6436fb1a 100644 --- a/lib/build-clan/interface.nix +++ b/lib/build-clan/interface.nix @@ -123,6 +123,15 @@ in }; # Outputs + darwinConfigurations = lib.mkOption { + # Hide from documentation. + # Exposed at the top-level of the flake, clan.darwinConfigurations should not used by the user. + # Instead, the user should use the `.#darwinConfigurations` attribute of the flake output. + visible = false; + type = types.lazyAttrsOf types.raw; + default = { }; + }; + nixosConfigurations = lib.mkOption { # Hide from documentation. # Exposed at the top-level of the flake, clan.nixosConfigurations should not used by the user. diff --git a/lib/build-clan/module.nix b/lib/build-clan/module.nix index 5072bf499..9f69bf99b 100644 --- a/lib/build-clan/module.nix +++ b/lib/build-clan/module.nix @@ -3,6 +3,7 @@ config, clan-core, nixpkgs, + nix-darwin, lib, ... }: @@ -48,51 +49,99 @@ let } ); - # TODO: remove default system once we have a hardware-config mechanism - nixosConfiguration = - { - system ? null, - name, - pkgs ? null, - extraConfig ? { }, - }: - nixpkgs.lib.nixosSystem { - modules = - let - hwConfig = "${directory}/machines/${name}/hardware-configuration.nix"; - diskoConfig = "${directory}/machines/${name}/disko.nix"; - in - [ + moduleSystemConstructor = { + # TODO: remove default system once we have a hardware-config mechanism + nixos = + { + system ? null, + name, + pkgs ? null, + extraConfig ? { }, + }: + nixpkgs.lib.nixosSystem { + modules = + let + hwConfig = "${directory}/machines/${name}/hardware-configuration.nix"; + diskoConfig = "${directory}/machines/${name}/disko.nix"; + in + [ + { + # Autoinclude configuration.nix and hardware-configuration.nix + imports = builtins.filter builtins.pathExists [ + "${directory}/machines/${name}/configuration.nix" + hwConfig + diskoConfig + ]; + } + clan-core.nixosModules.clanCore + extraConfig + (machines.${name} or { }) + # Inherit the inventory assertions ? + # { inherit (mergedInventory) assertions; } + { imports = inventoryClass.machines.${name}.machineImports or [ ]; } + + # Import the distribute services + { imports = config.clanInternals.distributedServices.allMachines.${name} or [ ]; } + ( + { + # Settings + clan.core.settings = { + inherit directory; + inherit (config.inventory.meta) name icon; + + machine = { + inherit name; + }; + }; + # Inherited from clan wide settings + # TODO: remove these + + networking.hostName = lib.mkDefault name; + + # For vars we need to override the system so we run vars + # generators on the machine that runs `clan vars generate`. If a + # users is using the `pkgsForSystem`, we don't set + # nixpkgs.hostPlatform it would conflict with the `nixpkgs.pkgs` + # option. + nixpkgs.hostPlatform = lib.mkIf (system != null && (pkgsForSystem system) != null) ( + lib.mkForce system + ); + } + // lib.optionalAttrs (pkgs != null) { nixpkgs.pkgs = lib.mkForce pkgs; } + ) + ]; + + specialArgs = { + inherit clan-core; + } // specialArgs; + }; + + darwin = + { + system ? null, + name, + pkgs ? null, + extraConfig ? { }, + }: + nix-darwin.lib.darwinSystem { + modules = [ { - # Autoinclude configuration.nix and hardware-configuration.nix imports = builtins.filter builtins.pathExists [ "${directory}/machines/${name}/configuration.nix" - hwConfig - diskoConfig ]; } - clan-core.nixosModules.clanCore + ( + if !lib.hasAttrByPath [ "darwinModules" "clanCore" ] clan-core then + { } + else + throw "this should import clan-core.darwinModules.clanCore" + ) extraConfig (machines.${name} or { }) - # Inherit the inventory assertions ? - # { inherit (mergedInventory) assertions; } - { imports = inventoryClass.machines.${name}.machineImports or [ ]; } - - # Import the distribute services - { imports = config.clanInternals.distributedServices.allMachines.${name} or [ ]; } + # TODO: import inventory when it has support for defining `nix-darwin` modules ( { - # Settings - clan.core.settings = { - inherit directory; - inherit (config.inventory.meta) name icon; - - machine = { - inherit name; - }; - }; - # Inherited from clan wide settings - # TODO: remove these + # TODO: set clan-core settings when clan-core has support for `nix-darwin` networking.hostName = lib.mkDefault name; @@ -109,16 +158,24 @@ let ) ]; - specialArgs = { - inherit clan-core; - } // specialArgs; - }; + specialArgs = { + inherit clan-core; + } // specialArgs; + }; + }; allMachines = inventory.machines or { } // machines; - nixosConfigurations = lib.mapAttrs (name: _: nixosConfiguration { inherit name; }) allMachines; + machineClass = lib.mapAttrs (name: _: inventory.machineClass.${name} or "nixos") allMachines; - # This instantiates nixos for each system that we support: + configurations = lib.mapAttrs ( + name: _: moduleSystemConstructor.${machineClass.${name}} { inherit name; } + ) allMachines; + + nixosConfigurations = lib.filterAttrs (name: _: machineClass.${name} == "nixos") configurations; + darwinConfigurations = lib.filterAttrs (name: _: machineClass.${name} == "darwin") configurations; + + # This instantiates NixOS for each system that we support: # configPerSystem = ..nixosConfiguration # We need this to build nixos secret generators for each system configsPerSystem = builtins.listToAttrs ( @@ -127,7 +184,7 @@ let lib.nameValuePair system ( lib.mapAttrs ( name: _: - nixosConfiguration { + moduleSystemConstructor.${machineClass.${name}} { inherit name system; pkgs = pkgsFor.${system}; } @@ -142,7 +199,7 @@ let lib.nameValuePair system ( lib.mapAttrs ( name: _: args: - nixosConfiguration ( + moduleSystemConstructor.${machineClass.${name}} ( args // { inherit name system; @@ -194,6 +251,7 @@ in ]; inherit nixosConfigurations; + inherit darwinConfigurations; clanInternals = { moduleSchemas = clan-core.lib.modules.getModulesSchema config.inventory.modules; @@ -223,11 +281,17 @@ in # machine specifics machines = configsPerSystem; machinesFunc = configsFuncPerSystem; - all-machines-json = lib.mapAttrs ( - system: configs: - nixpkgs.legacyPackages.${system}.writers.writeJSON "machines.json" ( - lib.mapAttrs (_: m: m.config.system.clan.deployment.data) configs - ) - ) configsPerSystem; + all-machines-json = + if !lib.hasAttrByPath [ "darwinModules" "clanCore" ] clan-core then + lib.mapAttrs ( + system: configs: + nixpkgs.legacyPackages.${system}.writers.writeJSON "machines.json" ( + lib.mapAttrs (_: m: m.config.system.clan.deployment.data) ( + lib.filterAttrs (_n: v: v.class == "nixos") configs + ) + ) + ) configsPerSystem + else + throw "remove NixOS filter and support nix-darwin as well"; }; } diff --git a/lib/build-clan/public.nix b/lib/build-clan/public.nix index fb34480a6..3f1783a9a 100644 --- a/lib/build-clan/public.nix +++ b/lib/build-clan/public.nix @@ -14,5 +14,6 @@ topLevel = [ "clanInternals" "nixosConfigurations" + "darwinConfigurations" ]; } diff --git a/lib/build-clan/tests.nix b/lib/build-clan/tests.nix index 68b85811c..f87918e7a 100644 --- a/lib/build-clan/tests.nix +++ b/lib/build-clan/tests.nix @@ -76,7 +76,7 @@ in }; directory = ./.; imports = [ - # What the user needs to specif + # What the user needs to specify { directory = ./.; inventory.meta.name = "test"; @@ -165,10 +165,9 @@ in }; directory = ./.; meta.name = "test"; - inventory.machines.machine1.meta.name = "machine1"; + inventory.machines.machine1 = { }; machines.machine2 = { }; - }; in { @@ -200,4 +199,55 @@ in expr = result.nixosConfigurations.machine2.config.networking.hostName; expected = "dream2nix"; }; + + test_buildClan_darwin_machines = + let + result = buildClan { + self = { + inputs = { }; + }; + directory = ./.; + meta.name = "test"; + + machines.machine1 = { }; + machines.machine2 = { }; + machines.machine3 = { }; + + inventory.machineClass.machine2 = "darwin"; + inventory.machineClass.machine3 = "nixos"; + }; + in + { + expr = { + nixos = builtins.attrNames result.nixosConfigurations; + darwin = builtins.attrNames result.darwinConfigurations; + }; + expected = { + nixos = [ + "machine1" + "machine3" + ]; + darwin = [ "machine2" ]; + }; + }; + + test_buildClan_all_machines_laziness = + let + result = buildClan { + self = { + inputs = { }; + }; + directory = ./.; + meta.name = "test"; + + machines.machine1.non_existent_option = throw "eval error"; + inventory.machines.machine1.other_non_existent_option = throw "different eval error"; + }; + in + { + expr = builtins.attrNames result.nixosConfigurations; + expected = [ + "machine1" + ]; + }; } diff --git a/lib/default.nix b/lib/default.nix index 2d31c3048..ada137e8b 100644 --- a/lib/default.nix +++ b/lib/default.nix @@ -2,6 +2,7 @@ lib, self, nixpkgs, + nix-darwin ? null, ... }: # Produces the @@ -20,7 +21,7 @@ lib.fix (clanLib: { clan-core = self; pkgs = nixpkgs.legacyPackages.x86_64-linux; }; - buildClanModule = clanLib.callLib ./build-clan { inherit nixpkgs; }; + buildClanModule = clanLib.callLib ./build-clan { inherit nixpkgs nix-darwin; }; buildClan = clanLib.buildClanModule.buildClanWith { clan-core = self; }; # ------------------------------------ diff --git a/lib/flake-module.nix b/lib/flake-module.nix index a7cd3d5b9..19c093391 100644 --- a/lib/flake-module.nix +++ b/lib/flake-module.nix @@ -15,7 +15,7 @@ rec { ]; flake.clanLib = import ./default.nix { inherit lib inputs self; - inherit (inputs) nixpkgs; + inherit (inputs) nixpkgs nix-darwin; }; # TODO: remove this legacy alias flake.lib = flake.clanLib; diff --git a/lib/inventory/build-inventory/interface.nix b/lib/inventory/build-inventory/interface.nix index b496bb962..e04f35ab1 100644 --- a/lib/inventory/build-inventory/interface.nix +++ b/lib/inventory/build-inventory/interface.nix @@ -277,6 +277,22 @@ in ) ); }; + + machineClass = lib.mkOption { + default = { }; + type = types.attrsOf ( + types.enum [ + "nixos" + "darwin" + ] + ); + description = '' + The module system that should be used to construct the machine + + Set this to `darwin` for macOS machines + ''; + }; + instances = lib.mkOption { # Keep as internal until all de-/serialization issues are resolved visible = false; diff --git a/pkgs/clan-cli/clan_cli/inventory/classes.py b/pkgs/clan-cli/clan_cli/inventory/classes.py index 3ed9d3342..d21fb139c 100644 --- a/pkgs/clan-cli/clan_cli/inventory/classes.py +++ b/pkgs/clan-cli/clan_cli/inventory/classes.py @@ -29,6 +29,7 @@ Service = dict[str, Any] class Inventory(TypedDict): + machineClass: NotRequired[dict[str, Any]] machines: NotRequired[dict[str, Machine]] meta: NotRequired[Meta] modules: NotRequired[dict[str, Any]] From 72ed0e258a14312895a9f21bc8597aca30131a2a Mon Sep 17 00:00:00 2001 From: Michael Hoang Date: Sun, 6 Apr 2025 18:45:16 +0200 Subject: [PATCH 4/5] cli: don't update macOS machines --- pkgs/clan-cli/clan_cli/machines/machines.py | 17 +++++++++++++++-- pkgs/clan-cli/clan_cli/machines/update.py | 7 +++++++ 2 files changed, 22 insertions(+), 2 deletions(-) diff --git a/pkgs/clan-cli/clan_cli/machines/machines.py b/pkgs/clan-cli/clan_cli/machines/machines.py index cc5638555..49bc70ed0 100644 --- a/pkgs/clan-cli/clan_cli/machines/machines.py +++ b/pkgs/clan-cli/clan_cli/machines/machines.py @@ -1,12 +1,13 @@ import importlib import json import logging +import re from dataclasses import dataclass, field from functools import cached_property from pathlib import Path from typing import TYPE_CHECKING, Any, Literal -from clan_cli.errors import ClanError +from clan_cli.errors import ClanCmdError, ClanError from clan_cli.facts import public_modules as facts_public_modules from clan_cli.facts import secret_modules as facts_secret_modules from clan_cli.flake import Flake @@ -56,10 +57,22 @@ class Machine: kwargs.update({"extra": {"command_prefix": self.name}}) log.error(msg, *args, **kwargs) + @property + # `class` is a keyword, `_class` triggers `SLF001` so we use a sunder name + def _class_(self) -> str: + try: + return self.flake.select( + f"clanInternals.inventory.machineClass.{self.name}" + ) + except ClanCmdError as e: + if re.search(f"error: attribute '{self.name}' missing", e.cmd.stderr): + return "nixos" + raise + @property def system(self) -> str: return self.flake.select( - f"nixosConfigurations.{self.name}.pkgs.hostPlatform.system" + f"{self._class_}Configurations.{self.name}.pkgs.hostPlatform.system" ) @property diff --git a/pkgs/clan-cli/clan_cli/machines/update.py b/pkgs/clan-cli/clan_cli/machines/update.py index 1f84ad347..2758eda87 100644 --- a/pkgs/clan-cli/clan_cli/machines/update.py +++ b/pkgs/clan-cli/clan_cli/machines/update.py @@ -238,6 +238,8 @@ def update_command(args: argparse.Namespace) -> None: if len(args.machines) == 0: ignored_machines = [] for machine in get_all_machines(args.flake, args.option): + if machine._class_ == "darwin": + continue if machine.deployment.get("requireExplicitUpdate", False): continue try: @@ -265,6 +267,11 @@ def update_command(args: argparse.Namespace) -> None: machine.override_build_host = args.build_host machine.host_key_check = HostKeyCheck.from_str(args.host_key_check) + for machine in machines: + if machine._class_ == "darwin": + machine.error("Updating macOS machines is not yet supported") + sys.exit(1) + deploy_machines(machines) except KeyboardInterrupt: log.warning("Interrupted by user") From 67745e1b276deed82e537602f86beccab462d540 Mon Sep 17 00:00:00 2001 From: Michael Hoang Date: Sun, 6 Apr 2025 22:58:29 +0200 Subject: [PATCH 5/5] tests: add `--show-trace` to `nix-unit` tests --- lib/build-clan/flake-module.nix | 1 + lib/introspection/flake-module.nix | 1 + lib/inventory/distributed-service/flake-module.nix | 1 + lib/inventory/flake-module.nix | 1 + lib/jsonschema/flake-module.nix | 3 ++- lib/select/flake-module.nix | 1 + nixosModules/clanCore/vars/flake-module.nix | 1 + 7 files changed, 8 insertions(+), 1 deletion(-) diff --git a/lib/build-clan/flake-module.nix b/lib/build-clan/flake-module.nix index ed3964171..c9c9502e8 100644 --- a/lib/build-clan/flake-module.nix +++ b/lib/build-clan/flake-module.nix @@ -37,6 +37,7 @@ in nix-unit --eval-store "$HOME" \ --extra-experimental-features flakes \ + --show-trace \ ${inputOverrides} \ --flake ${ self.filter { diff --git a/lib/introspection/flake-module.nix b/lib/introspection/flake-module.nix index ee9c2d368..bb72c4920 100644 --- a/lib/introspection/flake-module.nix +++ b/lib/introspection/flake-module.nix @@ -23,6 +23,7 @@ in nix-unit --eval-store "$HOME" \ --extra-experimental-features flakes \ + --show-trace \ ${inputOverrides} \ --flake ${ self.filter { diff --git a/lib/inventory/distributed-service/flake-module.nix b/lib/inventory/distributed-service/flake-module.nix index 87bacd8ee..0486b70ce 100644 --- a/lib/inventory/distributed-service/flake-module.nix +++ b/lib/inventory/distributed-service/flake-module.nix @@ -24,6 +24,7 @@ in export HOME="$(realpath .)" nix-unit --eval-store "$HOME" \ --extra-experimental-features flakes \ + --show-trace \ ${inputOverrides} \ --flake ${self}#legacyPackages.${system}.evalTests-distributedServices diff --git a/lib/inventory/flake-module.nix b/lib/inventory/flake-module.nix index 64a5e4f20..4fb95c908 100644 --- a/lib/inventory/flake-module.nix +++ b/lib/inventory/flake-module.nix @@ -48,6 +48,7 @@ in export NIX_ABORT_ON_WARN=1 nix-unit --eval-store "$HOME" \ --extra-experimental-features flakes \ + --show-trace \ ${inputOverrides} \ --flake ${ self.filter { diff --git a/lib/jsonschema/flake-module.nix b/lib/jsonschema/flake-module.nix index db133d602..0c69a271c 100644 --- a/lib/jsonschema/flake-module.nix +++ b/lib/jsonschema/flake-module.nix @@ -23,7 +23,8 @@ export NIX_PATH=nixpkgs=${pkgs.path} ${pkgs.nix-unit}/bin/nix-unit \ ${./.}/test.nix \ - --eval-store $(realpath .) + --eval-store $(realpath .) \ + --show-trace touch $out ''; }; diff --git a/lib/select/flake-module.nix b/lib/select/flake-module.nix index 0eb14accc..915a60f25 100644 --- a/lib/select/flake-module.nix +++ b/lib/select/flake-module.nix @@ -25,6 +25,7 @@ in export NIX_ABORT_ON_WARN=1 nix-unit --eval-store "$HOME" \ --extra-experimental-features flakes \ + --show-trace \ ${inputOverrides} \ --flake ${ self.filter { diff --git a/nixosModules/clanCore/vars/flake-module.nix b/nixosModules/clanCore/vars/flake-module.nix index 9473e4161..6ec77ce85 100644 --- a/nixosModules/clanCore/vars/flake-module.nix +++ b/nixosModules/clanCore/vars/flake-module.nix @@ -23,6 +23,7 @@ in nix-unit --eval-store "$HOME" \ --extra-experimental-features flakes \ + --show-trace \ ${inputOverrides} \ --flake ${ self.filter {