From 727d5ab1edd02ccede4d56ce7c27b036ef4353e2 Mon Sep 17 00:00:00 2001 From: Yipeng Sun Date: Thu, 19 Sep 2024 17:15:20 +0800 Subject: [PATCH] WIP #14: naive systemBuilder stolen from lite-config. --- lib/systemBuilder.nix | 196 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 196 insertions(+) create mode 100644 lib/systemBuilder.nix diff --git a/lib/systemBuilder.nix b/lib/systemBuilder.nix new file mode 100644 index 0000000..553fd5d --- /dev/null +++ b/lib/systemBuilder.nix @@ -0,0 +1,196 @@ +# stolen from `lite-config`: +# https://github.com/yelite/lite-config +# +# build NixOS/darwin systems + +{ inputs +, lib +, withSystem +, ... +} @ toplevel: +let + inherit (builtins) + attrValues + foldl' + ; + + inherit (lib) + mapAttrs + mkOption + types + literalExpression + recursiveUpdateUntil + ; + + + cfgSupport = toplevel.config.localNixpkgs; # external config options + cfg = toplevel.config.systemBuilder; # shortcut to user config + + + # types in config + typeHostConfig = types.submodule { + options = { + system = mkOption { + type = types.str; + description = '' + The system of the host. + ''; + example = + literalExpression + '' + "x86_64-linux" + ''; + }; + + systemSuites = mkOption { + type = types.listOf types.deferredModule; + default = [ ]; + description = '' + System suites (NixOS or nix-darwin) to be imported by this host. + ''; + }; + + homeSuites = mkOption { + type = types.listOf types.deferredModule; + default = [ ]; + description = '' + Home suites to be imported by this host. + ''; + }; + }; + }; + + typeSystemBuilderOptions = types.submodule { + options = { + hosts = mkOption { + type = types.attrsOf typeHostConfig; + default = { }; + description = '' + Host configurations. + ''; + }; + + hostModuleDir = mkOption { + type = types.path; + description = '' + The directory that contains host modules. Module at + `''${hostMouduleDir}/''${hostName}` will be imported in + the configuration of host `hostName` by default. + + The host module used by a host can be overridden in + {option}`lite-config.hosts..hostModule`. + ''; + }; + + nixosModules = mkOption { + type = types.listOf types.deferredModule; + default = [ ]; + description = '' + NixOS modules to be imported by all NixOS hosts. + ''; + }; + + darwinModules = mkOption { + type = types.listOf types.deferredModule; + default = [ ]; + description = '' + Darwin modules to be imported by all Darwin hosts. + ''; + }; + + homeModules = mkOption { + type = types.listOf types.deferredModule; + default = [ ]; + description = '' + Home modules to be imported by all hosts. + ''; + }; + }; + }; + + + # helper functions + errUnsupportedSys = system: throw "System type ${system} not supported."; + + + # the actual builder + systemBuilder = hostName: hostConfig: + withSystem hostConfig.system ({ pkgs, ... }: + let + hostPlatform = pkgs.stdenv.hostPlatform; + hostModule = "${cfg.hostModuleDir}/${hostName}"; + + systemModules = + if hostPlatform.isLinux then cfg.nixosModules + else if hostPlatform.isDarwin then cfg.darwinModules + else errUnsupportedSys hostPlatform.system; + + homeManagerFlake = inputs.home-manager; + homeManagerSystemModule = + if hostPlatform.isLinux then homeManagerFlake.nixosModules.default + else if hostPlatform.isDarwin then homeManagerFlake.darwinModules.default + else errUnsupportedSys hostPlatform.system; + + specialArgs = { + inherit inputs hostPlatform; + }; + + modules = [ + hostModule + { + _file = ./.; + nixpkgs.pkgs = pkgs; + networking.hostName = hostName; + } + ] + ++ systemModules ++ hostConfig.systemSuites + ++ + [ + homeManagerSystemModule + { + _file = ./.; + home-manager = { + sharedModules = cfg.homeModules ++ hostConfig.homeSuites; + useGlobalPkgs = true; + extraSpecialArgs = specialArgs; + }; + } + ]; + + # aggregated args + builderArgs = { inherit specialArgs modules; }; + in + if hostPlatform.isLinux + then { + nixosConfiguration.${hostName} = cfgSupport.nixpkgs.lib.nixosSystem builderArgs; + } + else if hostPlatform.isDarwin + then { + # NOTE: hard-coded darwin builder + darwinConfiguration.${hostName} = inputs.nix-darwin.lib.darwinSystem builderArgs; + } + else errUnsupportedSys hostPlatform.system); + + systemAttrset = + let + mergeSysConfig = a: b: recursiveUpdateUntil (path: _: _: (length path) > 2) a b; + sysConfigAttrsets = attrValues (mapAttrs systemBuilder cfg.hosts); + in + foldl' mergeSysConfig { } sysConfigAttrsets; +in +{ + options = { + systemBuilder = mkOption { + type = typeSystemBuilderOptions; + default = { }; + description = '' + Config for NixOS/Darwin systems. + ''; + }; + }; + + + config = { + flake = systemAttrset; + }; +}