avoid the with keyword

This commit is contained in:
do butterflies cry? 2025-12-14 21:37:20 +10:00
parent 0b13998fd4
commit 08ceff4581

253
flake.nix
View file

@ -35,145 +35,144 @@
nib, nib,
deploy-rs, deploy-rs,
... ...
} @ inputs: } @ inputs: let
with builtins; lib = nixpkgs.lib;
with nib.types; let
lib = nixpkgs.lib;
sys = with nib; sys = nib.mkUSys {
mkUSys { pkgs = nib.withPkgs nixpkgs {
pkgs = withPkgs nixpkgs { config.allowUnfree = false;
config.allowUnfree = false; overlays = builtins.attrValues self.overlays;
overlays = attrValues self.overlays; };
}; upkgs = nib.withPkgs nixpkgs-unstable {
upkgs = withPkgs nixpkgs-unstable { config.allowUnfree = false;
config.allowUnfree = false; };
}; };
in rec {
overlays = [
# deploy-rs is built from the flake input, not from nixpkgs!
# To take advantage of the nixpkgs binary cache,
# the deploy-rs package can be overwritten:
deploy-rs.overlays.default
(self: super: {
deploy-rs = {
inherit (super) deploy-rs;
lib = super.deploy-rs.lib;
}; };
in rec { })
overlays = [ ];
# deploy-rs is built from the flake input, not from nixpkgs!
# To take advantage of the nixpkgs binary cache,
# the deploy-rs package can be overwritten:
deploy-rs.overlays.default
(self: super: {
deploy-rs = {
inherit (super) deploy-rs;
lib = super.deploy-rs.lib;
};
})
];
mkNexusConfig = config: let mkNexusConfig = config: let
# abstract node instance that stores all default values # abstract node instance that stores all default values
templateNode = name: system: let templateNode = name: system: let
missing = msg: path: Terminal = nib.types.Terminal;
Terminal (abort ''
Each Cerulean Nexus node is required to specify ${msg}!
Ensure `cerulean.nexus.nodes.${name}.${path}` exists under your call to `cerulean.mkNexus`.
'');
in {
system = missing "its system type" "system"; # intentionally left missing!! (to raise errors)
modules = missing "its required modules" "modules";
specialArgs = Terminal {
inherit inputs;
pkgs = sys.pkgsFor system;
upkgs = sys.upkgsFor system;
};
deploy = { missing = msg: path:
user = "root"; Terminal (abort ''
sudo = "sudo -u"; Each Cerulean Nexus node is required to specify ${msg}!
interactiveSudo = false; Ensure `cerulean.nexus.nodes.${name}.${path}` exists under your call to `cerulean.mkNexus`.
'');
remoteBuild = false; # prefer local builds for remote deploys in {
system = missing "its system type" "system"; # intentionally left missing!! (to raise errors)
autoRollback = true; # reactivate previous profile if activation fails modules = missing "its required modules" "modules";
magicRollback = true; specialArgs = Terminal {
inherit inputs;
activationTimeout = 500; # timeout in seconds for profile activation pkgs = sys.pkgsFor system;
confirmTimeout = 30; # timeout in seconds for profile activation confirmation upkgs = sys.upkgsFor system;
ssh = {
host = missing "an SSH hostname (domain name or ip address) for deployment" "deploy.ssh.host";
user = missing "an SSH username for deployment" "deploy.ssh.user";
port = 22;
opts = [];
};
};
}; };
parseNode = name: nodeAttrs: deploy = {
if !(isAttrs nodeAttrs) user = "root";
then sudo = "sudo -u";
# fail if node is not an attribute set interactiveSudo = false;
abort ''
Cerulean Nexus nodes must be provided as an attribute set, got "${typeOf nodeAttrs}" instead!
Ensure all `cerulean.nexus.nodes.${name}` declarations are attribute sets under your call to `cerulean.mkNexus`.
''
# TODO: nodeAttrs.system won't display any nice error messages!!
# TODO: will mergeTypedStruct give nice error messages? or should I use mergeStructErr directly?
else let
templateAttrs = templateNode name nodeAttrs.system;
S = nib.parse.parseStructFor templateAttrs nodeAttrs;
in
unwrapRes (_:
abort ''
Cerulean failed to parse `cerulean.nexus.nodes.${name}`!
mergeStruct should never return `result.Err`... How are you here?!?
'')
S;
# TODO: mapNodes = f: mapAttrs (name: nodeAttrs: f name (parseNode name nodeAttrs)) config.nexus.nodes remoteBuild = false; # prefer local builds for remote deploys
mapNodes = f: mapAttrs f (mapAttrs parseNode config.nexus.nodes);
in rec {
nixosConfigurations = mapNodes (
_: node:
lib.nixosSystem {
system = node.system;
modules = node.modules;
# nix passes these to every single module autoRollback = true; # reactivate previous profile if activation fails
specialArgs = {} // node.modules.specialArgs; magicRollback = true;
}
);
deploy.nodes = mapNodes (_: node: { activationTimeout = 500; # timeout in seconds for profile activation
hostname = node.deploy.ssh.host; confirmTimeout = 30; # timeout in seconds for profile activation confirmation
profilesOrder = ["default"]; # profiles priority ssh = {
profiles.default = { host = missing "an SSH hostname (domain name or ip address) for deployment" "deploy.ssh.host";
path = deploy-rs.lib.${node.system}.activate.nixos nixosConfigurations.${node.system}; user = missing "an SSH username for deployment" "deploy.ssh.user";
port = 22;
user = node.deploy.user; opts = [];
sudo = node.deploy.sudo;
interactiveSudo = node.deploy.interactiveSudo;
fastConnection = false;
autoRollback = node.deploy.autoRollback;
magicRollback = node.deploy.magicRollback;
activationTimeout = node.deploy.activationTimeout;
confirmTimeout = node.deploy.confirmTimeout;
remoteBuild = node.deploy.remoteBuild;
sshUser = node.deploy.ssh.user;
sshOpts =
node.deploy.ssh.opts
++ (
if elem "-p" node.deploy.ssh.opts
then []
else ["-p" (toString node.deploy.ssh.port)]
);
}; };
}); };
checks = mapAttrs (system: deployLib: deployLib.deployChecks deploy) deploy-rs.lib;
}; };
mkNexus = outputs: let parseNode = name: nodeAttrs:
config = outputs.cerulean; if !(builtins.isAttrs nodeAttrs)
in then
(mkNexusConfig config) // (removeAttrs outputs ["cerulean"]); # fail if node is not an attribute set
abort ''
Cerulean Nexus nodes must be provided as an attribute set, got "${builtins.typeOf nodeAttrs}" instead!
Ensure all `cerulean.nexus.nodes.${name}` declarations are attribute sets under your call to `cerulean.mkNexus`.
''
# TODO: nodeAttrs.system won't display any nice error messages!!
# TODO: will mergeTypedStruct give nice error messages? or should I use mergeStructErr directly?
else let
templateAttrs = templateNode name nodeAttrs.system;
S = nib.parse.parseStructFor templateAttrs nodeAttrs;
in
nib.types.unwrapRes (_:
abort ''
Cerulean failed to parse `cerulean.nexus.nodes.${name}`!
mergeStruct should never return `result.Err`... How are you here?!?
'')
S;
# TODO: mapNodes = f: mapAttrs (name: nodeAttrs: f name (parseNode name nodeAttrs)) config.nexus.nodes
mapNodes = f: builtins.mapAttrs f (builtins.mapAttrs parseNode config.nexus.nodes);
in rec {
nixosConfigurations = mapNodes (
_: node:
lib.nixosSystem {
system = node.system;
modules = node.modules;
# nix passes these to every single module
specialArgs = {} // node.modules.specialArgs;
}
);
deploy.nodes = mapNodes (_: node: {
hostname = node.deploy.ssh.host;
profilesOrder = ["default"]; # profiles priority
profiles.default = {
path = deploy-rs.lib.${node.system}.activate.nixos nixosConfigurations.${node.system};
user = node.deploy.user;
sudo = node.deploy.sudo;
interactiveSudo = node.deploy.interactiveSudo;
fastConnection = false;
autoRollback = node.deploy.autoRollback;
magicRollback = node.deploy.magicRollback;
activationTimeout = node.deploy.activationTimeout;
confirmTimeout = node.deploy.confirmTimeout;
remoteBuild = node.deploy.remoteBuild;
sshUser = node.deploy.ssh.user;
sshOpts =
node.deploy.ssh.opts
++ (
if builtins.elem "-p" node.deploy.ssh.opts
then []
else ["-p" (toString node.deploy.ssh.port)]
);
};
});
checks = builtins.mapAttrs (system: deployLib: deployLib.deployChecks deploy) deploy-rs.lib;
}; };
mkNexus = outputs: let
config = outputs.cerulean;
in
(mkNexusConfig config) // (removeAttrs outputs ["cerulean"]);
};
} }