remove legacy nexus
This commit is contained in:
parent
45c53f025a
commit
be45d2a4d4
4 changed files with 3 additions and 421 deletions
|
|
@ -17,15 +17,15 @@
|
||||||
...
|
...
|
||||||
} @ args:
|
} @ args:
|
||||||
mix.newMixture args (mixture: {
|
mix.newMixture args (mixture: {
|
||||||
includes.public = [
|
|
||||||
./nexus
|
|
||||||
];
|
|
||||||
submods.public = [
|
submods.public = [
|
||||||
./snow
|
./snow
|
||||||
];
|
];
|
||||||
|
|
||||||
version = "0.2.3";
|
version = "0.2.3";
|
||||||
|
|
||||||
|
# WARNING: legacy
|
||||||
|
mkFlake = mixture.snow.flake;
|
||||||
|
|
||||||
overlays = [
|
overlays = [
|
||||||
# build deploy-rs as a package not from the flake input,
|
# build deploy-rs as a package not from the flake input,
|
||||||
# hence we can rely on a nixpkg binary cache.
|
# hence we can rely on a nixpkg binary cache.
|
||||||
|
|
|
||||||
|
|
@ -1,20 +0,0 @@
|
||||||
# Copyright 2025-2026 _cry64 (Emile Clark-Boman)
|
|
||||||
#
|
|
||||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
# you may not use this file except in compliance with the License.
|
|
||||||
# You may obtain a copy of the License at
|
|
||||||
#
|
|
||||||
# http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
#
|
|
||||||
# Unless required by applicable law or agreed to in writing, software
|
|
||||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
# See the License for the specific language governing permissions and
|
|
||||||
# limitations under the License.
|
|
||||||
{mix, ...} @ args:
|
|
||||||
mix.newMixture args (mixture: {
|
|
||||||
includes.public = [
|
|
||||||
./nodes.nix
|
|
||||||
./nexus.nix
|
|
||||||
];
|
|
||||||
})
|
|
||||||
|
|
@ -1,297 +0,0 @@
|
||||||
# Copyright 2025-2026 _cry64 (Emile Clark-Boman)
|
|
||||||
#
|
|
||||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
# you may not use this file except in compliance with the License.
|
|
||||||
# You may obtain a copy of the License at
|
|
||||||
#
|
|
||||||
# http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
#
|
|
||||||
# Unless required by applicable law or agreed to in writing, software
|
|
||||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
# See the License for the specific language governing permissions and
|
|
||||||
# limitations under the License.
|
|
||||||
{
|
|
||||||
self,
|
|
||||||
this,
|
|
||||||
nt,
|
|
||||||
inputs,
|
|
||||||
...
|
|
||||||
}: let
|
|
||||||
inherit
|
|
||||||
(builtins)
|
|
||||||
all
|
|
||||||
attrNames
|
|
||||||
concatLists
|
|
||||||
concatStringsSep
|
|
||||||
elem
|
|
||||||
filter
|
|
||||||
getAttr
|
|
||||||
isAttrs
|
|
||||||
isFunction
|
|
||||||
isList
|
|
||||||
mapAttrs
|
|
||||||
pathExists
|
|
||||||
typeOf
|
|
||||||
;
|
|
||||||
|
|
||||||
inherit
|
|
||||||
(this)
|
|
||||||
mapNodes
|
|
||||||
;
|
|
||||||
|
|
||||||
inherit
|
|
||||||
(nt)
|
|
||||||
findImport
|
|
||||||
;
|
|
||||||
|
|
||||||
templateNexus = let
|
|
||||||
inherit
|
|
||||||
(nt.naive.terminal)
|
|
||||||
Terminal
|
|
||||||
;
|
|
||||||
in {
|
|
||||||
base = null;
|
|
||||||
modules = [];
|
|
||||||
args = Terminal {};
|
|
||||||
homeManager = null;
|
|
||||||
|
|
||||||
groups = Terminal {};
|
|
||||||
nodes = Terminal {};
|
|
||||||
};
|
|
||||||
|
|
||||||
ROOT_GROUP_NAME = "all";
|
|
||||||
|
|
||||||
parseGroupDecl = groups: let
|
|
||||||
validGroup = g:
|
|
||||||
isAttrs g
|
|
||||||
|| throw ''
|
|
||||||
Cerulean Nexus groups must be provided as attribute sets, got "${typeOf g}" instead!
|
|
||||||
Ensure all the group definitions are attribute sets under your call to `cerulean.mkNexus`.
|
|
||||||
NOTE: Groups can be accessed via `self.groups.PATH.TO.YOUR.GROUP`
|
|
||||||
'';
|
|
||||||
delegate = parent: gName: g: let
|
|
||||||
result =
|
|
||||||
(g
|
|
||||||
// {
|
|
||||||
_name = gName;
|
|
||||||
_parent = parent;
|
|
||||||
})
|
|
||||||
|> mapAttrs (name: value:
|
|
||||||
if elem name ["_name" "_parent"]
|
|
||||||
# ignore metadata fields
|
|
||||||
then value
|
|
||||||
else assert validGroup value; (delegate result name value));
|
|
||||||
in
|
|
||||||
result;
|
|
||||||
in
|
|
||||||
assert validGroup groups;
|
|
||||||
delegate null ROOT_GROUP_NAME groups;
|
|
||||||
|
|
||||||
parseNexus = nexus:
|
|
||||||
assert isAttrs nexus
|
|
||||||
|| abort ''
|
|
||||||
Cerulean Nexus config must be provided as an attribute set, got "${typeOf nexus}" instead!
|
|
||||||
Ensure the `nexus` declaration is an attribute set under your call to `cerulean.mkNexus`.
|
|
||||||
''; let
|
|
||||||
decl = 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
|
|
||||||
decl
|
|
||||||
// {
|
|
||||||
groups = parseGroupDecl decl.groups;
|
|
||||||
};
|
|
||||||
|
|
||||||
parseDecl = outputsBuilder: let
|
|
||||||
decl = (
|
|
||||||
if isFunction outputsBuilder
|
|
||||||
then outputsBuilder final # provide `self`
|
|
||||||
else
|
|
||||||
assert (isAttrs outputsBuilder)
|
|
||||||
|| abort ''
|
|
||||||
Cerulean declaration must be provided as an attribute set, got "${typeOf outputsBuilder}" instead!
|
|
||||||
Ensure your declaration is an attribute set or function under your call to `cerulean.mkNexus`.
|
|
||||||
''; outputsBuilder
|
|
||||||
);
|
|
||||||
|
|
||||||
final =
|
|
||||||
decl
|
|
||||||
// {
|
|
||||||
nexus = parseNexus (decl.nexus or {});
|
|
||||||
};
|
|
||||||
in
|
|
||||||
final;
|
|
||||||
|
|
||||||
getGroupModules = root: nodeName: node:
|
|
||||||
assert isList node.groups
|
|
||||||
|| throw ''
|
|
||||||
Cerulean Nexus node "${nodeName}" does not declare group membership as a list, got "${typeOf node.groups}" instead!
|
|
||||||
Ensure `nexus.nodes.${nodeName}.groups` is a list under your call to `cerulean.mkNexus`.
|
|
||||||
'';
|
|
||||||
# ensure root group is always added
|
|
||||||
(node.groups
|
|
||||||
++ [
|
|
||||||
{
|
|
||||||
_parent = null;
|
|
||||||
_name = ROOT_GROUP_NAME;
|
|
||||||
}
|
|
||||||
])
|
|
||||||
# ensure all members are actually groups
|
|
||||||
|> map (group: let
|
|
||||||
got =
|
|
||||||
if ! isAttrs group
|
|
||||||
then toString group
|
|
||||||
else
|
|
||||||
group
|
|
||||||
|> attrNames
|
|
||||||
|> map (name: "${name} = <${typeOf (getAttr name group)}>;")
|
|
||||||
|> concatStringsSep " "
|
|
||||||
|> (x: "{ ${x} }");
|
|
||||||
in
|
|
||||||
if group ? _name
|
|
||||||
then group
|
|
||||||
else
|
|
||||||
throw ''
|
|
||||||
Cerulean Nexus node "${nodeName}" is a member of an incorrectly structured group.
|
|
||||||
Got "${got}" of primitive type "${typeOf group}".
|
|
||||||
NOTE: Groups can be accessed via `self.groups.PATH.TO.YOUR.GROUP`
|
|
||||||
'')
|
|
||||||
# add all inherited groups via _parent
|
|
||||||
|> map (let
|
|
||||||
delegate = g:
|
|
||||||
if g._parent == null
|
|
||||||
then [g]
|
|
||||||
else [g] ++ delegate (g._parent);
|
|
||||||
in
|
|
||||||
delegate)
|
|
||||||
# flatten recursion result
|
|
||||||
|> concatLists
|
|
||||||
# find import location
|
|
||||||
|> map (group: findImport (root + "/groups/${group._name}"))
|
|
||||||
# filter by uniqueness
|
|
||||||
|> nt.prim.unique
|
|
||||||
# ignore missing groups
|
|
||||||
|> filter pathExists;
|
|
||||||
in {
|
|
||||||
mkNexus = root: outputsBuilder: let
|
|
||||||
decl = parseDecl outputsBuilder;
|
|
||||||
|
|
||||||
inherit
|
|
||||||
(decl)
|
|
||||||
nexus
|
|
||||||
;
|
|
||||||
customOutputs = removeAttrs decl ["nexus"];
|
|
||||||
|
|
||||||
outputs = rec {
|
|
||||||
nixosConfigurations = mapNodes nexus (
|
|
||||||
{
|
|
||||||
base,
|
|
||||||
lib,
|
|
||||||
nodeName,
|
|
||||||
node,
|
|
||||||
...
|
|
||||||
}: let
|
|
||||||
nixosDecl = let
|
|
||||||
homeManager =
|
|
||||||
if node.homeManager != null
|
|
||||||
then node.homeManager
|
|
||||||
else nexus.homeManager;
|
|
||||||
|
|
||||||
userArgs = nexus.args // node.args;
|
|
||||||
ceruleanArgs = {
|
|
||||||
inherit root base;
|
|
||||||
inherit (node) system;
|
|
||||||
_cerulean = {
|
|
||||||
inherit inputs userArgs ceruleanArgs homeManager;
|
|
||||||
specialArgs = userArgs // ceruleanArgs;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
specialArgs = assert (userArgs
|
|
||||||
|> attrNames
|
|
||||||
|> all (argName:
|
|
||||||
! ceruleanArgs ? argName
|
|
||||||
|| abort ''
|
|
||||||
`specialArgs` are like super important to Cerulean my love... </3
|
|
||||||
But `args.${argName}` is a reserved argument name :(
|
|
||||||
''));
|
|
||||||
ceruleanArgs._cerulean.specialArgs;
|
|
||||||
in
|
|
||||||
lib.nixosSystem {
|
|
||||||
inherit (node) system;
|
|
||||||
inherit specialArgs;
|
|
||||||
modules =
|
|
||||||
[
|
|
||||||
self.nixosModules.default
|
|
||||||
(findImport (root + "/hosts/${nodeName}"))
|
|
||||||
|
|
||||||
# inputs.microvm.nixosModules.microvm
|
|
||||||
]
|
|
||||||
++ (homeManager.nixosModules.default or [])
|
|
||||||
++ (getGroupModules root nodeName node)
|
|
||||||
++ node.modules
|
|
||||||
++ nexus.modules;
|
|
||||||
};
|
|
||||||
in
|
|
||||||
nixosDecl
|
|
||||||
);
|
|
||||||
|
|
||||||
deploy.nodes = mapNodes nexus ({
|
|
||||||
nodeName,
|
|
||||||
node,
|
|
||||||
...
|
|
||||||
}: let
|
|
||||||
inherit
|
|
||||||
(node.deploy)
|
|
||||||
activationTimeout
|
|
||||||
autoRollback
|
|
||||||
confirmTimeout
|
|
||||||
interactiveSudo
|
|
||||||
magicRollback
|
|
||||||
remoteBuild
|
|
||||||
ssh
|
|
||||||
sudo
|
|
||||||
user
|
|
||||||
;
|
|
||||||
|
|
||||||
nixosFor = system: inputs.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) inputs.deploy-rs.lib;
|
|
||||||
};
|
|
||||||
in
|
|
||||||
outputs // customOutputs;
|
|
||||||
}
|
|
||||||
|
|
@ -1,101 +0,0 @@
|
||||||
# Copyright 2025-2026 _cry64 (Emile Clark-Boman)
|
|
||||||
#
|
|
||||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
# you may not use this file except in compliance with the License.
|
|
||||||
# You may obtain a copy of the License at
|
|
||||||
#
|
|
||||||
# http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
#
|
|
||||||
# Unless required by applicable law or agreed to in writing, software
|
|
||||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
# See the License for the specific language governing permissions and
|
|
||||||
# limitations under the License.
|
|
||||||
{nt, ...}: let
|
|
||||||
inherit
|
|
||||||
(builtins)
|
|
||||||
isAttrs
|
|
||||||
mapAttrs
|
|
||||||
typeOf
|
|
||||||
;
|
|
||||||
in rec {
|
|
||||||
# abstract node instance that stores all default values
|
|
||||||
templateNode = name: system: let
|
|
||||||
inherit
|
|
||||||
(nt.naive.terminal)
|
|
||||||
Terminal
|
|
||||||
;
|
|
||||||
|
|
||||||
missing = msg: path:
|
|
||||||
Terminal (abort ''
|
|
||||||
Each Cerulean Nexus node is required to specify ${msg}!
|
|
||||||
Ensure `nexus.${path}` exists under your call to `cerulean.mkNexus`.
|
|
||||||
'');
|
|
||||||
in {
|
|
||||||
enabled = true;
|
|
||||||
system = missing "its system architecture" "system";
|
|
||||||
groups = [];
|
|
||||||
modules = [];
|
|
||||||
args = Terminal {};
|
|
||||||
|
|
||||||
homeManager = null;
|
|
||||||
|
|
||||||
base = null;
|
|
||||||
|
|
||||||
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 = name;
|
|
||||||
user = "ceru-build"; # ceru-build is the default connection user
|
|
||||||
port = 22;
|
|
||||||
opts = [];
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
parseNode = name: nodeAttrs:
|
|
||||||
if !(isAttrs nodeAttrs)
|
|
||||||
then
|
|
||||||
# fail if node is not an attribute set
|
|
||||||
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`.
|
|
||||||
''
|
|
||||||
else let
|
|
||||||
templateAttrs = templateNode name nodeAttrs.system;
|
|
||||||
in
|
|
||||||
nt.projectOnto templateAttrs nodeAttrs;
|
|
||||||
|
|
||||||
mapNodes = nexus: f:
|
|
||||||
nexus.nodes
|
|
||||||
|> mapAttrs (nodeName: nodeAttrs: let
|
|
||||||
node = parseNode nodeName nodeAttrs;
|
|
||||||
|
|
||||||
# use per-node base or default to nexus base
|
|
||||||
base =
|
|
||||||
if node.base != null
|
|
||||||
then node.base
|
|
||||||
else if nexus.base != null
|
|
||||||
then nexus.base
|
|
||||||
else
|
|
||||||
abort ''
|
|
||||||
Cerulean cannot construct nexus node "${nodeName}" without a base package source.
|
|
||||||
Ensure `nexus.nodes.*.base` or `nexus.base` is a flake reference to the github:NixOS/nixpkgs repository.
|
|
||||||
'';
|
|
||||||
in
|
|
||||||
f {
|
|
||||||
inherit nodeName node base;
|
|
||||||
inherit (base) lib;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue