From 72d29b396fa7b5f31af06eed68185000f359194f Mon Sep 17 00:00:00 2001 From: Ivan Porto Wigner <47715589+iivvaannxx@users.noreply.github.com> Date: Thu, 31 Aug 2023 16:18:45 +0200 Subject: [PATCH] Added more functions to custom lib. Cleaned up host creation functions. --- lib/conditionals.nix | 8 ++ lib/default.nix | 29 ++++--- lib/global.nix | 30 ------- lib/make.nix | 33 ++++++++ lib/nixos.nix | 181 ++++++++++++++++++------------------------- lib/options.nix | 28 ++++--- 6 files changed, 157 insertions(+), 152 deletions(-) delete mode 100644 lib/global.nix create mode 100644 lib/make.nix diff --git a/lib/conditionals.nix b/lib/conditionals.nix index 2e2ca60..564bcef 100644 --- a/lib/conditionals.nix +++ b/lib/conditionals.nix @@ -16,6 +16,14 @@ in { in value; + # If the given set contains the given attribute, that value is returned. Otherwise the fallback value is returned. + tryGetAttr = attr: set: fallback: let + + hasAttribute = hasAttr attr set; + value = if hasAttribute then set.${attr} else fallback; + + in value; + # Makes either one value or another depending on the given predicate. mkIfElse = pred: truthy: falsy: mkMerge [ diff --git a/lib/default.nix b/lib/default.nix index 9839374..cc3f1d3 100644 --- a/lib/default.nix +++ b/lib/default.nix @@ -3,26 +3,22 @@ includeLib = customLib: import customLib { inherit lib; }; # Include every function lib file. - global = includeLib ./global.nix; conditionals = includeLib ./conditionals.nix; filesystem = includeLib ./filesystem.nix; generators = includeLib ./generators.nix; + global = includeLib ./global.nix; + make = includeLib ./make.nix; nixos = includeLib ./nixos.nix; options = includeLib ./options.nix; validation = includeLib ./validation.nix; in { - inherit (global) - - importProfile - importCommonConfig - ; - inherit (conditionals) nullUnless nullUnlessHasAttr + tryGetAttr mkIfElse mkIfHasAttr @@ -40,18 +36,33 @@ in { stringWithSuffix ; + inherit (global) + + importProfile + importConfig + ; + + inherit (make) + + mkPath + mkPkgs + mkUnfreePkgs + ; + inherit (nixos) mkHost - mkHostConfig ; inherit (options) - mkBoolOption mkStrOption mkStrListOption + + mkSubmoduleOption mkDynamicAttrsetOption + + mkPackageListOption ; inherit (validation) diff --git a/lib/global.nix b/lib/global.nix deleted file mode 100644 index fb97206..0000000 --- a/lib/global.nix +++ /dev/null @@ -1,30 +0,0 @@ -{ lib }: let - - inherit (lib.custom) stringWithSuffix; - paths = { - - # The path to the common folder. - commonBase = ../common; - profilesBase = ../profiles; - - commonConfigs = "${paths.commonBase}/configs"; - }; - -in { - - # Imports a profile file given it's name. - importProfile = profilePath: let - - profile = import "${paths.profilesBase}/${profilePath}"; - - in profile; - - # Imports a config file given it's name. - importCommonConfig = configFile: let - - configPath = stringWithSuffix configFile ".nix"; - config = import "${paths.commonConfigs}/${configPath}"; - - in config; -} - \ No newline at end of file diff --git a/lib/make.nix b/lib/make.nix new file mode 100644 index 0000000..752d5dd --- /dev/null +++ b/lib/make.nix @@ -0,0 +1,33 @@ +{ lib, ... } @ args: let + + inherit (builtins) pathExists; + inherit (lib) concatStringsSep throwIf; + +in rec { + + # Imports a package source and returns a package set. + mkPkgs = sourcePkgs: { system, unfree ? false, overlays ? [ ] }: import sourcePkgs { + + inherit system overlays; + config.allowUnfree = unfree; + }; + + # Imports a package source and returns a package set with unfree packages enabled. + mkUnfreePkgs = sourcePkgs: { system, overlays ? [ ] }: let + + unfreePkgs = mkPkgs sourcePkgs { + + inherit system overlays; + unfree = true; + }; + + in unfreePkgs; + + # Creates a full path from a source path and a sub path. Throws the given error if the path does not exist. + mkPath = sourcePath: subPath: notFoundError: let + + fullPath = concatStringsSep "/" [sourcePath subPath]; + isMissing = (! pathExists fullPath); + + in (throwIf isMissing notFoundError fullPath); +} \ No newline at end of file diff --git a/lib/nixos.nix b/lib/nixos.nix index b82c06d..5bc304f 100644 --- a/lib/nixos.nix +++ b/lib/nixos.nix @@ -1,140 +1,113 @@ { lib }: let - inherit (builtins) foldl' hasAttr pathExists baseNameOf; + inherit (builtins) baseNameOf listToAttrs; - inherit (lib) nixosSystem recursiveUpdate throwIf optionalAttrs mkMerge mkIf; - inherit (lib.custom) getSubfolders mkIfHasAttr nullUnlessHasAttr; + inherit (lib) nixosSystem; + inherit (lib.custom) mkUnfreePkgs mkPath; - # Traverses the given users folder and creates the users options for a system. - mkUsers = usersFolder: homeManagerModules: let + # Retrieves the profile of a user. + getProfile = userPath : let - # Each subfolder is a user. - subfolders = getSubfolders usersFolder; - baseUsers = { systemConfig = { }; homeConfig = { }; }; + # Import the profile of the user. + profilePath = mkPath userPath "profile.nix" "For user '${baseNameOf userPath}': Each user must define a 'profile.nix' file."; + profile = (import profilePath); - in foldl' (acc: folder: let + in profile; - mkPath = path: let + # Generates entries for each system user. + mkSystemUsers = users: { + + users.users = (listToAttrs (map (userPath: let - # Construct the full path to the given file. - fullPath = "${usersFolder}/${folder}/${path}"; - isMissing = (! pathExists fullPath); + # The profile of the current user. + profile = getProfile userPath; - in (throwIf isMissing "For user '${folder}': Each user must define a 'home.nix' and 'profile.nix' files." fullPath); + in { - profile = import (mkPath "profile.nix") { inherit lib; }; - homeModule = mkPath "home.nix"; - - # Set fallbacks for these properties: - username = if (hasAttr "username" profile) then profile.username else folder; - fullName = if (hasAttr "fullName" profile) then profile.fullName else username; - - in { - - # The system configuration for the users. - systemConfig = recursiveUpdate acc.systemConfig { - - users.users.${username} = { - - name = username; - description = fullName; - extraGroups = mkIfHasAttr "extraGroups" profile; + name = profile.username; + value = { + name = profile.username; + description = profile.fullName; isNormalUser = true; - }; - }; - - # The home configuration for the users. - homeConfig = recursiveUpdate acc.homeConfig { - ${username} = { + } // profile.systemUserOverride; - imports = homeManagerModules ++ [ homeModule ]; - }; - }; - - }) baseUsers subfolders; + }) users)); + }; - # Creates a system configuration. - mkSystem = { system, configPath, usersPath, modules, home-manager, extraSpecialArgs ? { } }: let + # Generates entries for each home manager user. + mkHomeUsers = homeUsers: (listToAttrs (map (userPath: let - # Make the users for this system. - users = mkUsers usersPath modules.homeManagerModules; + # The profile of the current user. + profile = getProfile userPath; in { - inherit system lib; - modules = modules.nixosModules ++ [ - - configPath - users.systemConfig - - # Add the HM module. See: https://github.com/nix-community/home-manager/ - home-manager.nixosModules.home-manager { + name = profile.username; + value = { + + _module.args.profile = profile; + imports = [ userPath ]; + }; - home-manager.useGlobalPkgs = true; - home-manager.useUserPackages = true; - - home-manager.extraSpecialArgs = { } // extraSpecialArgs; - home-manager.users = users.homeConfig; - } - ]; - }; - - # Creates a host module definition. - mkHostConfig = { system, hostPath, modules, inputs, extraArgs ? { } } @ args: let + }) homeUsers)); - hostName = baseNameOf hostPath; - mkPath = path: isFile: let +in { - fullPath = "${hostPath}/${path}"; - isMissing = (! pathExists fullPath); - resource = if isFile then "file" else "folder"; + # Creates a host from the given arguments. + mkHost = { hostPath, system, users, inputs, lib, nixpkgs, unstablepkgs, home-manager }: let - in (throwIf isMissing "For host '${hostName}': A '${path}' ${resource} must be created for the host to be built." fullPath); + inherit (lib) nixosSystem; - # Creates a preconfigured Nix package provider. - mkPkgs = system: pkgs: let + # The path where all the source code is located. + rootPath = ../.; + configsPath = "${rootPath}/configs"; - pkgsSource = import pkgs { + # The package sets. + pkgs = mkUnfreePkgs nixpkgs { inherit system; }; + upkgs = mkUnfreePkgs unstablepkgs { inherit system; }; + + # Resources used within NixOS configurations. + nixosModules = (import "${rootPath}/modules/nixos"); + nixosUsers = mkSystemUsers users; + nixosSpecialArgs = { - inherit system; - config.allowUnfree = true; - }; - - in pkgsSource; + inherit inputs configsPath pkgs upkgs; + presetsPath = "${rootPath}/presets/nixos"; + }; - # The two paths needed by mkSystem. - configPath = mkPath "configs/system.nix" true; - usersPath = mkPath "users" false; + # Resources used within Home Manager configurations. + homeManagerModules = (import "${rootPath}/modules/home-manager"); + homeManagerUsers = mkHomeUsers users; + homeManagerSpecialArgs = { - nixpkgs = nullUnlessHasAttr "nixpkgs" inputs; - unstablepkgs = nullUnlessHasAttr "unstablepkgs" inputs; - pkgs = optionalAttrs (nixpkgs != null) (mkPkgs system nixpkgs); - upkgs = optionalAttrs (unstablepkgs != null) (mkPkgs system unstablepkgs); + inherit inputs configsPath pkgs upkgs; + presetsPath = "${rootPath}/presets/home-manager"; + }; + + in nixosSystem { - # Ensure home-manager is inside the inputs. - home-manager = throwIf (! hasAttr "home-manager" inputs) - "For host '${hostName}': 'home-manager' is required to build the host. Please make sure is inside the flake inputs." - inputs.home-manager; + inherit system lib; - # Pass the inputs as extra args together with the given ones. - extraSpecialArgs = ((mkMerge [ + specialArgs = nixosSpecialArgs; + modules = nixosModules ++ [ - { inherit inputs; } + hostPath + nixosUsers - # Only include the packages if the input is correctly defined. - (if (nixpkgs != null) then { inherit pkgs; } else { }) - (if (unstablepkgs != null) then { inherit upkgs; } else { }) - - ]) // extraArgs); - - in (mkSystem { inherit system configPath usersPath modules extraSpecialArgs home-manager; }); + home-manager.nixosModules.home-manager { - # Creates a host definition ready to use in a flake as a nixosConfiguration. - mkHost = hostConfig: (nixosSystem hostConfig); + home-manager = { -in { + useGlobalPkgs = true; + useUserPackages = true; - inherit mkHostConfig mkHost; + users = homeManagerUsers; + sharedModules = homeManagerModules; + extraSpecialArgs = homeManagerSpecialArgs; + }; + } + ]; + }; } \ No newline at end of file diff --git a/lib/options.nix b/lib/options.nix index e13be0e..3ad6b02 100644 --- a/lib/options.nix +++ b/lib/options.nix @@ -5,33 +5,33 @@ in { - # Shorthand for creating boolean options in custom modules. - mkBoolOption = default: description: ( + # Shorthand for creating string options in custom modules. + mkStrOption = default: description: ( mkOption { inherit default description; - type = types.bool; + type = types.str; } ); - # Shorthand for creating string options in custom modules. - mkStrOption = default: description: ( + # Shorthand for creating string lists options in custom modules. + mkStrListOption = default: description: ( mkOption { inherit default description; - type = types.str; + type = types.listOf types.str; } ); - # Shorthand for creating string lists options in custom modules. - mkStrListOption = default: description: ( + # Shorthand for creating submodule options in custom modules. + mkSubmoduleOption = default: description: submodule: ( mkOption { inherit default description; - type = types.listOf types.str; + type = types.submodule { options = submodule; }; } ); @@ -44,4 +44,14 @@ in { type = types.attrsOf (types.submodule mkSubmodule); } ); + + # Shorthand for creating package lists options in custom modules. + mkPackageListOption = default: description: ( + + mkOption { + + inherit default description; + type = types.listOf types.package; + } + ); } \ No newline at end of file