flake-parts/setups: modularize home-manager submodule

It could be handy once we have other wider-scoped environments such as
nix-darwin or systems-manager (as long as it can have a home-manager
user inside of it).
This commit is contained in:
Gabriel Arazas 2024-06-07 20:15:11 +08:00
parent b9652dc8bb
commit 749e85ca49
No known key found for this signature in database
GPG Key ID: 62104B43D00AA360
2 changed files with 114 additions and 104 deletions

View File

@ -117,16 +117,8 @@ let
userConfig = lib.mkOption { userConfig = lib.mkOption {
type = with lib.types; attrsOf anything; type = with lib.types; attrsOf anything;
description = '' description = ''
The configuration applied for {option}`users.users.<name>` in the The configuration applied for individual users set in the
NixOS configuration. wider-scoped environment.
'';
};
additionalModules = lib.mkOption {
type = with lib.types; listOf deferredModule;
description = ''
A list of additional home-manager modules to be added with the
user.
''; '';
}; };
}; };
@ -151,7 +143,7 @@ let
}; };
}; };
configType = { config, name, lib, ... }: { configType = { options, config, name, lib, ... }: {
options = { options = {
formats = lib.mkOption { formats = lib.mkOption {
type = with lib.types; nullOr (listOf str); type = with lib.types; nullOr (listOf str);
@ -208,91 +200,35 @@ let
example = "nixos-unstable-small"; example = "nixos-unstable-small";
}; };
homeManagerBranch = lib.mkOption { home-manager = {
type = lib.types.str; users = lib.mkOption {
default = "home-manager"; type = with lib.types; attrsOf (submodule homeManagerUserType);
example = "home-manager-stable"; };
description = ''
The home-manager branch to be used for the NixOS module. By default, nixpkgsInstance = lib.mkOption {
it will use the `home-manager` flake input. type = lib.types.enum [ "global" "separate" "none" ];
''; default = "global";
}; description = ''
Indicates how to manage the nixpkgs instance (or instances)
homeManagerUsers = lib.mkOption { of the holistic system. This will also dictate how to import
type = lib.types.submodule { overlays from
options = { {option}`setups.home-manager.configs.<user>.overlays`.
users = lib.mkOption {
type = with lib.types; attrsOf (submodule homeManagerUserType); * `global` enforces to use one nixpkgs instance for all
default = { }; home-manager users and imports all of the overlays into the
description = '' nixpkgs instance of the NixOS system.
A set of home-manager users from {option}`setups.home-manager` to be * `separate` enforces the NixOS system to use individual
mapped within the NixOS system as a normal user with their nixpkgs instance for all home-manager users and imports the
home-manager configuration. This would be the preferred method of overlays to the nixpkgs instance of the home-manager user.
creating NixOS users if you have a more comprehensive home-manager * `none` leave the configuration alone and do not import
user that needed more setup to begin with. overlays at all where you have to set them yourself. This is
''; the best option if you want more control over each individual
}; NixOS and home-manager configuration.
nixpkgsInstance = lib.mkOption {
type = lib.types.enum [ "global" "separate" "none" ]; The default value is set to `global` which is the encouraged
default = "global"; practice with this module.
description = '' '';
Indicates how to manage the nixpkgs instance (or instances)
of the holistic system. This will also dictate how to import
overlays from
{option}`setups.home-manager.configs.<user>.overlays`.
* `global` enforces to use one nixpkgs instance for all
home-manager users and imports all of the overlays into the
nixpkgs instance of the NixOS system.
* `separate` enforces the NixOS system to use individual
nixpkgs instance for all home-manager users and imports the
overlays to the nixpkgs instance of the home-manager user.
* `none` leave the configuration alone and do not import
overlays at all where you have to set them yourself. This is
the best option if you want more control over each individual
NixOS and home-manager configuration.
The default value is set to `global` which is the encouraged
practice with this module.
'';
};
};
}; };
default = { };
example = lib.literalExpression ''
{
nixpkgsInstance = "global";
users.foo-dogsquared = {
userConfig = {
extraGroups = [
"adbusers"
"wheel"
"audio"
"docker"
"podman"
"networkmanager"
"wireshark"
];
hashedPassword =
"0000000000000000000000000000000000000000000000";
isNormalUser = true;
createHome = true;
home = "/home/foo-dogsquared";
description = "Gabriel Arazas";
};
additionalModules = [
({ config, lib, osConfig, ... }: {
programs.foo.enable = lib.mkIf osConfig.programs.bar.enable true;
})
];
};
}
'';
description = ''
Import home-manager users from
{option}`setups.home-manager.configs` and map them as a normal
NixOS user.
'';
}; };
deploy = lib.mkOption { deploy = lib.mkOption {
@ -336,18 +272,18 @@ let
config.modules = [ config.modules = [
# Bring in the required modules. # Bring in the required modules.
inputs.${config.homeManagerBranch}.nixosModules.home-manager inputs.${config.home-manager.branch}.nixosModules.home-manager
../../../configs/nixos/${config.configName} ../../../configs/nixos/${config.configName}
# Mapping the declarative home-manager users (if it has one) into NixOS # Mapping the declarative home-manager users (if it has one) into NixOS
# users. # users.
(lib.mkIf (config.homeManagerUsers.users != { }) (lib.mkIf (config.home-manager.users != { })
( (
let let
inherit (config.homeManagerUsers) nixpkgsInstance; inherit (config.home-manager) nixpkgsInstance;
setupConfig = config; setupConfig = config;
hasHomeManagerUsers = config.homeManagerUsers.users != { }; hasHomeManagerUsers = config.home-manager.users != { };
isNixpkgs = state: hasHomeManagerUsers && nixpkgsInstance == state; isNixpkgs = state: hasHomeManagerUsers && nixpkgsInstance == state;
in in
{ config, lib, pkgs, ... }: { { config, lib, pkgs, ... }: {
@ -356,7 +292,7 @@ let
users.users = users.users =
lib.mapAttrs lib.mapAttrs
(name: hmUser: hmUser.userConfig) (name: hmUser: hmUser.userConfig)
setupConfig.homeManagerUsers.users; setupConfig.home-manager.users;
home-manager.users = home-manager.users =
lib.mapAttrs lib.mapAttrs
@ -365,7 +301,7 @@ let
partsConfig.setups.home-manager.configs.${name}.modules partsConfig.setups.home-manager.configs.${name}.modules
++ hmUser.additionalModules; ++ hmUser.additionalModules;
}) })
setupConfig.homeManagerUsers.users; setupConfig.home-manager.users;
}) })
(lib.mkIf (isNixpkgs "global") { (lib.mkIf (isNixpkgs "global") {
@ -379,7 +315,7 @@ let
nixpkgs.overlays = lib.mkForce null; nixpkgs.overlays = lib.mkForce null;
nixpkgs.config = lib.mkForce null; nixpkgs.config = lib.mkForce null;
}) })
setupConfig.homeManagerUsers.users; setupConfig.home-manager.users;
# Then apply all of the user overlays into the nixpkgs instance # Then apply all of the user overlays into the nixpkgs instance
# of the NixOS system. # of the NixOS system.
@ -389,7 +325,7 @@ let
lib.mapAttrsToList lib.mapAttrsToList
(name: _: (name: _:
partsConfig.setups.home-manager.configs.${name}.overlays) partsConfig.setups.home-manager.configs.${name}.overlays)
setupConfig.homeManagerUsers.users; setupConfig.home-manager.users;
overlays = lib.lists.flatten hmUsersOverlays; overlays = lib.lists.flatten hmUsersOverlays;
in in
@ -412,7 +348,7 @@ let
nixpkgs.overlays = nixpkgs.overlays =
partsConfig.setups.home-manager.configs.${name}.overlays; partsConfig.setups.home-manager.configs.${name}.overlays;
}) })
setupConfig.homeManagerUsers.users; setupConfig.home-manager.users;
}) })
]; ];
} }
@ -488,6 +424,7 @@ in
(import ./shared/nix-conf.nix { inherit inputs; }) (import ./shared/nix-conf.nix { inherit inputs; })
./shared/config-options.nix ./shared/config-options.nix
./shared/nixvim-instance-options.nix ./shared/nixvim-instance-options.nix
./shared/home-manager-users.nix
configType configType
]; ];
}); });

View File

@ -0,0 +1,73 @@
# Take note that the individual setup module would have to take care of
# integrating the users into their respective environment.
{ config, options, lib, ... }:
let
homeManagerUserType = { name, config, lib, ... }: {
options = {
additionalModules = lib.mkOption {
type = with lib.types; listOf deferredModule;
description = ''
A list of additional home-manager modules to be added with the
user.
'';
};
};
};
in
{
# This option is for the wider-scoped environment to be easily compatible
# with the home-manager flake-parts module where it also shares the Nix
# configuration submodule. Without this option, it would not work (or we
# could just rename the options from the home-manager module).
options.homeManagerBranch = options.home-manager.branch // {
default = config.home-manager.branch;
};
options.home-manager = {
branch = lib.mkOption {
type = lib.types.nonEmptyStr;
description = ''
The name of the home-manager branch to be used. Take note this should
be set with care as home-manager typically recommends to be used with
the apprioriate nixpkgs branch.
'';
default = "home-manager";
example = "home-manager-stable";
};
users = lib.mkOption {
type = with lib.types; attrsOf (submodule homeManagerUserType);
description = ''
A set of home-manager users from {option}`setups.home-manager.configs` to
be included with the wider-scoped environment.
'';
default = { };
example = {
foo-dogsquared = {
userConfig = {
uid = 1000;
extraGroups = [
"adm"
"adbusers"
"wheel"
"audio"
"docker"
"podman"
"networkmanager"
"systemd-journal"
"wireshark"
];
};
};
plover.userConfig = {
extraGroups = [
"adm"
"wheel"
];
};
};
};
};
}