home-manager: migrate profiles to nix state directory

If the user runs a recent Nix version that places per-user profiles in
`$XDG_STATE_DIR/nix/profiles`, then migrate the home-manager profile
there.

Also clean up `setupVars` a bit.
This commit is contained in:
Robert Helgesson 2023-04-07 14:01:45 +02:00
parent 440faf5ae4
commit 93f5cb2482
No known key found for this signature in database
GPG key ID: 36BDAA14C2797E89
4 changed files with 113 additions and 88 deletions

View file

@ -117,18 +117,25 @@ function setHomeManagerNixPath() {
# Sets some useful Home Manager related paths as global read-only variables. # Sets some useful Home Manager related paths as global read-only variables.
function setHomeManagerPathVariables() { function setHomeManagerPathVariables() {
declare -r nixStateDir="${NIX_STATE_DIR:-/nix/var/nix}" declare -r globalNixStateDir="${NIX_STATE_DIR:-/nix/var/nix}"
declare -r globalProfilesDir="$nixStateDir/profiles/per-user/$USER" declare -r globalProfilesDir="$globalNixStateDir/profiles/per-user/$USER"
declare -r globalGcrootsDir="$nixStateDir/gcroots/per-user/$USER" declare -r globalGcrootsDir="$globalNixStateDir/gcroots/per-user/$USER"
declare -r stateHome="${XDG_STATE_HOME:-$HOME/.local/state}"
declare -r userNixStateDir="$stateHome/nix"
declare -gr HM_DATA_HOME="${XDG_DATA_HOME:-$HOME/.local/share}/home-manager" declare -gr HM_DATA_HOME="${XDG_DATA_HOME:-$HOME/.local/share}/home-manager"
declare -gr HM_STATE_DIR="${XDG_STATE_HOME:-$HOME/.local/state}/home-manager" declare -gr HM_STATE_DIR="$stateHome/home-manager"
declare -gr HM_GCROOT_LEGACY_PATH="$globalGcrootsDir/current-home" declare -gr HM_GCROOT_LEGACY_PATH="$globalGcrootsDir/current-home"
if [[ -d "$globalProfilesDir" ]]; then if [[ -d $userNixStateDir/profiles ]]; then
declare -gr HM_PROFILE_DIR="$userNixStateDir/profiles"
elif [[ -d $globalProfilesDir ]]; then
declare -gr HM_PROFILE_DIR="$globalProfilesDir" declare -gr HM_PROFILE_DIR="$globalProfilesDir"
else else
declare -gr HM_PROFILE_DIR="$HM_STATE_DIR/profiles" _iError 'Could not find suitable profile directory, tried %s and %s' \
"$HM_STATE_DIR/profiles" "$globalProfilesDir" >&2
exit 1
fi fi
} }
@ -769,6 +776,10 @@ function doUninstall() {
$DRY_RUN_CMD rm $VERBOSE_ARG -r "$HM_DATA_HOME" $DRY_RUN_CMD rm $VERBOSE_ARG -r "$HM_DATA_HOME"
fi fi
if [[ -e $HM_STATE_DIR ]]; then
$DRY_RUN_CMD rm $VERBOSE_ARG -r "$HM_STATE_DIR"
fi
if [[ -e $HM_PROFILE_DIR ]]; then if [[ -e $HM_PROFILE_DIR ]]; then
$DRY_RUN_CMD rm $VERBOSE_ARG "$HM_PROFILE_DIR/home-manager"* $DRY_RUN_CMD rm $VERBOSE_ARG "$HM_PROFILE_DIR/home-manager"*
fi fi
@ -776,10 +787,6 @@ function doUninstall() {
if [[ -e $HM_GCROOT_LEGACY_PATH ]]; then if [[ -e $HM_GCROOT_LEGACY_PATH ]]; then
$DRY_RUN_CMD rm $VERBOSE_ARG "$HM_GCROOT_LEGACY_PATH" $DRY_RUN_CMD rm $VERBOSE_ARG "$HM_GCROOT_LEGACY_PATH"
fi fi
if [[ -e $HM_STATE_DIR ]]; then
$DRY_RUN_CMD rm $VERBOSE_ARG -r "$HM_STATE_DIR"
fi
;; ;;
*) *)
_i "Yay!" _i "Yay!"

View file

@ -8,7 +8,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: Home Manager\n" "Project-Id-Version: Home Manager\n"
"Report-Msgid-Bugs-To: https://github.com/nix-community/home-manager/issues\n" "Report-Msgid-Bugs-To: https://github.com/nix-community/home-manager/issues\n"
"POT-Creation-Date: 2023-03-15 20:11+0100\n" "POT-Creation-Date: 2023-04-10 13:49+0200\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n" "Language-Team: LANGUAGE <LL@li.org>\n"
@ -25,7 +25,7 @@ msgstr ""
#. translators: The first '%s' specifier will be replaced by either #. translators: The first '%s' specifier will be replaced by either
#. 'home.nix' or 'flake.nix'. #. 'home.nix' or 'flake.nix'.
#: home-manager/home-manager:88 home-manager/home-manager:92 #: home-manager/home-manager:88 home-manager/home-manager:92
#: home-manager/home-manager:147 #: home-manager/home-manager:154
msgid "" msgid ""
"Keeping your Home Manager %s in %s is deprecated,\n" "Keeping your Home Manager %s in %s is deprecated,\n"
"please move it to %s" "please move it to %s"
@ -35,33 +35,37 @@ msgstr ""
msgid "No configuration file found. Please create one at %s" msgid "No configuration file found. Please create one at %s"
msgstr "" msgstr ""
#: home-manager/home-manager:183 #: home-manager/home-manager:136
msgid "Could not find suitable profile directory, tried %s and %s"
msgstr ""
#: home-manager/home-manager:190
msgid "Can't inspect options of a flake configuration" msgid "Can't inspect options of a flake configuration"
msgstr "" msgstr ""
#: home-manager/home-manager:245 home-manager/home-manager:268 #: home-manager/home-manager:252 home-manager/home-manager:275
#: home-manager/home-manager:907 #: home-manager/home-manager:970
msgid "%s: unknown option '%s'" msgid "%s: unknown option '%s'"
msgstr "" msgstr ""
#: home-manager/home-manager:250 home-manager/home-manager:908 #: home-manager/home-manager:257 home-manager/home-manager:971
msgid "Run '%s --help' for usage help" msgid "Run '%s --help' for usage help"
msgstr "" msgstr ""
#: home-manager/home-manager:276 home-manager/home-manager:326 #: home-manager/home-manager:283 home-manager/home-manager:382
msgid "The file %s already exists, leaving it unchanged..." msgid "The file %s already exists, leaving it unchanged..."
msgstr "" msgstr ""
#: home-manager/home-manager:278 home-manager/home-manager:328 #: home-manager/home-manager:285 home-manager/home-manager:384
msgid "Creating %s..." msgid "Creating %s..."
msgstr "" msgstr ""
#: home-manager/home-manager:370 #: home-manager/home-manager:426
msgid "Creating initial Home Manager generation..." msgid "Creating initial Home Manager generation..."
msgstr "" msgstr ""
#. translators: The "%s" specifier will be replaced by a file path. #. translators: The "%s" specifier will be replaced by a file path.
#: home-manager/home-manager:375 #: home-manager/home-manager:431
msgid "" msgid ""
"All done! The home-manager tool should now be installed and you can edit\n" "All done! The home-manager tool should now be installed and you can edit\n"
"\n" "\n"
@ -72,7 +76,7 @@ msgid ""
msgstr "" msgstr ""
#. translators: The "%s" specifier will be replaced by a URL. #. translators: The "%s" specifier will be replaced by a URL.
#: home-manager/home-manager:380 #: home-manager/home-manager:436
msgid "" msgid ""
"Uh oh, the installation failed! Please create an issue at\n" "Uh oh, the installation failed! Please create an issue at\n"
"\n" "\n"
@ -81,11 +85,11 @@ msgid ""
"if the error seems to be the fault of Home Manager." "if the error seems to be the fault of Home Manager."
msgstr "" msgstr ""
#: home-manager/home-manager:390 #: home-manager/home-manager:446
msgid "Can't instantiate a flake configuration" msgid "Can't instantiate a flake configuration"
msgstr "" msgstr ""
#: home-manager/home-manager:463 #: home-manager/home-manager:519
msgid "" msgid ""
"There is %d unread and relevant news item.\n" "There is %d unread and relevant news item.\n"
"Read it by running the command \"%s news\"." "Read it by running the command \"%s news\"."
@ -95,72 +99,76 @@ msgid_plural ""
msgstr[0] "" msgstr[0] ""
msgstr[1] "" msgstr[1] ""
#: home-manager/home-manager:477 #: home-manager/home-manager:533
msgid "Unknown \"news.display\" setting \"%s\"." msgid "Unknown \"news.display\" setting \"%s\"."
msgstr "" msgstr ""
#: home-manager/home-manager:484 #: home-manager/home-manager:540
#, sh-format #, sh-format
msgid "Please set the $EDITOR environment variable" msgid "Please set the $EDITOR environment variable"
msgstr "" msgstr ""
#: home-manager/home-manager:499 #: home-manager/home-manager:555
msgid "Cannot run build in read-only directory" msgid "Cannot run build in read-only directory"
msgstr "" msgstr ""
#: home-manager/home-manager:583 #: home-manager/home-manager:639
msgid "No generation with ID %s" msgid "No generation with ID %s"
msgstr "" msgstr ""
#: home-manager/home-manager:585 #: home-manager/home-manager:641
msgid "Cannot remove the current generation %s" msgid "Cannot remove the current generation %s"
msgstr "" msgstr ""
#: home-manager/home-manager:587 #: home-manager/home-manager:643
msgid "Removing generation %s" msgid "Removing generation %s"
msgstr "" msgstr ""
#: home-manager/home-manager:606 #: home-manager/home-manager:662
msgid "No generations to expire" msgid "No generations to expire"
msgstr "" msgstr ""
#: home-manager/home-manager:617 #: home-manager/home-manager:673
msgid "No home-manager packages seem to be installed." msgid "No home-manager packages seem to be installed."
msgstr "" msgstr ""
#: home-manager/home-manager:674 #: home-manager/home-manager:699
msgid "Sorry, this command is not yet supported in flake setup"
msgstr ""
#: home-manager/home-manager:736
msgid "Unknown argument %s" msgid "Unknown argument %s"
msgstr "" msgstr ""
#: home-manager/home-manager:690 #: home-manager/home-manager:752
msgid "This will remove Home Manager from your system." msgid "This will remove Home Manager from your system."
msgstr "" msgstr ""
#: home-manager/home-manager:693 #: home-manager/home-manager:755
msgid "This is a dry run, nothing will actually be uninstalled." msgid "This is a dry run, nothing will actually be uninstalled."
msgstr "" msgstr ""
#: home-manager/home-manager:697 #: home-manager/home-manager:759
msgid "Really uninstall Home Manager?" msgid "Really uninstall Home Manager?"
msgstr "" msgstr ""
#: home-manager/home-manager:703 #: home-manager/home-manager:765
msgid "Switching to empty Home Manager configuration..." msgid "Switching to empty Home Manager configuration..."
msgstr "" msgstr ""
#: home-manager/home-manager:730 #: home-manager/home-manager:792
msgid "Yay!" msgid "Yay!"
msgstr "" msgstr ""
#: home-manager/home-manager:735 #: home-manager/home-manager:797
msgid "Home Manager is uninstalled but your home.nix is left untouched." msgid "Home Manager is uninstalled but your home.nix is left untouched."
msgstr "" msgstr ""
#: home-manager/home-manager:945 #: home-manager/home-manager:1008
msgid "expire-generations expects one argument, got %d." msgid "expire-generations expects one argument, got %d."
msgstr "" msgstr ""
#: home-manager/home-manager:967 #: home-manager/home-manager:1030
msgid "Unknown command: %s" msgid "Unknown command: %s"
msgstr "" msgstr ""

View file

@ -1,55 +1,61 @@
# Moves the existing profile from /nix to ~ to match changed behavior in Nix # Moves the existing profile from /nix or $XDG_STATE_HOME/home-manager to
# 2.14. See https://github.com/NixOS/nix/pull/5226. # $XDG_STATE_HOME/nix to match changed behavior in Nix 2.14. See
# # https://github.com/NixOS/nix/pull/5226.
# Note, this function is intentionally unused for now. There remains a few open
# questions about backwards compatibility and support from
# `nix-collect-garbage`.
function migrateProfile() { function migrateProfile() {
declare -r stateHome="${XDG_STATE_HOME:-$HOME/.local/state}" declare -r stateHome="${XDG_STATE_HOME:-$HOME/.local/state}"
declare -r userNixStateDir="$stateHome/nix"
declare -r hmStateDir="$stateHome/home-manager" declare -r hmStateDir="$stateHome/home-manager"
declare -r nixStateDir="${NIX_STATE_DIR:-/nix/var/nix}"
declare -r newProfilesDir="$hmStateDir/profiles" declare -r globalNixStateDir="${NIX_STATE_DIR:-/nix/var/nix}"
declare -r oldProfilesDir="$nixStateDir/profiles/per-user/$USER" declare -r globalProfilesDir="$globalNixStateDir/profiles/per-user/$USER"
if [[ ! -d $newProfilesDir ]]; then if [[ -e $globalProfilesDir/home-manager ]]; then
_i 'Migrating profiles from %s to %s' "$oldProfilesDir" "$newProfilesDir" declare -r oldProfilesDir="$globalProfilesDir"
mkdir -p "$newProfilesDir" elif [[ -e $hmStateDir/profiles/home-manager ]]; then
for p in "$oldProfilesDir"/home-manager-*; do declare -r oldProfilesDir="$hmStateDir/profiles"
declare -r name="${p##*/}"
nix-store --realise "$p" --add-root "$newProfilesDir/$name" > /dev/null
done
cp -P "$oldProfilesDir/home-manager" "$newProfilesDir"
fi fi
rm "$oldProfilesDir"/home-manager-* declare -r newProfilesDir="$userNixStateDir/profiles"
if [[ -v oldProfilesDir && -e $newProfilesDir ]]; then
if [[ ! -e $newProfilesDir/home-manager ]]; then
_i 'Migrating profile from %s to %s' "$oldProfilesDir" "$newProfilesDir"
for p in "$oldProfilesDir"/home-manager-*; do
declare name="${p##*/}"
nix-store --realise "$p" --add-root "$newProfilesDir/$name" > /dev/null
done
cp -P "$oldProfilesDir/home-manager" "$newProfilesDir"
fi
rm "$oldProfilesDir/home-manager" "$oldProfilesDir"/home-manager-*
fi
} }
function setupVars() { function setupVars() {
declare -r nixStateDir="${NIX_STATE_DIR:-/nix/var/nix}"
declare -r globalProfilesDir="$nixStateDir/profiles/per-user/$USER"
declare -r globalGcrootsDir="$nixStateDir/gcroots/per-user/$USER"
declare -r stateHome="${XDG_STATE_HOME:-$HOME/.local/state}" declare -r stateHome="${XDG_STATE_HOME:-$HOME/.local/state}"
declare -r hmStateDir="$stateHome/home-manager" declare -r userNixStateDir="$stateHome/nix"
declare -r hmGcrootsDir="$hmStateDir/gcroots" declare -r hmGcrootsDir="$stateHome/home-manager/gcroots"
# If the global profiles path exists or we can create it, then place the HM declare -r globalNixStateDir="${NIX_STATE_DIR:-/nix/var/nix}"
# profile there. Otherwise place it in the HM data directory. We prefer to declare -r globalProfilesDir="$globalNixStateDir/profiles/per-user/$USER"
# use the global location since it makes it visible to declare -r globalGcrootsDir="$globalNixStateDir/gcroots/per-user/$USER"
# `nix-collect-garbage`.
# # If the user Nix profiles path exists, then place the HM profile there.
# In the future we may perform a one-shot migration to the new location. # Otherwise, if the global Nix per-user state directory exists then use
# that. If neither exists, then we give up.
# #
# shellcheck disable=2174 # shellcheck disable=2174
if [[ -d "$globalProfilesDir" ]] || mkdir -m 0755 -p "$globalProfilesDir" 2>/dev/null; then if [[ -d $userNixStateDir/profiles ]]; then
declare -r hmProfilesDir="$globalProfilesDir" declare -r profilesDir="$userNixStateDir/profiles"
elif [[ -d $globalProfilesDir ]]; then
declare -r profilesDir="$globalProfilesDir"
else else
declare -r hmProfilesDir="$hmStateDir/profiles" _iError 'Could not find suitable profile directory, tried %s and %s' \
mkdir -m 0755 -p "$hmProfilesDir" "$userNixStateDir/profiles" "$globalProfilesDir" >&2
exit 1
fi fi
declare -gr genProfilePath="$hmProfilesDir/home-manager" declare -gr genProfilePath="$profilesDir/home-manager"
declare -gr newGenPath="@GENERATION_DIR@"; declare -gr newGenPath="@GENERATION_DIR@";
declare -gr newGenGcPath="$hmGcrootsDir/current-home" declare -gr newGenGcPath="$hmGcrootsDir/current-home"
declare -gr legacyGenGcPath="$globalGcrootsDir/current-home" declare -gr legacyGenGcPath="$globalGcrootsDir/current-home"
@ -77,7 +83,7 @@ function setupVars() {
|| ! -v oldGenNum && -v oldGenPath ]]; then || ! -v oldGenNum && -v oldGenPath ]]; then
_i $'The previous generation number and path are in conflict! These\nmust be either both empty or both set but are now set to\n\n \'%s\' and \'%s\'\n\nIf you don\'t mind losing previous profile generations then\nthe easiest solution is probably to run\n\n rm %s/home-manager*\n rm %s/current-home\n\nand trying home-manager switch again. Good luck!' \ _i $'The previous generation number and path are in conflict! These\nmust be either both empty or both set but are now set to\n\n \'%s\' and \'%s\'\n\nIf you don\'t mind losing previous profile generations then\nthe easiest solution is probably to run\n\n rm %s/home-manager*\n rm %s/current-home\n\nand trying home-manager switch again. Good luck!' \
"${oldGenNum:-}" "${oldGenPath:-}" \ "${oldGenNum:-}" "${oldGenPath:-}" \
"$hmProfilesDir" "$hmGcrootsDir" "$profilesDir" "$hmGcrootsDir"
exit 1 exit 1
fi fi
} }
@ -99,6 +105,7 @@ _i "Starting Home Manager activation"
$VERBOSE_RUN _i "Sanity checking Nix" $VERBOSE_RUN _i "Sanity checking Nix"
nix-build --expr '{}' --no-out-link nix-build --expr '{}' --no-out-link
migrateProfile
setupVars setupVars
if [[ -v DRY_RUN ]] ; then if [[ -v DRY_RUN ]] ; then
@ -109,7 +116,6 @@ else
$VERBOSE_RUN _i "This is a live run" $VERBOSE_RUN _i "This is a live run"
export DRY_RUN_CMD="" export DRY_RUN_CMD=""
export DRY_RUN_NULL=/dev/null export DRY_RUN_NULL=/dev/null
fi fi
if [[ -v VERBOSE ]]; then if [[ -v VERBOSE ]]; then

View file

@ -8,7 +8,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: Home Manager Modules\n" "Project-Id-Version: Home Manager Modules\n"
"Report-Msgid-Bugs-To: https://github.com/nix-community/home-manager/issues\n" "Report-Msgid-Bugs-To: https://github.com/nix-community/home-manager/issues\n"
"POT-Creation-Date: 2023-03-15 20:11+0100\n" "POT-Creation-Date: 2023-04-10 13:49+0200\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n" "Language-Team: LANGUAGE <LL@li.org>\n"
@ -53,15 +53,19 @@ msgstr ""
msgid "Activating %s" msgid "Activating %s"
msgstr "" msgstr ""
#: modules/lib-bash/activation-init.sh:16 #: modules/lib-bash/activation-init.sh:22
msgid "Migrating profiles from %s to %s" msgid "Migrating profile from %s to %s"
msgstr "" msgstr ""
#: modules/lib-bash/activation-init.sh:75 #: modules/lib-bash/activation-init.sh:53
msgid "Could not find suitable profile directory, tried %s and %s"
msgstr ""
#: modules/lib-bash/activation-init.sh:81
msgid "Sanity checking oldGenNum and oldGenPath" msgid "Sanity checking oldGenNum and oldGenPath"
msgstr "" msgstr ""
#: modules/lib-bash/activation-init.sh:78 #: modules/lib-bash/activation-init.sh:84
msgid "" msgid ""
"The previous generation number and path are in conflict! These\n" "The previous generation number and path are in conflict! These\n"
"must be either both empty or both set but are now set to\n" "must be either both empty or both set but are now set to\n"
@ -77,26 +81,26 @@ msgid ""
"and trying home-manager switch again. Good luck!" "and trying home-manager switch again. Good luck!"
msgstr "" msgstr ""
#: modules/lib-bash/activation-init.sh:95 #: modules/lib-bash/activation-init.sh:101
msgid "Starting Home Manager activation" msgid "Starting Home Manager activation"
msgstr "" msgstr ""
#: modules/lib-bash/activation-init.sh:99 #: modules/lib-bash/activation-init.sh:105
msgid "Sanity checking Nix" msgid "Sanity checking Nix"
msgstr "" msgstr ""
#: modules/lib-bash/activation-init.sh:105 #: modules/lib-bash/activation-init.sh:112
msgid "This is a dry run" msgid "This is a dry run"
msgstr "" msgstr ""
#: modules/lib-bash/activation-init.sh:109 #: modules/lib-bash/activation-init.sh:116
msgid "This is a live run" msgid "This is a live run"
msgstr "" msgstr ""
#: modules/lib-bash/activation-init.sh:116 #: modules/lib-bash/activation-init.sh:122
msgid "Using Nix version: %s" msgid "Using Nix version: %s"
msgstr "" msgstr ""
#: modules/lib-bash/activation-init.sh:119 #: modules/lib-bash/activation-init.sh:125
msgid "Activation variables:" msgid "Activation variables:"
msgstr "" msgstr ""