nixos module: support NixOS user packages install
When using the NixOS module we cannot guarantee that the Nix store will be writable during startup. Installing the user packages through `nix-env -i` will fail in these cases. This commit adds a NixOS option `home-manager.useUserPackages` that, when enabled, installs user packages through the NixOS users.users.<name?>.packages option. Note, when submodule support and external package install is enabled then the installed packages are not available in `~/.nix-profile`. We therefore set `home.profileDirectory` directly to the HM profile packages.
This commit is contained in:
parent
2093cf425f
commit
ef168979bf
|
@ -269,7 +269,11 @@ in
|
||||||
home.username = mkDefault (builtins.getEnv "USER");
|
home.username = mkDefault (builtins.getEnv "USER");
|
||||||
home.homeDirectory = mkDefault (builtins.getEnv "HOME");
|
home.homeDirectory = mkDefault (builtins.getEnv "HOME");
|
||||||
|
|
||||||
home.profileDirectory = cfg.homeDirectory + "/.nix-profile";
|
home.profileDirectory =
|
||||||
|
if config.submoduleSupport.enable
|
||||||
|
&& config.submoduleSupport.externalPackageInstall
|
||||||
|
then config.home.path
|
||||||
|
else cfg.homeDirectory + "/.nix-profile";
|
||||||
|
|
||||||
home.sessionVariables =
|
home.sessionVariables =
|
||||||
let
|
let
|
||||||
|
@ -307,9 +311,33 @@ in
|
||||||
home.activation.writeBoundary = dag.entryAnywhere "";
|
home.activation.writeBoundary = dag.entryAnywhere "";
|
||||||
|
|
||||||
# Install packages to the user environment.
|
# Install packages to the user environment.
|
||||||
home.activation.installPackages = dag.entryAfter ["writeBoundary"] ''
|
#
|
||||||
$DRY_RUN_CMD nix-env -i ${cfg.path}
|
# Note, sometimes our target may not allow modification of the Nix
|
||||||
'';
|
# store and then we cannot rely on `nix-env -i`. This is the case,
|
||||||
|
# for example, if we are running as a NixOS module and building a
|
||||||
|
# virtual machine. Then we must instead rely on an external
|
||||||
|
# mechanism for installing packages, which in NixOS is provided by
|
||||||
|
# the `users.users.<name?>.packages` option. The activation
|
||||||
|
# command is still needed since some modules need to run their
|
||||||
|
# activation commands after the packages are guaranteed to be
|
||||||
|
# installed.
|
||||||
|
#
|
||||||
|
# In case the user has moved from a user-install of Home Manager
|
||||||
|
# to a submodule managed one we attempt to uninstall the
|
||||||
|
# `home-manager-path` package if it is installed.
|
||||||
|
home.activation.installPackages = dag.entryAfter ["writeBoundary"] (
|
||||||
|
if config.submoduleSupport.externalPackageInstall
|
||||||
|
then
|
||||||
|
''
|
||||||
|
if nix-env -q | grep '^home-manager-path$'; then
|
||||||
|
$DRY_RUN_CMD nix-env -e home-manager-path
|
||||||
|
fi
|
||||||
|
''
|
||||||
|
else
|
||||||
|
''
|
||||||
|
$DRY_RUN_CMD nix-env -i ${cfg.path}
|
||||||
|
''
|
||||||
|
);
|
||||||
|
|
||||||
home.activationPackage =
|
home.activationPackage =
|
||||||
let
|
let
|
||||||
|
|
|
@ -966,6 +966,24 @@ in
|
||||||
as an Emacs daemon.
|
as an Emacs daemon.
|
||||||
'';
|
'';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
time = "2019-02-16T20:33:56+00:00";
|
||||||
|
condition = hostPlatform.isLinux;
|
||||||
|
message = ''
|
||||||
|
When using Home Manager as a NixOS submodule it is now
|
||||||
|
possible to install packages using the NixOS
|
||||||
|
|
||||||
|
users.users.<name?>.packages
|
||||||
|
|
||||||
|
option. This is enabled by adding
|
||||||
|
|
||||||
|
home-manager.useUserPackages = true;
|
||||||
|
|
||||||
|
to your NixOS system configuration. This mode of operation
|
||||||
|
is necessary if you want to use 'nixos-rebuild build-vm'.
|
||||||
|
'';
|
||||||
|
}
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,5 +15,18 @@ with lib;
|
||||||
in, for example, NixOS or nix-darwin.
|
in, for example, NixOS or nix-darwin.
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
|
|
||||||
|
externalPackageInstall = mkOption {
|
||||||
|
type = types.bool;
|
||||||
|
default = false;
|
||||||
|
internal = true;
|
||||||
|
description = ''
|
||||||
|
Whether the packages of <option>home.packages</option> are
|
||||||
|
installed separately from the Home Manager activation script.
|
||||||
|
In NixOS, for example, this may be accomplished by installing
|
||||||
|
the packages through
|
||||||
|
<option>users.users.<name?>.packages</option>.
|
||||||
|
'';
|
||||||
|
};
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,6 +11,7 @@ let
|
||||||
|
|
||||||
config = {
|
config = {
|
||||||
submoduleSupport.enable = true;
|
submoduleSupport.enable = true;
|
||||||
|
submoduleSupport.externalPackageInstall = cfg.useUserPackages;
|
||||||
home.username = config.users.users.${name}.name;
|
home.username = config.users.users.${name}.name;
|
||||||
home.homeDirectory = config.users.users.${name}.home;
|
home.homeDirectory = config.users.users.${name}.home;
|
||||||
};
|
};
|
||||||
|
@ -20,16 +21,29 @@ in
|
||||||
|
|
||||||
{
|
{
|
||||||
options = {
|
options = {
|
||||||
home-manager.users = mkOption {
|
home-manager = {
|
||||||
type = types.attrsOf hmModule;
|
useUserPackages = mkEnableOption ''
|
||||||
default = {};
|
installation of user packages through the
|
||||||
description = ''
|
<option>users.users.<name?>.packages</option> option.
|
||||||
Per-user Home Manager configuration.
|
|
||||||
'';
|
'';
|
||||||
|
|
||||||
|
users = mkOption {
|
||||||
|
type = types.attrsOf hmModule;
|
||||||
|
default = {};
|
||||||
|
description = ''
|
||||||
|
Per-user Home Manager configuration.
|
||||||
|
'';
|
||||||
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
config = mkIf (cfg.users != {}) {
|
config = mkIf (cfg.users != {}) {
|
||||||
|
users.users = mkIf cfg.useUserPackages (
|
||||||
|
mapAttrs (username: usercfg: {
|
||||||
|
packages = usercfg.home.packages;
|
||||||
|
}) cfg.users
|
||||||
|
);
|
||||||
|
|
||||||
systemd.services = mapAttrs' (username: usercfg:
|
systemd.services = mapAttrs' (username: usercfg:
|
||||||
nameValuePair ("home-manager-${utils.escapeSystemdPath username}") {
|
nameValuePair ("home-manager-${utils.escapeSystemdPath username}") {
|
||||||
description = "Home Manager environment for ${username}";
|
description = "Home Manager environment for ${username}";
|
||||||
|
|
Loading…
Reference in a new issue