mirror of
https://github.com/privatevoid-net/nix-super.git
synced 2024-11-25 23:36:16 +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
|
||||
|
||||
# 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_MSG_CHECKING([for the canonical Nix system name])
|
||||
|
||||
|
|
|
@ -281,7 +281,7 @@ const redirects = {
|
|||
"chap-introduction": "introduction.html",
|
||||
"ch-basic-package-mgmt": "package-management/basic-package-mgmt.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",
|
||||
"sec-garbage-collection": "package-management/garbage-collection.html",
|
||||
"ssec-gc-roots": "package-management/garbage-collector-roots.html",
|
||||
|
|
|
@ -21,7 +21,6 @@
|
|||
- [Profiles](package-management/profiles.md)
|
||||
- [Garbage Collection](package-management/garbage-collection.md)
|
||||
- [Garbage Collector Roots](package-management/garbage-collector-roots.md)
|
||||
- [Channels](package-management/channels.md)
|
||||
- [Sharing Packages Between Machines](package-management/sharing-packages.md)
|
||||
- [Serving a Nix store via HTTP](package-management/binary-cache-substituter.md)
|
||||
- [Copying Closures via SSH](package-management/copy-closure.md)
|
||||
|
|
|
@ -8,36 +8,46 @@
|
|||
|
||||
# Description
|
||||
|
||||
A Nix channel is a mechanism that allows you to automatically stay
|
||||
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.
|
||||
Channels are a mechanism for referencing remote Nix expressions and conveniently retrieving their latest version.
|
||||
|
||||
To see the list of official NixOS channels, visit
|
||||
<https://nixos.org/channels>.
|
||||
The moving parts of channels are:
|
||||
- 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:
|
||||
|
||||
- `--add` *url* \[*name*\]\
|
||||
Adds a channel named *name* with URL *url* to the list of subscribed
|
||||
channels. If *name* is omitted, it defaults to the last component of
|
||||
*url*, with the suffixes `-stable` or `-unstable` removed.
|
||||
Add a channel *name* located at *url* to the list of subscribed channels.
|
||||
If *name* is omitted, default to the last component of *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`.
|
||||
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*\
|
||||
Removes the channel named *name* from the list of subscribed
|
||||
channels.
|
||||
Remove the channel *name* from the list of subscribed channels.
|
||||
|
||||
- `--list`\
|
||||
Prints the names and URLs of all subscribed channels on standard
|
||||
output.
|
||||
Print the names and URLs of all subscribed channels on standard output.
|
||||
|
||||
- `--update` \[*names*…\]\
|
||||
Downloads the Nix expressions of all subscribed channels (or only
|
||||
those included in *names* if specified) and makes them the default
|
||||
for `nix-env` operations (by symlinking them from the directory
|
||||
`~/.nix-defexpr`).
|
||||
Download the Nix expressions of subscribed channels and create a new generation.
|
||||
Update all channels if none is specified, and only those included in *names* otherwise.
|
||||
|
||||
- `--list-generations`\
|
||||
Prints a list of all the current existing generations for the
|
||||
|
@ -49,13 +59,8 @@ This command has the following operations:
|
|||
```
|
||||
|
||||
- `--rollback` \[*generation*\]\
|
||||
Reverts the previous call to `nix-channel
|
||||
--update`. Optionally, you can specify a specific channel generation
|
||||
number to restore.
|
||||
|
||||
Note that `--add` does not automatically perform an update.
|
||||
|
||||
The list of subscribed channels is stored in `~/.nix-channels`.
|
||||
Revert channels to the state before the last call to `nix-channel --update`.
|
||||
Optionally, you can specify a specific channel *generation* number to restore.
|
||||
|
||||
{{#include ./opt-common.md}}
|
||||
|
||||
|
@ -69,23 +74,33 @@ The list of subscribed channels is stored in `~/.nix-channels`.
|
|||
|
||||
# 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
|
||||
$ nix-channel --add https://nixos.org/channels/nixpkgs-unstable
|
||||
$ nix-channel --list
|
||||
nixpkgs https://nixos.org/channels/nixpkgs
|
||||
$ 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
|
||||
$ nix-instantiate --eval --expr '(import <nixpkgs> {}).lib.version'
|
||||
"14.04.527.0e935f1"
|
||||
$ nix-instantiate --eval '<nixpkgs>' --attr lib.version
|
||||
"22.11pre296212.530a53dcbc9"
|
||||
|
||||
$ nix-channel --rollback
|
||||
switching from generation 483 to 482
|
||||
|
||||
$ nix-instantiate --eval --expr '(import <nixpkgs> {}).lib.version'
|
||||
"14.04.526.dbadfad"
|
||||
$ nix-instantiate --eval '<nixpkgs>' --attr lib.version
|
||||
"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
|
||||
|
||||
As specified in [`flake.nix`], Nix can be built for various platforms:
|
||||
|
||||
- `aarch64-linux`
|
||||
- `i686-linux`
|
||||
- `x86_64-darwin`
|
||||
- `x86_64-linux`
|
||||
Nix can be built for various platforms, as specified in [`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
|
||||
on, you need to have some way for your system Nix to build code for that
|
||||
platform. Common solutions include [remote builders] and [binfmt emulation]
|
||||
on, you need a way for your current Nix installation to build code for that
|
||||
platform. Common solutions include [remote builders] and [binary format emulation]
|
||||
(only supported on NixOS).
|
||||
|
||||
[remote builders]: ../advanced-topics/distributed-builds.md
|
||||
[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
|
||||
executing the build is as simple as
|
||||
|
||||
```console
|
||||
$ nix build .#packages.aarch64-linux.default
|
||||
```
|
||||
|
||||
for flake-enabled Nix, or
|
||||
Given such a setup, executing the build only requires selecting the respective attribute.
|
||||
For example, to compile for `aarch64-linux`:
|
||||
|
||||
```console
|
||||
$ 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
|
||||
|
||||
|
|
|
@ -92,10 +92,10 @@ In this fragment from `all-packages.nix`,
|
|||
```nix
|
||||
graphviz = (import ../tools/graphics/graphviz) {
|
||||
inherit fetchurl stdenv libpng libjpeg expat x11 yacc;
|
||||
inherit (xlibs) libXaw;
|
||||
inherit (xorg) libXaw;
|
||||
};
|
||||
|
||||
xlibs = {
|
||||
xorg = {
|
||||
libX11 = ...;
|
||||
libXaw = ...;
|
||||
...
|
||||
|
@ -109,7 +109,7 @@ libjpg = ...;
|
|||
the set used in the function call to the function defined in
|
||||
`../tools/graphics/graphviz` inherits a number of variables from the
|
||||
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
|
||||
|
||||
|
@ -208,30 +208,41 @@ three kinds of patterns:
|
|||
```nix
|
||||
{ x, y, z, ... } @ args: z + y + x + args.a
|
||||
```
|
||||
|
||||
Here `args` is bound to the entire argument, which is further
|
||||
matched against the pattern `{ x, y, z,
|
||||
... }`. `@`-pattern makes mainly sense with an ellipsis(`...`) as
|
||||
|
||||
Here `args` is bound to the argument *as passed*, which is further
|
||||
matched against the pattern `{ x, y, z, ... }`.
|
||||
The `@`-pattern makes mainly sense with an ellipsis(`...`) as
|
||||
you can access attribute names as `a`, using `args.a`, which was
|
||||
given as an additional attribute to the function.
|
||||
|
||||
|
||||
> **Warning**
|
||||
>
|
||||
> The `args@` expression is bound to the argument passed to the
|
||||
> function which means that attributes with defaults that aren't
|
||||
> explicitly specified in the function call won't cause an
|
||||
> evaluation error, but won't exist in `args`.
|
||||
>
|
||||
>
|
||||
> `args@` binds the name `args` to the attribute set that is passed to the function.
|
||||
> In particular, `args` does *not* include any default values specified with `?` in the function's set pattern.
|
||||
>
|
||||
> For instance
|
||||
>
|
||||
>
|
||||
> ```nix
|
||||
> let
|
||||
> function = args@{ a ? 23, ... }: args;
|
||||
> f = args@{ a ? 23, ... }: [ a args ];
|
||||
> in
|
||||
> function {}
|
||||
> ````
|
||||
>
|
||||
> will evaluate to an empty attribute set.
|
||||
> f {}
|
||||
> ```
|
||||
>
|
||||
> 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,
|
||||
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
|
||||
<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
|
||||
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
|
||||
|
|
|
@ -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 "outputs-spec.hh"
|
||||
#include "derived-path.hh"
|
||||
#include "built-path.hh"
|
||||
#include "store-api.hh"
|
||||
#include "build-result.hh"
|
||||
|
||||
|
|
|
@ -594,6 +594,10 @@ void LocalDerivationGoal::startBuilder()
|
|||
else
|
||||
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;
|
||||
|
||||
/* Add the closure of store paths to the chroot. */
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
#include "derived-path.hh"
|
||||
#include "derivations.hh"
|
||||
#include "store-api.hh"
|
||||
|
||||
#include <nlohmann/json.hpp>
|
||||
|
@ -30,30 +29,6 @@ nlohmann::json DerivedPath::Built::toJSON(ref<Store> store) const {
|
|||
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
|
||||
{
|
||||
return store.printStorePath(path);
|
||||
|
@ -121,35 +96,4 @@ DerivedPath DerivedPath::parseLegacy(const Store & store, std::string_view 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);
|
||||
};
|
||||
|
||||
/**
|
||||
* 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<BuiltPath> BuiltPaths;
|
||||
|
||||
}
|
||||
|
|
|
@ -193,18 +193,24 @@ public:
|
|||
Setting<std::string> thisSystem{
|
||||
this, SYSTEM, "system",
|
||||
R"(
|
||||
This option specifies the canonical Nix system name of the current
|
||||
installation, such as `i686-linux` or `x86_64-darwin`. Nix can only
|
||||
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`.
|
||||
The system type of the current Nix installation.
|
||||
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).
|
||||
|
||||
It defaults to the canonical Nix system name detected by `configure`
|
||||
at build time.
|
||||
The default value is set when Nix itself is compiled for the system it will run on.
|
||||
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{
|
||||
|
@ -670,18 +676,20 @@ public:
|
|||
getDefaultExtraPlatforms(),
|
||||
"extra-platforms",
|
||||
R"(
|
||||
Platforms other than the native one which this machine is capable of
|
||||
building for. This can be useful for supporting additional
|
||||
architectures on compatible machines: i686-linux can be built on
|
||||
x86\_64-linux machines (and the default for this setting reflects
|
||||
this); armv7 is backwards-compatible with armv6 and armv5tel; some
|
||||
aarch64 machines can also natively run 32-bit ARM code; and
|
||||
qemu-user may be used to support non-native platforms (though this
|
||||
may be slow and buggy). Most values for this are not enabled by
|
||||
default because build systems will often misdetect the target
|
||||
platform and generate incompatible code, so you may wish to
|
||||
cross-check the results of using this option against proper
|
||||
natively-built versions of your derivations.
|
||||
System types of executables that can be run on this machine.
|
||||
|
||||
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).
|
||||
|
||||
Setting this can be useful to build derivations locally on compatible machines:
|
||||
- `i686-linux` executables can be run on `x86_64-linux` machines (set by default)
|
||||
- `x86_64-darwin` executables can be run on macOS `aarch64-darwin` with Rosetta 2 (set by default where applicable)
|
||||
- `armv6` and `armv5tel` executables can be run on `armv7`
|
||||
- some `aarch64` machines can also natively run 32-bit ARM code
|
||||
- `qemu-user` may be used to support non-native platforms (though this
|
||||
may be slow and buggy)
|
||||
|
||||
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};
|
||||
|
||||
Setting<StringSet> systemFeatures{
|
||||
|
@ -1010,7 +1018,7 @@ public:
|
|||
| `~/.nix-defexpr` | `$XDG_STATE_HOME/nix/defexpr` |
|
||||
| `~/.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`.
|
||||
This can be achieved with the following shell commands:
|
||||
|
||||
|
|
|
@ -42,7 +42,10 @@ void SSHMaster::addCommonSSHOpts(Strings & args)
|
|||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
|
|
@ -120,7 +120,8 @@ nix_tests = \
|
|||
path-from-hash-part.sh \
|
||||
test-libstoreconsumer.sh \
|
||||
toString-path.sh \
|
||||
read-only-store.sh
|
||||
read-only-store.sh \
|
||||
nested-sandboxing.sh
|
||||
|
||||
ifeq ($(HAVE_LIBCPUID), 1)
|
||||
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.succeed("systemctl restart sshd")
|
||||
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.
|
||||
client.fail("nix-store --check-validity ${pkgB}")
|
||||
|
|
Loading…
Reference in a new issue