minimal working state
This commit is contained in:
parent
855430ef16
commit
6c1a0a5d33
26 changed files with 331 additions and 326 deletions
|
|
@ -1,4 +1,5 @@
|
|||
{
|
||||
self,
|
||||
this,
|
||||
inputs,
|
||||
systems,
|
||||
|
|
@ -16,14 +17,20 @@
|
|||
inherit (inputs.nixpkgs) lib;
|
||||
in {
|
||||
# snow.flake
|
||||
# XXX: TODO: stop taking in root as parameter (maybe take self instead?)
|
||||
flake = flakeInputs: root: let
|
||||
snowflake = lib.evalModules {
|
||||
class = "snowflake";
|
||||
specialArgs = let
|
||||
reservedSpecialArgs = {
|
||||
inherit (this) snow;
|
||||
# inherit (this) snow;
|
||||
snow = this;
|
||||
inherit systems root;
|
||||
inputs = flakeInputs;
|
||||
|
||||
_snowFlake = {
|
||||
inherit self inputs;
|
||||
};
|
||||
};
|
||||
|
||||
warnIfReserved = let
|
||||
|
|
@ -50,7 +57,10 @@ in {
|
|||
flakeInputs // reservedSpecialArgs;
|
||||
|
||||
modules = [
|
||||
./module.nix
|
||||
./nodes
|
||||
./modules
|
||||
./outputs
|
||||
(this.lib.findImport /${root}/snow)
|
||||
];
|
||||
};
|
||||
in
|
||||
|
|
|
|||
|
|
@ -1,24 +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.
|
||||
{
|
||||
root,
|
||||
snow,
|
||||
...
|
||||
}: {
|
||||
imports = [
|
||||
./nodes
|
||||
./modules
|
||||
(snow.findImport /${root}/snow)
|
||||
];
|
||||
}
|
||||
|
|
@ -10,7 +10,7 @@
|
|||
;
|
||||
|
||||
inherit
|
||||
(snow)
|
||||
(snow.lib)
|
||||
mkPerSystemFlakeOutput
|
||||
;
|
||||
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@
|
|||
types
|
||||
;
|
||||
inherit
|
||||
(snow)
|
||||
(snow.lib)
|
||||
mkPerSystemFlakeOutput
|
||||
;
|
||||
in
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@
|
|||
literalExpression
|
||||
;
|
||||
inherit
|
||||
(snow)
|
||||
(snow.lib)
|
||||
mkPerSystemFlakeOutput
|
||||
;
|
||||
in
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@
|
|||
types
|
||||
;
|
||||
inherit
|
||||
(snow)
|
||||
(snow.lib)
|
||||
mkPerSystemFlakeOutput
|
||||
;
|
||||
in
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@
|
|||
types
|
||||
;
|
||||
inherit
|
||||
(snow)
|
||||
(snow.lib)
|
||||
mkPerSystemFlakeOutput
|
||||
;
|
||||
in
|
||||
|
|
|
|||
|
|
@ -8,38 +8,39 @@
|
|||
mkOption
|
||||
types
|
||||
;
|
||||
|
||||
outputs = mkOption {
|
||||
type = types.submoduleWith {
|
||||
modules = [
|
||||
{
|
||||
freeformType =
|
||||
types.lazyAttrsOf
|
||||
(types.unique
|
||||
{
|
||||
message = ''
|
||||
No option has been declared for this flake output attribute, so its definitions can't be merged automatically.
|
||||
Possible solutions:
|
||||
- Load a module that defines this flake output attribute
|
||||
- Declare an option for this flake output attribute
|
||||
- Make sure the output attribute is spelled correctly
|
||||
- Define the value only once, with a single definition in a single module
|
||||
'';
|
||||
}
|
||||
types.raw);
|
||||
}
|
||||
];
|
||||
};
|
||||
description = ''
|
||||
Raw flake output attributes. Any attribute can be set here, but some
|
||||
attributes are represented by options, to provide appropriate
|
||||
configuration merging.
|
||||
'';
|
||||
};
|
||||
in {
|
||||
options = {
|
||||
inherit outputs;
|
||||
outputs = mkOption {
|
||||
type = types.submoduleWith {
|
||||
modules = [
|
||||
{
|
||||
freeformType =
|
||||
types.lazyAttrsOf
|
||||
(types.unique
|
||||
{
|
||||
message = ''
|
||||
No option has been declared for this flake output attribute, so its definitions can't be merged automatically.
|
||||
Possible solutions:
|
||||
- Load a module that defines this flake output attribute
|
||||
- Declare an option for this flake output attribute
|
||||
- Make sure the output attribute is spelled correctly
|
||||
- Define the value only once, with a single definition in a single module
|
||||
'';
|
||||
}
|
||||
types.raw);
|
||||
}
|
||||
];
|
||||
};
|
||||
description = ''
|
||||
Raw flake output attributes. Any attribute can be set here, but some
|
||||
attributes are represented by options, to provide appropriate
|
||||
configuration merging.
|
||||
'';
|
||||
};
|
||||
};
|
||||
|
||||
config = {inherit (config) flake;};
|
||||
config = {
|
||||
# ensure a minimal version is set
|
||||
outputs = {};
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@
|
|||
;
|
||||
|
||||
inherit
|
||||
(snow)
|
||||
(snow.lib)
|
||||
mkPerSystemFlakeOutput
|
||||
;
|
||||
in
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@
|
|||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
{
|
||||
_snow,
|
||||
_snowFlake,
|
||||
lib,
|
||||
specialArgs,
|
||||
...
|
||||
|
|
@ -39,7 +39,7 @@
|
|||
|
||||
config = {
|
||||
nodes = {
|
||||
base = _snow.inputs.nixpkgs;
|
||||
base = _snowFlake.inputs.nixpkgs;
|
||||
};
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,73 +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)
|
||||
concatLists
|
||||
elem
|
||||
filter
|
||||
isAttrs
|
||||
mapAttrs
|
||||
pathExists
|
||||
typeOf
|
||||
;
|
||||
|
||||
rootGroupName = "all";
|
||||
in {
|
||||
parseGroupsDecl = groups: let
|
||||
validGroup = g:
|
||||
isAttrs g
|
||||
|| throw ''
|
||||
Snow node groups must be provided as attribute sets, got "${typeOf g}" instead!
|
||||
Ensure all the group definitions are attribute sets under your call to `snow.flake`.
|
||||
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 rootGroupName groups;
|
||||
|
||||
getGroupModules = root: groups:
|
||||
# ensure root group is always added
|
||||
groups
|
||||
# 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: nt.findImport /${root}/groups/${group._name})
|
||||
# filter by uniqueness
|
||||
|> nt.prim.unique
|
||||
# ignore missing groups
|
||||
|> filter pathExists;
|
||||
}
|
||||
|
|
@ -14,8 +14,9 @@
|
|||
{
|
||||
lib,
|
||||
systems,
|
||||
config,
|
||||
nodesConfig,
|
||||
groups,
|
||||
groupLibs,
|
||||
...
|
||||
}: {
|
||||
options = let
|
||||
|
|
@ -25,6 +26,11 @@
|
|||
types
|
||||
;
|
||||
|
||||
inherit
|
||||
(groupLibs)
|
||||
resolveGroupsInheritance
|
||||
;
|
||||
|
||||
flakeRef = types.either types.str types.path;
|
||||
in {
|
||||
enabled = lib.mkOption {
|
||||
|
|
@ -113,8 +119,8 @@
|
|||
A function from the `groups` hierarchy to a list of groups this node inherits from.
|
||||
'';
|
||||
|
||||
apply = groupsFn:
|
||||
groupsFn nodesConfig.groups;
|
||||
# apply = groupsFn:
|
||||
# groupsFn nodesConfig.groups |> resolveGroupsInheritance;
|
||||
};
|
||||
|
||||
deploy = {
|
||||
|
|
@ -266,32 +272,32 @@
|
|||
};
|
||||
};
|
||||
|
||||
config = let
|
||||
throwGotNull = name:
|
||||
throw ''
|
||||
[snow] `nodes.<name>.${name}` must be set for all nodes! (got: <null>)
|
||||
'';
|
||||
givenSystem =
|
||||
(config.system != null)
|
||||
|| throwGotNull "system";
|
||||
# config = let
|
||||
# throwGotNull = name:
|
||||
# throw ''
|
||||
# [snow] `nodes.<name>.${name}` must be set for all nodes! (got: <null>)
|
||||
# '';
|
||||
# givenSystem =
|
||||
# (config.system != null)
|
||||
# || throwGotNull "system";
|
||||
|
||||
givenBase =
|
||||
(config.base != null)
|
||||
|| throwGotNull "base";
|
||||
# givenBase =
|
||||
# (config.base != null)
|
||||
# || throwGotNull "base";
|
||||
|
||||
givenHomeManager =
|
||||
(config.homeManager != null)
|
||||
|| throwGotNull "homeManager";
|
||||
# givenHomeManager =
|
||||
# (config.homeManager != null)
|
||||
# || throwGotNull "homeManager";
|
||||
|
||||
givenDeployHost =
|
||||
(config.deploy.ssh.host != null)
|
||||
|| throwGotNull "deploy.ssh.host";
|
||||
in
|
||||
assert givenSystem
|
||||
&& givenBase
|
||||
&& givenHomeManager
|
||||
&& givenDeployHost; {
|
||||
# extend these from the nodes configuration
|
||||
inherit (nodesConfig) modules args;
|
||||
};
|
||||
# givenDeployHost =
|
||||
# (config.deploy.ssh.host != null)
|
||||
# || throwGotNull "deploy.ssh.host";
|
||||
# in
|
||||
# assert givenSystem
|
||||
# && givenBase
|
||||
# && givenHomeManager
|
||||
# && givenDeployHost; {
|
||||
# # extend these from the nodes configuration
|
||||
# inherit (nodesConfig) modules args;
|
||||
# };
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,7 +12,9 @@
|
|||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
{
|
||||
_snow,
|
||||
_snowFlake,
|
||||
snow,
|
||||
root,
|
||||
lib,
|
||||
config,
|
||||
specialArgs,
|
||||
|
|
@ -26,7 +28,10 @@
|
|||
|
||||
flakeRef = types.either types.str types.path;
|
||||
|
||||
groupLibs = import ./groups.nix {inherit (_snow.inputs) nt;};
|
||||
groupLibs = import ./groups.nix {
|
||||
inherit snow root;
|
||||
inherit (_snowFlake.inputs) nt;
|
||||
};
|
||||
in {
|
||||
options = {
|
||||
base = lib.mkOption {
|
||||
|
|
@ -94,8 +99,6 @@ in {
|
|||
description = ''
|
||||
Hierarchical groups that nodes can be a member of.
|
||||
'';
|
||||
|
||||
apply = groupLibs.parseGroupsDecl;
|
||||
};
|
||||
|
||||
nodes = mkOption {
|
||||
|
|
@ -103,7 +106,8 @@ in {
|
|||
specialArgs =
|
||||
specialArgs
|
||||
// {
|
||||
nodeConfig = config;
|
||||
nodesConfig = config;
|
||||
inherit groupLibs;
|
||||
};
|
||||
modules = [./node.nix];
|
||||
});
|
||||
|
|
|
|||
|
|
@ -1,10 +1,10 @@
|
|||
{
|
||||
config,
|
||||
_snow,
|
||||
_snowFlake,
|
||||
...
|
||||
}: {
|
||||
outputs.checks =
|
||||
_snow.inputs.deploy-rs.lib
|
||||
_snowFlake.inputs.deploy-rs.lib
|
||||
|> builtins.mapAttrs (system: deployLib:
|
||||
deployLib.deployChecks config.outputs.deploy);
|
||||
}
|
||||
|
|
|
|||
7
nix/snow/flake/outputs/default.nix
Normal file
7
nix/snow/flake/outputs/default.nix
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
{...}: {
|
||||
imports = [
|
||||
./checks.nix
|
||||
./deploy.nix
|
||||
./nixosConfigurations.nix
|
||||
];
|
||||
}
|
||||
|
|
@ -1,37 +1,10 @@
|
|||
{
|
||||
_snow,
|
||||
_snowFlake,
|
||||
snow,
|
||||
config,
|
||||
...
|
||||
}: let
|
||||
inherit
|
||||
(builtins)
|
||||
mapAttrs
|
||||
;
|
||||
|
||||
mapNodes = nodes: f:
|
||||
nodes.nodes
|
||||
|> mapAttrs (name: node: let
|
||||
# use per-node base or default to nodes' base
|
||||
base =
|
||||
if node.base != null
|
||||
then node.base
|
||||
else if nodes.base != null
|
||||
then nodes.base
|
||||
else
|
||||
abort ''
|
||||
snow cannot construct nodes node "${name}" without a base package source.
|
||||
Ensure `nodes.nodes.*.base` or `nodes.base` is a flake reference to the github:NixOS/nixpkgs repository.
|
||||
'';
|
||||
in
|
||||
f rec {
|
||||
inherit name node base;
|
||||
inherit (base) lib;
|
||||
|
||||
groups = node.groups (parseGroupsDecl nodes.groups);
|
||||
groupModules = root: getGroupModules root groups;
|
||||
});
|
||||
in {
|
||||
outputs.deploy.nodes = mapNodes config.nodes ({
|
||||
}: {
|
||||
outputs.deploy.nodes = snow.lib.mapNodes config.nodes ({
|
||||
name,
|
||||
node,
|
||||
...
|
||||
|
|
@ -49,7 +22,7 @@ in {
|
|||
confirmTimeout
|
||||
;
|
||||
|
||||
nixosFor = system: _snow.inputs.deploy-rs.lib.${system}.activate.nixos;
|
||||
nixosFor = system: _snowFlake.inputs.deploy-rs.lib.${system}.activate.nixos;
|
||||
in {
|
||||
hostname =
|
||||
if ssh.host != null
|
||||
|
|
|
|||
|
|
@ -1,14 +1,5 @@
|
|||
# {
|
||||
# _module = { ... };
|
||||
# _type = "configuration";
|
||||
# class = null;
|
||||
# config = { ... };
|
||||
# extendModules = «lambda extendModules @ /nix/store/9hfp0agnm43kz72l5lpfn9var5p0x2fa-source/lib/modules.nix:340:9»;
|
||||
# graph = [ ... ];
|
||||
# options = { ... };
|
||||
# type = { ... };
|
||||
# }
|
||||
{
|
||||
_snowFlake,
|
||||
snow,
|
||||
config,
|
||||
systems,
|
||||
|
|
@ -27,59 +18,67 @@
|
|||
nodes
|
||||
;
|
||||
in {
|
||||
outputs.nixosConfigurations = mapNodes nodes (
|
||||
{
|
||||
base,
|
||||
lib,
|
||||
name,
|
||||
node,
|
||||
groupModules,
|
||||
...
|
||||
}: let
|
||||
homeManager =
|
||||
if node.homeManager != null
|
||||
then node.homeManager
|
||||
else if nodes.homeManager != null
|
||||
then nodes.homeManager
|
||||
else
|
||||
warn ''
|
||||
[snowflake] Neither `nodes.homeManager` nor `nodes.nodes.${name}.homeManager` were specified!
|
||||
[snowflake] home-manager will NOT be used! User configuration will be ignored!
|
||||
''
|
||||
null;
|
||||
outputs.nixosConfigurations = let
|
||||
groups = snow.lib.parseGroupDecls root config.nodes.groups;
|
||||
in
|
||||
snow.lib.mapNodes nodes (
|
||||
{
|
||||
base,
|
||||
lib,
|
||||
name,
|
||||
node,
|
||||
...
|
||||
}: let
|
||||
nodeGroups =
|
||||
(node.groups groups)
|
||||
|> snow.lib.resolveGroupsInheritance
|
||||
|> snow.lib.groupModules;
|
||||
|
||||
userArgs = nodes.args // node.args;
|
||||
snowArgs = {
|
||||
inherit systems snow root base nodes node;
|
||||
inherit (node) system;
|
||||
hostname = name;
|
||||
homeManager =
|
||||
if node.homeManager != null
|
||||
then node.homeManager
|
||||
else if nodes.homeManager != null
|
||||
then nodes.homeManager
|
||||
else
|
||||
warn ''
|
||||
[snowflake] Neither `nodes.homeManager` nor `nodes.nodes.${name}.homeManager` were specified!
|
||||
[snowflake] home-manager will NOT be used! User configuration will be ignored!
|
||||
''
|
||||
null;
|
||||
|
||||
_snow = {
|
||||
inherit inputs userArgs snowArgs homeManager;
|
||||
specialArgs = userArgs // snowArgs;
|
||||
userArgs = nodes.args // node.args;
|
||||
snowArgs = {
|
||||
inherit systems snow root base nodes node;
|
||||
inherit (node) system;
|
||||
hostname = name;
|
||||
|
||||
_snow = {
|
||||
inherit (_snowFlake) inputs;
|
||||
inherit userArgs snowArgs homeManager;
|
||||
specialArgs = userArgs // snowArgs;
|
||||
};
|
||||
};
|
||||
};
|
||||
specialArgs = assert (userArgs
|
||||
|> attrNames
|
||||
|> all (argName:
|
||||
! snowArgs ? argName
|
||||
|| abort ''
|
||||
`specialArgs` are like super important to Snow my love... </3
|
||||
But `args.${argName}` is a reserved argument name :(
|
||||
''));
|
||||
snowArgs._snow.specialArgs;
|
||||
in
|
||||
lib.nixosSystem {
|
||||
inherit (node) system;
|
||||
inherit specialArgs;
|
||||
modules =
|
||||
[
|
||||
snow.nixosModules.default
|
||||
(snow.findImport /${root}/hosts/${name})
|
||||
]
|
||||
++ (groupModules root)
|
||||
++ node.modules
|
||||
++ nodes.modules;
|
||||
}
|
||||
);
|
||||
specialArgs = assert (userArgs
|
||||
|> attrNames
|
||||
|> all (argName:
|
||||
! snowArgs ? argName
|
||||
|| abort ''
|
||||
`specialArgs` are like super important to Snow my love... </3
|
||||
But `args.${argName}` is a reserved argument name :(
|
||||
''));
|
||||
snowArgs._snow.specialArgs;
|
||||
in
|
||||
lib.nixosSystem {
|
||||
inherit (node) system;
|
||||
inherit specialArgs;
|
||||
modules =
|
||||
[
|
||||
_snowFlake.self.nixosModules.default
|
||||
(snow.lib.findImport /${root}/hosts/${name})
|
||||
]
|
||||
++ nodeGroups
|
||||
++ node.modules
|
||||
++ nodes.modules;
|
||||
}
|
||||
);
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue