{ description = "GKleen's flakey nixos configuration"; inputs = { nixpkgs = { type = "github"; owner = "NixOS"; repo = "nixpkgs"; ref = "master"; }; home-manager = { type = "github"; owner = "nix-community"; repo = "home-manager"; ref = "master"; inputs.nixpkgs.follows = "nixpkgs"; }; sops-nix = { type = "github"; owner = "Mic92"; repo = "sops-nix"; ref = "master"; inputs.nixpkgs.follows = "nixpkgs"; }; }; outputs = { self, nixpkgs, home-manager, sops-nix }@inputs: let inherit (builtins) attrNames attrValues elemAt toJSON isNull pathExists; inherit (nixpkgs) lib; utils = import ./utils { inherit lib; }; inherit (utils) recImport overrideModule; inherit (lib) nixosSystem mkIf splitString filterAttrs listToAttrs mapAttrsToList nameValuePair concatMap composeManyExtensions mapAttrs mapAttrs' recursiveUpdate genAttrs unique elem optionalAttrs; accountUserName = accountName: let accountName' = splitString "@" accountName; in elemAt accountName' 0; accountHostName = accountName: let accountName' = splitString "@" accountName; in elemAt accountName' 1; mkNixosConfiguration = addProfiles: dir: path: hostName: nixosSystem rec { specialArgs = { flake = self; flakeInputs = inputs; path = ./.; }; modules = let defaultProfiles = with self.nixosModules.systemProfiles; [ core ]; local = dir + "/${path}"; argsModule._module.args = { customUtils = utils; inherit hostName; }; accountModules = attrValues (filterAttrs accountMatchesHost self.nixosModules.accounts); accountMatchesHost = n: _v: accountHostName n == hostName; in attrValues (filterAttrs (n: _v: !(elem n ["systemProfiles" "users" "userProfiles" "accounts"])) self.nixosModules) ++ [ argsModule ] ++ defaultProfiles ++ addProfiles ++ [ local ] ++ accountModules; }; mkSystemProfile = dir: path: profileName: { imports = [ (dir + "/${path}") ]; config = { system.profiles = [profileName]; }; }; defaultUserProfiles = userName: with self.nixosModules.userProfiles.${userName}; [ core ]; mkUserModule = dir: path: userName: overrideModule (import (dir + "/${path}")) (inputs: inputs // { inherit userName; }) (outputs: { _file = dir + "/${path}"; } // outputs // { imports = defaultUserProfiles userName ++ (outputs.imports or []); }); mkUserProfile = userName: dir: path: profileName: let profileModule = overrideModule (import (dir + "/${path}")) (inputs: inputs // { inherit userName; }) (outputs: { _file = dir + "/${path}"; } // outputs); in { imports = [profileModule]; config = { users.users.${userName}.profiles = [profileName]; }; }; mkAccountModule = dir: path: accountName: let userName = accountUserName accountName; in overrideModule (import (dir + "/${path}")) (inputs: inputs // { inherit userName; }) (outputs: { _file = dir + "/${path}"; } // outputs // { imports = [self.nixosModules.users.${userName} or ({...}: { imports = defaultUserProfiles userName; })] ++ (outputs.imports or []); }); forAllSystems = f: mapAttrs f nixpkgs.legacyPackages; forAllUsers = genAttrs (unique (map accountUserName (attrNames self.nixosModules.accounts))); activateNixosConfigurations = forAllSystems (system: _pkgs: mapAttrs' (hostName: nixosConfig: nameValuePair "${hostName}-activate" { type = "app"; program = "${nixosConfig.config.system.build.toplevel}/bin/switch-to-configuration"; }) self.nixosConfigurations); overlayPaths = recImport rec { dir = ./overlays; _import = (path: _name: dir + "/${path}"); } // { pkgs = ./pkgs; }; installerProfiles = system: let nixpkgs-path = nixpkgs.legacyPackages.${system}.path; in mapAttrs (name: {path, output}: { profile = mkSystemProfile nixpkgs-path path "installer-${name}"; inherit output; }) { cd-dvd = { path = "nixos/modules/installer/cd-dvd/installation-cd-minimal.nix"; output = out: out.config.system.build.isoImage; }; netboot = { path = "nixos/modules/installer/netboot/netboot-minimal.nix"; output = out: (self.legacyPackages.${system}.symlinkJoin { name = "netboot"; paths = with out.config.system.build; [ netbootRamdisk kernel netbootIpxeScript ]; preferLocalBuild = true; }); }; }; installerConfig = if pathExists ./installer.nix then "installer.nix" else (if pathExists ./installer then "installer" else null); installers = let mkInstallers = system: mapAttrs (mkInstaller system) (installerProfiles system); mkInstaller = system: name: {profile, output}: output (mkNixosConfiguration [profile { config = { nixpkgs.system = system; }; }] ./. installerConfig "installer"); in if !(isNull installerConfig) then { installers = forAllSystems (system: _systemPkgs: mkInstallers system); } else {}; in { nixosModules = let modulesAttrs = recImport { dir = ./modules; }; systemProfiles = recImport rec { dir = ./system-profiles; _import = mkSystemProfile dir; }; users = recImport rec { dir = ./users; _import = mkUserModule dir; }; userProfiles = forAllUsers (userName: recImport rec { dir = ./user-profiles; _import = mkUserProfile userName dir; }); accounts = recursiveUpdate rootAccounts (recImport rec { dir = ./accounts; _import = mkAccountModule dir; }); rootAccounts = mapAttrs' (hostName: _value: nameValuePair "root@${hostName}" ({...}: { imports = [ self.nixosModules.users.root or ({...}: { imports = defaultUserProfiles "root"; }) ]; })) self.nixosConfigurations; in modulesAttrs // { inherit systemProfiles users userProfiles accounts; }; nixosConfigurations = optionalAttrs (!(isNull installerConfig)) { installer = installerConfig; } // recImport rec { dir = ./hosts; _import = mkNixosConfiguration [] dir; }; homeManagerModules = recImport rec { dir = ./home-modules; }; overlay = import overlayPaths.pkgs; overlays = mapAttrs (_name: path: import path) overlayPaths; overlays-path = forAllSystems (system: _: self.legacyPackages.${system}.writeText "overlays.nix" '' map import (builtins.attrValues (builtins.fromJSON (builtins.readFile ${self.legacyPackages.${system}.writeText "overlays.json" (toJSON overlayPaths)}))) ''); packages = forAllSystems (system: systemPkgs: composeManyExtensions (attrValues self.overlays) (self.legacyPackages.${system}) systemPkgs); legacyPackages = forAllSystems (system: systemPkgs: recursiveUpdate systemPkgs self.packages.${system}); apps = activateNixosConfigurations; devShell = forAllSystems (system: systemPkgs: import ./shell.nix { pkgs = self.legacyPackages.${system}; }); defaultTemplate = { path = ./.; description = "GKleen's flakey nixos configuration"; }; } // installers; }