From 1f1ddb521b99cd029a7318aaa66cc62a3318640c Mon Sep 17 00:00:00 2001 From: NullBite Date: Sun, 9 Feb 2025 01:44:57 -0500 Subject: [PATCH] flake: functional prototype of modular systems --- flake.nix | 75 ++++++++--- flake/default.nix | 5 +- flake/meta.nix | 11 ++ flake/overlays.nix | 19 +++ flake/system.nix | 209 +++++++++++++++++++++++++++++- hosts/nixos-wsl/configuration.nix | 3 + lib/nixfiles/flake-legacy.nix | 38 +----- lib/nixfiles/module.nix | 8 +- lib/nixfiles/types.nix | 22 +++- 9 files changed, 321 insertions(+), 69 deletions(-) create mode 100644 flake/meta.nix create mode 100644 flake/overlays.nix diff --git a/flake.nix b/flake.nix index b793bb3..5222c93 100644 --- a/flake.nix +++ b/flake.nix @@ -3,6 +3,7 @@ description = "NixOS Configuration"; inputs = { + # {{{ nixpkgs.url = "github:NixOS/nixpkgs/nixos-24.11"; # ^^^^^^^^^^^^^ this part is optional nixpkgs-unstable.url = "github:NixOS/nixpkgs/nixpkgs-unstable"; @@ -103,7 +104,7 @@ inputs.nixpkgs.follows = "nixpkgs"; inputs.systems.follows = "systems"; }; - }; + }; # }}} outputs = { self, @@ -130,13 +131,69 @@ # flake-parts systems (still uses nix-systems) systems = import inputs.systems; + # expose vars to nix repl debug = lib.mkDefault true; + nixfiles = { + vars = { + ### Configuration + # My username + username = "nullbite"; + # My current timezone for any mobile devices (i.e., my laptop) + mobileTimeZone = "America/New_York"; + }; + + common.overlays = let + nix-minecraft-patched-overlay = let + normal = inputs.nix-minecraft-upstream.overlays.default; + quilt = inputs.nix-minecraft.overlays.default; + in + lib.composeExtensions + normal + (final: prev: let + x = quilt final prev; + in { + inherit (x) quiltServers quilt-server; + minecraftServers = prev.minecraftServers // x.quiltServers; + }); + + packagesOverlay = final: prev: let + packages = import ./pkgs {inherit (prev) pkgs;}; + in { + inherit (packages) mopidy-autoplay google-fonts; + atool-wrapped = packages.atool; + }; + in [ + packagesOverlay + # various temporary fixes that automatically revert + self.overlays.mitigations + + # auto backports from nixpkgs unstable + self.overlays.backports + + # modpacks (keeps modpack version in sync between hosts so i can reverse + # proxy create track map because it's broken) + self.overlays.modpacks + + inputs.hyprwm-contrib.overlays.default + inputs.rust-overlay.overlays.default + inputs.nixfiles-assets.overlays.default + nix-minecraft-patched-overlay + ]; + + systems.testsys = { + system = "x86_64-linux"; + enable = false; + }; + }; + flake = let # {{{ inherit (nixfiles-lib.flake-legacy) mkSystem mkWSLSystem mkISOSystem mkHome; inherit (inputs) nixpkgs nixpkgs-unstable; inherit (self) outputs; + inherit (config.nixfiles.vars) username mobileTimeZone; + # inputs is already defined lib = nixpkgs.lib; systems = ["x86_64-linux" "aarch64-linux"]; @@ -178,18 +235,7 @@ nix-minecraft-patched-overlay ]; - ### Configuration - # My username - username = "nullbite"; - # My current timezone for any mobile devices (i.e., my laptop) - mobileTimeZone = "Europe/Amsterdam"; - - # Variables to be passed to NixOS modules in the vars attrset - vars = { - inherit username mobileTimeZone self; - }; - - # funciton to generate packages for each system + # function to generate packages for each system eachSystem = lib.genAttrs (import inputs.systems); # values to be passed to nixosModules and homeManagerModules wrappers @@ -197,9 +243,6 @@ }; # }}} in { - # for repl debugging via :lf . - inherit inputs vars; - devShells = eachSystem (system: let pkgs = import nixpkgs-unstable {inherit system;}; in { diff --git a/flake/default.nix b/flake/default.nix index cb6f6cb..b99bc33 100644 --- a/flake/default.nix +++ b/flake/default.nix @@ -1,8 +1,9 @@ -{ ... }: -{ +{...}: { imports = [ ./packages.nix ./home.nix ./system.nix + ./meta.nix + ./overlays.nix ]; } diff --git a/flake/meta.nix b/flake/meta.nix new file mode 100644 index 0000000..3293185 --- /dev/null +++ b/flake/meta.nix @@ -0,0 +1,11 @@ +{ + config, + lib, + ... +}: { + options.nixfiles.vars = lib.mkOption { + description = "Global variables"; + type = lib.types.attrs; + default = {}; + }; +} diff --git a/flake/overlays.nix b/flake/overlays.nix new file mode 100644 index 0000000..1f38b80 --- /dev/null +++ b/flake/overlays.nix @@ -0,0 +1,19 @@ +{ + config, + lib, + inputs, + ... +}: let + overlayType = lib.mkOptionType { + name = "nixpkgs-overlay"; + description = "nixpkgs overlay"; + check = lib.isFunction; + merge = lib.mergeOneOption; + }; +in { + options.nixfiles.common.overlays = lib.mkOption { + description = "List of overlays shared between various parts of the flake."; + type = lib.types.listOf overlayType; + default = []; + }; +} diff --git a/flake/system.nix b/flake/system.nix index bc9e949..9047500 100644 --- a/flake/system.nix +++ b/flake/system.nix @@ -1,7 +1,204 @@ -{ config, lib, nixfiles-lib, ... }: -let - cfg = config.nixfiles.hosts; - inherit (lib) types mkOption mkIf; - inherit (nixfiles-lib.flake-legacy) mkSystem mkHome mkWSLSystem mkISOSystem; -in { } +{ + config, + options, + lib, + nixfiles-lib, + inputs, + self, + ... +}: let + cfg = config.nixfiles.systems; + inherit + (lib) + types + mkOption + mkIf + filterAttrs + mapAttrs + ; + inherit (builtins) attrNames; + + inherit (nixfiles-lib.flake-legacy) mkSystem mkHome mkWSLSystem mkISOSystem; + inherit (nixfiles-lib.types) mkCheckedType; + + mkConfigurationOption = systemType: + mkOption { + description = "${systemType} configuration type"; + type = with types; nullOr mkCheckedType "configuration"; + default = null; + }; +in { + options.nixfiles.systems = let + systemModule = let + outerConfig = config; + outerOptions = options; + in + { + name, + config, + ... + }: { + options = { + enable = + lib.mkEnableOption "" + // { + description = '' + Whether to install this configuration into the flake outputs. + ''; + default = true; + }; + + nixpkgs = mkOption { + description = "nixpkgs input to build system with"; + type = nixfiles-lib.types.flake; + default = inputs.nixpkgs-unstable; + }; + + extraConfig = mkOption { + description = '' + Arguments to pass to nixpkgs.lib.nixosSystem + ''; + type = types.attrs; + default = {}; + }; + + system = mkOption { + description = "Nix system value"; + type = types.str; + example = "x86_64-linux"; + }; + + modules = mkOption { + description = "NixOS modules"; + type = with types; listOf deferredModule; + default = []; + }; + + name = mkOption { + description = '' + Name of NixOS configuration. This influences the default + directory to load configuration from. This does *not* modify the + system's hostname, but should probably be set to the same value. + ''; + type = lib.types.str; + default = name; + }; + + configPath = mkOption { + description = "Path to main system configuration module."; + type = lib.types.path; + default = self + "/hosts/${config.name}/configuration.nix"; + }; + + home-manager = { + enable = + lib.mkEnableOption "" + // { + description = '' + Whether to enable home-manager for this configuration. + ''; + default = true; + }; + + input = mkOption { + description = "home-manager input"; + type = nixfiles-lib.types.flake; + default = inputs.home-manager-unstable; + }; + + configPath = mkOption { + description = "Path to main home configuration module."; + type = lib.types.path; + default = self + "/hosts/${config.name}/home.nix"; + }; + + modules = mkOption { + description = "home-manager modules"; + type = with types; listOf deferredModule; + }; + }; + + wsl = + lib.mkEnableOption "" + // { + description = '' + Whether to import WSL related configuration + ''; + }; + + result = lib.mkOption { + description = "Resulting system configuration"; + type = with types; nullOr (mkCheckedType "configuration"); + }; + }; + + config = { + home-manager.input = lib.mkIf (config.nixpkgs == inputs.nixpkgs) (lib.mkDefault inputs.home-manager); + + modules = let + nixfilesModule = self + "/system"; + defaultsModule = {...}: { + # Values for every single system that would not conceivably need + # to be made modular + + # this should be set in the system config + # system.stateVersion = stateVersion; + nixpkgs = { + inherit (outerConfig.nixfiles.common) overlays; + config = { + # not having the freedom to install unfree programs is unfree + allowUnfree = true; + }; + }; + # this should be on by default and there is no reason to turn it + # off because this flake will literally stop working otheriwse + nix.settings.experimental-features = ["nix-command" "flakes"]; + }; + wslModule = {...}: { + imports = [ + inputs.nix-wsl.nixosModules.wsl + ]; + wsl.enable = true; + wsl.defaultUser = outerConfig.nixfiles.vars.username; + }; + in + [ + nixfilesModule + defaultsModule + # TODO + # import /hosts/ path + # home manager init + ] + ++ lib.optionals config.wsl wslModule; + extraConfig = { + inherit (config) system modules; + # TODO get rid of specialArgs and pass things as a module + specialArgs = let + inherit (self) outputs; + in { + inherit inputs outputs; + inherit (outerConfig.nixfiles) vars; + inherit (config) nixpkgs; + inherit (config.home-manager) input; + }; + }; + result = config.nixpkgs.lib.nixosSystem config.extraConfig; + }; + }; + in + lib.mkOption { + description = '' + NixOS system configurations + ''; + type = with types; attrsOf (submodule systemModule); + default = {}; + }; + + config = { + flake.nixosConfigurations = let + enabledSystems = filterAttrs (n: v: v.enable) cfg; + in + mapAttrs (_: v: v.result) enabledSystems; + }; +} diff --git a/hosts/nixos-wsl/configuration.nix b/hosts/nixos-wsl/configuration.nix index b9f59cd..228e40f 100644 --- a/hosts/nixos-wsl/configuration.nix +++ b/hosts/nixos-wsl/configuration.nix @@ -47,5 +47,8 @@ device = "/"; options = [ "bind" ]; }; + + # standard disclaimer don't change this for any reason whatsoever + system.stateVersion = "23.11"; }; } diff --git a/lib/nixfiles/flake-legacy.nix b/lib/nixfiles/flake-legacy.nix index 3177d0a..5c4f336 100644 --- a/lib/nixfiles/flake-legacy.nix +++ b/lib/nixfiles/flake-legacy.nix @@ -1,44 +1,10 @@ { self, lib, + moduleAttrs, ... }: let - overlays = let - nix-minecraft-patched-overlay = let - normal = inputs.nix-minecraft-upstream.overlays.default; - quilt = inputs.nix-minecraft.overlays.default; - in - lib.composeExtensions - normal - (final: prev: let - x = quilt final prev; - in { - inherit (x) quiltServers quilt-server; - minecraftServers = prev.minecraftServers // x.quiltServers; - }); - in [ - (final: prev: let - packages = import ./pkgs {inherit (prev) pkgs;}; - in { - inherit (packages) mopidy-autoplay google-fonts; - atool-wrapped = packages.atool; - }) - - # various temporary fixes that automatically revert - self.overlays.mitigations - - # auto backports from nixpkgs unstable - self.overlays.backports - - # modpacks (keeps modpack version in sync between hosts so i can reverse - # proxy create track map because it's broken) - self.overlays.modpacks - - inputs.hyprwm-contrib.overlays.default - inputs.rust-overlay.overlays.default - inputs.nixfiles-assets.overlays.default - nix-minecraft-patched-overlay - ]; + inherit (moduleAttrs.config.nixfiles.common) overlays; ### Configuration # My username diff --git a/lib/nixfiles/module.nix b/lib/nixfiles/module.nix index bbb0a1f..131f450 100644 --- a/lib/nixfiles/module.nix +++ b/lib/nixfiles/module.nix @@ -1,6 +1,10 @@ -{lib, self, ...}: let +{ + lib, + self, + ... +} @ moduleAttrs: let inherit (lib) types; - nixfiles-lib = (import ./.) {inherit lib self;}; + nixfiles-lib = (import ./.) {inherit lib self moduleAttrs;}; in { options.nixfiles.lib = lib.mkOption { description = "nixfiles library"; diff --git a/lib/nixfiles/types.nix b/lib/nixfiles/types.nix index b81e3bd..04f5aa8 100644 --- a/lib/nixfiles/types.nix +++ b/lib/nixfiles/types.nix @@ -1,13 +1,21 @@ -{ pkgs, ... }: -let +{pkgs, ...}: let inherit (pkgs) lib; inherit (lib.types) mkOptionType; inherit (lib.options) mergeEqualOption; -in -{ +in { + mkCheckedType = type: + mkOptionType { + name = "${type}"; + description = "Attribute set of type ${type}"; + descriptionClass = "noun"; + merge = mergeEqualOption; + check = value: value._type or "" == "${type}"; + }; flake = mkOptionType { - name="flake"; - description="Nix flake"; + name = "flake"; + description = "Nix flake"; descriptionClass = "noun"; - merge = mergeEqualOption; check = (value: value._type or "" == "flake"); }; + merge = mergeEqualOption; + check = value: value._type or "" == "flake"; + }; }