mirror of
https://github.com/nix-community/home-manager.git
synced 2025-11-08 19:46:05 +01:00
home-manager: avoid profile management during activation
This commit deprecates profile management from the activation script. The profile management is instead the responsibility of the driving software, for example, the `home-manager` tool in the case of standalone installs. The legacy behavior is still available for backwards compatibility but may be removed in the future. The new behavior resolves (or moves us closer to resolving) a number of long standing open issues: - `home-manager switch --rollback`, which performs a rollback to the previous Home Manager generation before activating. While it was previously possible to accomplish this by activating an old generation, it did always create a new profile generation. This option has been implemented as part of this commit. - `home-manager switch --specialisation NAME`, which switches to the named specialisation. While it was previously possible to accomplish this by manually running the specialisation activate script, it did always create a new profile generation. This option has been implemented as part of this commit. - `home-manager switch --test`, which activates the configuration but does not create a new profile generation. This option has _not_ been implemented here since it relies on the current configuration being activated on login, which we do not currently do. - When using the "Home Manager as a NixOS module" installation method we previously created an odd `home-manager` per-user "shadow profile" for the user. This is no longer necessary. This has been implemented as part of this commit. Fixes #3450
This commit is contained in:
parent
e4bf85da68
commit
de448dcb57
21 changed files with 692 additions and 127 deletions
|
|
@ -477,6 +477,18 @@ in
|
|||
description = "The package containing the complete activation script.";
|
||||
};
|
||||
|
||||
home.activationGenerateGcRoot = mkOption {
|
||||
internal = true;
|
||||
type = types.bool;
|
||||
default = true;
|
||||
description = ''
|
||||
Whether the activation script should create a GC root to avoid being
|
||||
garbage collected. Typically you want this but if you know for certain
|
||||
that the Home Manager generation is referenced from some other GC root,
|
||||
then it may be appropriate to not create our own root.
|
||||
'';
|
||||
};
|
||||
|
||||
home.extraActivationPath = mkOption {
|
||||
internal = true;
|
||||
type = types.listOf types.package;
|
||||
|
|
@ -627,12 +639,16 @@ in
|
|||
# The entry acting as a boundary between the activation script's "check" and
|
||||
# the "write" phases. This is where we commit to attempting to actually
|
||||
# activate the configuration.
|
||||
#
|
||||
# Note, if we are run by a version 0 driver then we update the profile here.
|
||||
home.activation.writeBoundary = lib.hm.dag.entryAnywhere ''
|
||||
if [[ ! -v oldGenPath || "$oldGenPath" != "$newGenPath" ]] ; then
|
||||
_i "Creating new profile generation"
|
||||
run nix-env $VERBOSE_ARG --profile "$genProfilePath" --set "$newGenPath"
|
||||
else
|
||||
_i "No change so reusing latest profile generation"
|
||||
if (( $hmDriverVersion < 1 )); then
|
||||
if [[ ! -v oldGenPath || "$oldGenPath" != "$newGenPath" ]] ; then
|
||||
_i "Creating new profile generation"
|
||||
run nix-env $VERBOSE_ARG --profile "$genProfilePath" --set "$newGenPath"
|
||||
else
|
||||
_i "No change so reusing latest profile generation"
|
||||
fi
|
||||
fi
|
||||
'';
|
||||
|
||||
|
|
@ -763,6 +779,38 @@ in
|
|||
export PATH="${activationBinPaths}"
|
||||
${config.lib.bash.initHomeManagerLib}
|
||||
|
||||
# The driver version indicates the behavior expected by the caller of
|
||||
# this script.
|
||||
#
|
||||
# - 0 : legacy behavior
|
||||
# - 1 : the script will not attempt to update the Home Manager Nix profile.
|
||||
hmDriverVersion=0
|
||||
|
||||
while (( $# > 0 )); do
|
||||
opt="$1"
|
||||
shift
|
||||
|
||||
case $opt in
|
||||
--driver-version)
|
||||
if (( $# == 0 )); then
|
||||
errorEcho "$0: no driver version specified" >&2
|
||||
exit 1
|
||||
elif (( 0 <= $1 && $1 <= 1 )); then
|
||||
hmDriverVersion=$1
|
||||
else
|
||||
errorEcho "$0: unexpected driver version $1" >&2
|
||||
exit 1
|
||||
fi
|
||||
shift
|
||||
;;
|
||||
*)
|
||||
_iError "%s: unknown option '%s'" "$0" "$opt" >&2
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
done
|
||||
unset opt
|
||||
|
||||
${builtins.readFile ./lib-bash/activation-init.sh}
|
||||
|
||||
if [[ ! -v SKIP_SANITY_CHECKS ]]; then
|
||||
|
|
@ -770,13 +818,15 @@ in
|
|||
checkHomeDirectory ${lib.escapeShellArg config.home.homeDirectory}
|
||||
fi
|
||||
|
||||
# Create a temporary GC root to prevent collection during activation.
|
||||
trap 'run rm -f $VERBOSE_ARG "$newGenGcPath"' EXIT
|
||||
run --silence nix-store --realise "$newGenPath" --add-root "$newGenGcPath"
|
||||
${lib.optionalString config.home.activationGenerateGcRoot ''
|
||||
# Create a temporary GC root to prevent collection during activation.
|
||||
trap 'run rm -f $VERBOSE_ARG "$newGenGcPath"' EXIT
|
||||
run --silence nix-store --realise "$newGenPath" --add-root "$newGenGcPath"
|
||||
''}
|
||||
|
||||
${activationCmds}
|
||||
|
||||
${lib.optionalString (!config.uninstall) ''
|
||||
${lib.optionalString (config.home.activationGenerateGcRoot && !config.uninstall) ''
|
||||
# Create the "current generation" GC root.
|
||||
run --silence nix-store --realise "$newGenPath" --add-root "$currentGenGcPath"
|
||||
|
||||
|
|
@ -797,6 +847,11 @@ in
|
|||
|
||||
echo "${config.home.version.full}" > $out/hm-version
|
||||
|
||||
# The gen-version indicates the format of the generation package
|
||||
# itself. It allows us to make backwards incompatible changes in the
|
||||
# package output and have surrounding tooling adapt.
|
||||
echo 1 > $out/gen-version
|
||||
|
||||
cp ${activationScript} $out/activate
|
||||
|
||||
mkdir $out/bin
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue