From fb67c1a1fb5eba91abe3ab411a93cb49960454cf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Th=C3=A9ophane=20Hufschmitt?= Date: Tue, 21 Mar 2023 13:37:19 +0100 Subject: [PATCH] Factor out the generation of the profile/channel directory Make sure that all the code paths use the same one, and that the backwards-compatibility measures are probably in place when needed --- src/libexpr/eval.cc | 5 +++-- src/libstore/profiles.cc | 30 +++++++++++++++++++++++++----- src/libstore/profiles.hh | 9 +++++++++ src/nix-channel/nix-channel.cc | 7 +------ src/nix-env/nix-env.cc | 4 ++-- 5 files changed, 40 insertions(+), 15 deletions(-) diff --git a/src/libexpr/eval.cc b/src/libexpr/eval.cc index 2721b6733..584bbc879 100644 --- a/src/libexpr/eval.cc +++ b/src/libexpr/eval.cc @@ -8,6 +8,7 @@ #include "eval-inline.hh" #include "filetransfer.hh" #include "function-trace.hh" +#include "profiles.hh" #include #include @@ -2491,8 +2492,8 @@ Strings EvalSettings::getDefaultNixPath() if (!evalSettings.restrictEval && !evalSettings.pureEval) { add(settings.useXDGBaseDirectories ? getStateDir() + "/nix/defexpr/channels" : getHome() + "/.nix-defexpr/channels"); - add(settings.nixStateDir + "/profiles/per-user/root/channels/nixpkgs", "nixpkgs"); - add(settings.nixStateDir + "/profiles/per-user/root/channels"); + add(rootChannelsDir() + "/nixpkgs", "nixpkgs"); + add(rootChannelsDir()); } return res; diff --git a/src/libstore/profiles.cc b/src/libstore/profiles.cc index 179161ff7..ba5c8583f 100644 --- a/src/libstore/profiles.cc +++ b/src/libstore/profiles.cc @@ -282,28 +282,48 @@ std::string optimisticLockProfile(const Path & profile) Path profilesDir() { - auto profileRoot = createNixStateDir() + "/profiles"; + auto profileRoot = + (getuid() == 0) + ? rootProfilesDir() + : createNixStateDir() + "/profiles"; createDirs(profileRoot); return profileRoot; } +Path rootProfilesDir() +{ + return settings.nixStateDir + "/profiles/per-user/root"; +} + Path getDefaultProfile() { Path profileLink = settings.useXDGBaseDirectories ? createNixStateDir() + "/profile" : getHome() + "/.nix-profile"; try { - auto profile = - getuid() == 0 - ? settings.nixStateDir + "/profiles/default" - : profilesDir() + "/profile"; + auto profile = profilesDir() + "/profile"; if (!pathExists(profileLink)) { replaceSymlink(profile, profileLink); } + // Backwards compatibiliy measure: Make root's profile available as + // `.../default` as it's what NixOS and most of the init scripts expect + Path globalProfileLink = settings.nixStateDir + "/profiles/default"; + if (getuid() == 0 && !pathExists(globalProfileLink)) { + replaceSymlink(profile, globalProfileLink); + } return absPath(readLink(profileLink), dirOf(profileLink)); } catch (Error &) { return profileLink; } } +Path defaultChannelsDir() +{ + return profilesDir() + "/channels"; +} + +Path rootChannelsDir() +{ + return rootProfilesDir() + "/channels"; +} } diff --git a/src/libstore/profiles.hh b/src/libstore/profiles.hh index fbf95b850..9d5d4779c 100644 --- a/src/libstore/profiles.hh +++ b/src/libstore/profiles.hh @@ -72,6 +72,15 @@ std::string optimisticLockProfile(const Path & profile); profiles. */ Path profilesDir(); +/* Returns the path to the profile directory for root (but doesn't try creating it) */ +Path rootProfilesDir(); + +/* Creates and returns the path to the file used for storing the users's channels */ +Path defaultChannelsDir(); + +/* Returns the path to the channel directory for root (but doesn't try creating it) */ +Path rootChannelsDir(); + /* Resolve the default profile (~/.nix-profile by default, $XDG_STATE_HOME/ nix/profile if XDG Base Directory Support is enabled), and create if doesn't exist */ diff --git a/src/nix-channel/nix-channel.cc b/src/nix-channel/nix-channel.cc index a79354404..740737ffe 100755 --- a/src/nix-channel/nix-channel.cc +++ b/src/nix-channel/nix-channel.cc @@ -168,12 +168,7 @@ static int main_nix_channel(int argc, char ** argv) nixDefExpr = settings.useXDGBaseDirectories ? createNixStateDir() + "/defexpr" : home + "/.nix-defexpr"; // Figure out the name of the channels profile. - // For backwards-compatibility, install the root channels under - // a custom location, as these are also used as "global" channeles, and - // their location is hardcoded in a number of places. - profile = getuid() == 0 - ? settings.nixStateDir + "/profiles/per-user/root/channels" - : profilesDir() + "/channels"; + profile = profilesDir() + "/channels"; createDirs(dirOf(profile)); enum { diff --git a/src/nix-env/nix-env.cc b/src/nix-env/nix-env.cc index 3a012638b..aa7ada37d 100644 --- a/src/nix-env/nix-env.cc +++ b/src/nix-env/nix-env.cc @@ -1403,11 +1403,11 @@ static int main_nix_env(int argc, char * * argv) try { createDirs(globals.instSource.nixExprPath); replaceSymlink( - fmt("%s/profiles/per-user/%s/channels", settings.nixStateDir, getUserName()), + defaultChannelsDir(), globals.instSource.nixExprPath + "/channels"); if (getuid() != 0) replaceSymlink( - fmt("%s/profiles/per-user/root/channels", settings.nixStateDir), + rootChannelsDir(), globals.instSource.nixExprPath + "/channels_root"); } catch (Error &) { } }