Skip to content

Commit

Permalink
TEMP
Browse files Browse the repository at this point in the history
  • Loading branch information
Ericson2314 committed May 16, 2023
1 parent a4a4111 commit adf8f48
Show file tree
Hide file tree
Showing 16 changed files with 326 additions and 80 deletions.
22 changes: 17 additions & 5 deletions doc/manual/src/command-ref/files/channels.md
Original file line number Diff line number Diff line change
@@ -1,13 +1,25 @@
## Channels

A directory containing symlinks to Nix channels, managed by [`nix-channel`]:
A directory containing symlinks to Nix channels, managed by [`nix-channel`].

- `$XDG_STATE_HOME/nix/profiles/channels` for regular users
- `$NIX_STATE_DIR/profiles/per-user/root/channels` for `root`

[`nix-channel`] uses a [profile](@docroot@/command-ref/files/profiles.md) to store channels.
The channels directory is a [profile](@docroot@/command-ref/files/profiles.md), so as to allow easy management of multiple versions and switching between them.
This profile contains symlinks to the contents of those channels.

### User-specific and global channels

Channels are managed either for a specific user, or for all users globally on the system to share.
This matches the [user-specific vs global conventions](@docroot@/command-ref/files/profiles.md#user-specific-and-global-profiles) of profiles themselves.

- [User-specific channels]{#user-channels} are stored in:
```
$XDG_STATE_HOME/nix/profiles/channels
```

- [Global channels]{#global-channels} are stored in
```
$NIX_STATE_DIR/profiles/per-user/root/channels
```

## Subscribed channels

The list of subscribed channels is stored in
Expand Down
4 changes: 2 additions & 2 deletions doc/manual/src/command-ref/files/default-nix-expression.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,8 @@ A symlink that ensures that [`nix-env`] can find your channels:

This symlink points to:

- `$XDG_STATE_HOME/profiles/channels` for regular users
- `$NIX_STATE_DIR/profiles/per-user/root/channels` for `root`
- The [user-specific channels](@docroot@/command-ref/files/profiles.md#user-channels) (`$XDG_STATE_HOME/profiles/channels`) for regular users
- The [global channels](@docroot@/command-ref/files/profiles.md#global-channels) (`$NIX_STATE_DIR/profiles/per-user/root/channels`) for `root`

In a multi-user installation, you may also have `~/.nix-defexpr/channels_root`, which links to the channels of the root user.[`nix-env`]: ../nix-env.md

Expand Down
33 changes: 27 additions & 6 deletions doc/manual/src/command-ref/files/profiles.md
Original file line number Diff line number Diff line change
@@ -1,11 +1,32 @@
## Profiles

A directory that contains links to profiles managed by [`nix-env`] and [`nix profile`]:
A directory that contains links to profiles managed by [`nix-env`] and [`nix profile`].

- `$XDG_STATE_HOME/nix/profiles` for regular users
- `$NIX_STATE_DIR/profiles/per-user/root` if the user is `root`
### [User-specific and global profiles]{#user-specific-and-global-profiles}

A profile is a directory of symlinks to files in the Nix store.
Profiles can be placed in any directory, but by default, different locations are used depending on whether the profile is intended to be used by a single user, or shared globally by all users.

- The default directory for user-specific profiles is:
```
$XDG_STATE_HOME/nix/profiles
```

Within it, the [default user profile]{#default-user-profile} is:
```
$XDG_STATE_HOME/nix/profiles/profile
```

- The default directory for global profiles is
```
$NIX_STATE_DIR/profiles
```

Within it, the [default global profile]{#default-global-profile} is
```
$NIX_STATE_DIR/profiles/default
```

Nix command will default to the default user profile for regular users, and the default global profiles for root, but often provide flags to override this behavior.

### Filesystem layout

Expand Down Expand Up @@ -63,8 +84,8 @@ A symbolic link to the user's current profile:

By default, this symlink points to:

- `$XDG_STATE_HOME/nix/profiles/profile` for regular users
- `$NIX_STATE_DIR/profiles/per-user/root/profile` for `root`
- The [default user profile](#default-user-profile) (`$XDG_STATE_HOME/nix/profiles/profile`) for regular users
- The [default global profile](#default-global-profile) (`$NIX_STATE_DIR/profiles/per-user/root/profile`) for `root`

The `PATH` environment variable should include `/bin` subdirectory of the profile link (e.g. `~/.nix-profile/bin`) for the user environment to be visible to the user.
The [installer](@docroot@/installation/installing-binary.md) sets this up by default, unless you enable [`use-xdg-base-directories`].
Expand Down
8 changes: 8 additions & 0 deletions doc/manual/src/command-ref/nix-channel.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,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](@docroot@/command-ref/files/channels.md#global-channels), i.e. the channels shared by all users.

- `--user`\
Operate on the [user channels](@docroot@/command-ref/files/channels.md#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
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 user profile](@docroot@/command-ref/files/profiles.md#default-user-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](@docroot@/command-ref/files/profiles.md#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
13 changes: 13 additions & 0 deletions src/libexpr/def-expr.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
#include "def-expr.hh"
#include "globals.hh"

namespace nix {

Path getNixDefExpr()
{
return settings.useXDGBaseDirectories ?
getStateDir() + "/nix/defexpr"
: getHome() + "/.nix-defexpr";
}

}
13 changes: 13 additions & 0 deletions src/libexpr/def-expr.hh
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
#pragma once
///@file

#include "types.hh"

namespace nix {

/**
* Conventionally part of the default nix path in impure mode.
*/
Path getNixDefExpr();

}
8 changes: 5 additions & 3 deletions src/libexpr/eval.cc
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@
#include "function-trace.hh"
#include "profiles.hh"
#include "print.hh"
#include "profiles/channels.hh"
#include "def-expr.hh"

#include <algorithm>
#include <chrono>
Expand Down Expand Up @@ -2629,9 +2631,9 @@ 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(getNixDefExpr() + "/channels");
add(globalChannelsDir() + "/nixpkgs", "nixpkgs");
add(globalChannelsDir());
}

return res;
Expand Down
96 changes: 76 additions & 20 deletions src/libstore/profiles.cc
Original file line number Diff line number Diff line change
Expand Up @@ -280,50 +280,106 @@ 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 getDefaultGlobalProfile()
{
return globalProfilesDir() + "/default";
}

Path getDefaultProfile()
DefaultProfileKind defaultDefaultProfileKind()
{
Path profileLink = settings.useXDGBaseDirectories ? createNixStateDir() + "/profile" : getHome() + "/.nix-profile";
return getuid() == 0
? DefaultProfileKind::Global
: DefaultProfileKind::User;
}

Path defaultProfileLink()
{
return settings.useXDGBaseDirectories ? createNixStateDir() + "/profile" : getHome() + "/.nix-profile";
}

std::optional<Path> tryGetDefaultProfile()
{
Path profileLink = defaultProfileLink();
if (pathExists(profileLink))
return absPath(readLink(profileLink), dirOf(profileLink));
else
return std::nullopt;
}

Path getDefaultProfile(DefaultProfileKind profileKind)
{
Path profileLink = defaultProfileLink();
try {
auto profile = profilesDir() + "/profile";
if (!pathExists(profileLink)) {
Path profile;
switch (profileKind) {
case DefaultProfileKind::Global:
profile = getDefaultGlobalProfile();
break;
case DefaultProfileKind::User:
profile = getDefaultUserProfile();
break;
default:
assert(false);
}
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";
}

}
Loading

0 comments on commit adf8f48

Please sign in to comment.