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
This commit is contained in:
Théophane Hufschmitt 2023-03-21 13:37:19 +01:00
parent 82bd9535dd
commit fb67c1a1fb
5 changed files with 40 additions and 15 deletions

View file

@ -8,6 +8,7 @@
#include "eval-inline.hh" #include "eval-inline.hh"
#include "filetransfer.hh" #include "filetransfer.hh"
#include "function-trace.hh" #include "function-trace.hh"
#include "profiles.hh"
#include <algorithm> #include <algorithm>
#include <chrono> #include <chrono>
@ -2491,8 +2492,8 @@ Strings EvalSettings::getDefaultNixPath()
if (!evalSettings.restrictEval && !evalSettings.pureEval) { if (!evalSettings.restrictEval && !evalSettings.pureEval) {
add(settings.useXDGBaseDirectories ? getStateDir() + "/nix/defexpr/channels" : getHome() + "/.nix-defexpr/channels"); add(settings.useXDGBaseDirectories ? getStateDir() + "/nix/defexpr/channels" : getHome() + "/.nix-defexpr/channels");
add(settings.nixStateDir + "/profiles/per-user/root/channels/nixpkgs", "nixpkgs"); add(rootChannelsDir() + "/nixpkgs", "nixpkgs");
add(settings.nixStateDir + "/profiles/per-user/root/channels"); add(rootChannelsDir());
} }
return res; return res;

View file

@ -282,28 +282,48 @@ std::string optimisticLockProfile(const Path & profile)
Path profilesDir() Path profilesDir()
{ {
auto profileRoot = createNixStateDir() + "/profiles"; auto profileRoot =
(getuid() == 0)
? rootProfilesDir()
: createNixStateDir() + "/profiles";
createDirs(profileRoot); createDirs(profileRoot);
return profileRoot; return profileRoot;
} }
Path rootProfilesDir()
{
return settings.nixStateDir + "/profiles/per-user/root";
}
Path getDefaultProfile() Path getDefaultProfile()
{ {
Path profileLink = settings.useXDGBaseDirectories ? createNixStateDir() + "/profile" : getHome() + "/.nix-profile"; Path profileLink = settings.useXDGBaseDirectories ? createNixStateDir() + "/profile" : getHome() + "/.nix-profile";
try { try {
auto profile = auto profile = profilesDir() + "/profile";
getuid() == 0
? settings.nixStateDir + "/profiles/default"
: profilesDir() + "/profile";
if (!pathExists(profileLink)) { if (!pathExists(profileLink)) {
replaceSymlink(profile, 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)); return absPath(readLink(profileLink), dirOf(profileLink));
} catch (Error &) { } catch (Error &) {
return profileLink; return profileLink;
} }
} }
Path defaultChannelsDir()
{
return profilesDir() + "/channels";
}
Path rootChannelsDir()
{
return rootProfilesDir() + "/channels";
}
} }

View file

@ -72,6 +72,15 @@ std::string optimisticLockProfile(const Path & profile);
profiles. */ profiles. */
Path profilesDir(); 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/ /* 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 nix/profile if XDG Base Directory Support is enabled), and create if doesn't
exist */ exist */

View file

@ -168,12 +168,7 @@ static int main_nix_channel(int argc, char ** argv)
nixDefExpr = settings.useXDGBaseDirectories ? createNixStateDir() + "/defexpr" : home + "/.nix-defexpr"; nixDefExpr = settings.useXDGBaseDirectories ? createNixStateDir() + "/defexpr" : home + "/.nix-defexpr";
// Figure out the name of the channels profile. // Figure out the name of the channels profile.
// For backwards-compatibility, install the root channels under profile = profilesDir() + "/channels";
// 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";
createDirs(dirOf(profile)); createDirs(dirOf(profile));
enum { enum {

View file

@ -1403,11 +1403,11 @@ static int main_nix_env(int argc, char * * argv)
try { try {
createDirs(globals.instSource.nixExprPath); createDirs(globals.instSource.nixExprPath);
replaceSymlink( replaceSymlink(
fmt("%s/profiles/per-user/%s/channels", settings.nixStateDir, getUserName()), defaultChannelsDir(),
globals.instSource.nixExprPath + "/channels"); globals.instSource.nixExprPath + "/channels");
if (getuid() != 0) if (getuid() != 0)
replaceSymlink( replaceSymlink(
fmt("%s/profiles/per-user/root/channels", settings.nixStateDir), rootChannelsDir(),
globals.instSource.nixExprPath + "/channels_root"); globals.instSource.nixExprPath + "/channels_root");
} catch (Error &) { } } catch (Error &) { }
} }