mirror of
https://github.com/privatevoid-net/nix-super.git
synced 2024-11-10 00:08:07 +02:00
Merge branch 'master' into overlayfs-store
This commit is contained in:
commit
21b9e15d25
21 changed files with 366 additions and 246 deletions
|
@ -5,7 +5,14 @@ AC_CONFIG_AUX_DIR(config)
|
||||||
|
|
||||||
AC_PROG_SED
|
AC_PROG_SED
|
||||||
|
|
||||||
# Construct a Nix system name (like "i686-linux").
|
# Construct a Nix system name (like "i686-linux"):
|
||||||
|
# https://www.gnu.org/software/autoconf/manual/html_node/Canonicalizing.html#index-AC_005fCANONICAL_005fHOST-1
|
||||||
|
# The inital value is produced by the `config/config.guess` script:
|
||||||
|
# upstream: https://git.savannah.gnu.org/cgit/config.git/tree/config.guess
|
||||||
|
# It has the following form, which is not documented anywhere:
|
||||||
|
# <cpu>-<vendor>-<os>[<version>][-<abi>]
|
||||||
|
# If `./configure` is passed any of the `--host`, `--build`, `--target` options, the value comes from `config/config.sub` instead:
|
||||||
|
# upstream: https://git.savannah.gnu.org/cgit/config.git/tree/config.sub
|
||||||
AC_CANONICAL_HOST
|
AC_CANONICAL_HOST
|
||||||
AC_MSG_CHECKING([for the canonical Nix system name])
|
AC_MSG_CHECKING([for the canonical Nix system name])
|
||||||
|
|
||||||
|
|
|
@ -281,7 +281,7 @@ const redirects = {
|
||||||
"chap-introduction": "introduction.html",
|
"chap-introduction": "introduction.html",
|
||||||
"ch-basic-package-mgmt": "package-management/basic-package-mgmt.html",
|
"ch-basic-package-mgmt": "package-management/basic-package-mgmt.html",
|
||||||
"ssec-binary-cache-substituter": "package-management/binary-cache-substituter.html",
|
"ssec-binary-cache-substituter": "package-management/binary-cache-substituter.html",
|
||||||
"sec-channels": "package-management/channels.html",
|
"sec-channels": "command-ref/nix-channel.html",
|
||||||
"ssec-copy-closure": "package-management/copy-closure.html",
|
"ssec-copy-closure": "package-management/copy-closure.html",
|
||||||
"sec-garbage-collection": "package-management/garbage-collection.html",
|
"sec-garbage-collection": "package-management/garbage-collection.html",
|
||||||
"ssec-gc-roots": "package-management/garbage-collector-roots.html",
|
"ssec-gc-roots": "package-management/garbage-collector-roots.html",
|
||||||
|
|
|
@ -21,7 +21,6 @@
|
||||||
- [Profiles](package-management/profiles.md)
|
- [Profiles](package-management/profiles.md)
|
||||||
- [Garbage Collection](package-management/garbage-collection.md)
|
- [Garbage Collection](package-management/garbage-collection.md)
|
||||||
- [Garbage Collector Roots](package-management/garbage-collector-roots.md)
|
- [Garbage Collector Roots](package-management/garbage-collector-roots.md)
|
||||||
- [Channels](package-management/channels.md)
|
|
||||||
- [Sharing Packages Between Machines](package-management/sharing-packages.md)
|
- [Sharing Packages Between Machines](package-management/sharing-packages.md)
|
||||||
- [Serving a Nix store via HTTP](package-management/binary-cache-substituter.md)
|
- [Serving a Nix store via HTTP](package-management/binary-cache-substituter.md)
|
||||||
- [Copying Closures via SSH](package-management/copy-closure.md)
|
- [Copying Closures via SSH](package-management/copy-closure.md)
|
||||||
|
|
|
@ -8,36 +8,46 @@
|
||||||
|
|
||||||
# Description
|
# Description
|
||||||
|
|
||||||
A Nix channel is a mechanism that allows you to automatically stay
|
Channels are a mechanism for referencing remote Nix expressions and conveniently retrieving their latest version.
|
||||||
up-to-date with a set of pre-built Nix expressions. A Nix channel is
|
|
||||||
just a URL that points to a place containing a set of Nix expressions.
|
|
||||||
|
|
||||||
To see the list of official NixOS channels, visit
|
The moving parts of channels are:
|
||||||
<https://nixos.org/channels>.
|
- The official channels listed at <https://nixos.org/channels>
|
||||||
|
- The user-specific list of [subscribed channels](#subscribed-channels)
|
||||||
|
- The [downloaded channel contents](#channels)
|
||||||
|
- The [Nix expression search path](@docroot@/command-ref/conf-file.md#conf-nix-path), set with the [`-I` option](#opt-i) or the [`NIX_PATH` environment variable](#env-NIX_PATH)
|
||||||
|
|
||||||
|
> **Note**
|
||||||
|
>
|
||||||
|
> The state of a subscribed channel is external to the Nix expressions relying on it.
|
||||||
|
> This may limit reproducibility.
|
||||||
|
>
|
||||||
|
> Dependencies on other Nix expressions can be declared explicitly with:
|
||||||
|
> - [`fetchurl`](@docroot@/language/builtins.md#builtins-fetchurl), [`fetchTarball`](@docroot@/language/builtins.md#builtins-fetchTarball), or [`fetchGit`](@docroot@/language/builtins.md#builtins-fetchGit) in Nix expressions
|
||||||
|
> - the [`-I` option](@docroot@/command-ref/opt-common.md#opt-I) in command line invocations
|
||||||
|
|
||||||
This command has the following operations:
|
This command has the following operations:
|
||||||
|
|
||||||
- `--add` *url* \[*name*\]\
|
- `--add` *url* \[*name*\]\
|
||||||
Adds a channel named *name* with URL *url* to the list of subscribed
|
Add a channel *name* located at *url* to the list of subscribed channels.
|
||||||
channels. If *name* is omitted, it defaults to the last component of
|
If *name* is omitted, default to the last component of *url*, with the suffixes `-stable` or `-unstable` removed.
|
||||||
*url*, with the suffixes `-stable` or `-unstable` removed.
|
|
||||||
|
> **Note**
|
||||||
|
>
|
||||||
|
> `--add` does not automatically perform an update.
|
||||||
|
> Use `--update` explicitly.
|
||||||
|
|
||||||
A channel URL must point to a directory containing a file `nixexprs.tar.gz`.
|
A channel URL must point to a directory containing a file `nixexprs.tar.gz`.
|
||||||
At the top level, that tarball must contain a single directory with a `default.nix` file that serves as the channel’s entry point.
|
At the top level, that tarball must contain a single directory with a `default.nix` file that serves as the channel’s entry point.
|
||||||
|
|
||||||
- `--remove` *name*\
|
- `--remove` *name*\
|
||||||
Removes the channel named *name* from the list of subscribed
|
Remove the channel *name* from the list of subscribed channels.
|
||||||
channels.
|
|
||||||
|
|
||||||
- `--list`\
|
- `--list`\
|
||||||
Prints the names and URLs of all subscribed channels on standard
|
Print the names and URLs of all subscribed channels on standard output.
|
||||||
output.
|
|
||||||
|
|
||||||
- `--update` \[*names*…\]\
|
- `--update` \[*names*…\]\
|
||||||
Downloads the Nix expressions of all subscribed channels (or only
|
Download the Nix expressions of subscribed channels and create a new generation.
|
||||||
those included in *names* if specified) and makes them the default
|
Update all channels if none is specified, and only those included in *names* otherwise.
|
||||||
for `nix-env` operations (by symlinking them from the directory
|
|
||||||
`~/.nix-defexpr`).
|
|
||||||
|
|
||||||
- `--list-generations`\
|
- `--list-generations`\
|
||||||
Prints a list of all the current existing generations for the
|
Prints a list of all the current existing generations for the
|
||||||
|
@ -49,13 +59,8 @@ This command has the following operations:
|
||||||
```
|
```
|
||||||
|
|
||||||
- `--rollback` \[*generation*\]\
|
- `--rollback` \[*generation*\]\
|
||||||
Reverts the previous call to `nix-channel
|
Revert channels to the state before the last call to `nix-channel --update`.
|
||||||
--update`. Optionally, you can specify a specific channel generation
|
Optionally, you can specify a specific channel *generation* number to restore.
|
||||||
number to restore.
|
|
||||||
|
|
||||||
Note that `--add` does not automatically perform an update.
|
|
||||||
|
|
||||||
The list of subscribed channels is stored in `~/.nix-channels`.
|
|
||||||
|
|
||||||
{{#include ./opt-common.md}}
|
{{#include ./opt-common.md}}
|
||||||
|
|
||||||
|
@ -69,23 +74,33 @@ The list of subscribed channels is stored in `~/.nix-channels`.
|
||||||
|
|
||||||
# Examples
|
# Examples
|
||||||
|
|
||||||
To subscribe to the Nixpkgs channel and install the GNU Hello package:
|
Subscribe to the Nixpkgs channel and run `hello` from the GNU Hello package:
|
||||||
|
|
||||||
```console
|
```console
|
||||||
$ nix-channel --add https://nixos.org/channels/nixpkgs-unstable
|
$ nix-channel --add https://nixos.org/channels/nixpkgs-unstable
|
||||||
|
$ nix-channel --list
|
||||||
|
nixpkgs https://nixos.org/channels/nixpkgs
|
||||||
$ nix-channel --update
|
$ nix-channel --update
|
||||||
$ nix-env --install --attr nixpkgs.hello
|
$ nix-shell -p hello --run hello
|
||||||
|
hello
|
||||||
```
|
```
|
||||||
|
|
||||||
You can revert channel updates using `--rollback`:
|
Revert channel updates using `--rollback`:
|
||||||
|
|
||||||
```console
|
```console
|
||||||
$ nix-instantiate --eval --expr '(import <nixpkgs> {}).lib.version'
|
$ nix-instantiate --eval '<nixpkgs>' --attr lib.version
|
||||||
"14.04.527.0e935f1"
|
"22.11pre296212.530a53dcbc9"
|
||||||
|
|
||||||
$ nix-channel --rollback
|
$ nix-channel --rollback
|
||||||
switching from generation 483 to 482
|
switching from generation 483 to 482
|
||||||
|
|
||||||
$ nix-instantiate --eval --expr '(import <nixpkgs> {}).lib.version'
|
$ nix-instantiate --eval '<nixpkgs>' --attr lib.version
|
||||||
"14.04.526.dbadfad"
|
"22.11pre281526.d0419badfad"
|
||||||
|
```
|
||||||
|
|
||||||
|
Remove a channel:
|
||||||
|
|
||||||
|
```console
|
||||||
|
$ nix-channel --remove nixpkgs
|
||||||
|
$ nix-channel --list
|
||||||
```
|
```
|
||||||
|
|
|
@ -110,41 +110,72 @@ You can also build Nix for one of the [supported platforms](#platforms).
|
||||||
|
|
||||||
## Platforms
|
## Platforms
|
||||||
|
|
||||||
As specified in [`flake.nix`], Nix can be built for various platforms:
|
Nix can be built for various platforms, as specified in [`flake.nix`]:
|
||||||
|
|
||||||
- `aarch64-linux`
|
|
||||||
- `i686-linux`
|
|
||||||
- `x86_64-darwin`
|
|
||||||
- `x86_64-linux`
|
|
||||||
|
|
||||||
[`flake.nix`]: https://github.com/nixos/nix/blob/master/flake.nix
|
[`flake.nix`]: https://github.com/nixos/nix/blob/master/flake.nix
|
||||||
|
|
||||||
|
- `x86_64-linux`
|
||||||
|
- `x86_64-darwin`
|
||||||
|
- `i686-linux`
|
||||||
|
- `aarch64-linux`
|
||||||
|
- `aarch64-darwin`
|
||||||
|
- `armv6l-linux`
|
||||||
|
- `armv7l-linux`
|
||||||
|
|
||||||
In order to build Nix for a different platform than the one you're currently
|
In order to build Nix for a different platform than the one you're currently
|
||||||
on, you need to have some way for your system Nix to build code for that
|
on, you need a way for your current Nix installation to build code for that
|
||||||
platform. Common solutions include [remote builders] and [binfmt emulation]
|
platform. Common solutions include [remote builders] and [binary format emulation]
|
||||||
(only supported on NixOS).
|
(only supported on NixOS).
|
||||||
|
|
||||||
[remote builders]: ../advanced-topics/distributed-builds.md
|
[remote builders]: ../advanced-topics/distributed-builds.md
|
||||||
[binfmt emulation]: https://nixos.org/manual/nixos/stable/options.html#opt-boot.binfmt.emulatedSystems
|
[binfmt emulation]: https://nixos.org/manual/nixos/stable/options.html#opt-boot.binfmt.emulatedSystems
|
||||||
|
|
||||||
These solutions let Nix perform builds as if you're on the native platform, so
|
Given such a setup, executing the build only requires selecting the respective attribute.
|
||||||
executing the build is as simple as
|
For example, to compile for `aarch64-linux`:
|
||||||
|
|
||||||
```console
|
|
||||||
$ nix build .#packages.aarch64-linux.default
|
|
||||||
```
|
|
||||||
|
|
||||||
for flake-enabled Nix, or
|
|
||||||
|
|
||||||
```console
|
```console
|
||||||
$ nix-build --attr packages.aarch64-linux.default
|
$ nix-build --attr packages.aarch64-linux.default
|
||||||
```
|
```
|
||||||
|
|
||||||
for classic Nix.
|
or for Nix with the [`flakes`] and [`nix-command`] experimental features enabled:
|
||||||
|
|
||||||
You can use any of the other supported platforms in place of `aarch64-linux`.
|
```console
|
||||||
|
$ nix build .#packages.aarch64-linux.default
|
||||||
|
```
|
||||||
|
|
||||||
Cross-compiled builds are available for ARMv6 and ARMv7, and Nix on unsupported platforms can be bootstrapped by adding more `crossSystems` in `flake.nix`.
|
Cross-compiled builds are available for ARMv6 (`armv6l-linux`) and ARMv7 (`armv7l-linux`).
|
||||||
|
Add more [system types](#system-type) to `crossSystems` in `flake.nix` to bootstrap Nix on unsupported platforms.
|
||||||
|
|
||||||
|
## System type
|
||||||
|
|
||||||
|
Nix uses a string with he following format to identify the *system type* or *platform* it runs on:
|
||||||
|
|
||||||
|
```
|
||||||
|
<cpu>-<os>[-<abi>]
|
||||||
|
```
|
||||||
|
|
||||||
|
It is set when Nix is compiled for the given system, and based on the output of [`config.guess`](https://github.com/nixos/nix/blob/master/config/config.guess) ([upstream](https://git.savannah.gnu.org/cgit/config.git/tree/config.guess)):
|
||||||
|
|
||||||
|
```
|
||||||
|
<cpu>-<vendor>-<os>[<version>][-<abi>]
|
||||||
|
```
|
||||||
|
|
||||||
|
When Nix is built such that `./configure` is passed any of the `--host`, `--build`, `--target` options, the value is based on the output of [`config.sub`](https://github.com/nixos/nix/blob/master/config/config.sub) ([upstream](https://git.savannah.gnu.org/cgit/config.git/tree/config.sub)):
|
||||||
|
|
||||||
|
```
|
||||||
|
<cpu>-<vendor>[-<kernel>]-<os>
|
||||||
|
```
|
||||||
|
|
||||||
|
For historic reasons and backward-compatibility, some CPU and OS identifiers are translated from the GNU Autotools naming convention in [`configure.ac`](https://github.com/nixos/nix/blob/master/config/config.sub) as follows:
|
||||||
|
|
||||||
|
| `config.guess` | Nix |
|
||||||
|
|----------------------------|---------------------|
|
||||||
|
| `amd64` | `x86_64` |
|
||||||
|
| `i*86` | `i686` |
|
||||||
|
| `arm6` | `arm6l` |
|
||||||
|
| `arm7` | `arm7l` |
|
||||||
|
| `linux-gnu*` | `linux` |
|
||||||
|
| `linux-musl*` | `linux` |
|
||||||
|
|
||||||
## Compilation environments
|
## Compilation environments
|
||||||
|
|
||||||
|
|
|
@ -92,10 +92,10 @@ In this fragment from `all-packages.nix`,
|
||||||
```nix
|
```nix
|
||||||
graphviz = (import ../tools/graphics/graphviz) {
|
graphviz = (import ../tools/graphics/graphviz) {
|
||||||
inherit fetchurl stdenv libpng libjpeg expat x11 yacc;
|
inherit fetchurl stdenv libpng libjpeg expat x11 yacc;
|
||||||
inherit (xlibs) libXaw;
|
inherit (xorg) libXaw;
|
||||||
};
|
};
|
||||||
|
|
||||||
xlibs = {
|
xorg = {
|
||||||
libX11 = ...;
|
libX11 = ...;
|
||||||
libXaw = ...;
|
libXaw = ...;
|
||||||
...
|
...
|
||||||
|
@ -109,7 +109,7 @@ libjpg = ...;
|
||||||
the set used in the function call to the function defined in
|
the set used in the function call to the function defined in
|
||||||
`../tools/graphics/graphviz` inherits a number of variables from the
|
`../tools/graphics/graphviz` inherits a number of variables from the
|
||||||
surrounding scope (`fetchurl` ... `yacc`), but also inherits `libXaw`
|
surrounding scope (`fetchurl` ... `yacc`), but also inherits `libXaw`
|
||||||
(the X Athena Widgets) from the `xlibs` (X11 client-side libraries) set.
|
(the X Athena Widgets) from the `xorg` set.
|
||||||
|
|
||||||
Summarizing the fragment
|
Summarizing the fragment
|
||||||
|
|
||||||
|
@ -208,30 +208,41 @@ three kinds of patterns:
|
||||||
```nix
|
```nix
|
||||||
{ x, y, z, ... } @ args: z + y + x + args.a
|
{ x, y, z, ... } @ args: z + y + x + args.a
|
||||||
```
|
```
|
||||||
|
|
||||||
Here `args` is bound to the entire argument, which is further
|
Here `args` is bound to the argument *as passed*, which is further
|
||||||
matched against the pattern `{ x, y, z,
|
matched against the pattern `{ x, y, z, ... }`.
|
||||||
... }`. `@`-pattern makes mainly sense with an ellipsis(`...`) as
|
The `@`-pattern makes mainly sense with an ellipsis(`...`) as
|
||||||
you can access attribute names as `a`, using `args.a`, which was
|
you can access attribute names as `a`, using `args.a`, which was
|
||||||
given as an additional attribute to the function.
|
given as an additional attribute to the function.
|
||||||
|
|
||||||
> **Warning**
|
> **Warning**
|
||||||
>
|
>
|
||||||
> The `args@` expression is bound to the argument passed to the
|
> `args@` binds the name `args` to the attribute set that is passed to the function.
|
||||||
> function which means that attributes with defaults that aren't
|
> In particular, `args` does *not* include any default values specified with `?` in the function's set pattern.
|
||||||
> explicitly specified in the function call won't cause an
|
>
|
||||||
> evaluation error, but won't exist in `args`.
|
|
||||||
>
|
|
||||||
> For instance
|
> For instance
|
||||||
>
|
>
|
||||||
> ```nix
|
> ```nix
|
||||||
> let
|
> let
|
||||||
> function = args@{ a ? 23, ... }: args;
|
> f = args@{ a ? 23, ... }: [ a args ];
|
||||||
> in
|
> in
|
||||||
> function {}
|
> f {}
|
||||||
> ````
|
> ```
|
||||||
>
|
>
|
||||||
> will evaluate to an empty attribute set.
|
> is equivalent to
|
||||||
|
>
|
||||||
|
> ```nix
|
||||||
|
> let
|
||||||
|
> f = args @ { ... }: [ (args.a or 23) args ];
|
||||||
|
> in
|
||||||
|
> f {}
|
||||||
|
> ```
|
||||||
|
>
|
||||||
|
> and both expressions will evaluate to:
|
||||||
|
>
|
||||||
|
> ```nix
|
||||||
|
> [ 23 {} ]
|
||||||
|
> ```
|
||||||
|
|
||||||
Note that functions do not have names. If you want to give them a name,
|
Note that functions do not have names. If you want to give them a name,
|
||||||
you can bind them to an attribute, e.g.,
|
you can bind them to an attribute, e.g.,
|
||||||
|
|
|
@ -25,7 +25,7 @@ or completely new ones.)
|
||||||
|
|
||||||
You can manually download the latest version of Nixpkgs from
|
You can manually download the latest version of Nixpkgs from
|
||||||
<https://github.com/NixOS/nixpkgs>. However, it’s much more
|
<https://github.com/NixOS/nixpkgs>. However, it’s much more
|
||||||
convenient to use the Nixpkgs [*channel*](channels.md), since it makes
|
convenient to use the Nixpkgs [*channel*](../command-ref/nix-channel.md), since it makes
|
||||||
it easy to stay up to date with new versions of Nixpkgs. Nixpkgs is
|
it easy to stay up to date with new versions of Nixpkgs. Nixpkgs is
|
||||||
automatically added to your list of “subscribed” channels when you
|
automatically added to your list of “subscribed” channels when you
|
||||||
install Nix. If this is not the case for some reason, you can add it
|
install Nix. If this is not the case for some reason, you can add it
|
||||||
|
|
|
@ -1,50 +0,0 @@
|
||||||
# Channels
|
|
||||||
|
|
||||||
If you want to stay up to date with a set of packages, it’s not very
|
|
||||||
convenient to manually download the latest set of Nix expressions for
|
|
||||||
those packages and upgrade using `nix-env`. Fortunately, there’s a
|
|
||||||
better way: *Nix channels*.
|
|
||||||
|
|
||||||
A Nix channel is just a URL that points to a place that contains a set
|
|
||||||
of Nix expressions and a manifest. Using the command
|
|
||||||
[`nix-channel`](../command-ref/nix-channel.md) you can automatically
|
|
||||||
stay up to date with whatever is available at that URL.
|
|
||||||
|
|
||||||
To see the list of official NixOS channels, visit
|
|
||||||
<https://nixos.org/channels>.
|
|
||||||
|
|
||||||
You can “subscribe” to a channel using `nix-channel --add`, e.g.,
|
|
||||||
|
|
||||||
```console
|
|
||||||
$ nix-channel --add https://nixos.org/channels/nixpkgs-unstable
|
|
||||||
```
|
|
||||||
|
|
||||||
subscribes you to a channel that always contains that latest version of
|
|
||||||
the Nix Packages collection. (Subscribing really just means that the URL
|
|
||||||
is added to the file `~/.nix-channels`, where it is read by subsequent
|
|
||||||
calls to `nix-channel
|
|
||||||
--update`.) You can “unsubscribe” using `nix-channel
|
|
||||||
--remove`:
|
|
||||||
|
|
||||||
```console
|
|
||||||
$ nix-channel --remove nixpkgs
|
|
||||||
```
|
|
||||||
|
|
||||||
To obtain the latest Nix expressions available in a channel, do
|
|
||||||
|
|
||||||
```console
|
|
||||||
$ nix-channel --update
|
|
||||||
```
|
|
||||||
|
|
||||||
This downloads and unpacks the Nix expressions in every channel
|
|
||||||
(downloaded from `url/nixexprs.tar.bz2`). It also makes the union of
|
|
||||||
each channel’s Nix expressions available by default to `nix-env`
|
|
||||||
operations (via the symlink `~/.nix-defexpr/channels`). Consequently,
|
|
||||||
you can then say
|
|
||||||
|
|
||||||
```console
|
|
||||||
$ nix-env --upgrade
|
|
||||||
```
|
|
||||||
|
|
||||||
to upgrade all packages in your profile to the latest versions available
|
|
||||||
in the subscribed channels.
|
|
67
src/libcmd/built-path.cc
Normal file
67
src/libcmd/built-path.cc
Normal file
|
@ -0,0 +1,67 @@
|
||||||
|
#include "built-path.hh"
|
||||||
|
#include "derivations.hh"
|
||||||
|
#include "store-api.hh"
|
||||||
|
|
||||||
|
#include <nlohmann/json.hpp>
|
||||||
|
|
||||||
|
#include <optional>
|
||||||
|
|
||||||
|
namespace nix {
|
||||||
|
|
||||||
|
nlohmann::json BuiltPath::Built::toJSON(ref<Store> store) const {
|
||||||
|
nlohmann::json res;
|
||||||
|
res["drvPath"] = store->printStorePath(drvPath);
|
||||||
|
for (const auto& [output, path] : outputs) {
|
||||||
|
res["outputs"][output] = store->printStorePath(path);
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
StorePathSet BuiltPath::outPaths() const
|
||||||
|
{
|
||||||
|
return std::visit(
|
||||||
|
overloaded{
|
||||||
|
[](const BuiltPath::Opaque & p) { return StorePathSet{p.path}; },
|
||||||
|
[](const BuiltPath::Built & b) {
|
||||||
|
StorePathSet res;
|
||||||
|
for (auto & [_, path] : b.outputs)
|
||||||
|
res.insert(path);
|
||||||
|
return res;
|
||||||
|
},
|
||||||
|
}, raw()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
RealisedPath::Set BuiltPath::toRealisedPaths(Store & store) const
|
||||||
|
{
|
||||||
|
RealisedPath::Set res;
|
||||||
|
std::visit(
|
||||||
|
overloaded{
|
||||||
|
[&](const BuiltPath::Opaque & p) { res.insert(p.path); },
|
||||||
|
[&](const BuiltPath::Built & p) {
|
||||||
|
auto drvHashes =
|
||||||
|
staticOutputHashes(store, store.readDerivation(p.drvPath));
|
||||||
|
for (auto& [outputName, outputPath] : p.outputs) {
|
||||||
|
if (experimentalFeatureSettings.isEnabled(
|
||||||
|
Xp::CaDerivations)) {
|
||||||
|
auto drvOutput = get(drvHashes, outputName);
|
||||||
|
if (!drvOutput)
|
||||||
|
throw Error(
|
||||||
|
"the derivation '%s' has unrealised output '%s' (derived-path.cc/toRealisedPaths)",
|
||||||
|
store.printStorePath(p.drvPath), outputName);
|
||||||
|
auto thisRealisation = store.queryRealisation(
|
||||||
|
DrvOutput{*drvOutput, outputName});
|
||||||
|
assert(thisRealisation); // We’ve built it, so we must
|
||||||
|
// have the realisation
|
||||||
|
res.insert(*thisRealisation);
|
||||||
|
} else {
|
||||||
|
res.insert(outputPath);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
raw());
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
47
src/libcmd/built-path.hh
Normal file
47
src/libcmd/built-path.hh
Normal file
|
@ -0,0 +1,47 @@
|
||||||
|
#include "derived-path.hh"
|
||||||
|
|
||||||
|
namespace nix {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A built derived path with hints in the form of optional concrete output paths.
|
||||||
|
*
|
||||||
|
* See 'BuiltPath' for more an explanation.
|
||||||
|
*/
|
||||||
|
struct BuiltPathBuilt {
|
||||||
|
StorePath drvPath;
|
||||||
|
std::map<std::string, StorePath> outputs;
|
||||||
|
|
||||||
|
nlohmann::json toJSON(ref<Store> store) const;
|
||||||
|
static BuiltPathBuilt parse(const Store & store, std::string_view);
|
||||||
|
|
||||||
|
GENERATE_CMP(BuiltPathBuilt, me->drvPath, me->outputs);
|
||||||
|
};
|
||||||
|
|
||||||
|
using _BuiltPathRaw = std::variant<
|
||||||
|
DerivedPath::Opaque,
|
||||||
|
BuiltPathBuilt
|
||||||
|
>;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A built path. Similar to a DerivedPath, but enriched with the corresponding
|
||||||
|
* output path(s).
|
||||||
|
*/
|
||||||
|
struct BuiltPath : _BuiltPathRaw {
|
||||||
|
using Raw = _BuiltPathRaw;
|
||||||
|
using Raw::Raw;
|
||||||
|
|
||||||
|
using Opaque = DerivedPathOpaque;
|
||||||
|
using Built = BuiltPathBuilt;
|
||||||
|
|
||||||
|
inline const Raw & raw() const {
|
||||||
|
return static_cast<const Raw &>(*this);
|
||||||
|
}
|
||||||
|
|
||||||
|
StorePathSet outPaths() const;
|
||||||
|
RealisedPath::Set toRealisedPaths(Store & store) const;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef std::vector<BuiltPath> BuiltPaths;
|
||||||
|
|
||||||
|
}
|
|
@ -5,6 +5,7 @@
|
||||||
#include "path.hh"
|
#include "path.hh"
|
||||||
#include "outputs-spec.hh"
|
#include "outputs-spec.hh"
|
||||||
#include "derived-path.hh"
|
#include "derived-path.hh"
|
||||||
|
#include "built-path.hh"
|
||||||
#include "store-api.hh"
|
#include "store-api.hh"
|
||||||
#include "build-result.hh"
|
#include "build-result.hh"
|
||||||
|
|
||||||
|
|
|
@ -594,6 +594,10 @@ void LocalDerivationGoal::startBuilder()
|
||||||
else
|
else
|
||||||
dirsInChroot[i.substr(0, p)] = {i.substr(p + 1), optional};
|
dirsInChroot[i.substr(0, p)] = {i.substr(p + 1), optional};
|
||||||
}
|
}
|
||||||
|
if (hasPrefix(worker.store.storeDir, tmpDirInSandbox))
|
||||||
|
{
|
||||||
|
throw Error("`sandbox-build-dir` must not contain the storeDir");
|
||||||
|
}
|
||||||
dirsInChroot[tmpDirInSandbox] = tmpDir;
|
dirsInChroot[tmpDirInSandbox] = tmpDir;
|
||||||
|
|
||||||
/* Add the closure of store paths to the chroot. */
|
/* Add the closure of store paths to the chroot. */
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
#include "derived-path.hh"
|
#include "derived-path.hh"
|
||||||
#include "derivations.hh"
|
|
||||||
#include "store-api.hh"
|
#include "store-api.hh"
|
||||||
|
|
||||||
#include <nlohmann/json.hpp>
|
#include <nlohmann/json.hpp>
|
||||||
|
@ -30,30 +29,6 @@ nlohmann::json DerivedPath::Built::toJSON(ref<Store> store) const {
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
nlohmann::json BuiltPath::Built::toJSON(ref<Store> store) const {
|
|
||||||
nlohmann::json res;
|
|
||||||
res["drvPath"] = store->printStorePath(drvPath);
|
|
||||||
for (const auto& [output, path] : outputs) {
|
|
||||||
res["outputs"][output] = store->printStorePath(path);
|
|
||||||
}
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
StorePathSet BuiltPath::outPaths() const
|
|
||||||
{
|
|
||||||
return std::visit(
|
|
||||||
overloaded{
|
|
||||||
[](const BuiltPath::Opaque & p) { return StorePathSet{p.path}; },
|
|
||||||
[](const BuiltPath::Built & b) {
|
|
||||||
StorePathSet res;
|
|
||||||
for (auto & [_, path] : b.outputs)
|
|
||||||
res.insert(path);
|
|
||||||
return res;
|
|
||||||
},
|
|
||||||
}, raw()
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string DerivedPath::Opaque::to_string(const Store & store) const
|
std::string DerivedPath::Opaque::to_string(const Store & store) const
|
||||||
{
|
{
|
||||||
return store.printStorePath(path);
|
return store.printStorePath(path);
|
||||||
|
@ -121,35 +96,4 @@ DerivedPath DerivedPath::parseLegacy(const Store & store, std::string_view s)
|
||||||
return parseWith(store, s, "!");
|
return parseWith(store, s, "!");
|
||||||
}
|
}
|
||||||
|
|
||||||
RealisedPath::Set BuiltPath::toRealisedPaths(Store & store) const
|
|
||||||
{
|
|
||||||
RealisedPath::Set res;
|
|
||||||
std::visit(
|
|
||||||
overloaded{
|
|
||||||
[&](const BuiltPath::Opaque & p) { res.insert(p.path); },
|
|
||||||
[&](const BuiltPath::Built & p) {
|
|
||||||
auto drvHashes =
|
|
||||||
staticOutputHashes(store, store.readDerivation(p.drvPath));
|
|
||||||
for (auto& [outputName, outputPath] : p.outputs) {
|
|
||||||
if (experimentalFeatureSettings.isEnabled(
|
|
||||||
Xp::CaDerivations)) {
|
|
||||||
auto drvOutput = get(drvHashes, outputName);
|
|
||||||
if (!drvOutput)
|
|
||||||
throw Error(
|
|
||||||
"the derivation '%s' has unrealised output '%s' (derived-path.cc/toRealisedPaths)",
|
|
||||||
store.printStorePath(p.drvPath), outputName);
|
|
||||||
auto thisRealisation = store.queryRealisation(
|
|
||||||
DrvOutput{*drvOutput, outputName});
|
|
||||||
assert(thisRealisation); // We’ve built it, so we must
|
|
||||||
// have the realisation
|
|
||||||
res.insert(*thisRealisation);
|
|
||||||
} else {
|
|
||||||
res.insert(outputPath);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
},
|
|
||||||
raw());
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -109,47 +109,6 @@ struct DerivedPath : _DerivedPathRaw {
|
||||||
static DerivedPath parseLegacy(const Store & store, std::string_view);
|
static DerivedPath parseLegacy(const Store & store, std::string_view);
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
|
||||||
* A built derived path with hints in the form of optional concrete output paths.
|
|
||||||
*
|
|
||||||
* See 'BuiltPath' for more an explanation.
|
|
||||||
*/
|
|
||||||
struct BuiltPathBuilt {
|
|
||||||
StorePath drvPath;
|
|
||||||
std::map<std::string, StorePath> outputs;
|
|
||||||
|
|
||||||
nlohmann::json toJSON(ref<Store> store) const;
|
|
||||||
static BuiltPathBuilt parse(const Store & store, std::string_view);
|
|
||||||
|
|
||||||
GENERATE_CMP(BuiltPathBuilt, me->drvPath, me->outputs);
|
|
||||||
};
|
|
||||||
|
|
||||||
using _BuiltPathRaw = std::variant<
|
|
||||||
DerivedPath::Opaque,
|
|
||||||
BuiltPathBuilt
|
|
||||||
>;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A built path. Similar to a DerivedPath, but enriched with the corresponding
|
|
||||||
* output path(s).
|
|
||||||
*/
|
|
||||||
struct BuiltPath : _BuiltPathRaw {
|
|
||||||
using Raw = _BuiltPathRaw;
|
|
||||||
using Raw::Raw;
|
|
||||||
|
|
||||||
using Opaque = DerivedPathOpaque;
|
|
||||||
using Built = BuiltPathBuilt;
|
|
||||||
|
|
||||||
inline const Raw & raw() const {
|
|
||||||
return static_cast<const Raw &>(*this);
|
|
||||||
}
|
|
||||||
|
|
||||||
StorePathSet outPaths() const;
|
|
||||||
RealisedPath::Set toRealisedPaths(Store & store) const;
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef std::vector<DerivedPath> DerivedPaths;
|
typedef std::vector<DerivedPath> DerivedPaths;
|
||||||
typedef std::vector<BuiltPath> BuiltPaths;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -193,18 +193,24 @@ public:
|
||||||
Setting<std::string> thisSystem{
|
Setting<std::string> thisSystem{
|
||||||
this, SYSTEM, "system",
|
this, SYSTEM, "system",
|
||||||
R"(
|
R"(
|
||||||
This option specifies the canonical Nix system name of the current
|
The system type of the current Nix installation.
|
||||||
installation, such as `i686-linux` or `x86_64-darwin`. Nix can only
|
Nix will only build a given [derivation](@docroot@/language/derivations.md) locally when its `system` attribute equals any of the values specified here or in [`extra-platforms`](#conf-extra-platforms).
|
||||||
build derivations whose `system` attribute equals the value
|
|
||||||
specified here. In general, it never makes sense to modify this
|
|
||||||
value from its default, since you can use it to ‘lie’ about the
|
|
||||||
platform you are building on (e.g., perform a Mac OS build on a
|
|
||||||
Linux machine; the result would obviously be wrong). It only makes
|
|
||||||
sense if the Nix binaries can run on multiple platforms, e.g.,
|
|
||||||
‘universal binaries’ that run on `x86_64-linux` and `i686-linux`.
|
|
||||||
|
|
||||||
It defaults to the canonical Nix system name detected by `configure`
|
The default value is set when Nix itself is compiled for the system it will run on.
|
||||||
at build time.
|
The following system types are widely used, as [Nix is actively supported on these platforms](@docroot@/contributing/hacking.md#platforms):
|
||||||
|
|
||||||
|
- `x86_64-linux`
|
||||||
|
- `x86_64-darwin`
|
||||||
|
- `i686-linux`
|
||||||
|
- `aarch64-linux`
|
||||||
|
- `aarch64-darwin`
|
||||||
|
- `armv6l-linux`
|
||||||
|
- `armv7l-linux`
|
||||||
|
|
||||||
|
In general, you do not have to modify this setting.
|
||||||
|
While you can force Nix to run a Darwin-specific `builder` executable on a Linux machine, the result would obviously be wrong.
|
||||||
|
|
||||||
|
This value is available in the Nix language as [`builtins.currentSystem`](@docroot@/language/builtin-constants.md#builtins-currentSystem).
|
||||||
)"};
|
)"};
|
||||||
|
|
||||||
Setting<time_t> maxSilentTime{
|
Setting<time_t> maxSilentTime{
|
||||||
|
@ -670,18 +676,20 @@ public:
|
||||||
getDefaultExtraPlatforms(),
|
getDefaultExtraPlatforms(),
|
||||||
"extra-platforms",
|
"extra-platforms",
|
||||||
R"(
|
R"(
|
||||||
Platforms other than the native one which this machine is capable of
|
System types of executables that can be run on this machine.
|
||||||
building for. This can be useful for supporting additional
|
|
||||||
architectures on compatible machines: i686-linux can be built on
|
Nix will only build a given [derivation](@docroot@/language/derivations.md) locally when its `system` attribute equals any of the values specified here or in the [`system` option](#conf-system).
|
||||||
x86\_64-linux machines (and the default for this setting reflects
|
|
||||||
this); armv7 is backwards-compatible with armv6 and armv5tel; some
|
Setting this can be useful to build derivations locally on compatible machines:
|
||||||
aarch64 machines can also natively run 32-bit ARM code; and
|
- `i686-linux` executables can be run on `x86_64-linux` machines (set by default)
|
||||||
qemu-user may be used to support non-native platforms (though this
|
- `x86_64-darwin` executables can be run on macOS `aarch64-darwin` with Rosetta 2 (set by default where applicable)
|
||||||
may be slow and buggy). Most values for this are not enabled by
|
- `armv6` and `armv5tel` executables can be run on `armv7`
|
||||||
default because build systems will often misdetect the target
|
- some `aarch64` machines can also natively run 32-bit ARM code
|
||||||
platform and generate incompatible code, so you may wish to
|
- `qemu-user` may be used to support non-native platforms (though this
|
||||||
cross-check the results of using this option against proper
|
may be slow and buggy)
|
||||||
natively-built versions of your derivations.
|
|
||||||
|
Build systems will usually detect the target platform to be the current physical system and therefore produce machine code incompatible with what may be intended in the derivation.
|
||||||
|
You should design your derivation's `builder` accordingly and cross-check the results when using this option against natively-built versions of your derivation.
|
||||||
)", {}, false};
|
)", {}, false};
|
||||||
|
|
||||||
Setting<StringSet> systemFeatures{
|
Setting<StringSet> systemFeatures{
|
||||||
|
@ -1010,7 +1018,7 @@ public:
|
||||||
| `~/.nix-defexpr` | `$XDG_STATE_HOME/nix/defexpr` |
|
| `~/.nix-defexpr` | `$XDG_STATE_HOME/nix/defexpr` |
|
||||||
| `~/.nix-channels` | `$XDG_STATE_HOME/nix/channels` |
|
| `~/.nix-channels` | `$XDG_STATE_HOME/nix/channels` |
|
||||||
|
|
||||||
If you already have Nix installed and are using [profiles](@docroot@/package-management/profiles.md) or [channels](@docroot@/package-management/channels.md), you should migrate manually when you enable this option.
|
If you already have Nix installed and are using [profiles](@docroot@/package-management/profiles.md) or [channels](@docroot@/command-ref/nix-channel.md), you should migrate manually when you enable this option.
|
||||||
If `$XDG_STATE_HOME` is not set, use `$HOME/.local/state/nix` instead of `$XDG_STATE_HOME/nix`.
|
If `$XDG_STATE_HOME` is not set, use `$HOME/.local/state/nix` instead of `$XDG_STATE_HOME/nix`.
|
||||||
This can be achieved with the following shell commands:
|
This can be achieved with the following shell commands:
|
||||||
|
|
||||||
|
|
|
@ -42,7 +42,10 @@ void SSHMaster::addCommonSSHOpts(Strings & args)
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SSHMaster::isMasterRunning() {
|
bool SSHMaster::isMasterRunning() {
|
||||||
auto res = runProgram(RunOptions {.program = "ssh", .args = {"-O", "check", host}, .mergeStderrToStdout = true});
|
Strings args = {"-O", "check", host};
|
||||||
|
addCommonSSHOpts(args);
|
||||||
|
|
||||||
|
auto res = runProgram(RunOptions {.program = "ssh", .args = args, .mergeStderrToStdout = true});
|
||||||
return res.first == 0;
|
return res.first == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -120,7 +120,8 @@ nix_tests = \
|
||||||
path-from-hash-part.sh \
|
path-from-hash-part.sh \
|
||||||
test-libstoreconsumer.sh \
|
test-libstoreconsumer.sh \
|
||||||
toString-path.sh \
|
toString-path.sh \
|
||||||
read-only-store.sh
|
read-only-store.sh \
|
||||||
|
nested-sandboxing.sh
|
||||||
|
|
||||||
ifeq ($(HAVE_LIBCPUID), 1)
|
ifeq ($(HAVE_LIBCPUID), 1)
|
||||||
nix_tests += compute-levels.sh
|
nix_tests += compute-levels.sh
|
||||||
|
|
11
tests/nested-sandboxing.sh
Normal file
11
tests/nested-sandboxing.sh
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
source common.sh
|
||||||
|
# This test is run by `tests/nested-sandboxing/runner.nix` in an extra layer of sandboxing.
|
||||||
|
[[ -d /nix/store ]] || skipTest "running this test without Nix's deps being drawn from /nix/store is not yet supported"
|
||||||
|
|
||||||
|
requireSandboxSupport
|
||||||
|
|
||||||
|
source ./nested-sandboxing/command.sh
|
||||||
|
|
||||||
|
expectStderr 100 runNixBuild badStoreUrl 2 | grepQuiet '`sandbox-build-dir` must not contain'
|
||||||
|
|
||||||
|
runNixBuild goodStoreUrl 5
|
29
tests/nested-sandboxing/command.sh
Normal file
29
tests/nested-sandboxing/command.sh
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
export NIX_BIN_DIR=$(dirname $(type -p nix))
|
||||||
|
# TODO Get Nix and its closure more flexibly
|
||||||
|
export EXTRA_SANDBOX="/nix/store $(dirname $NIX_BIN_DIR)"
|
||||||
|
|
||||||
|
badStoreUrl () {
|
||||||
|
local altitude=$1
|
||||||
|
echo $TEST_ROOT/store-$altitude
|
||||||
|
}
|
||||||
|
|
||||||
|
goodStoreUrl () {
|
||||||
|
local altitude=$1
|
||||||
|
echo $("badStoreUrl" "$altitude")?store=/foo-$altitude
|
||||||
|
}
|
||||||
|
|
||||||
|
# The non-standard sandbox-build-dir helps ensure that we get the same behavior
|
||||||
|
# whether this test is being run in a derivation as part of the nix build or
|
||||||
|
# being manually run by a developer outside a derivation
|
||||||
|
runNixBuild () {
|
||||||
|
local storeFun=$1
|
||||||
|
local altitude=$2
|
||||||
|
nix-build \
|
||||||
|
--no-substitute --no-out-link \
|
||||||
|
--store "$("$storeFun" "$altitude")" \
|
||||||
|
--extra-sandbox-paths "$EXTRA_SANDBOX" \
|
||||||
|
./nested-sandboxing/runner.nix \
|
||||||
|
--arg altitude "$((altitude - 1))" \
|
||||||
|
--argstr storeFun "$storeFun" \
|
||||||
|
--sandbox-build-dir /build-non-standard
|
||||||
|
}
|
24
tests/nested-sandboxing/runner.nix
Normal file
24
tests/nested-sandboxing/runner.nix
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
{ altitude, storeFun }:
|
||||||
|
|
||||||
|
with import ../config.nix;
|
||||||
|
|
||||||
|
mkDerivation {
|
||||||
|
name = "nested-sandboxing";
|
||||||
|
busybox = builtins.getEnv "busybox";
|
||||||
|
EXTRA_SANDBOX = builtins.getEnv "EXTRA_SANDBOX";
|
||||||
|
buildCommand = if altitude == 0 then ''
|
||||||
|
echo Deep enough! > $out
|
||||||
|
'' else ''
|
||||||
|
cp -r ${../common} ./common
|
||||||
|
cp ${../common.sh} ./common.sh
|
||||||
|
cp ${../config.nix} ./config.nix
|
||||||
|
cp -r ${./.} ./nested-sandboxing
|
||||||
|
|
||||||
|
export PATH=${builtins.getEnv "NIX_BIN_DIR"}:$PATH
|
||||||
|
|
||||||
|
source common.sh
|
||||||
|
source ./nested-sandboxing/command.sh
|
||||||
|
|
||||||
|
runNixBuild ${storeFun} ${toString altitude} >> $out
|
||||||
|
'';
|
||||||
|
}
|
|
@ -79,6 +79,15 @@ in {
|
||||||
server.copy_from_host("key.pub", "/root/.ssh/authorized_keys")
|
server.copy_from_host("key.pub", "/root/.ssh/authorized_keys")
|
||||||
server.succeed("systemctl restart sshd")
|
server.succeed("systemctl restart sshd")
|
||||||
client.succeed(f"ssh -o StrictHostKeyChecking=no {server.name} 'echo hello world'")
|
client.succeed(f"ssh -o StrictHostKeyChecking=no {server.name} 'echo hello world'")
|
||||||
|
client.succeed(f"ssh -O check {server.name}")
|
||||||
|
client.succeed(f"ssh -O exit {server.name}")
|
||||||
|
client.fail(f"ssh -O check {server.name}")
|
||||||
|
|
||||||
|
# Check that an explicit master will work
|
||||||
|
client.succeed(f"ssh -MNfS /tmp/master {server.name}")
|
||||||
|
client.succeed(f"ssh -S /tmp/master -O check {server.name}")
|
||||||
|
client.succeed("NIX_SSHOPTS='-oControlPath=/tmp/master' nix copy --to ssh://server ${pkgA} >&2")
|
||||||
|
client.succeed(f"ssh -S /tmp/master -O exit {server.name}")
|
||||||
|
|
||||||
# Copy the closure of package B from the server to the client, using ssh-ng.
|
# Copy the closure of package B from the server to the client, using ssh-ng.
|
||||||
client.fail("nix-store --check-validity ${pkgB}")
|
client.fail("nix-store --check-validity ${pkgB}")
|
||||||
|
|
Loading…
Reference in a new issue