diff --git a/flake.lock b/flake.lock index 6f3fefe..fc8e402 100644 --- a/flake.lock +++ b/flake.lock @@ -9,11 +9,11 @@ "utils": "utils" }, "locked": { - "lastModified": 1770019181, - "narHash": "sha256-hwsYgDnby50JNVpTRYlF3UR/Rrpt01OrxVuryF40CFY=", + "lastModified": 1766051518, + "narHash": "sha256-znKOwPXQnt3o7lDb3hdf19oDo0BLP4MfBOYiWkEHoik=", "owner": "serokell", "repo": "deploy-rs", - "rev": "77c906c0ba56aabdbc72041bf9111b565cdd6171", + "rev": "d5eff7f948535b9c723d60cd8239f8f11ddc90fa", "type": "github" }, "original": { @@ -68,11 +68,11 @@ "spectrum": "spectrum" }, "locked": { - "lastModified": 1773018425, - "narHash": "sha256-fpgZBmZpKoEXEowBK/6m8g9FcOLWQ4UxhXHqCw2CpSM=", + "lastModified": 1771365290, + "narHash": "sha256-1XJOslVyF7yzf6yd/yl1VjGLywsbtwmQh3X1LuJcLI4=", "owner": "microvm-nix", "repo": "microvm.nix", - "rev": "25ebda3c558e923720c965832dc9a04f559a055c", + "rev": "789c90b164b55b4379e7a94af8b9c01489024c18", "type": "github" }, "original": { @@ -129,11 +129,11 @@ }, "nixpkgs": { "locked": { - "lastModified": 1773375660, - "narHash": "sha256-SEzUWw2Rf5Ki3bcM26nSKgbeoqi2uYy8IHVBqOKjX3w=", + "lastModified": 1768323494, + "narHash": "sha256-yBXJLE6WCtrGo7LKiB6NOt6nisBEEkguC/lq/rP3zRQ=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "3e20095fe3c6cbb1ddcef89b26969a69a1570776", + "rev": "2c3e5ec5df46d3aeee2a1da0bfedd74e21f4bf3a", "type": "github" }, "original": { @@ -166,11 +166,11 @@ "systems": "systems_2" }, "locked": { - "lastModified": 1773738366, - "narHash": "sha256-oH22HyNHEdCoCQo734sQCHUr6C0jmGQJMZ13dsgEHkk=", + "lastModified": 1770975056, + "narHash": "sha256-ZXTz/P3zUbbM6lNXzt91u8EwfNqhXpYMu8+wvFZqQHE=", "owner": "cry128", "repo": "nt", - "rev": "f32c3a726a3d608d30aaaa1df2301c1eaf5ef8f4", + "rev": "f42dcdd49a7921a7f433512e83d5f93696632412", "type": "github" }, "original": { @@ -185,38 +185,17 @@ "microvm": "microvm", "nixpkgs": "nixpkgs", "nt": "nt", - "sops-nix": "sops-nix", "systems": "systems_3" } }, - "sops-nix": { - "inputs": { - "nixpkgs": [ - "nixpkgs" - ] - }, - "locked": { - "lastModified": 1773096132, - "narHash": "sha256-M3zEnq9OElB7zqc+mjgPlByPm1O5t2fbUrH3t/Hm5Ag=", - "owner": "Mic92", - "repo": "sops-nix", - "rev": "d1ff3b1034d5bab5d7d8086a7803c5a5968cd784", - "type": "github" - }, - "original": { - "owner": "Mic92", - "repo": "sops-nix", - "type": "github" - } - }, "spectrum": { "flake": false, "locked": { - "lastModified": 1772189877, - "narHash": "sha256-i1p90Rgssb//aNiTDFq46ZG/fk3LmyRLChtp/9lddyA=", + "lastModified": 1759482047, + "narHash": "sha256-H1wiXRQHxxPyMMlP39ce3ROKCwI5/tUn36P8x6dFiiQ=", "ref": "refs/heads/main", - "rev": "fe39e122d898f66e89ffa17d4f4209989ccb5358", - "revCount": 1255, + "rev": "c5d5786d3dc938af0b279c542d1e43bce381b4b9", + "revCount": 996, "type": "git", "url": "https://spectrum-os.org/git/spectrum" }, diff --git a/flake.nix b/flake.nix index 83bb612..80faf5c 100644 --- a/flake.nix +++ b/flake.nix @@ -44,7 +44,7 @@ nt, ... } @ inputs: - import ./nix + import ./cerulean { inherit inputs self nt; inherit (nt) mix; diff --git a/nix/default.nix b/nix/default.nix index 6364a63..6c488a1 100644 --- a/nix/default.nix +++ b/nix/default.nix @@ -15,28 +15,22 @@ mix, inputs, ... -} @ args: let - mixArgs = - args - // { - inherit (inputs.nixpkgs) lib; - }; -in - mix.newMixture mixArgs (mixture: { - submods.public = [ - ./snow - ]; +} @ args: +mix.newMixture args (mixture: { + submods.public = [ + ./snow + ]; - version = "0.2.6-alpha"; + version = "0.2.6-alpha"; - overlays = [ - # build deploy-rs as a package not from the flake input, - # hence we can rely on a nixpkg binary cache. - inputs.deploy-rs.overlays.default - ]; + overlays = [ + # build deploy-rs as a package not from the flake input, + # hence we can rely on a nixpkg binary cache. + inputs.deploy-rs.overlays.default + ]; - nixosModules = rec { - default = cerulean; - cerulean = ./nixos; - }; - }) + nixosModules = rec { + default = cerulean; + cerulean = ./nixos; + }; +}) diff --git a/nix/nixos/default.nix b/nix/nixos/default.nix index a91df1a..a716c2f 100644 --- a/nix/nixos/default.nix +++ b/nix/nixos/default.nix @@ -18,13 +18,13 @@ node, pkgs, lib, - _snow, + _cerulean, ... } @ args: { imports = [ - _snow.inputs.sops-nix.nixosModules.sops - # _snow.inputs.microvm.nixosModules.microvm + _cerulean.inputs.sops-nix.nixosModules.sops + # _cerulean.inputs.microvm.nixosModules.microvm # add support for `options.legacyImports` # ./legacy-imports.nix @@ -36,7 +36,7 @@ (import /${root}/nixpkgs.nix) ] # homemanager options declarations - ++ (lib.optional (_snow.homeManager != null) ./home.nix) + ++ (lib.optional (_cerulean.homeManager != null) ./home.nix) # remote deployment configuration ++ (lib.optional (node.deploy.ssh.host != null) ./remote-deploy); @@ -46,7 +46,7 @@ (with pkgs; [ sops ]) - ++ (with _snow.inputs; [ + ++ (with _cerulean.inputs; [ deploy-rs.packages.${system}.default ]); } diff --git a/nix/nixos/home.nix b/nix/nixos/home.nix index cf24f74..82117d8 100644 --- a/nix/nixos/home.nix +++ b/nix/nixos/home.nix @@ -12,7 +12,7 @@ # See the License for the specific language governing permissions and # limitations under the License. { - _snow, + _cerulean, config, root, lib, @@ -30,7 +30,7 @@ ; in { imports = [ - _snow.homeManager.nixosModules.default + _cerulean.homeManager.nixosModules.default ]; options = { @@ -69,7 +69,7 @@ in { _module.args.username = name; }); - extraSpecialArgs = _snow.specialArgs; + extraSpecialArgs = _cerulean.specialArgs; sharedModules = [ ../home diff --git a/nix/snow/default.nix b/nix/snow/default.nix index 89e1772..6993ff1 100644 --- a/nix/snow/default.nix +++ b/nix/snow/default.nix @@ -12,16 +12,180 @@ # See the License for the specific language governing permissions and # limitations under the License. { + this, + self, + inputs, + systems, nt, mix, ... -} @ args: -mix.newMixture (removeAttrs args ["this"]) (mixture: { - submods.public = [ - ./lib - ]; +} @ args: let + inherit + (builtins) + all + attrNames + elem + mapAttrs + warn + ; - includes.public = [ - ./flake - ]; -}) + inherit (inputs.nixpkgs) lib; + + inherit (nt) findImport; +in + mix.newMixture args (mixture: let + inherit (mixture) mapNodes; + in { + includes.private = [ + ./lib/nodes.nix + ]; + + inherit findImport; + + # snow.flake + flake = flakeInputs: root: let + module = lib.evalModules { + class = "snowflake"; + # TODO: abort if inputs contains reserved names + specialArgs = + (flakeInputs + // { + inherit systems root; + inherit (this) snow; + inputs = flakeInputs; + }) + |> (x: builtins.removeAttrs x ["self" "nodes"]); + + modules = [ + ./module.nix + ({config, ...}: { + _module.args = { + self = config; + nodes = config.nodes.nodes; + }; + }) + ]; + }; + + nodes = module.config.nodes; + in rec { + 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; + + userArgs = nodes.args // node.args; + ceruleanArgs = { + inherit systems root base nodes node; + inherit (node) system; + inherit (this) snow; + hostname = name; + + _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... rollback; + magicRollback = magicRollback -> rollback; + 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 = + inputs.deploy-rs.lib + |> mapAttrs (system: deployLib: + deployLib.deployChecks deploy); + }; + }) diff --git a/nix/snow/flake/default.nix b/nix/snow/flake/default.nix deleted file mode 100644 index 828f59b..0000000 --- a/nix/snow/flake/default.nix +++ /dev/null @@ -1,68 +0,0 @@ -{ - self, - this, - inputs, - systems, - ... -}: let - inherit - (builtins) - attrNames - concatStringsSep - filter - length - warn - ; - - 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; - snow = this; - inherit systems root; - inputs = flakeInputs; - - _snowFlake = { - inherit self inputs; - }; - }; - - warnIfReserved = let - getReservedNames = names: - reservedSpecialArgs - |> attrNames - |> filter (name: names?${name}); - - reservedNames = - flakeInputs - |> attrNames - |> getReservedNames; - in - (length reservedNames == 0) - || warn '' - [snow] Your `flake.nix` declares inputs with reserved names! - [snow] These will be accessible only via `inputs.''${NAME}` - [snow] Please rename the following: - [snow] ${concatStringsSep reservedNames ", "} - '' - true; - in - assert warnIfReserved; - flakeInputs // reservedSpecialArgs; - - modules = [ - ./nodes - ./modules - ./outputs - (this.lib.findImport /${root}/snow) - ]; - }; - in - snowflake.config.outputs; -} diff --git a/nix/snow/flake/modules/README.md b/nix/snow/flake/modules/README.md deleted file mode 100644 index d19dbc1..0000000 --- a/nix/snow/flake/modules/README.md +++ /dev/null @@ -1,3 +0,0 @@ -# Snow Module Backend -This source code was tedious so it's just a modified version of the module backend of -[github:hercules-ci/flake-parts](https://github.com/hercules-ci/flake-parts/tree/main/modules). diff --git a/nix/snow/flake/modules/apps.nix b/nix/snow/flake/modules/apps.nix deleted file mode 100644 index cbe12f0..0000000 --- a/nix/snow/flake/modules/apps.nix +++ /dev/null @@ -1,69 +0,0 @@ -{ - lib, - snow, - ... -}: let - inherit - (lib) - mkOption - types - ; - - inherit - (snow.lib) - mkPerSystemFlakeOutput - ; - - derivationType = - lib.types.package - // { - check = lib.isDerivation; - }; - - programType = lib.types.coercedTo derivationType lib.getExe lib.types.str; - - appType = lib.types.submodule { - options = { - type = mkOption { - type = lib.types.enum ["app"]; - default = "app"; - description = '' - A type tag for `apps` consumers. - ''; - }; - program = mkOption { - type = programType; - description = '' - A path to an executable or a derivation with `meta.mainProgram`. - ''; - }; - meta = mkOption { - type = types.lazyAttrsOf lib.types.raw; - default = {}; - # TODO refer to Nix manual 2.25 - description = '' - Metadata information about the app. - Standardized in Nix at . - - Note: `nix flake check` is only aware of the `description` attribute in `meta`. - ''; - }; - }; - }; -in - mkPerSystemFlakeOutput { - name = "apps"; - option = mkOption { - type = types.lazyAttrsOf appType; - default = {}; - description = '' - Programs runnable with nix run ``. - ''; - example = lib.literalExpression '' - { - default.program = "''${config.packages.hello}/bin/hello"; - } - ''; - }; - file = ./apps.nix; - } diff --git a/nix/snow/flake/modules/checks.nix b/nix/snow/flake/modules/checks.nix deleted file mode 100644 index d10d6d5..0000000 --- a/nix/snow/flake/modules/checks.nix +++ /dev/null @@ -1,26 +0,0 @@ -{ - lib, - snow, - ... -}: let - inherit - (lib) - mkOption - types - ; - inherit - (snow.lib) - mkPerSystemFlakeOutput - ; -in - mkPerSystemFlakeOutput { - name = "checks"; - option = mkOption { - type = types.lazyAttrsOf types.package; - default = {}; - description = '' - Derivations to be built by [`nix flake check`](https://nixos.org/manual/nix/stable/command-ref/new-cli/nix3-flake-check.html). - ''; - }; - file = ./checks.nix; - } diff --git a/nix/snow/flake/modules/default.nix b/nix/snow/flake/modules/default.nix deleted file mode 100644 index e6914a0..0000000 --- a/nix/snow/flake/modules/default.nix +++ /dev/null @@ -1,15 +0,0 @@ -{...}: { - imports = [ - ./outputs.nix - - ./apps.nix - ./checks.nix - ./devShells.nix - ./formatter.nix - ./legacyPackages.nix - ./nixosConfigurations.nix - ./nixosModules.nix - ./overlays.nix - ./packages.nix - ]; -} diff --git a/nix/snow/flake/modules/devShells.nix b/nix/snow/flake/modules/devShells.nix deleted file mode 100644 index 04ace01..0000000 --- a/nix/snow/flake/modules/devShells.nix +++ /dev/null @@ -1,35 +0,0 @@ -{ - lib, - snow, - ... -}: let - inherit - (lib) - mkOption - types - literalExpression - ; - inherit - (snow.lib) - mkPerSystemFlakeOutput - ; -in - mkPerSystemFlakeOutput { - name = "devShells"; - option = mkOption { - type = types.lazyAttrsOf types.package; - default = {}; - description = '' - An attribute set of packages to be used as shells. - [`nix develop .#`](https://nixos.org/manual/nix/stable/command-ref/new-cli/nix3-develop.html) will run `devShells.`. - ''; - example = literalExpression '' - { - default = pkgs.mkShell { - nativeBuildInputs = with pkgs; [ wget bat cargo ]; - }; - } - ''; - }; - file = ./devShells.nix; - } diff --git a/nix/snow/flake/modules/formatter.nix b/nix/snow/flake/modules/formatter.nix deleted file mode 100644 index 5cce36b..0000000 --- a/nix/snow/flake/modules/formatter.nix +++ /dev/null @@ -1,26 +0,0 @@ -{ - lib, - snow, - ... -}: let - inherit - (lib) - mkOption - types - ; - inherit - (snow.lib) - mkPerSystemFlakeOutput - ; -in - mkPerSystemFlakeOutput { - name = "formatter"; - option = mkOption { - type = types.nullOr types.package; - default = null; - description = '' - A package used by [`nix fmt`](https://nixos.org/manual/nix/stable/command-ref/new-cli/nix3-fmt.html). - ''; - }; - file = ./apps.nix; - } diff --git a/nix/snow/flake/modules/legacyPackages.nix b/nix/snow/flake/modules/legacyPackages.nix deleted file mode 100644 index 9adc91d..0000000 --- a/nix/snow/flake/modules/legacyPackages.nix +++ /dev/null @@ -1,26 +0,0 @@ -{ - lib, - snow, - ... -}: let - inherit - (lib) - mkOption - types - ; - inherit - (snow.lib) - mkPerSystemFlakeOutput - ; -in - mkPerSystemFlakeOutput { - name = "legacyPackages"; - option = mkOption { - type = types.lazyAttrsOf types.raw; - default = {}; - description = '' - Used for nixpkgs packages, also accessible via `nix build .#` [`nix build .#`](https://nixos.org/manual/nix/stable/command-ref/new-cli/nix3-build.html). - ''; - }; - file = ./legacyPackages.nix; - } diff --git a/nix/snow/flake/modules/nixosConfigurations.nix b/nix/snow/flake/modules/nixosConfigurations.nix deleted file mode 100644 index 7db8077..0000000 --- a/nix/snow/flake/modules/nixosConfigurations.nix +++ /dev/null @@ -1,35 +0,0 @@ -{lib, ...}: let - inherit - (lib) - mkOption - types - literalExpression - ; -in { - options = { - outputs.nixosConfigurations = mkOption { - type = types.lazyAttrsOf types.raw; - default = {}; - description = '' - Instantiated NixOS configurations. Used by `nixos-rebuild`. - - `nixosConfigurations` is for specific machines. If you want to expose - reusable configurations, add them to [`nixosModules`](#opt-flake.nixosModules) - in the form of modules (no `lib.nixosSystem`), so that you can reference - them in this or another flake's `nixosConfigurations`. - ''; - example = literalExpression '' - { - my-machine = inputs.nixpkgs.lib.nixosSystem { - # system is not needed with freshly generated hardware-configuration.nix - # system = "x86_64-linux"; # or set nixpkgs.hostPlatform in a module. - modules = [ - ./my-machine/nixos-configuration.nix - config.nixosModules.my-module - ]; - }; - } - ''; - }; - }; -} diff --git a/nix/snow/flake/modules/nixosModules.nix b/nix/snow/flake/modules/nixosModules.nix deleted file mode 100644 index 6819570..0000000 --- a/nix/snow/flake/modules/nixosModules.nix +++ /dev/null @@ -1,29 +0,0 @@ -{ - lib, - moduleLocation, - ... -}: let - inherit - (lib) - mapAttrs - mkOption - types - ; -in { - options = { - outputs.nixosModules = mkOption { - type = types.lazyAttrsOf types.deferredModule; - default = {}; - apply = mapAttrs (k: v: { - _class = "nixos"; - _file = "${toString moduleLocation}#nixosModules.${k}"; - imports = [v]; - }); - description = '' - NixOS modules. - - You may use this for reusable pieces of configuration, service modules, etc. - ''; - }; - }; -} diff --git a/nix/snow/flake/modules/outputs.nix b/nix/snow/flake/modules/outputs.nix deleted file mode 100644 index bf7d9f5..0000000 --- a/nix/snow/flake/modules/outputs.nix +++ /dev/null @@ -1,46 +0,0 @@ -{ - lib, - config, - ... -}: let - inherit - (lib) - mkOption - types - ; -in { - options = { - 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 = { - # ensure a minimal version is set - outputs = {}; - }; -} diff --git a/nix/snow/flake/modules/overlays.nix b/nix/snow/flake/modules/overlays.nix deleted file mode 100644 index 55423c2..0000000 --- a/nix/snow/flake/modules/overlays.nix +++ /dev/null @@ -1,31 +0,0 @@ -{lib, ...}: let - inherit - (lib) - mkOption - types - ; -in { - options = { - outputs.overlays = mkOption { - # uniq -> ordered: https://github.com/NixOS/nixpkgs/issues/147052 - # also update description when done - type = types.lazyAttrsOf (types.uniq (types.functionTo (types.functionTo (types.lazyAttrsOf types.unspecified)))); - # This eta expansion exists for the sole purpose of making nix flake check happy. - apply = lib.mapAttrs (_k: f: final: prev: f final prev); - default = {}; - example = lib.literalExpression '' - { - default = final: prev: {}; - } - ''; - description = '' - An attribute set of [overlays](https://nixos.org/manual/nixpkgs/stable/#chap-overlays). - - Note that the overlays themselves are not mergeable. While overlays - can be composed, the order of composition is significant, but the - module system does not guarantee sufficiently deterministic - definition ordering, across versions and when changing `imports`. - ''; - }; - }; -} diff --git a/nix/snow/flake/modules/packages.nix b/nix/snow/flake/modules/packages.nix deleted file mode 100644 index ef970bc..0000000 --- a/nix/snow/flake/modules/packages.nix +++ /dev/null @@ -1,29 +0,0 @@ -{ - lib, - snow, - ... -}: let - inherit - (lib) - mkOption - types - ; - - inherit - (snow.lib) - mkPerSystemFlakeOutput - ; -in - mkPerSystemFlakeOutput { - name = "packages"; - option = mkOption { - type = types.lazyAttrsOf types.package; - default = {}; - description = '' - An attribute set of packages to be built by [`nix build`](https://nixos.org/manual/nix/stable/command-ref/new-cli/nix3-build.html). - - `nix build .#` will build `packages.`. - ''; - }; - file = ./packages.nix; - } diff --git a/nix/snow/flake/outputs/checks.nix b/nix/snow/flake/outputs/checks.nix deleted file mode 100644 index de6a9c0..0000000 --- a/nix/snow/flake/outputs/checks.nix +++ /dev/null @@ -1,10 +0,0 @@ -{ - config, - _snowFlake, - ... -}: { - outputs.checks = - _snowFlake.inputs.deploy-rs.lib - |> builtins.mapAttrs (system: deployLib: - deployLib.deployChecks config.outputs.deploy); -} diff --git a/nix/snow/flake/outputs/default.nix b/nix/snow/flake/outputs/default.nix deleted file mode 100644 index 2c0a9ca..0000000 --- a/nix/snow/flake/outputs/default.nix +++ /dev/null @@ -1,7 +0,0 @@ -{...}: { - imports = [ - ./checks.nix - ./deploy.nix - ./nixosConfigurations.nix - ]; -} diff --git a/nix/snow/flake/outputs/deploy.nix b/nix/snow/flake/outputs/deploy.nix deleted file mode 100644 index 59bbb49..0000000 --- a/nix/snow/flake/outputs/deploy.nix +++ /dev/null @@ -1,63 +0,0 @@ -{ - _snowFlake, - snow, - config, - ... -}: { - outputs.deploy.nodes = snow.lib.mapNodes config.nodes ({ - name, - node, - ... - }: let - inherit - (node.deploy) - ssh - user - interactiveSudo - remoteBuild - rollback - autoRollback - magicRollback - activationTimeout - confirmTimeout - ; - - nixosFor = system: _snowFlake.inputs.deploy-rs.lib.${system}.activate.nixos; - in { - hostname = - if ssh.host != null - then ssh.host - else ""; - - profilesOrder = ["default"]; # profiles priority - profiles.default = { - path = nixosFor node.system config.outputs.nixosConfigurations.${name}; - - user = user; - sudo = "sudo -u"; - interactiveSudo = interactiveSudo; - - fastConnection = false; - - autoRollback = autoRollback -> rollback; - magicRollback = magicRollback -> rollback; - activationTimeout = activationTimeout; - confirmTimeout = confirmTimeout; - - remoteBuild = remoteBuild; - sshUser = ssh.user; - sshOpts = - ssh.opts - ++ ( - if builtins.elem "-p" ssh.opts - then [] - else ["-p" (toString ssh.port)] - ) - ++ ( - if builtins.elem "-A" ssh.opts - then [] - else ["-A"] - ); - }; - }); -} diff --git a/nix/snow/flake/outputs/nixosConfigurations.nix b/nix/snow/flake/outputs/nixosConfigurations.nix deleted file mode 100644 index 977fa22..0000000 --- a/nix/snow/flake/outputs/nixosConfigurations.nix +++ /dev/null @@ -1,84 +0,0 @@ -{ - _snowFlake, - snow, - config, - systems, - root, - ... -}: let - inherit - (builtins) - all - attrNames - warn - ; - - inherit - (config) - nodes - ; -in { - 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; - - 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; - - 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... = 0) - || abort '' - The nixpkgs dependency of snow was overridden but is too old. - The minimum supported version of nixpkgs-lib is ${minVersion}, - but the actual version is ${lib.version}${revInfo}. - ''; -in - assert isNixpkgsValidVersion; { - # Helper function for defining a per-system option that - # gets transposed by the usual flake system logic to a - # top-level outputs attribute. - mkPerSystemFlakeOutput = { - name, - option, - file, - }: { - _file = file; - - options = { - outputs.${name} = mkOption { - type = types.attrsWith { - elemType = option.type; - lazy = true; - placeholder = "system"; - }; - default = {}; - description = '' - See {option}`perSystem.${name}` for description and examples. - ''; - }; - }; - }; - } diff --git a/nix/snow/lib/nodes.nix b/nix/snow/lib/nodes.nix index 6f799cf..48a583d 100644 --- a/nix/snow/lib/nodes.nix +++ b/nix/snow/lib/nodes.nix @@ -1,8 +1,17 @@ -{ - this, - nt, - ... -}: let +# 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 @@ -14,9 +23,53 @@ typeOf ; - inherit (nt.prim) uniq; - rootGroupName = "all"; + + parseGroupsDecl = 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 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; in { mapNodes = nodes: f: nodes.nodes @@ -29,7 +82,7 @@ in { then nodes.base else abort '' - snow cannot construct nodes node "${name}" without a base package source. + Cerulean 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 @@ -37,51 +90,7 @@ in { inherit name node base; inherit (base) lib; - inherit (node) groups; + groups = node.groups (parseGroupsDecl nodes.groups); + groupModules = root: getGroupModules root groups; }); - - groupModules = map (group: group._module); - - parseGroupDecls = root: groupDecls: 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`. - ''; - delegate = parent: gName: g: let - result = - (g - // { - _name = gName; - _parent = parent; - _module = this.lib.findImport /${root}/groups/${gName}; - }) - |> mapAttrs (name: value: - if elem name ["_name" "_parent" "_module"] - # ignore metadata fields - then value - else assert validGroup value; (delegate result name value)); - in - result; - in - assert validGroup groupDecls; - delegate null rootGroupName groupDecls; - - resolveGroupsInheritance = groups: - 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 - # ignore missing groups - |> filter (group: pathExists group._module) - # filter by uniqueness - |> uniq; } diff --git a/nix/snow/lib/util.nix b/nix/snow/lib/util.nix deleted file mode 100644 index 6bfcd17..0000000 --- a/nix/snow/lib/util.nix +++ /dev/null @@ -1,3 +0,0 @@ -{nt, ...}: { - inherit (nt) findImport; -} diff --git a/nix/snow/lib/default.nix b/nix/snow/module.nix similarity index 82% rename from nix/snow/lib/default.nix rename to nix/snow/module.nix index f3b3d66..79b8804 100644 --- a/nix/snow/lib/default.nix +++ b/nix/snow/module.nix @@ -12,14 +12,12 @@ # See the License for the specific language governing permissions and # limitations under the License. { - nt, - mix, + root, + snow, ... -} @ args: -mix.newMixture args (mixture: { - includes.public = [ - ./util.nix - ./nixpkgs.nix - ./nodes.nix +}: { + imports = [ + ./nodes + (snow.findImport /${root}/snow) ]; -}) +} diff --git a/nix/snow/flake/nodes/default.nix b/nix/snow/nodes/default.nix similarity index 50% rename from nix/snow/flake/nodes/default.nix rename to nix/snow/nodes/default.nix index 07ad153..d3bc9b7 100644 --- a/nix/snow/flake/nodes/default.nix +++ b/nix/snow/nodes/default.nix @@ -12,7 +12,6 @@ # See the License for the specific language governing permissions and # limitations under the License. { - _snowFlake, lib, specialArgs, ... @@ -26,20 +25,38 @@ in mkOption { description = '' - Snowflake node declarations. + Cerulean node declarations. ''; type = types.submoduleWith { inherit specialArgs; modules = [ - ./nodes.nix + { + imports = [./shared.nix]; + + options = { + groups = mkOption { + type = types.attrs; + default = {}; + example = lib.literalExpression "{ servers = { staging = {}; production = {}; }; }"; + description = '' + Hierarchical groups that nodes can be a member of. + ''; + }; + + nodes = mkOption { + type = types.attrsOf (types.submoduleWith { + inherit specialArgs; + modules = [(import ./submodule.nix)]; + }); + # example = { ... }; # TODO + description = '' + Node (host systems) declarations. + ''; + }; + }; + } ]; }; }; - - config = { - nodes = { - base = _snowFlake.inputs.nixpkgs; - }; - }; } diff --git a/nix/snow/flake/nodes/nodes.nix b/nix/snow/nodes/shared.nix similarity index 80% rename from nix/snow/flake/nodes/nodes.nix rename to nix/snow/nodes/shared.nix index d5e5a59..c840d22 100644 --- a/nix/snow/flake/nodes/nodes.nix +++ b/nix/snow/nodes/shared.nix @@ -11,15 +11,7 @@ # 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. -{ - _snowFlake, - snow, - root, - lib, - config, - specialArgs, - ... -}: let +{lib, ...}: let inherit (lib) mkOption @@ -27,11 +19,6 @@ ; flakeRef = types.either types.str types.path; - - groupLibs = import ./groups.nix { - inherit snow root; - inherit (_snowFlake.inputs) nt; - }; in { options = { base = lib.mkOption { @@ -62,18 +49,6 @@ in { ''; }; - homeManager = mkOption { - type = types.nullOr flakeRef; - default = null; - example = lib.literalExpression "inputs.home-manager"; - description = '' - The path to the home-manager source. A `homeManager` flake reference - is required to be set for `homes/` to be evaluated, and can be specified via either: - 1. `options.nodes.homeManager` (default `homManager` used for all systems) - 2. `options.nodes.nodes..homeManager` (takes prescedence over `options.nodes.homeManager`) - ''; - }; - modules = mkOption { type = types.listOf types.raw; default = []; @@ -92,27 +67,15 @@ in { ''; }; - groups = mkOption { - type = types.attrs; - default = {}; - example = lib.literalExpression "{ servers = { staging = {}; production = {}; }; }"; + homeManager = mkOption { + type = types.nullOr flakeRef; + default = null; + example = lib.literalExpression "inputs.home-manager"; description = '' - Hierarchical groups that nodes can be a member of. - ''; - }; - - nodes = mkOption { - type = types.attrsOf (types.submoduleWith { - specialArgs = - specialArgs - // { - nodesConfig = config; - inherit groupLibs; - }; - modules = [./node.nix]; - }); - description = '' - Node (host systems) declarations. + The path to the home-manager source. A `homeManager` flake reference + is required to be set for `homes/` to be evaluated, and can be specified via either: + 1. `options.nodes.homeManager` (default `homManager` used for all systems) + 2. `options.nodes.nodes..homeManager` (takes prescedence over `options.nodes.homeManager`) ''; }; }; diff --git a/nix/snow/flake/nodes/node.nix b/nix/snow/nodes/submodule.nix similarity index 61% rename from nix/snow/flake/nodes/node.nix rename to nix/snow/nodes/submodule.nix index 11c2b98..6b4ae05 100644 --- a/nix/snow/flake/nodes/node.nix +++ b/nix/snow/nodes/submodule.nix @@ -14,24 +14,16 @@ { lib, systems, - nodesConfig, - groups, - groupLibs, ... }: { + imports = [./shared.nix]; + options = let inherit (lib) mkOption types ; - - inherit - (groupLibs) - resolveGroupsInheritance - ; - - flakeRef = types.either types.str types.path; in { enabled = lib.mkOption { type = types.bool; @@ -51,65 +43,6 @@ ''; }; - base = lib.mkOption { - # In newer Nix versions, particularly with lazy trees, outPath of - # flakes becomes a Nix-language path object. We deliberately allow this - # to gracefully come through the interface in discussion with @roberth. - # - # See: https://github.com/NixOS/nixpkgs/pull/278522#discussion_r1460292639 - type = types.nullOr flakeRef; - - default = nodesConfig.base; - defaultText = "nodes.base"; - - example = lib.literalExpression "inputs.nixpkgs"; - - description = '' - The path to the nixpkgs source used to build a system. A `base` package set - is required to be set, and can be specified via either: - 1. `options.nodes.base` (default `base` used for all systems) - 2. `options.nodes.nodes..base` (takes prescedence over `options.nodes.base`) - - This can also be optionally set if the NixOS system is not built with a flake but still uses - pinned sources: set this to the store path for the nixpkgs sources used to build the system, - as may be obtained by `fetchTarball`, for example. - - Note: the name of the store path must be "source" due to - . - ''; - }; - - homeManager = mkOption { - type = types.nullOr flakeRef; - default = nodesConfig.homeManager; - defaultText = "nodes.homeManager"; - example = lib.literalExpression "inputs.home-manager"; - description = '' - The path to the home-manager source. A `homeManager` flake reference - is required to be set for `homes/` to be evaluated, and can be specified via either: - 1. `options.nodes.homeManager` (default `homManager` used for all systems) - 2. `options.nodes.nodes..homeManager` (takes prescedence over `options.nodes.homeManager`) - ''; - }; - - modules = mkOption { - type = types.listOf types.raw; - default = []; - example = lib.literalExpression "[ { environment.systemPackages = [ pkgs.git ]; } ]"; - description = '' - Shared modules to import; equivalent to the NixOS module system's `extraModules`. - ''; - }; - - args = mkOption { - type = types.attrs; - default = {}; - example = lib.literalExpression "{ inherit inputs; }"; - description = '' - Shared args to provided for each node; equivalent to the NixOS module system's `specialArgs`. - ''; - }; - groups = mkOption { # TODO: write a custom group type that validates better than types.attrs lol type = types.functionTo (types.listOf types.attrs); @@ -118,9 +51,6 @@ description = '' A function from the `groups` hierarchy to a list of groups this node inherits from. ''; - - # apply = groupsFn: - # groupsFn nodesConfig.groups |> resolveGroupsInheritance; }; deploy = { @@ -161,7 +91,7 @@ example = false; description = '' Whether to enable interactive sudo (password based sudo). - NOT RECOMMENDED. Use one of Snowflake's recommended auth methods instead. + NOT RECOMMENDED. Use one of Cerulean's recommended auth methods instead. ''; }; @@ -234,7 +164,7 @@ user = mkOption { type = types.str; - default = "snowbld"; + default = "cerubld"; example = "custom-user"; description = '' The user to connect to over ssh during deployment. @@ -253,7 +183,7 @@ publicKeys = mkOption { type = types.listOf types.str; default = []; - example = ["ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIIeyZuUUmyUYrYaEJwEMvcXqZFYm1NaZab8klOyK6Imr me@myputer"]; + example = ["ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIIeyZuUUmyUYrYaEJwEMvcXqZFYm1NaZab8klOyK6Imr me@puter"]; description = '' SSH public keys that will be authorized to the deployment user. This key is intended solely for deployment, allowing for fine-grained permission control. @@ -271,33 +201,4 @@ }; }; }; - - # config = let - # throwGotNull = name: - # throw '' - # [snow] `nodes..${name}` must be set for all nodes! (got: ) - # ''; - # givenSystem = - # (config.system != null) - # || throwGotNull "system"; - - # givenBase = - # (config.base != null) - # || throwGotNull "base"; - - # 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; - # }; }