major refactoring
argument self is now provided via recursion a naive implementation of host groups is added
This commit is contained in:
parent
be916c8674
commit
5c5f3fb65e
3 changed files with 183 additions and 105 deletions
|
|
@ -23,8 +23,12 @@
|
||||||
}: let
|
}: let
|
||||||
inherit
|
inherit
|
||||||
(builtins)
|
(builtins)
|
||||||
|
attrNames
|
||||||
|
concatStringsSep
|
||||||
elem
|
elem
|
||||||
|
getAttr
|
||||||
isAttrs
|
isAttrs
|
||||||
|
isFunction
|
||||||
mapAttrs
|
mapAttrs
|
||||||
pathExists
|
pathExists
|
||||||
typeOf
|
typeOf
|
||||||
|
|
@ -37,7 +41,7 @@
|
||||||
|
|
||||||
templateNexus = let
|
templateNexus = let
|
||||||
inherit
|
inherit
|
||||||
(nt.types)
|
(nt.naive.terminal)
|
||||||
Terminal
|
Terminal
|
||||||
;
|
;
|
||||||
|
|
||||||
|
|
@ -47,112 +51,185 @@
|
||||||
Ensure `nexus.${path}` exists under your call to `cerulean.mkNexus`.
|
Ensure `nexus.${path}` exists under your call to `cerulean.mkNexus`.
|
||||||
'');
|
'');
|
||||||
in {
|
in {
|
||||||
groups = missing "an list of all valid node group names." "groups";
|
groups = Terminal {};
|
||||||
overlays = [];
|
overlays = [];
|
||||||
nodes = Terminal {};
|
nodes = Terminal {};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
parseGroups = groups: let
|
||||||
|
validGroup = g:
|
||||||
|
isAttrs g
|
||||||
|
|| throw ''
|
||||||
|
Cerulean Nexus groups must be provided as attribute sets, got "${typeOf g}" instead!
|
||||||
|
Ensure all the `groups` definitions are attribute sets under your call to `cerulean.mkNexus`.
|
||||||
|
'';
|
||||||
|
delegate = parent: g:
|
||||||
|
g
|
||||||
|
|> mapAttrs (name: value:
|
||||||
|
assert validGroup value;
|
||||||
|
(delegate g value)
|
||||||
|
// {
|
||||||
|
_name = name;
|
||||||
|
_parent = parent;
|
||||||
|
});
|
||||||
|
in
|
||||||
|
assert validGroup groups;
|
||||||
|
delegate null groups;
|
||||||
|
|
||||||
parseNexus = nexus:
|
parseNexus = nexus:
|
||||||
if ! isAttrs nexus
|
assert isAttrs nexus
|
||||||
then
|
|| abort ''
|
||||||
abort ''
|
Cerulean Nexus config must be provided as an attribute set, got "${typeOf nexus}" instead!
|
||||||
Cerulean Nexus config must be provided as an attribute set, got "${typeOf nexus}" instead!
|
Ensure all the `nexus` declaration is an attribute set under your call to `cerulean.mkNexus`.
|
||||||
Ensure all the `nexus` declaration is an attribute set under your call to `cerulean.mkNexus`.
|
''; let
|
||||||
''
|
base = nt.projectOnto templateNexus nexus;
|
||||||
else nt.projectOnto templateNexus nexus;
|
in
|
||||||
|
# XXX: TODO: create a different version of nt.projectOnto that can actually
|
||||||
|
# XXX: TODO: handle applying a transformation to the result of each datapoint
|
||||||
|
base
|
||||||
|
// {
|
||||||
|
groups = parseGroups base.groups;
|
||||||
|
};
|
||||||
|
|
||||||
mkNexus' = root: nexus': let
|
parseDecl = outputsBuilder: let
|
||||||
nexus = parseNexus nexus';
|
decl = (
|
||||||
in rec {
|
if isFunction outputsBuilder
|
||||||
nixosConfigurations = mapNodes nexus.nodes (
|
then outputsBuilder final # provide `self`
|
||||||
nodeName: node:
|
else
|
||||||
lib.nixosSystem {
|
assert (isAttrs outputsBuilder)
|
||||||
system = node.system;
|
|| abort ''
|
||||||
modules = let
|
Cerulean declaration must be provided as an attribute set, got "${typeOf outputsBuilder}" instead!
|
||||||
host' = root + "/hosts/${nodeName}";
|
Ensure your declaration is an attribute set or function under your call to `cerulean.mkNexus`.
|
||||||
host =
|
''; outputsBuilder
|
||||||
if pathExists host'
|
|
||||||
then host'
|
|
||||||
else host' + ".nix";
|
|
||||||
in
|
|
||||||
[../nixos-module host] ++ node.extraModules;
|
|
||||||
|
|
||||||
# nix passes these to every single module
|
|
||||||
specialArgs = let
|
|
||||||
pkgConfig =
|
|
||||||
{
|
|
||||||
inherit (node) system;
|
|
||||||
# XXX: WARNING: TODO: i've stopped caring
|
|
||||||
# XXX: WARNING: TODO: just figure out a better solution to pkgConfig
|
|
||||||
config.allowUnfree = true;
|
|
||||||
overlays = self.overlays ++ nexus.overlays ++ node.overlays;
|
|
||||||
}
|
|
||||||
// node.extraPkgConfig;
|
|
||||||
in
|
|
||||||
node.specialArgs
|
|
||||||
// {
|
|
||||||
pkgs = import nixpkgs pkgConfig;
|
|
||||||
upkgs = import nixpkgs-unstable pkgConfig;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
);
|
);
|
||||||
|
|
||||||
deploy.nodes = mapNodes nexus.nodes (nodeName: node: let
|
final =
|
||||||
inherit
|
decl
|
||||||
(node.deploy)
|
// {
|
||||||
activationTimeout
|
nexus = parseNexus (decl.nexus or {});
|
||||||
autoRollback
|
|
||||||
confirmTimeout
|
|
||||||
interactiveSudo
|
|
||||||
magicRollback
|
|
||||||
remoteBuild
|
|
||||||
ssh
|
|
||||||
sudo
|
|
||||||
user
|
|
||||||
;
|
|
||||||
|
|
||||||
nixosFor = system: deploy-rs.lib.${system}.activate.nixos;
|
|
||||||
in {
|
|
||||||
hostname = ssh.host;
|
|
||||||
|
|
||||||
profilesOrder = ["default"]; # profiles priority
|
|
||||||
profiles.default = {
|
|
||||||
path = nixosFor node.system nixosConfigurations.${nodeName};
|
|
||||||
|
|
||||||
user = user;
|
|
||||||
sudo = sudo;
|
|
||||||
interactiveSudo = interactiveSudo;
|
|
||||||
|
|
||||||
fastConnection = false;
|
|
||||||
|
|
||||||
autoRollback = autoRollback;
|
|
||||||
magicRollback = magicRollback;
|
|
||||||
activationTimeout = activationTimeout;
|
|
||||||
confirmTimeout = confirmTimeout;
|
|
||||||
|
|
||||||
remoteBuild = remoteBuild;
|
|
||||||
sshUser = ssh.user;
|
|
||||||
sshOpts =
|
|
||||||
ssh.opts
|
|
||||||
++ (
|
|
||||||
if elem "-p" ssh.opts
|
|
||||||
then []
|
|
||||||
else ["-p" (toString ssh.port)]
|
|
||||||
)
|
|
||||||
++ (
|
|
||||||
if elem "-A" ssh.opts
|
|
||||||
then []
|
|
||||||
else ["-A"]
|
|
||||||
);
|
|
||||||
};
|
};
|
||||||
});
|
|
||||||
|
|
||||||
checks = mapAttrs (system: deployLib: deployLib.deployChecks deploy) deploy-rs.lib;
|
|
||||||
};
|
|
||||||
in {
|
|
||||||
mkNexus = root: outputs': let
|
|
||||||
autogen = mkNexus' root (outputs'.nexus or {});
|
|
||||||
outputs = removeAttrs outputs' ["nexus"];
|
|
||||||
in
|
in
|
||||||
autogen // outputs; # XXX: TODO: replace this with a deep merge
|
final;
|
||||||
|
|
||||||
|
# XXX: TODO: create a function in NixTypes that handles this instead
|
||||||
|
findImport = path:
|
||||||
|
if pathExists path
|
||||||
|
then path
|
||||||
|
else path + ".nix";
|
||||||
|
in {
|
||||||
|
mkNexus = root: outputsBuilder: let
|
||||||
|
decl = parseDecl outputsBuilder;
|
||||||
|
|
||||||
|
inherit
|
||||||
|
(decl)
|
||||||
|
nexus
|
||||||
|
;
|
||||||
|
customOutputs = removeAttrs decl ["nexus"];
|
||||||
|
|
||||||
|
outputs = rec {
|
||||||
|
nixosConfigurations = mapNodes nexus.nodes (
|
||||||
|
nodeName: node:
|
||||||
|
lib.nixosSystem {
|
||||||
|
system = node.system;
|
||||||
|
modules = let
|
||||||
|
host = findImport (root + "/hosts/${nodeName}");
|
||||||
|
# XXX: TODO: don't use a naive type for this (ie _name property)
|
||||||
|
# XXX: TODO: i really need NixTypes to be stable and use that instead
|
||||||
|
groups =
|
||||||
|
node.groups
|
||||||
|
|> map (group:
|
||||||
|
assert group ? _name
|
||||||
|
|| throw (let
|
||||||
|
got =
|
||||||
|
if ! isAttrs group
|
||||||
|
then toString group
|
||||||
|
else
|
||||||
|
group
|
||||||
|
|> attrNames
|
||||||
|
|> map (name: "${name} = <${typeOf (getAttr name group)}>;")
|
||||||
|
|> concatStringsSep " "
|
||||||
|
|> (x: "{ ${x} }");
|
||||||
|
in ''
|
||||||
|
Cerulean Nexus node "${nodeName}" is a member of a nonexistent group.
|
||||||
|
Got "${got}" of primitive type "${typeOf group}".
|
||||||
|
NOTE: Groups can be accessed via `self.groups.PATH.TO.YOUR.GROUP`
|
||||||
|
'');
|
||||||
|
findImport (root + "/groups/${group._name}"));
|
||||||
|
in
|
||||||
|
[../nixos-module host] ++ groups ++ node.extraModules;
|
||||||
|
|
||||||
|
# nix passes these to every single module
|
||||||
|
specialArgs = let
|
||||||
|
pkgConfig =
|
||||||
|
{
|
||||||
|
inherit (node) system;
|
||||||
|
# XXX: WARNING: TODO: i've stopped caring
|
||||||
|
# XXX: WARNING: TODO: just figure out a better solution to pkgConfig
|
||||||
|
config.allowUnfree = true;
|
||||||
|
overlays = self.overlays ++ nexus.overlays ++ node.overlays;
|
||||||
|
}
|
||||||
|
// node.extraPkgConfig;
|
||||||
|
in
|
||||||
|
node.specialArgs
|
||||||
|
// {
|
||||||
|
pkgs = import nixpkgs pkgConfig;
|
||||||
|
upkgs = import nixpkgs-unstable pkgConfig;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
deploy.nodes = mapNodes nexus.nodes (nodeName: node: let
|
||||||
|
inherit
|
||||||
|
(node.deploy)
|
||||||
|
activationTimeout
|
||||||
|
autoRollback
|
||||||
|
confirmTimeout
|
||||||
|
interactiveSudo
|
||||||
|
magicRollback
|
||||||
|
remoteBuild
|
||||||
|
ssh
|
||||||
|
sudo
|
||||||
|
user
|
||||||
|
;
|
||||||
|
|
||||||
|
nixosFor = system: deploy-rs.lib.${system}.activate.nixos;
|
||||||
|
in {
|
||||||
|
hostname = ssh.host;
|
||||||
|
|
||||||
|
profilesOrder = ["default"]; # profiles priority
|
||||||
|
profiles.default = {
|
||||||
|
path = nixosFor node.system nixosConfigurations.${nodeName};
|
||||||
|
|
||||||
|
user = user;
|
||||||
|
sudo = sudo;
|
||||||
|
interactiveSudo = interactiveSudo;
|
||||||
|
|
||||||
|
fastConnection = false;
|
||||||
|
|
||||||
|
autoRollback = autoRollback;
|
||||||
|
magicRollback = magicRollback;
|
||||||
|
activationTimeout = activationTimeout;
|
||||||
|
confirmTimeout = confirmTimeout;
|
||||||
|
|
||||||
|
remoteBuild = remoteBuild;
|
||||||
|
sshUser = ssh.user;
|
||||||
|
sshOpts =
|
||||||
|
ssh.opts
|
||||||
|
++ (
|
||||||
|
if elem "-p" ssh.opts
|
||||||
|
then []
|
||||||
|
else ["-p" (toString ssh.port)]
|
||||||
|
)
|
||||||
|
++ (
|
||||||
|
if elem "-A" ssh.opts
|
||||||
|
then []
|
||||||
|
else ["-A"]
|
||||||
|
);
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
checks = mapAttrs (system: deployLib: deployLib.deployChecks deploy) deploy-rs.lib;
|
||||||
|
};
|
||||||
|
in
|
||||||
|
outputs // customOutputs;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -22,11 +22,12 @@ in rec {
|
||||||
# abstract node instance that stores all default values
|
# abstract node instance that stores all default values
|
||||||
templateNode = name: system: let
|
templateNode = name: system: let
|
||||||
inherit
|
inherit
|
||||||
(nt.types)
|
(nt.naive.terminal)
|
||||||
Terminal
|
Terminal
|
||||||
;
|
;
|
||||||
in {
|
in {
|
||||||
system = "x86_64-linux"; # sane default (i hope...)
|
system = "x86_64-linux"; # sane default (i hope...)
|
||||||
|
groups = [];
|
||||||
extraModules = [];
|
extraModules = [];
|
||||||
specialArgs = Terminal {};
|
specialArgs = Terminal {};
|
||||||
overlays = [];
|
overlays = [];
|
||||||
|
|
|
||||||
10
flake.nix
10
flake.nix
|
|
@ -31,9 +31,9 @@
|
||||||
...
|
...
|
||||||
} @ inputs:
|
} @ inputs:
|
||||||
import ./cerulean
|
import ./cerulean
|
||||||
<| inputs
|
(inputs
|
||||||
// {
|
// {
|
||||||
inherit (nixpkgs) lib;
|
inherit (nixpkgs) lib;
|
||||||
inherit (nt) mix;
|
inherit (nt) mix;
|
||||||
};
|
});
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue