From 93f5cb2482dd20e57eb8ca6c819cdad9738f98a0 Mon Sep 17 00:00:00 2001 From: Robert Helgesson Date: Fri, 7 Apr 2023 14:01:45 +0200 Subject: [PATCH] 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. --- home-manager/home-manager | 27 ++++++---- home-manager/po/home-manager.pot | 68 +++++++++++++----------- modules/lib-bash/activation-init.sh | 80 ++++++++++++++++------------- modules/po/hm-modules.pot | 26 ++++++---- 4 files changed, 113 insertions(+), 88 deletions(-) diff --git a/home-manager/home-manager b/home-manager/home-manager index b6ca244b..70cfe11c 100644 --- a/home-manager/home-manager +++ b/home-manager/home-manager @@ -117,18 +117,25 @@ function setHomeManagerNixPath() { # Sets some useful Home Manager related paths as global read-only variables. function setHomeManagerPathVariables() { - 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 globalNixStateDir="${NIX_STATE_DIR:-/nix/var/nix}" + declare -r globalProfilesDir="$globalNixStateDir/profiles/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_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" - 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" 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 } @@ -769,6 +776,10 @@ function doUninstall() { $DRY_RUN_CMD rm $VERBOSE_ARG -r "$HM_DATA_HOME" fi + if [[ -e $HM_STATE_DIR ]]; then + $DRY_RUN_CMD rm $VERBOSE_ARG -r "$HM_STATE_DIR" + fi + if [[ -e $HM_PROFILE_DIR ]]; then $DRY_RUN_CMD rm $VERBOSE_ARG "$HM_PROFILE_DIR/home-manager"* fi @@ -776,10 +787,6 @@ function doUninstall() { if [[ -e $HM_GCROOT_LEGACY_PATH ]]; then $DRY_RUN_CMD rm $VERBOSE_ARG "$HM_GCROOT_LEGACY_PATH" fi - - if [[ -e $HM_STATE_DIR ]]; then - $DRY_RUN_CMD rm $VERBOSE_ARG -r "$HM_STATE_DIR" - fi ;; *) _i "Yay!" diff --git a/home-manager/po/home-manager.pot b/home-manager/po/home-manager.pot index d202eec9..4476cdf5 100644 --- a/home-manager/po/home-manager.pot +++ b/home-manager/po/home-manager.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: Home Manager\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" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -25,7 +25,7 @@ msgstr "" #. translators: The first '%s' specifier will be replaced by either #. 'home.nix' or 'flake.nix'. #: home-manager/home-manager:88 home-manager/home-manager:92 -#: home-manager/home-manager:147 +#: home-manager/home-manager:154 msgid "" "Keeping your Home Manager %s in %s is deprecated,\n" "please move it to %s" @@ -35,33 +35,37 @@ msgstr "" msgid "No configuration file found. Please create one at %s" 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" msgstr "" -#: home-manager/home-manager:245 home-manager/home-manager:268 -#: home-manager/home-manager:907 +#: home-manager/home-manager:252 home-manager/home-manager:275 +#: home-manager/home-manager:970 msgid "%s: unknown option '%s'" 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" 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..." msgstr "" -#: home-manager/home-manager:278 home-manager/home-manager:328 +#: home-manager/home-manager:285 home-manager/home-manager:384 msgid "Creating %s..." msgstr "" -#: home-manager/home-manager:370 +#: home-manager/home-manager:426 msgid "Creating initial Home Manager generation..." msgstr "" #. translators: The "%s" specifier will be replaced by a file path. -#: home-manager/home-manager:375 +#: home-manager/home-manager:431 msgid "" "All done! The home-manager tool should now be installed and you can edit\n" "\n" @@ -72,7 +76,7 @@ msgid "" msgstr "" #. translators: The "%s" specifier will be replaced by a URL. -#: home-manager/home-manager:380 +#: home-manager/home-manager:436 msgid "" "Uh oh, the installation failed! Please create an issue at\n" "\n" @@ -81,11 +85,11 @@ msgid "" "if the error seems to be the fault of Home Manager." msgstr "" -#: home-manager/home-manager:390 +#: home-manager/home-manager:446 msgid "Can't instantiate a flake configuration" msgstr "" -#: home-manager/home-manager:463 +#: home-manager/home-manager:519 msgid "" "There is %d unread and relevant news item.\n" "Read it by running the command \"%s news\"." @@ -95,72 +99,76 @@ msgid_plural "" msgstr[0] "" msgstr[1] "" -#: home-manager/home-manager:477 +#: home-manager/home-manager:533 msgid "Unknown \"news.display\" setting \"%s\"." msgstr "" -#: home-manager/home-manager:484 +#: home-manager/home-manager:540 #, sh-format msgid "Please set the $EDITOR environment variable" msgstr "" -#: home-manager/home-manager:499 +#: home-manager/home-manager:555 msgid "Cannot run build in read-only directory" msgstr "" -#: home-manager/home-manager:583 +#: home-manager/home-manager:639 msgid "No generation with ID %s" msgstr "" -#: home-manager/home-manager:585 +#: home-manager/home-manager:641 msgid "Cannot remove the current generation %s" msgstr "" -#: home-manager/home-manager:587 +#: home-manager/home-manager:643 msgid "Removing generation %s" msgstr "" -#: home-manager/home-manager:606 +#: home-manager/home-manager:662 msgid "No generations to expire" msgstr "" -#: home-manager/home-manager:617 +#: home-manager/home-manager:673 msgid "No home-manager packages seem to be installed." 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" msgstr "" -#: home-manager/home-manager:690 +#: home-manager/home-manager:752 msgid "This will remove Home Manager from your system." msgstr "" -#: home-manager/home-manager:693 +#: home-manager/home-manager:755 msgid "This is a dry run, nothing will actually be uninstalled." msgstr "" -#: home-manager/home-manager:697 +#: home-manager/home-manager:759 msgid "Really uninstall Home Manager?" msgstr "" -#: home-manager/home-manager:703 +#: home-manager/home-manager:765 msgid "Switching to empty Home Manager configuration..." msgstr "" -#: home-manager/home-manager:730 +#: home-manager/home-manager:792 msgid "Yay!" msgstr "" -#: home-manager/home-manager:735 +#: home-manager/home-manager:797 msgid "Home Manager is uninstalled but your home.nix is left untouched." msgstr "" -#: home-manager/home-manager:945 +#: home-manager/home-manager:1008 msgid "expire-generations expects one argument, got %d." msgstr "" -#: home-manager/home-manager:967 +#: home-manager/home-manager:1030 msgid "Unknown command: %s" msgstr "" diff --git a/modules/lib-bash/activation-init.sh b/modules/lib-bash/activation-init.sh index b68b7681..54649545 100644 --- a/modules/lib-bash/activation-init.sh +++ b/modules/lib-bash/activation-init.sh @@ -1,55 +1,61 @@ -# Moves the existing profile from /nix to ~ 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`. +# Moves the existing profile from /nix or $XDG_STATE_HOME/home-manager to +# $XDG_STATE_HOME/nix to match changed behavior in Nix 2.14. See +# https://github.com/NixOS/nix/pull/5226. function migrateProfile() { declare -r stateHome="${XDG_STATE_HOME:-$HOME/.local/state}" + declare -r userNixStateDir="$stateHome/nix" declare -r hmStateDir="$stateHome/home-manager" - declare -r nixStateDir="${NIX_STATE_DIR:-/nix/var/nix}" - declare -r newProfilesDir="$hmStateDir/profiles" - declare -r oldProfilesDir="$nixStateDir/profiles/per-user/$USER" + declare -r globalNixStateDir="${NIX_STATE_DIR:-/nix/var/nix}" + declare -r globalProfilesDir="$globalNixStateDir/profiles/per-user/$USER" - if [[ ! -d $newProfilesDir ]]; then - _i 'Migrating profiles from %s to %s' "$oldProfilesDir" "$newProfilesDir" - mkdir -p "$newProfilesDir" - for p in "$oldProfilesDir"/home-manager-*; do - declare -r name="${p##*/}" - nix-store --realise "$p" --add-root "$newProfilesDir/$name" > /dev/null - done - cp -P "$oldProfilesDir/home-manager" "$newProfilesDir" + if [[ -e $globalProfilesDir/home-manager ]]; then + declare -r oldProfilesDir="$globalProfilesDir" + elif [[ -e $hmStateDir/profiles/home-manager ]]; then + declare -r oldProfilesDir="$hmStateDir/profiles" 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() { - 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 hmStateDir="$stateHome/home-manager" - declare -r hmGcrootsDir="$hmStateDir/gcroots" + declare -r userNixStateDir="$stateHome/nix" + declare -r hmGcrootsDir="$stateHome/home-manager/gcroots" - # If the global profiles path exists or we can create it, then place the HM - # profile there. Otherwise place it in the HM data directory. We prefer to - # use the global location since it makes it visible to - # `nix-collect-garbage`. - # - # In the future we may perform a one-shot migration to the new location. + declare -r globalNixStateDir="${NIX_STATE_DIR:-/nix/var/nix}" + declare -r globalProfilesDir="$globalNixStateDir/profiles/per-user/$USER" + declare -r globalGcrootsDir="$globalNixStateDir/gcroots/per-user/$USER" + + # If the user Nix profiles path exists, then place the HM profile there. + # Otherwise, if the global Nix per-user state directory exists then use + # that. If neither exists, then we give up. # # shellcheck disable=2174 - if [[ -d "$globalProfilesDir" ]] || mkdir -m 0755 -p "$globalProfilesDir" 2>/dev/null; then - declare -r hmProfilesDir="$globalProfilesDir" + if [[ -d $userNixStateDir/profiles ]]; then + declare -r profilesDir="$userNixStateDir/profiles" + elif [[ -d $globalProfilesDir ]]; then + declare -r profilesDir="$globalProfilesDir" else - declare -r hmProfilesDir="$hmStateDir/profiles" - mkdir -m 0755 -p "$hmProfilesDir" + _iError 'Could not find suitable profile directory, tried %s and %s' \ + "$userNixStateDir/profiles" "$globalProfilesDir" >&2 + exit 1 fi - declare -gr genProfilePath="$hmProfilesDir/home-manager" + declare -gr genProfilePath="$profilesDir/home-manager" declare -gr newGenPath="@GENERATION_DIR@"; declare -gr newGenGcPath="$hmGcrootsDir/current-home" declare -gr legacyGenGcPath="$globalGcrootsDir/current-home" @@ -77,7 +83,7 @@ function setupVars() { || ! -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!' \ "${oldGenNum:-}" "${oldGenPath:-}" \ - "$hmProfilesDir" "$hmGcrootsDir" + "$profilesDir" "$hmGcrootsDir" exit 1 fi } @@ -99,6 +105,7 @@ _i "Starting Home Manager activation" $VERBOSE_RUN _i "Sanity checking Nix" nix-build --expr '{}' --no-out-link +migrateProfile setupVars if [[ -v DRY_RUN ]] ; then @@ -109,7 +116,6 @@ else $VERBOSE_RUN _i "This is a live run" export DRY_RUN_CMD="" export DRY_RUN_NULL=/dev/null - fi if [[ -v VERBOSE ]]; then diff --git a/modules/po/hm-modules.pot b/modules/po/hm-modules.pot index 79687ded..a2b65875 100644 --- a/modules/po/hm-modules.pot +++ b/modules/po/hm-modules.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: Home Manager Modules\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" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -53,15 +53,19 @@ msgstr "" msgid "Activating %s" msgstr "" -#: modules/lib-bash/activation-init.sh:16 -msgid "Migrating profiles from %s to %s" +#: modules/lib-bash/activation-init.sh:22 +msgid "Migrating profile from %s to %s" 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" msgstr "" -#: modules/lib-bash/activation-init.sh:78 +#: modules/lib-bash/activation-init.sh:84 msgid "" "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" @@ -77,26 +81,26 @@ msgid "" "and trying home-manager switch again. Good luck!" msgstr "" -#: modules/lib-bash/activation-init.sh:95 +#: modules/lib-bash/activation-init.sh:101 msgid "Starting Home Manager activation" msgstr "" -#: modules/lib-bash/activation-init.sh:99 +#: modules/lib-bash/activation-init.sh:105 msgid "Sanity checking Nix" msgstr "" -#: modules/lib-bash/activation-init.sh:105 +#: modules/lib-bash/activation-init.sh:112 msgid "This is a dry run" msgstr "" -#: modules/lib-bash/activation-init.sh:109 +#: modules/lib-bash/activation-init.sh:116 msgid "This is a live run" msgstr "" -#: modules/lib-bash/activation-init.sh:116 +#: modules/lib-bash/activation-init.sh:122 msgid "Using Nix version: %s" msgstr "" -#: modules/lib-bash/activation-init.sh:119 +#: modules/lib-bash/activation-init.sh:125 msgid "Activation variables:" msgstr ""