Skip to content

Commit

Permalink
TEMP
Browse files Browse the repository at this point in the history
  • Loading branch information
Ericson2314 committed May 10, 2023
1 parent f60b215 commit 304acaa
Show file tree
Hide file tree
Showing 11 changed files with 214 additions and 62 deletions.
10 changes: 9 additions & 1 deletion doc/manual/src/command-ref/nix-channel.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,14 @@ This command has the following operations:

Note that `--add` does not automatically perform an update.

It also has the following flags, which affect all operations:

- `--global`\
Operate on the global channels, i.e. the channels shared by all users.

- `--user`\
Operate on the user channels, i.e. the channels just for the current user.

The list of subscribed channels is stored in `~/.nix-channels`.

{{#include ./opt-common.md}}
Expand Down Expand Up @@ -86,7 +94,7 @@ $ nix-instantiate --eval -E '(import <nixpkgs> {}).lib.version'
`${XDG_STATE_HOME-$HOME/.local/state}/nix/profiles/channels`. It ensures that
`nix-env` can find your channels. In a multi-user installation, you
may also have `~/.nix-defexpr/channels_root`, which links to the
channels of the root user.
global channels.

# Channel format

Expand Down
2 changes: 1 addition & 1 deletion doc/manual/src/command-ref/nix-env.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
[`--arg` *name* *value*]
[`--argstr` *name* *value*]
[{`--file` | `-f`} *path*]
[{`--profile` | `-p`} *path*]
[{`--profile` | `-p`} *path* | `--global` | `--user`]
[`--system-filter` *system*]
[`--dry-run`]

Expand Down
10 changes: 10 additions & 0 deletions doc/manual/src/command-ref/nix-env/opt-common.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,16 @@ The following options are allowed for all `nix-env` operations, but may not alwa
sequence of user environments called *generations*, one of which is
the *current generation*.

- `--user`\
Specifies the profile as the default profile private to this user.
This is a shorthand for passing `--profile` and the path to that
default profile. This is default if the current user is not root.

- `--global`\
Specifies the profile as the default global profile shared between all
users. A shorthand instead of passing `--profile` and the path to that
default profile. This is default if the current user is root.

- `--dry-run`\
For the `--install`, `--upgrade`, `--uninstall`,
`--switch-generation`, `--delete-generations` and `--rollback`
Expand Down
19 changes: 18 additions & 1 deletion src/libcmd/command.cc
Original file line number Diff line number Diff line change
Expand Up @@ -271,7 +271,24 @@ void MixProfile::updateProfile(const BuiltPaths & buildables)

MixDefaultProfile::MixDefaultProfile()
{
profile = getDefaultProfile();

addFlag({
.longName = "user-profile",
.description = "Act on the profile for this current user",
.handler = {[this]() {
profile = getDefaultProfile(DefaultProfileKind::User);
}}
});

addFlag({
.longName = "global-profile",
.description = "Act on the global profile shared between all default users",
.handler = {[this]() {
profile = getDefaultProfile(DefaultProfileKind::Global);
}}
});

profile = getDefaultProfile(defaultDefaultProfileKind());
}

MixEnvironment::MixEnvironment() : ignoreEnvironment(false)
Expand Down
5 changes: 3 additions & 2 deletions src/libexpr/eval.cc
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
#include "function-trace.hh"
#include "profiles.hh"
#include "print.hh"
#include "profiles/channels.hh"

#include <algorithm>
#include <chrono>
Expand Down Expand Up @@ -2535,8 +2536,8 @@ Strings EvalSettings::getDefaultNixPath()

if (!evalSettings.restrictEval && !evalSettings.pureEval) {
add(settings.useXDGBaseDirectories ? getStateDir() + "/nix/defexpr/channels" : getHome() + "/.nix-defexpr/channels");
add(rootChannelsDir() + "/nixpkgs", "nixpkgs");
add(rootChannelsDir());
add(globalChannelsDir() + "/nixpkgs", "nixpkgs");
add(globalChannelsDir());
}

return res;
Expand Down
80 changes: 61 additions & 19 deletions src/libstore/profiles.cc
Original file line number Diff line number Diff line change
Expand Up @@ -280,50 +280,92 @@ std::string optimisticLockProfile(const Path & profile)
}


Path profilesDir()
Path userProfilesDir()
{
auto profileRoot =
(getuid() == 0)
? rootProfilesDir()
: createNixStateDir() + "/profiles";
auto profileRoot = createNixStateDir() + "/profiles";
createDirs(profileRoot);
return profileRoot;
}

Path rootProfilesDir()
/**
* Return the path to the global profile directory (but don't try creating it)
*
* Just used for the global profile and the global channels, but those
* go in different subdirs, so we do not expose this.
*/
static Path globalProfilesDir()
{
return settings.nixStateDir + "/profiles/per-user/root";
return settings.nixStateDir + "/profiles";
}

/**
* The other directory used for global profiles
*/
static Path perUsersRootDir()
{
return globalProfilesDir() + "/per-user/root/";
}

std::vector<Path> globalProfilesDirs()
{
return {
globalProfilesDir(),
perUsersRootDir(),
};
}

Path getDefaultUserProfile()
{
return userProfilesDir() + "/profile";
}

Path getDefaultProfile()
Path getDefaultGlobalProfile()
{
return globalProfilesDir() + "/default";
}

DefaultProfileKind defaultDefaultProfileKind()
{
return getuid() == 0
? DefaultProfileKind::Global
: DefaultProfileKind::User;
}

Path getDefaultProfile(DefaultProfileKind profileKind)
{
Path profileLink = settings.useXDGBaseDirectories ? createNixStateDir() + "/profile" : getHome() + "/.nix-profile";
try {
auto profile = profilesDir() + "/profile";
Path profile = "";
switch (profileKind) {
case DefaultProfileKind::Global:
profile = getDefaultGlobalProfile();
break;
case DefaultProfileKind::User:
profile = getDefaultUserProfile();
break;
default:
assert(false);
}
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()
Path userChannelsDir()
{
return profilesDir() + "/channels";
return userProfilesDir() + "/channels";
}

Path rootChannelsDir()
Path globalChannelsDir()
{
return rootProfilesDir() + "/channels";
/* "per-user" might seem like a weird thing to include in the path
to the "global" channels dir; it is done this way for
back-compat. */
return perUsersRootDir() + "/channels";
}

}
32 changes: 23 additions & 9 deletions src/libstore/profiles.hh
Original file line number Diff line number Diff line change
Expand Up @@ -81,28 +81,42 @@ std::string optimisticLockProfile(const Path & profile);
* Create and return the path to a directory suitable for storing the user’s
* profiles.
*/
Path profilesDir();
Path userProfilesDir();

/**
* Return the path to the profile directory for root (but don't try creating it)
* Create and return the paths to the directories use for storing the
* global profiles. There are multiple for backwards compatibility
* reasons.
*/
Path rootProfilesDir();
std::vector<Path> globalProfilesDirs();

/**
* Create and return the path to the file used for storing the users's channels
* We have two types of default profiles:
*
* - User, just for the current user (read/write).
*
* - Global, shared (read-only) by all users.
*/
Path defaultChannelsDir();
enum class DefaultProfileKind
{
User,
Global,
};

/**
* Return the path to the channel directory for root (but don't try creating it)
* Returns the default kind of default profile.
*
* For regular users, this is DefaultProfileKind::Global, but for root it is DefaultProfileKind::User.
*/
Path rootChannelsDir();
DefaultProfileKind defaultDefaultProfileKind();

/**
* 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
* and create if doesn't exist.
*
* @param kind Just used if the profile doesn't exist.
*/
Path getDefaultProfile();
Path getDefaultProfile(DefaultProfileKind kind);

}
17 changes: 17 additions & 0 deletions src/libstore/profiles/channels.hh
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
#pragma once

#include "types.hh"

namespace nix {

/**
* Create and return the path to the file used for storing the user's channels
*/
Path userChannelsDir();

/**
* Return the path to the global channel directory (but don't try creating it)
*/
Path globalChannelsDir();

}
25 changes: 21 additions & 4 deletions src/nix-channel/nix-channel.cc
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#include "profiles.hh"
#include "profiles/channels.hh"
#include "shared.hh"
#include "globals.hh"
#include "filetransfer.hh"
Expand Down Expand Up @@ -167,10 +168,6 @@ static int main_nix_channel(int argc, char ** argv)
channelsList = settings.useXDGBaseDirectories ? createNixStateDir() + "/channels" : home + "/.nix-channels";
nixDefExpr = settings.useXDGBaseDirectories ? createNixStateDir() + "/defexpr" : home + "/.nix-defexpr";

// Figure out the name of the channels profile.
profile = profilesDir() + "/channels";
createDirs(dirOf(profile));

enum {
cNone,
cAdd,
Expand All @@ -179,6 +176,9 @@ static int main_nix_channel(int argc, char ** argv)
cUpdate,
cRollback
} cmd = cNone;

DefaultProfileKind profileKind = defaultDefaultProfileKind();

std::vector<std::string> args;
parseCmdLine(argc, argv, [&](Strings::iterator & arg, const Strings::iterator & end) {
if (*arg == "--help") {
Expand All @@ -195,6 +195,10 @@ static int main_nix_channel(int argc, char ** argv)
cmd = cUpdate;
} else if (*arg == "--rollback") {
cmd = cRollback;
} else if (*arg == "--user") {
profileKind = DefaultProfileKind::User;
} else if (*arg == "--global") {
profileKind = DefaultProfileKind::Global;
} else {
if (hasPrefix(*arg, "-"))
throw UsageError("unsupported argument '%s'", *arg);
Expand All @@ -203,6 +207,19 @@ static int main_nix_channel(int argc, char ** argv)
return true;
});

// Figure out the name of the channels profile.
switch (profileKind) {
case DefaultProfileKind::User:
profile = userChannelsDir();
break;
case DefaultProfileKind::Global:
profile = globalChannelsDir();
break;
default:
assert(false);
};
createDirs(dirOf(profile));

switch (cmd) {
case cNone:
throw UsageError("no command specified");
Expand Down
7 changes: 6 additions & 1 deletion src/nix-collect-garbage/nix-collect-garbage.cc
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,12 @@ static int main_nix_collect_garbage(int argc, char * * argv)
return true;
});

if (removeOld) removeOldGenerations(profilesDir());
if (removeOld) {
removeOldGenerations(userProfilesDir());
if (getuid() == 0)
for (auto && dir : globalProfilesDirs())
removeOldGenerations(dir);
}

// Run the actual garbage collector.
if (!dryRun) {
Expand Down
Loading

0 comments on commit 304acaa

Please sign in to comment.