implement: mkNexus now configures NixOS and deploy-rs
Deployment information is parsed via nib.parse.mergeTypedStruct. Overall much less boilerplate will be required for endusers. deploy-rs also now supports retrieval from a nix binary cache!
This commit is contained in:
parent
eae4f89f60
commit
ccc1e46dec
1 changed files with 94 additions and 11 deletions
105
flake.nix
105
flake.nix
|
|
@ -36,8 +36,18 @@
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
in rec {
|
in rec {
|
||||||
# overlays.default = final: prev: {
|
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;
|
||||||
|
};
|
||||||
|
})
|
||||||
|
];
|
||||||
|
|
||||||
# checks = self.packages;
|
# checks = self.packages;
|
||||||
# packages =
|
# packages =
|
||||||
|
|
@ -45,24 +55,97 @@
|
||||||
# });
|
# });
|
||||||
|
|
||||||
mkNexusConfig = config: let
|
mkNexusConfig = config: let
|
||||||
mapNodes = f: lib.mapAttrs f config.nexus.nodes;
|
# abstract node instance that stores all default values
|
||||||
|
templateNode = let
|
||||||
|
missing = msg: path:
|
||||||
|
builtins.abort ''
|
||||||
|
Each Cerulean Nexus node is required to specify ${msg}!
|
||||||
|
Ensure `cerulean.nexus.nodes.$${NODE}.${path}` exists under your call to `cerulean.mkNexus`.
|
||||||
|
'';
|
||||||
|
in
|
||||||
|
system: {
|
||||||
|
system = missing "its system type" "system"; # intentionally left missing!! (to raise errors)
|
||||||
|
modules = missing "its required modules" "modules";
|
||||||
|
specialArgs = {
|
||||||
|
inherit inputs;
|
||||||
|
pkgs = sys.pkgsFor system;
|
||||||
|
upkgs = sys.upkgsFor system;
|
||||||
|
};
|
||||||
|
|
||||||
|
deploy = {
|
||||||
|
user = "root";
|
||||||
|
sudo = "sudo -u";
|
||||||
|
interactiveSudo = false;
|
||||||
|
|
||||||
|
remoteBuild = false; # prefer local builds for remote deploys
|
||||||
|
|
||||||
|
autoRollback = true; # reactivate previous profile if activation fails
|
||||||
|
magicRollback = true;
|
||||||
|
|
||||||
|
activationTimeout = 500; # timeout in seconds for profile activation
|
||||||
|
confirmTimeout = 30; # timeout in seconds for profile activation confirmation
|
||||||
|
|
||||||
|
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:
|
||||||
|
if !(builtins.isAttrs nodeAttrs)
|
||||||
|
then
|
||||||
|
# fail if node is not an attribute set
|
||||||
|
builtins.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 nib.parse.mergeTypedStruct (templateNode nodeAttrs.system) nodeAttrs;
|
||||||
|
|
||||||
|
mapNodes = f: lib.mapAttrs f (parseNode config.nexus.nodes);
|
||||||
in rec {
|
in rec {
|
||||||
nixosConfigurations = mapNodes (
|
nixosConfigurations = mapNodes (
|
||||||
name: node:
|
name: node:
|
||||||
lib.nixosSystem {
|
lib.nixosSystem {
|
||||||
system = node.system;
|
system = node.system;
|
||||||
modules = node.modules;
|
modules = node.modules;
|
||||||
|
|
||||||
|
# nix passes these to every single module
|
||||||
|
specialArgs = [] // node.modules.specialArgs;
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
deploy.nodes = mapNodes (name: node: {
|
deploy.nodes = mapNodes (nodeName: node: {
|
||||||
hostname = name;
|
hostname = node.deploy.ssh.host;
|
||||||
profiles.system = {
|
|
||||||
user = "root";
|
profilesOrder = ["default"]; # profiles priority
|
||||||
path = let
|
profiles.default = {
|
||||||
system = node.system;
|
path = deploy-rs.lib.${node.system}.activate.nixos nixosConfigurations.${node.system};
|
||||||
in
|
|
||||||
deploy-rs.lib.${system}.activate.nixos nixosConfigurations.${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" (builtins.toString node.deploy.ssh.port)]
|
||||||
|
);
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue