diff --git a/assets/default.nix b/assets/default.nix index 4e3187c..123d12c 100644 --- a/assets/default.nix +++ b/assets/default.nix @@ -1,8 +1,8 @@ -{ lib }: +{ lib, ... }: { - options.assets = lib.options.create { - type = lib.types.raw; - writable = false; + options.assets = lib.mkOption { + type = lib.types.unspecified; + readOnly = true; }; config.assets = { diff --git a/flake.lock b/flake.lock index a07e474..d40edeb 100644 --- a/flake.lock +++ b/flake.lock @@ -276,6 +276,26 @@ } }, "flake-parts_2": { + "inputs": { + "nixpkgs-lib": [ + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1741352980, + "narHash": "sha256-+u2UunDA4Cl5Fci3m7S643HzKmIDAe+fiXrLqYsR2fs=", + "owner": "hercules-ci", + "repo": "flake-parts", + "rev": "f4330d22f1c5d2ba72d3d22df5597d123fdb60a9", + "type": "github" + }, + "original": { + "owner": "hercules-ci", + "repo": "flake-parts", + "type": "github" + } + }, + "flake-parts_3": { "inputs": { "nixpkgs-lib": "nixpkgs-lib" }, @@ -489,7 +509,7 @@ }, "niko-nur": { "inputs": { - "flake-parts": "flake-parts_2", + "flake-parts": "flake-parts_3", "nixpkgs": "nixpkgs" }, "locked": { @@ -702,6 +722,7 @@ "disko": "disko", "fenix": "fenix", "firefox-darwin": "firefox-darwin", + "flake-parts": "flake-parts_2", "helix": "helix", "home-manager": "home-manager", "lix": "lix", diff --git a/flake.nix b/flake.nix index bf7d117..30729a5 100644 --- a/flake.nix +++ b/flake.nix @@ -1,37 +1,73 @@ { outputs = - inputs: + inputs@{ flake-parts, ... }: let nilla = import ./nilla.nix { inherit inputs; }; + transpose = + attrs: + let + inherit (inputs.nixpkgs) lib; + # maps an attrset of systems to packages to list of [ {name; system; value;} ] + pkgToListAll = + name: pkg: + map (system: { + inherit name system; + value = pkg.${system}; + }) (builtins.attrNames pkg); + pkgsToListAll = pkgs: map (name: pkgToListAll name pkgs.${name}) (builtins.attrNames pkgs); + # list of all packages in format [ {name; system; value;} ] + allPkgs = lib.flatten (pkgsToListAll attrs); + systems = builtins.groupBy (pkg: pkg.system) allPkgs; + in + builtins.mapAttrs (_: pkgs: lib.listToAttrs pkgs) systems; + in + flake-parts.lib.mkFlake { inherit inputs; } { systems = [ "x86_64-linux" "aarch64-linux" "aarch64-darwin" ]; - # NOTE: Assumes every package is available for every system. - # For now let's say this is always the case. - transpose = - attrs: - let - inherit (inputs.nixpkgs) lib; - mappedForSystem = system: builtins.mapAttrs (_: pkg: pkg.result.${system}) attrs; - in - lib.genAttrs systems mappedForSystem; - in - { - inherit (nilla) nixosModules; - inherit (nilla) darwinModules; - inherit (nilla) homeModules; - inherit (nilla) nixosConfigurations; - inherit (nilla) darwinConfigurations; - inherit (nilla) homeConfigurations; - devShells = transpose nilla.shells; - packages = transpose nilla.packages; - formatter = nilla.packages.formatter.result; + + imports = [ + inputs.treefmt.flakeModule + + ./assets + ./hosts + ./modules + ./services + ]; + + flake.devShells = transpose (builtins.mapAttrs (_: shell: shell.result) nilla.shells); + flake.packages = transpose (builtins.mapAttrs (_: pkg: pkg.result) nilla.packages); + + perSystem = { + treefmt = { + programs.deadnix.enable = true; + programs.nixfmt.enable = true; + programs.statix.enable = true; + programs.fish_indent.enable = true; + programs.deno.enable = true; + programs.stylua.enable = true; + programs.shfmt.enable = true; + settings.global.excludes = [ + # agenix + "*.age" + + # racket + "*.rkt" + "**/rashrc" + ]; + settings.on-unmatched = "fatal"; + }; + }; }; inputs = { nixpkgs.url = "github:nixos/nixpkgs?ref=nixpkgs-unstable"; + flake-parts = { + url = "github:hercules-ci/flake-parts"; + inputs.nixpkgs-lib.follows = "nixpkgs"; + }; disko = { url = "github:nix-community/disko"; inputs.nixpkgs.follows = "nixpkgs"; diff --git a/hosts/default.nix b/hosts/default.nix index ac91988..03d464d 100644 --- a/hosts/default.nix +++ b/hosts/default.nix @@ -1,11 +1,11 @@ { config, + self, + inputs, + ... }: -let - inputs = builtins.mapAttrs (_: input: input.result) config.inputs; -in { - includes = [ + imports = [ ./kazuki ./hijiri-vm ./hijiri @@ -17,20 +17,20 @@ in ./youko ]; - config.configBuilders = + builders = let sharedOptions = { _file = ./default.nix; settei.sane-defaults.allSshKeys = config.assets.sshKeys.user; settei.flake-qol.inputs = inputs // { - settei = inputs.self; + settei = self; }; }; baseNixos = inputs.nixpkgs.lib.nixosSystem { modules = [ - config.nixosModules.combined + self.nixosModules.combined sharedOptions ]; specialArgs.configurationName = "base"; @@ -38,7 +38,7 @@ in baseDarwin = inputs.darwin.lib.darwinSystem { modules = [ - config.darwinModules.combined + self.darwinModules.combined sharedOptions ]; specialArgs.configurationName = "base"; @@ -50,7 +50,7 @@ in baseNixos.extendModules { modules = [ module - config.extraHostConfigs.${name} or { } + config.__extraHostConfigs.${name} or { } ]; specialArgs.configurationName = name; }; @@ -61,7 +61,7 @@ in eval = baseDarwin._module.args.extendModules { modules = [ module - config.extraHostConfigs.${name} or { } + config.__extraHostConfigs.${name} or { } ]; specialArgs.configurationName = name; }; diff --git a/hosts/hijiri-vm/default.nix b/hosts/hijiri-vm/default.nix index 5f6d088..db26c63 100644 --- a/hosts/hijiri-vm/default.nix +++ b/hosts/hijiri-vm/default.nix @@ -1,5 +1,5 @@ { - config.configurations.nixos.hijiri-vm = + configurations.nixos.hijiri-vm = { modulesPath, lib, diff --git a/hosts/hijiri/default.nix b/hosts/hijiri/default.nix index a0e6857..bb7db92 100644 --- a/hosts/hijiri/default.nix +++ b/hosts/hijiri/default.nix @@ -1,5 +1,5 @@ { - config.configurations.darwin.hijiri = + configurations.darwin.hijiri = { config, pkgs, diff --git a/hosts/installer/default.nix b/hosts/installer/default.nix index a1692c6..24bdef8 100644 --- a/hosts/installer/default.nix +++ b/hosts/installer/default.nix @@ -1,6 +1,6 @@ { lib, ... }: { - config.configurations.nixos = + configurations.nixos = let mkInstaller = system: diff --git a/hosts/kazuki/default.nix b/hosts/kazuki/default.nix index 029d7d0..df92f1c 100644 --- a/hosts/kazuki/default.nix +++ b/hosts/kazuki/default.nix @@ -1,5 +1,5 @@ { - config.configurations.nixos.kazuki = + configurations.nixos.kazuki = { modulesPath, ... diff --git a/hosts/kogata/default.nix b/hosts/kogata/default.nix index 3e7c21f..6bf9e2f 100644 --- a/hosts/kogata/default.nix +++ b/hosts/kogata/default.nix @@ -1,5 +1,5 @@ { - config.configurations.darwin.kogata = + configurations.darwin.kogata = { pkgs, ... }: { nixpkgs.system = "aarch64-darwin"; diff --git a/hosts/legion/default.nix b/hosts/legion/default.nix index 1b41b1e..92c95be 100644 --- a/hosts/legion/default.nix +++ b/hosts/legion/default.nix @@ -1,5 +1,5 @@ { - config.configurations.nixos.legion = + configurations.nixos.legion = { config, username, diff --git a/hosts/ude/default.nix b/hosts/ude/default.nix index fd3e19b..d395fbd 100644 --- a/hosts/ude/default.nix +++ b/hosts/ude/default.nix @@ -1,5 +1,5 @@ { - config.configurations.nixos.ude = + configurations.nixos.ude = { config, modulesPath, diff --git a/hosts/youko/default.nix b/hosts/youko/default.nix index b801507..3a2fe49 100644 --- a/hosts/youko/default.nix +++ b/hosts/youko/default.nix @@ -1,5 +1,5 @@ { - config.configurations.nixos.youko = + configurations.nixos.youko = { config, lib, diff --git a/modules/default.nix b/modules/default.nix index 08dc44b..32f8e5f 100644 --- a/modules/default.nix +++ b/modules/default.nix @@ -1,21 +1,29 @@ { config, + inputs, + ... }: let - inputs = builtins.mapAttrs (_: input: input.result) config.inputs; - perInput = system: flake: { - packages = flake.packages.${system}; - }; + flakeModule = import ./flake { inherit (inputs) nixpkgs darwin home-manager; }; in { - config.homeModules = rec { + imports = [ + flakeModule + ]; + + flake.homeModules = rec { settei = ./home; default = settei; }; - config.nixosModules = rec { + flake.flakeModules = rec { + settei = flakeModule; + default = settei; + }; + + flake.nixosModules = rec { settei = import ./system { - inherit perInput; + inherit (config) perInput; isLinux = true; }; combined = { @@ -38,9 +46,9 @@ in default = combined; }; - config.darwinModules = rec { + flake.darwinModules = rec { settei = import ./system { - inherit perInput; + inherit (config) perInput; isLinux = false; }; combined = { diff --git a/modules/flake/configurations.nix b/modules/flake/configurations.nix new file mode 100644 index 0000000..67ccc1b --- /dev/null +++ b/modules/flake/configurations.nix @@ -0,0 +1,54 @@ +{ + nixpkgs, + darwin, + home-manager, +}: +{ + config, + lib, + ... +}: +with lib; +{ + _file = ./configurations.nix; + + options = { + # Those functions take the final arguments and emit a valid configuration. + # Probably should hardly ever be overriden + builders = { + nixos = mkOption { + type = types.functionTo types.unspecified; + default = _name: nixpkgs.lib.nixosSystem; + }; + darwin = mkOption { + type = types.functionTo types.unspecified; + default = _name: darwin.lib.darwinSystem; + }; + home = mkOption { + type = types.functionTo types.unspecified; + default = _name: home-manager.lib.homeManagerConfiguration; + }; + }; + + configurations = { + nixos = mkOption { + type = types.lazyAttrsOf types.deferredModule; + default = { }; + }; + darwin = mkOption { + type = types.lazyAttrsOf types.deferredModule; + default = { }; + }; + home = mkOption { + type = types.lazyAttrsOf types.deferredModule; + default = { }; + }; + }; + }; + + config.flake = { + nixosConfigurations = mapAttrs config.builders.nixos config.configurations.nixos; + darwinConfigurations = mapAttrs config.builders.darwin config.configurations.darwin; + homeConfigurations = mapAttrs config.builders.home config.configurations.home; + }; +} diff --git a/modules/flake/default.nix b/modules/flake/default.nix new file mode 100644 index 0000000..78bb73d --- /dev/null +++ b/modules/flake/default.nix @@ -0,0 +1,13 @@ +{ + nixpkgs, + darwin, + home-manager, +}: +{ + _file = ./default.nix; + + imports = [ + (import ./configurations.nix { inherit nixpkgs darwin home-manager; }) + ./services.nix + ]; +} diff --git a/modules/flake/services.nix b/modules/flake/services.nix new file mode 100644 index 0000000..f2f07d4 --- /dev/null +++ b/modules/flake/services.nix @@ -0,0 +1,95 @@ +# List of features I want this module to eventually have +# TODO: Automatic port allocation +# TODO: Making it possible to conveniently isolate services (running them in NixOS containers) +# TODO: Handling specializations +# TODO: Convenient http handling +# TODO: Automatic backup +{ config, lib, ... }: +let + serviceModule = + { config, ... }: + { + options = { + host = lib.mkOption { + type = lib.types.str; + }; + ports = lib.mkOption { + type = with lib.types; listOf port; + default = [ ]; + }; + hosts = lib.mkOption { + type = with lib.types; listOf str; + default = [ config.host ]; + }; + config = lib.mkOption { + type = lib.types.deferredModule; + default = { }; + }; + hostConfig = lib.mkOption { + type = with lib.types; attrsOf deferredModule; + default = { }; + }; + }; + }; + + moduleToHostConfigs = + cfg: + lib.genAttrs cfg.hosts (host: { + imports = [ + cfg.config + (cfg.hostConfig.${host} or { }) + ]; + }); + + maybeGetPreviousConfigs = acc: host: (acc.${host} or { imports = [ ]; }).imports; +in +{ + _file = ./services.nix; + + options = { + services = lib.mkOption { + type = with lib.types; attrsOf (submodule serviceModule); + default = { }; + }; + + __extraHostConfigs = lib.mkOption { + type = with lib.types; attrsOf deferredModule; + readOnly = true; + }; + }; + + config.__extraHostConfigs = + let + duplicatePorts = lib.pipe config.services [ + lib.attrValues + (map (cfg: cfg.ports)) + lib.flatten + (lib.groupBy' (cnt: _: cnt + 1) 0 toString) + (lib.filterAttrs (_: cnt: cnt > 1)) + lib.attrNames + ]; + assertMsg = + let + plural = lib.length duplicatePorts > 1; + in + "\nBad service config:\nThe following port${if plural then "s" else ""} ${ + if plural then "were" else "was" + } declared multiple times: ${lib.concatStringsSep ", " duplicatePorts}"; + # Here I collect all the services..config into a flat + # __extraHostConfigs..imports = [ + # ... + # ] + # so that I can easily import them in hosts/default.nix + hostConfigs = lib.pipe config.services [ + lib.attrValues + (lib.foldl' ( + acc: cfg: + acc + // lib.mapAttrs (host: c: { + imports = c.imports ++ (maybeGetPreviousConfigs acc host); + }) (moduleToHostConfigs cfg) + ) { }) + ]; + in + if duplicatePorts != [ ] then throw assertMsg else hostConfigs; +} diff --git a/modules/nilla/builders/custom-load.nix b/modules/nilla/builders/custom-load.nix index b340dec..b89bc36 100644 --- a/modules/nilla/builders/custom-load.nix +++ b/modules/nilla/builders/custom-load.nix @@ -1,7 +1,12 @@ { lib }: { config.builders.custom-load = { - settings.type = lib.types.submodule { }; + settings.type = lib.types.submodule { + options.args = lib.options.create { + type = lib.types.null; + default.value = null; + }; + }; settings.default = { }; build = pkg: lib.attrs.generate pkg.systems (system: pkg.package { inherit system; }); }; diff --git a/modules/nilla/configurations.nix b/modules/nilla/configurations.nix deleted file mode 100644 index 6f02f7e..0000000 --- a/modules/nilla/configurations.nix +++ /dev/null @@ -1,47 +0,0 @@ -{ config, lib }: -{ - options = { - configBuilders = { - nixos = lib.options.create { - type = lib.types.function lib.types.raw; - default.value = _name: config.inputs.nixpkgs.result.lib.nixosSystem; - }; - darwin = lib.options.create { - type = lib.types.function lib.types.raw; - default.value = _name: config.inputs.darwin.result.lib.darwinSystem; - }; - home = lib.options.create { - type = lib.types.function lib.types.raw; - default.value = _name: config.inputs.home-manager.result.lib.homeManagerConfiguration; - }; - }; - - configurations = { - nixos = lib.options.create { - type = lib.types.attrs.lazy lib.types.raw; - default.value = { }; - }; - darwin = lib.options.create { - type = lib.types.attrs.lazy lib.types.raw; - default.value = { }; - }; - home = lib.options.create { - type = lib.types.attrs.lazy lib.types.raw; - default.value = { }; - }; - }; - - nixosConfigurations = lib.options.create { - type = lib.types.attrs.lazy lib.types.raw; - default.value = builtins.mapAttrs config.configBuilders.nixos config.configurations.nixos; - }; - darwinConfigurations = lib.options.create { - type = lib.types.attrs.lazy lib.types.raw; - default.value = builtins.mapAttrs config.configBuilders.darwin config.configurations.darwin; - }; - homeConfigurations = lib.options.create { - type = lib.types.attrs.lazy lib.types.raw; - default.value = builtins.mapAttrs config.configBuilders.home config.configurations.home; - }; - }; -} diff --git a/modules/nilla/default.nix b/modules/nilla/default.nix index bfcd452..f9e4319 100644 --- a/modules/nilla/default.nix +++ b/modules/nilla/default.nix @@ -1,8 +1,3 @@ { - includes = [ - ./builders - ./services.nix - ./configurations.nix - ./modules.nix - ]; + includes = [ ./builders ]; } diff --git a/modules/nilla/modules.nix b/modules/nilla/modules.nix deleted file mode 100644 index 7b8a6dc..0000000 --- a/modules/nilla/modules.nix +++ /dev/null @@ -1,17 +0,0 @@ -{ lib }: -{ - options = { - nixosModules = lib.options.create { - type = lib.types.attrs.of lib.types.raw; - default.value = { }; - }; - darwinModules = lib.options.create { - type = lib.types.attrs.of lib.types.raw; - default.value = { }; - }; - homeModules = lib.options.create { - type = lib.types.attrs.of lib.types.raw; - default.value = { }; - }; - }; -} diff --git a/modules/nilla/services.nix b/modules/nilla/services.nix deleted file mode 100644 index 1045a4a..0000000 --- a/modules/nilla/services.nix +++ /dev/null @@ -1,95 +0,0 @@ -{ lib, config }: -let - inherit (builtins) - attrNames - attrValues - concatStringsSep - mapAttrs - foldl' - groupBy - length - ; - serviceModule = - { config }: - { - options = { - host = lib.options.create { - type = lib.types.string; - }; - ports = lib.options.create { - type = lib.types.list.of lib.types.port; - default.value = [ ]; - }; - hosts = lib.options.create { - type = lib.types.list.of lib.types.string; - default.value = [ config.host ]; - }; - module = lib.options.create { - type = lib.types.raw; - default.value = { }; - }; - hostModule = lib.options.create { - type = lib.types.attrs.of lib.types.raw; - default.value = { }; - }; - }; - }; - - moduleToHostConfigs = - cfg: - lib.attrs.generate cfg.hosts (host: { - imports = [ - cfg.module - (cfg.hostModule.${host} or { }) - ]; - }); - - maybeGetPreviousConfigs = acc: host: (acc.${host} or { imports = [ ]; }).imports; - - # Copied from nixpkgs/lib/lists.nix - groupBy' = - op: nul: pred: lst: - mapAttrs (_name: foldl' op nul) (groupBy pred lst); - duplicatePorts = lib.fp.pipe [ - attrValues - (map (cfg: cfg.ports)) - lib.lists.flatten - (groupBy' (cnt: _: cnt + 1) 0 toString) - (lib.attrs.filter (_: cnt: cnt > 1)) - attrNames - ] config.services; -in -{ - options.services = lib.options.create { - type = lib.types.attrs.of (lib.types.submodule serviceModule); - default.value = { }; - }; - - options.extraHostConfigs = lib.options.create { - type = lib.types.attrs.of lib.types.raw; - writable = false; - default.value = lib.fp.pipe [ - attrValues - (foldl' ( - acc: cfg: - acc - // mapAttrs (host: c: { - imports = c.imports ++ (maybeGetPreviousConfigs acc host); - }) (moduleToHostConfigs cfg) - ) { }) - ] config.services; - }; - - config.assertions = [ - { - assertion = duplicatePorts == [ ]; - message = - let - plural = length duplicatePorts > 1; - in - "\nBad service config:\nThe following port${if plural then "s" else ""} ${ - if plural then "were" else "was" - } declared multiple times: ${concatStringsSep ", " duplicatePorts}"; - } - ]; -} diff --git a/nilla.nix b/nilla.nix index bc20103..302900a 100644 --- a/nilla.nix +++ b/nilla.nix @@ -8,10 +8,6 @@ ./modules/nilla ./pkgs ./wrappers - ./hosts - ./assets - ./services - ./modules ]; config.inputs = builtins.mapAttrs (_: src: { @@ -59,23 +55,13 @@ name = "settei-base"; paths = with (getPkgs system); [ # TODO: wrappers - helix - fish + # helix + # fish git-commit-last git-fixup ]; } ); - formatter = { - inherit systems; - builder = "custom-load"; - package = - { system }: - let - eval = inputs.treefmt.lib.evalModule inputs.nixpkgs.legacyPackages.${system} ./treefmt.nix; - in - eval.config.build.wrapper; - }; }; config.shells.default = { diff --git a/services/attic.nix b/services/attic.nix index f9d7501..91d675f 100644 --- a/services/attic.nix +++ b/services/attic.nix @@ -1,12 +1,12 @@ { - config.services.attic = + services.attic = let atticPort = 9476; in { host = "kazuki"; ports = [ atticPort ]; - module = + config = { config, ... }: { age.secrets.attic-creds = { diff --git a/services/default.nix b/services/default.nix index c87f779..1837462 100644 --- a/services/default.nix +++ b/services/default.nix @@ -1,5 +1,5 @@ { - includes = [ + imports = [ ./attic.nix ./forgejo-runner.nix ]; diff --git a/services/forgejo-runner.nix b/services/forgejo-runner.nix index 98574a1..693d1d1 100644 --- a/services/forgejo-runner.nix +++ b/services/forgejo-runner.nix @@ -1,10 +1,10 @@ { - config.services.forgejo-runner = { + services.forgejo-runner = { hosts = [ "ude" "youko" ]; - module = + config = { config, lib, diff --git a/treefmt.nix b/treefmt.nix deleted file mode 100644 index e033626..0000000 --- a/treefmt.nix +++ /dev/null @@ -1,19 +0,0 @@ -{ - projectRootFile = "nilla.nix"; - programs.deadnix.enable = true; - programs.nixfmt.enable = true; - programs.statix.enable = true; - programs.fish_indent.enable = true; - programs.deno.enable = true; - programs.stylua.enable = true; - programs.shfmt.enable = true; - settings.global.excludes = [ - # agenix - "*.age" - - # racket - "*.rkt" - "**/rashrc" - ]; - settings.on-unmatched = "fatal"; -}