Merge pull request 'build-clan: support constructing darwinConfigurations' (#3115) from mac into main
Reviewed-on: https://git.clan.lol/clan/clan-core/pulls/3115
This commit is contained in:
21
flake.lock
generated
21
flake.lock
generated
@@ -69,6 +69,26 @@
|
|||||||
"type": "github"
|
"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": {
|
"nixos-facter-modules": {
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1743671943,
|
"lastModified": 1743671943,
|
||||||
@@ -102,6 +122,7 @@
|
|||||||
"data-mesher": "data-mesher",
|
"data-mesher": "data-mesher",
|
||||||
"disko": "disko",
|
"disko": "disko",
|
||||||
"flake-parts": "flake-parts",
|
"flake-parts": "flake-parts",
|
||||||
|
"nix-darwin": "nix-darwin",
|
||||||
"nixos-facter-modules": "nixos-facter-modules",
|
"nixos-facter-modules": "nixos-facter-modules",
|
||||||
"nixpkgs": "nixpkgs",
|
"nixpkgs": "nixpkgs",
|
||||||
"sops-nix": "sops-nix",
|
"sops-nix": "sops-nix",
|
||||||
|
|||||||
@@ -4,6 +4,9 @@
|
|||||||
inputs = {
|
inputs = {
|
||||||
nixpkgs.url = "https://nixos.org/channels/nixpkgs-unstable/nixexprs.tar.xz";
|
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.url = "github:hercules-ci/flake-parts";
|
||||||
flake-parts.inputs.nixpkgs-lib.follows = "nixpkgs";
|
flake-parts.inputs.nixpkgs-lib.follows = "nixpkgs";
|
||||||
|
|
||||||
|
|||||||
@@ -34,7 +34,7 @@ in
|
|||||||
type = types.submoduleWith {
|
type = types.submoduleWith {
|
||||||
specialArgs = {
|
specialArgs = {
|
||||||
inherit clan-core self;
|
inherit clan-core self;
|
||||||
inherit (inputs) nixpkgs;
|
inherit (inputs) nixpkgs nix-darwin;
|
||||||
# TODO: inject the inventory interface
|
# TODO: inject the inventory interface
|
||||||
# inventoryInterface = {};
|
# inventoryInterface = {};
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -4,6 +4,7 @@
|
|||||||
{
|
{
|
||||||
lib,
|
lib,
|
||||||
nixpkgs,
|
nixpkgs,
|
||||||
|
nix-darwin ? null,
|
||||||
...
|
...
|
||||||
}:
|
}:
|
||||||
{
|
{
|
||||||
@@ -54,6 +55,7 @@
|
|||||||
inherit
|
inherit
|
||||||
lib
|
lib
|
||||||
nixpkgs
|
nixpkgs
|
||||||
|
nix-darwin
|
||||||
clan-core
|
clan-core
|
||||||
self
|
self
|
||||||
;
|
;
|
||||||
|
|||||||
@@ -37,6 +37,7 @@ in
|
|||||||
|
|
||||||
nix-unit --eval-store "$HOME" \
|
nix-unit --eval-store "$HOME" \
|
||||||
--extra-experimental-features flakes \
|
--extra-experimental-features flakes \
|
||||||
|
--show-trace \
|
||||||
${inputOverrides} \
|
${inputOverrides} \
|
||||||
--flake ${
|
--flake ${
|
||||||
self.filter {
|
self.filter {
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
{
|
{
|
||||||
lib,
|
lib,
|
||||||
nixpkgs,
|
nixpkgs,
|
||||||
|
nix-darwin ? null,
|
||||||
clan-core,
|
clan-core,
|
||||||
self,
|
self,
|
||||||
specialArgs ? { },
|
specialArgs ? { },
|
||||||
@@ -9,7 +10,12 @@
|
|||||||
module:
|
module:
|
||||||
(lib.evalModules {
|
(lib.evalModules {
|
||||||
specialArgs = {
|
specialArgs = {
|
||||||
inherit self clan-core nixpkgs;
|
inherit
|
||||||
|
self
|
||||||
|
clan-core
|
||||||
|
nixpkgs
|
||||||
|
nix-darwin
|
||||||
|
;
|
||||||
};
|
};
|
||||||
modules = [
|
modules = [
|
||||||
./interface.nix
|
./interface.nix
|
||||||
|
|||||||
@@ -123,6 +123,15 @@ in
|
|||||||
};
|
};
|
||||||
|
|
||||||
# Outputs
|
# 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 {
|
nixosConfigurations = lib.mkOption {
|
||||||
# Hide from documentation.
|
# Hide from documentation.
|
||||||
# Exposed at the top-level of the flake, clan.nixosConfigurations should not used by the user.
|
# Exposed at the top-level of the flake, clan.nixosConfigurations should not used by the user.
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
config,
|
config,
|
||||||
clan-core,
|
clan-core,
|
||||||
nixpkgs,
|
nixpkgs,
|
||||||
|
nix-darwin,
|
||||||
lib,
|
lib,
|
||||||
...
|
...
|
||||||
}:
|
}:
|
||||||
@@ -48,51 +49,99 @@ let
|
|||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
# TODO: remove default system once we have a hardware-config mechanism
|
moduleSystemConstructor = {
|
||||||
nixosConfiguration =
|
# TODO: remove default system once we have a hardware-config mechanism
|
||||||
{
|
nixos =
|
||||||
system ? null,
|
{
|
||||||
name,
|
system ? null,
|
||||||
pkgs ? null,
|
name,
|
||||||
extraConfig ? { },
|
pkgs ? null,
|
||||||
}:
|
extraConfig ? { },
|
||||||
nixpkgs.lib.nixosSystem {
|
}:
|
||||||
modules =
|
nixpkgs.lib.nixosSystem {
|
||||||
let
|
modules =
|
||||||
hwConfig = "${directory}/machines/${name}/hardware-configuration.nix";
|
let
|
||||||
diskoConfig = "${directory}/machines/${name}/disko.nix";
|
hwConfig = "${directory}/machines/${name}/hardware-configuration.nix";
|
||||||
in
|
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 [
|
imports = builtins.filter builtins.pathExists [
|
||||||
"${directory}/machines/${name}/configuration.nix"
|
"${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
|
extraConfig
|
||||||
(machines.${name} or { })
|
(machines.${name} or { })
|
||||||
# Inherit the inventory assertions ?
|
# TODO: import inventory when it has support for defining `nix-darwin` modules
|
||||||
# { inherit (mergedInventory) assertions; }
|
|
||||||
{ imports = inventoryClass.machines.${name}.machineImports or [ ]; }
|
|
||||||
|
|
||||||
# Import the distribute services
|
|
||||||
{ imports = config.clanInternals.distributedServices.allMachines.${name} or [ ]; }
|
|
||||||
(
|
(
|
||||||
{
|
{
|
||||||
# Settings
|
# TODO: set clan-core settings when clan-core has support for `nix-darwin`
|
||||||
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;
|
networking.hostName = lib.mkDefault name;
|
||||||
|
|
||||||
@@ -109,16 +158,24 @@ let
|
|||||||
)
|
)
|
||||||
];
|
];
|
||||||
|
|
||||||
specialArgs = {
|
specialArgs = {
|
||||||
inherit clan-core;
|
inherit clan-core;
|
||||||
} // specialArgs;
|
} // specialArgs;
|
||||||
};
|
};
|
||||||
|
};
|
||||||
|
|
||||||
allMachines = inventory.machines or { } // machines;
|
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 = <system>.<machine>.nixosConfiguration
|
# configPerSystem = <system>.<machine>.nixosConfiguration
|
||||||
# We need this to build nixos secret generators for each system
|
# We need this to build nixos secret generators for each system
|
||||||
configsPerSystem = builtins.listToAttrs (
|
configsPerSystem = builtins.listToAttrs (
|
||||||
@@ -127,7 +184,7 @@ let
|
|||||||
lib.nameValuePair system (
|
lib.nameValuePair system (
|
||||||
lib.mapAttrs (
|
lib.mapAttrs (
|
||||||
name: _:
|
name: _:
|
||||||
nixosConfiguration {
|
moduleSystemConstructor.${machineClass.${name}} {
|
||||||
inherit name system;
|
inherit name system;
|
||||||
pkgs = pkgsFor.${system};
|
pkgs = pkgsFor.${system};
|
||||||
}
|
}
|
||||||
@@ -142,7 +199,7 @@ let
|
|||||||
lib.nameValuePair system (
|
lib.nameValuePair system (
|
||||||
lib.mapAttrs (
|
lib.mapAttrs (
|
||||||
name: _: args:
|
name: _: args:
|
||||||
nixosConfiguration (
|
moduleSystemConstructor.${machineClass.${name}} (
|
||||||
args
|
args
|
||||||
// {
|
// {
|
||||||
inherit name system;
|
inherit name system;
|
||||||
@@ -194,6 +251,7 @@ in
|
|||||||
];
|
];
|
||||||
|
|
||||||
inherit nixosConfigurations;
|
inherit nixosConfigurations;
|
||||||
|
inherit darwinConfigurations;
|
||||||
|
|
||||||
clanInternals = {
|
clanInternals = {
|
||||||
moduleSchemas = clan-core.lib.modules.getModulesSchema config.inventory.modules;
|
moduleSchemas = clan-core.lib.modules.getModulesSchema config.inventory.modules;
|
||||||
@@ -223,11 +281,17 @@ in
|
|||||||
# machine specifics
|
# machine specifics
|
||||||
machines = configsPerSystem;
|
machines = configsPerSystem;
|
||||||
machinesFunc = configsFuncPerSystem;
|
machinesFunc = configsFuncPerSystem;
|
||||||
all-machines-json = lib.mapAttrs (
|
all-machines-json =
|
||||||
system: configs:
|
if !lib.hasAttrByPath [ "darwinModules" "clanCore" ] clan-core then
|
||||||
nixpkgs.legacyPackages.${system}.writers.writeJSON "machines.json" (
|
lib.mapAttrs (
|
||||||
lib.mapAttrs (_: m: m.config.system.clan.deployment.data) configs
|
system: configs:
|
||||||
)
|
nixpkgs.legacyPackages.${system}.writers.writeJSON "machines.json" (
|
||||||
) configsPerSystem;
|
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";
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,5 +14,6 @@
|
|||||||
topLevel = [
|
topLevel = [
|
||||||
"clanInternals"
|
"clanInternals"
|
||||||
"nixosConfigurations"
|
"nixosConfigurations"
|
||||||
|
"darwinConfigurations"
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -76,7 +76,7 @@ in
|
|||||||
};
|
};
|
||||||
directory = ./.;
|
directory = ./.;
|
||||||
imports = [
|
imports = [
|
||||||
# What the user needs to specif
|
# What the user needs to specify
|
||||||
{
|
{
|
||||||
directory = ./.;
|
directory = ./.;
|
||||||
inventory.meta.name = "test";
|
inventory.meta.name = "test";
|
||||||
@@ -165,10 +165,9 @@ in
|
|||||||
};
|
};
|
||||||
directory = ./.;
|
directory = ./.;
|
||||||
meta.name = "test";
|
meta.name = "test";
|
||||||
inventory.machines.machine1.meta.name = "machine1";
|
|
||||||
|
|
||||||
|
inventory.machines.machine1 = { };
|
||||||
machines.machine2 = { };
|
machines.machine2 = { };
|
||||||
|
|
||||||
};
|
};
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
@@ -200,4 +199,55 @@ in
|
|||||||
expr = result.nixosConfigurations.machine2.config.networking.hostName;
|
expr = result.nixosConfigurations.machine2.config.networking.hostName;
|
||||||
expected = "dream2nix";
|
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"
|
||||||
|
];
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
lib,
|
lib,
|
||||||
self,
|
self,
|
||||||
nixpkgs,
|
nixpkgs,
|
||||||
|
nix-darwin ? null,
|
||||||
...
|
...
|
||||||
}:
|
}:
|
||||||
# Produces the
|
# Produces the
|
||||||
@@ -20,7 +21,7 @@ lib.fix (clanLib: {
|
|||||||
clan-core = self;
|
clan-core = self;
|
||||||
pkgs = nixpkgs.legacyPackages.x86_64-linux;
|
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; };
|
buildClan = clanLib.buildClanModule.buildClanWith { clan-core = self; };
|
||||||
# ------------------------------------
|
# ------------------------------------
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ rec {
|
|||||||
];
|
];
|
||||||
flake.clanLib = import ./default.nix {
|
flake.clanLib = import ./default.nix {
|
||||||
inherit lib inputs self;
|
inherit lib inputs self;
|
||||||
inherit (inputs) nixpkgs;
|
inherit (inputs) nixpkgs nix-darwin;
|
||||||
};
|
};
|
||||||
# TODO: remove this legacy alias
|
# TODO: remove this legacy alias
|
||||||
flake.lib = flake.clanLib;
|
flake.lib = flake.clanLib;
|
||||||
|
|||||||
@@ -23,6 +23,7 @@ in
|
|||||||
|
|
||||||
nix-unit --eval-store "$HOME" \
|
nix-unit --eval-store "$HOME" \
|
||||||
--extra-experimental-features flakes \
|
--extra-experimental-features flakes \
|
||||||
|
--show-trace \
|
||||||
${inputOverrides} \
|
${inputOverrides} \
|
||||||
--flake ${
|
--flake ${
|
||||||
self.filter {
|
self.filter {
|
||||||
|
|||||||
@@ -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 {
|
instances = lib.mkOption {
|
||||||
# Keep as internal until all de-/serialization issues are resolved
|
# Keep as internal until all de-/serialization issues are resolved
|
||||||
visible = false;
|
visible = false;
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ in
|
|||||||
export HOME="$(realpath .)"
|
export HOME="$(realpath .)"
|
||||||
nix-unit --eval-store "$HOME" \
|
nix-unit --eval-store "$HOME" \
|
||||||
--extra-experimental-features flakes \
|
--extra-experimental-features flakes \
|
||||||
|
--show-trace \
|
||||||
${inputOverrides} \
|
${inputOverrides} \
|
||||||
--flake ${self}#legacyPackages.${system}.evalTests-distributedServices
|
--flake ${self}#legacyPackages.${system}.evalTests-distributedServices
|
||||||
|
|
||||||
|
|||||||
@@ -48,6 +48,7 @@ in
|
|||||||
export NIX_ABORT_ON_WARN=1
|
export NIX_ABORT_ON_WARN=1
|
||||||
nix-unit --eval-store "$HOME" \
|
nix-unit --eval-store "$HOME" \
|
||||||
--extra-experimental-features flakes \
|
--extra-experimental-features flakes \
|
||||||
|
--show-trace \
|
||||||
${inputOverrides} \
|
${inputOverrides} \
|
||||||
--flake ${
|
--flake ${
|
||||||
self.filter {
|
self.filter {
|
||||||
|
|||||||
@@ -309,7 +309,13 @@ rec {
|
|||||||
option.type.name == "enum"
|
option.type.name == "enum"
|
||||||
# return jsonschema property definition for enum
|
# return jsonschema property definition for enum
|
||||||
then
|
then
|
||||||
exposedModuleInfo // default // example // description // { enum = option.type.functor.payload; }
|
exposedModuleInfo
|
||||||
|
// default
|
||||||
|
// example
|
||||||
|
// description
|
||||||
|
// {
|
||||||
|
enum = option.type.functor.payload.values;
|
||||||
|
}
|
||||||
# parse listOf submodule
|
# parse listOf submodule
|
||||||
else if
|
else if
|
||||||
option.type.name == "listOf" && option.type.nestedTypes.elemType.name == "submodule"
|
option.type.name == "listOf" && option.type.nestedTypes.elemType.name == "submodule"
|
||||||
|
|||||||
@@ -50,6 +50,16 @@
|
|||||||
];
|
];
|
||||||
description = "A list of enabled kernel modules";
|
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 {
|
destinations = lib.mkOption {
|
||||||
type = lib.types.attrsOf (
|
type = lib.types.attrsOf (
|
||||||
lib.types.submodule (
|
lib.types.submodule (
|
||||||
|
|||||||
@@ -46,6 +46,12 @@
|
|||||||
},
|
},
|
||||||
"description": "Some attributes"
|
"description": "Some attributes"
|
||||||
},
|
},
|
||||||
|
"colour": {
|
||||||
|
"$exportedModuleInfo": { "path": ["colour"] },
|
||||||
|
"default": "red",
|
||||||
|
"description": "The colour of the user",
|
||||||
|
"enum": ["red", "blue", "green"]
|
||||||
|
},
|
||||||
"services": {
|
"services": {
|
||||||
"$exportedModuleInfo": { "path": ["services"] },
|
"$exportedModuleInfo": { "path": ["services"] },
|
||||||
"type": "object",
|
"type": "object",
|
||||||
|
|||||||
@@ -23,7 +23,8 @@
|
|||||||
export NIX_PATH=nixpkgs=${pkgs.path}
|
export NIX_PATH=nixpkgs=${pkgs.path}
|
||||||
${pkgs.nix-unit}/bin/nix-unit \
|
${pkgs.nix-unit}/bin/nix-unit \
|
||||||
${./.}/test.nix \
|
${./.}/test.nix \
|
||||||
--eval-store $(realpath .)
|
--eval-store $(realpath .) \
|
||||||
|
--show-trace
|
||||||
touch $out
|
touch $out
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -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": {
|
"age": {
|
||||||
"declarations": [
|
"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": {
|
"default": {
|
||||||
"_type": "literalExpression",
|
"_type": "literalExpression",
|
||||||
@@ -12,9 +19,57 @@
|
|||||||
"readOnly": false,
|
"readOnly": false,
|
||||||
"type": "signed integer"
|
"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>.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>", "name"],
|
||||||
|
"readOnly": false,
|
||||||
|
"type": "string matching the pattern ^[a-zA-Z0-9._-]+$"
|
||||||
|
},
|
||||||
|
"destinations.<name>.repo": {
|
||||||
|
"declarations": [
|
||||||
|
"/Users/enzime/Work/clan/clan-core/lib/jsonschema/example-interface.nix"
|
||||||
|
],
|
||||||
|
"description": "the borgbackup repository to backup to",
|
||||||
|
"loc": ["destinations", "<name>", "repo"],
|
||||||
|
"readOnly": false,
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
"isAdmin": {
|
"isAdmin": {
|
||||||
"declarations": [
|
"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": {
|
"default": {
|
||||||
"_type": "literalExpression",
|
"_type": "literalExpression",
|
||||||
@@ -27,7 +82,7 @@
|
|||||||
},
|
},
|
||||||
"kernelModules": {
|
"kernelModules": {
|
||||||
"declarations": [
|
"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": {
|
"default": {
|
||||||
"_type": "literalExpression",
|
"_type": "literalExpression",
|
||||||
@@ -40,7 +95,7 @@
|
|||||||
},
|
},
|
||||||
"name": {
|
"name": {
|
||||||
"declarations": [
|
"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": {
|
"default": {
|
||||||
"_type": "literalExpression",
|
"_type": "literalExpression",
|
||||||
@@ -53,7 +108,7 @@
|
|||||||
},
|
},
|
||||||
"services": {
|
"services": {
|
||||||
"declarations": [
|
"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,
|
"description": null,
|
||||||
"loc": ["services"],
|
"loc": ["services"],
|
||||||
@@ -62,7 +117,7 @@
|
|||||||
},
|
},
|
||||||
"services.opt": {
|
"services.opt": {
|
||||||
"declarations": [
|
"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": {
|
"default": {
|
||||||
"_type": "literalExpression",
|
"_type": "literalExpression",
|
||||||
@@ -75,7 +130,7 @@
|
|||||||
},
|
},
|
||||||
"userIds": {
|
"userIds": {
|
||||||
"declarations": [
|
"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": {
|
"default": {
|
||||||
"_type": "literalExpression",
|
"_type": "literalExpression",
|
||||||
|
|||||||
@@ -4,6 +4,6 @@
|
|||||||
slib ? (import ./. { inherit lib; } { }),
|
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; };
|
parseOptions = import ./test_parseOptions.nix { inherit lib slib; };
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -25,6 +25,7 @@ in
|
|||||||
export NIX_ABORT_ON_WARN=1
|
export NIX_ABORT_ON_WARN=1
|
||||||
nix-unit --eval-store "$HOME" \
|
nix-unit --eval-store "$HOME" \
|
||||||
--extra-experimental-features flakes \
|
--extra-experimental-features flakes \
|
||||||
|
--show-trace \
|
||||||
${inputOverrides} \
|
${inputOverrides} \
|
||||||
--flake ${
|
--flake ${
|
||||||
self.filter {
|
self.filter {
|
||||||
|
|||||||
@@ -23,6 +23,7 @@ in
|
|||||||
|
|
||||||
nix-unit --eval-store "$HOME" \
|
nix-unit --eval-store "$HOME" \
|
||||||
--extra-experimental-features flakes \
|
--extra-experimental-features flakes \
|
||||||
|
--show-trace \
|
||||||
${inputOverrides} \
|
${inputOverrides} \
|
||||||
--flake ${
|
--flake ${
|
||||||
self.filter {
|
self.filter {
|
||||||
|
|||||||
@@ -29,6 +29,7 @@ Service = dict[str, Any]
|
|||||||
|
|
||||||
|
|
||||||
class Inventory(TypedDict):
|
class Inventory(TypedDict):
|
||||||
|
machineClass: NotRequired[dict[str, Any]]
|
||||||
machines: NotRequired[dict[str, Machine]]
|
machines: NotRequired[dict[str, Machine]]
|
||||||
meta: NotRequired[Meta]
|
meta: NotRequired[Meta]
|
||||||
modules: NotRequired[dict[str, Any]]
|
modules: NotRequired[dict[str, Any]]
|
||||||
|
|||||||
@@ -1,12 +1,13 @@
|
|||||||
import importlib
|
import importlib
|
||||||
import json
|
import json
|
||||||
import logging
|
import logging
|
||||||
|
import re
|
||||||
from dataclasses import dataclass, field
|
from dataclasses import dataclass, field
|
||||||
from functools import cached_property
|
from functools import cached_property
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from typing import TYPE_CHECKING, Any, Literal
|
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 public_modules as facts_public_modules
|
||||||
from clan_cli.facts import secret_modules as facts_secret_modules
|
from clan_cli.facts import secret_modules as facts_secret_modules
|
||||||
from clan_cli.flake import Flake
|
from clan_cli.flake import Flake
|
||||||
@@ -56,10 +57,22 @@ class Machine:
|
|||||||
kwargs.update({"extra": {"command_prefix": self.name}})
|
kwargs.update({"extra": {"command_prefix": self.name}})
|
||||||
log.error(msg, *args, **kwargs)
|
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
|
@property
|
||||||
def system(self) -> str:
|
def system(self) -> str:
|
||||||
return self.flake.select(
|
return self.flake.select(
|
||||||
f"nixosConfigurations.{self.name}.pkgs.hostPlatform.system"
|
f"{self._class_}Configurations.{self.name}.pkgs.hostPlatform.system"
|
||||||
)
|
)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
|
|||||||
@@ -238,6 +238,8 @@ def update_command(args: argparse.Namespace) -> None:
|
|||||||
if len(args.machines) == 0:
|
if len(args.machines) == 0:
|
||||||
ignored_machines = []
|
ignored_machines = []
|
||||||
for machine in get_all_machines(args.flake, args.option):
|
for machine in get_all_machines(args.flake, args.option):
|
||||||
|
if machine._class_ == "darwin":
|
||||||
|
continue
|
||||||
if machine.deployment.get("requireExplicitUpdate", False):
|
if machine.deployment.get("requireExplicitUpdate", False):
|
||||||
continue
|
continue
|
||||||
try:
|
try:
|
||||||
@@ -265,6 +267,11 @@ def update_command(args: argparse.Namespace) -> None:
|
|||||||
machine.override_build_host = args.build_host
|
machine.override_build_host = args.build_host
|
||||||
machine.host_key_check = HostKeyCheck.from_str(args.host_key_check)
|
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)
|
deploy_machines(machines)
|
||||||
except KeyboardInterrupt:
|
except KeyboardInterrupt:
|
||||||
log.warning("Interrupted by user")
|
log.warning("Interrupted by user")
|
||||||
|
|||||||
Reference in New Issue
Block a user