aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohn Ericson <John.Ericson@Obsidian.Systems>2023-01-30 09:46:43 -0500
committerJohn Ericson <John.Ericson@Obsidian.Systems>2023-01-30 09:46:43 -0500
commitadb36080342488c0414a944c20c949938132e153 (patch)
tree485992ab68908a240b534a545a9724107de0cf14
parent4540e7b940ca56db821fe7c7d7d79fafa488f55e (diff)
parentf3e272ba02c3167b65a635389394f97a733440ca (diff)
Merge branch 'small-storePath-cleanups' into path-info
-rw-r--r--.github/PULL_REQUEST_TEMPLATE.md2
-rw-r--r--.github/workflows/backport.yml2
-rw-r--r--boehmgc-coroutine-sp-fallback.diff77
-rw-r--r--doc/manual/src/command-ref/nix-store.md4
-rw-r--r--doc/manual/src/glossary.md4
-rw-r--r--doc/manual/src/language/advanced-attributes.md6
-rw-r--r--doc/manual/src/release-notes/rl-2.13.md4
-rw-r--r--doc/manual/src/release-notes/rl-next.md12
-rw-r--r--flake.nix73
-rw-r--r--src/libexpr/eval.cc36
-rw-r--r--src/libexpr/eval.hh13
-rw-r--r--src/libstore/build/local-derivation-goal.cc27
-rw-r--r--src/libstore/daemon.cc3
-rw-r--r--src/libstore/globals.hh25
-rw-r--r--src/libstore/local-store.cc16
-rw-r--r--src/libstore/local-store.hh2
-rw-r--r--src/libstore/profiles.cc18
-rw-r--r--src/libstore/profiles.hh4
-rw-r--r--src/libstore/store-api.hh3
-rw-r--r--src/libutil/error.hh2
-rw-r--r--src/libutil/experimental-features.cc1
-rw-r--r--src/libutil/experimental-features.hh1
-rw-r--r--src/libutil/tests/url.cc21
-rw-r--r--src/libutil/url.cc6
-rw-r--r--src/libutil/util.cc18
-rw-r--r--src/libutil/util.hh3
-rwxr-xr-xsrc/nix-channel/nix-channel.cc4
-rw-r--r--src/nix/daemon.cc1
-rw-r--r--src/nix/flake.cc29
-rw-r--r--src/nix/show-config.cc31
-rw-r--r--tests/check-refs.nix7
-rw-r--r--tests/check-refs.sh9
-rw-r--r--tests/common.sh.in2
-rw-r--r--tests/config.sh5
-rw-r--r--tests/export-graph.sh2
-rw-r--r--tests/flakes/common.sh6
-rw-r--r--tests/flakes/init.sh4
-rw-r--r--tests/flakes/show.sh39
-rw-r--r--tests/local.mk2
-rw-r--r--tests/nix_path.sh5
-rw-r--r--tests/nixos/containers/containers.nix (renamed from tests/containers.nix)11
-rw-r--r--tests/nixos/containers/id-test.nix (renamed from tests/id-test.nix)0
-rw-r--r--tests/nixos/containers/systemd-nspawn.nix (renamed from tests/systemd-nspawn.nix)0
-rw-r--r--tests/nixos/github-flakes.nix (renamed from tests/github-flakes.nix)15
-rw-r--r--tests/nixos/nix-copy-closure.nix (renamed from tests/nix-copy-closure.nix)17
-rw-r--r--tests/nixos/nss-preload.nix (renamed from tests/nss-preload.nix)16
-rw-r--r--tests/nixos/remote-builds.nix (renamed from tests/remote-builds.nix)14
-rw-r--r--tests/nixos/setuid.nix (renamed from tests/setuid.nix)11
-rw-r--r--tests/nixos/sourcehut-flakes.nix (renamed from tests/sourcehut-flakes.nix)14
-rw-r--r--tests/remote-store.sh4
-rw-r--r--tests/restricted.sh3
-rw-r--r--tests/user-envs-migration.sh35
52 files changed, 475 insertions, 194 deletions
diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md
index a268d7caf..344f9405f 100644
--- a/.github/PULL_REQUEST_TEMPLATE.md
+++ b/.github/PULL_REQUEST_TEMPLATE.md
@@ -21,7 +21,7 @@ Maintainers: tick if completed or explain if not relevant
- [ ] tests, as appropriate
- functional tests - `tests/**.sh`
- unit tests - `src/*/tests`
- - integration tests
+ - integration tests - `tests/nixos/*`
- [ ] documentation in the manual
- [ ] code and comments are self-explanatory
- [ ] commit message explains why the change was made
diff --git a/.github/workflows/backport.yml b/.github/workflows/backport.yml
index 9f8d14509..ca5af260f 100644
--- a/.github/workflows/backport.yml
+++ b/.github/workflows/backport.yml
@@ -21,7 +21,7 @@ jobs:
fetch-depth: 0
- name: Create backport PRs
# should be kept in sync with `version`
- uses: zeebe-io/backport-action@v1.0.1
+ uses: zeebe-io/backport-action@v1.1.0
with:
# Config README: https://github.com/zeebe-io/backport-action#backport-action
github_token: ${{ secrets.GITHUB_TOKEN }}
diff --git a/boehmgc-coroutine-sp-fallback.diff b/boehmgc-coroutine-sp-fallback.diff
new file mode 100644
index 000000000..2826486fb
--- /dev/null
+++ b/boehmgc-coroutine-sp-fallback.diff
@@ -0,0 +1,77 @@
+diff --git a/darwin_stop_world.c b/darwin_stop_world.c
+index 3dbaa3fb..36a1d1f7 100644
+--- a/darwin_stop_world.c
++++ b/darwin_stop_world.c
+@@ -352,6 +352,7 @@ GC_INNER void GC_push_all_stacks(void)
+ int nthreads = 0;
+ word total_size = 0;
+ mach_msg_type_number_t listcount = (mach_msg_type_number_t)THREAD_TABLE_SZ;
++ size_t stack_limit;
+ if (!EXPECT(GC_thr_initialized, TRUE))
+ GC_thr_init();
+
+@@ -407,6 +408,19 @@ GC_INNER void GC_push_all_stacks(void)
+ GC_push_all_stack_sections(lo, hi, p->traced_stack_sect);
+ }
+ if (altstack_lo) {
++ // When a thread goes into a coroutine, we lose its original sp until
++ // control flow returns to the thread.
++ // While in the coroutine, the sp points outside the thread stack,
++ // so we can detect this and push the entire thread stack instead,
++ // as an approximation.
++ // We assume that the coroutine has similarly added its entire stack.
++ // This could be made accurate by cooperating with the application
++ // via new functions and/or callbacks.
++ stack_limit = pthread_get_stacksize_np(p->id);
++ if (altstack_lo >= altstack_hi || altstack_lo < altstack_hi - stack_limit) { // sp outside stack
++ altstack_lo = altstack_hi - stack_limit;
++ }
++
+ total_size += altstack_hi - altstack_lo;
+ GC_push_all_stack(altstack_lo, altstack_hi);
+ }
+diff --git a/pthread_stop_world.c b/pthread_stop_world.c
+index b5d71e62..aed7b0bf 100644
+--- a/pthread_stop_world.c
++++ b/pthread_stop_world.c
+@@ -768,6 +768,8 @@ STATIC void GC_restart_handler(int sig)
+ /* world is stopped. Should not fail if it isn't. */
+ GC_INNER void GC_push_all_stacks(void)
+ {
++ size_t stack_limit;
++ pthread_attr_t pattr;
+ GC_bool found_me = FALSE;
+ size_t nthreads = 0;
+ int i;
+@@ -851,6 +853,31 @@ GC_INNER void GC_push_all_stacks(void)
+ hi = p->altstack + p->altstack_size;
+ /* FIXME: Need to scan the normal stack too, but how ? */
+ /* FIXME: Assume stack grows down */
++ } else {
++ if (pthread_getattr_np(p->id, &pattr)) {
++ ABORT("GC_push_all_stacks: pthread_getattr_np failed!");
++ }
++ if (pthread_attr_getstacksize(&pattr, &stack_limit)) {
++ ABORT("GC_push_all_stacks: pthread_attr_getstacksize failed!");
++ }
++ if (pthread_attr_destroy(&pattr)) {
++ ABORT("GC_push_all_stacks: pthread_attr_destroy failed!");
++ }
++ // When a thread goes into a coroutine, we lose its original sp until
++ // control flow returns to the thread.
++ // While in the coroutine, the sp points outside the thread stack,
++ // so we can detect this and push the entire thread stack instead,
++ // as an approximation.
++ // We assume that the coroutine has similarly added its entire stack.
++ // This could be made accurate by cooperating with the application
++ // via new functions and/or callbacks.
++ #ifndef STACK_GROWS_UP
++ if (lo >= hi || lo < hi - stack_limit) { // sp outside stack
++ lo = hi - stack_limit;
++ }
++ #else
++ #error "STACK_GROWS_UP not supported in boost_coroutine2 (as of june 2021), so we don't support it in Nix."
++ #endif
+ }
+ GC_push_all_stack_sections(lo, hi, traced_stack_sect);
+ # ifdef STACK_GROWS_UP
diff --git a/doc/manual/src/command-ref/nix-store.md b/doc/manual/src/command-ref/nix-store.md
index f6017481c..403cf285d 100644
--- a/doc/manual/src/command-ref/nix-store.md
+++ b/doc/manual/src/command-ref/nix-store.md
@@ -82,8 +82,8 @@ paths. Realisation is a somewhat overloaded term:
produced through substitutes. If there are no (successful)
substitutes, realisation fails.
-[valid]: ../glossary.md#validity
-[substitutes]: ../glossary.md#substitute
+[valid]: ../glossary.md#gloss-validity
+[substitutes]: ../glossary.md#gloss-substitute
The output path of each derivation is printed on standard output. (For
non-derivations argument, the argument itself is printed.)
diff --git a/doc/manual/src/glossary.md b/doc/manual/src/glossary.md
index 5a49af8dc..6004df833 100644
--- a/doc/manual/src/glossary.md
+++ b/doc/manual/src/glossary.md
@@ -156,6 +156,8 @@
to path `Q`, then `Q` is in the closure of `P`. Further, if `Q`
references `R` then `R` is also in the closure of `P`.
+ [closure]: #gloss-closure
+
- [output path]{#gloss-output-path}\
A [store path] produced by a [derivation].
@@ -172,6 +174,8 @@
- The store path is listed in the Nix database as being valid.
- All paths in the store path's [closure] are valid.
+ [validity]: #gloss-validity
+
- [user environment]{#gloss-user-env}\
An automatically generated store object that consists of a set of
symlinks to “active” applications, i.e., other store paths. These
diff --git a/doc/manual/src/language/advanced-attributes.md b/doc/manual/src/language/advanced-attributes.md
index 2e7e80ed0..f02425b13 100644
--- a/doc/manual/src/language/advanced-attributes.md
+++ b/doc/manual/src/language/advanced-attributes.md
@@ -207,13 +207,13 @@ Derivations can declare some infrequently used optional attributes.
the hash in either hexadecimal or base-32 notation. (See the
[`nix-hash` command](../command-ref/nix-hash.md) for information
about converting to and from base-32 notation.)
-
+
- [`__contentAddressed`]{#adv-attr-__contentAddressed}
If this **experimental** attribute is set to true, then the derivation
outputs will be stored in a content-addressed location rather than the
traditional input-addressed one.
- This only has an effect if the `ca-derivation` experimental feature is enabled.
-
+ This only has an effect if the `ca-derivations` experimental feature is enabled.
+
Setting this attribute also requires setting `outputHashMode` and `outputHashAlgo` like for *fixed-output derivations* (see above).
- [`passAsFile`]{#adv-attr-passAsFile}\
diff --git a/doc/manual/src/release-notes/rl-2.13.md b/doc/manual/src/release-notes/rl-2.13.md
index 2ebf19f60..168708113 100644
--- a/doc/manual/src/release-notes/rl-2.13.md
+++ b/doc/manual/src/release-notes/rl-2.13.md
@@ -25,11 +25,11 @@
* Allow explicitly selecting outputs in a store derivation installable, just like we can do with other sorts of installables.
For example,
```shell-session
- # nix-build /nix/store/gzaflydcr6sb3567hap9q6srzx8ggdgg-glibc-2.33-78.drv^dev
+ # nix build /nix/store/gzaflydcr6sb3567hap9q6srzx8ggdgg-glibc-2.33-78.drv^dev
```
now works just as
```shell-session
- # nix-build glibc^dev
+ # nix build nixpkgs#glibc^dev
```
does already.
diff --git a/doc/manual/src/release-notes/rl-next.md b/doc/manual/src/release-notes/rl-next.md
index 8a79703ab..7e8344e63 100644
--- a/doc/manual/src/release-notes/rl-next.md
+++ b/doc/manual/src/release-notes/rl-next.md
@@ -8,3 +8,15 @@
discovered by making multiple syscalls. This change makes these operations
lazy such that these lookups will only be performed if the attribute is used.
This optimization affects a minority of filesystems and operating systems.
+
+* In derivations that use structured attributes, you can now use `unsafeDiscardReferences`
+ to disable scanning a given output for runtime dependencies:
+ ```nix
+ __structuredAttrs = true;
+ unsafeDiscardReferences.out = true;
+ ```
+ This is useful e.g. when generating self-contained filesystem images with
+ their own embedded Nix store: hashes found inside such an image refer
+ to the embedded store and not to the host's Nix store.
+
+ This requires the `discard-references` experimental feature.
diff --git a/flake.nix b/flake.nix
index 5796c54ea..0325f33b1 100644
--- a/flake.nix
+++ b/flake.nix
@@ -131,9 +131,14 @@
});
propagatedDeps =
- [ (boehmgc.override {
+ [ ((boehmgc.override {
enableLargeConfig = true;
+ }).overrideAttrs(o: {
+ patches = (o.patches or []) ++ [
+ ./boehmgc-coroutine-sp-fallback.diff
+ ];
})
+ )
nlohmann_json
];
};
@@ -404,6 +409,18 @@
};
};
+ nixos-lib = import (nixpkgs + "/nixos/lib") { };
+
+ # https://nixos.org/manual/nixos/unstable/index.html#sec-calling-nixos-tests
+ runNixOSTestFor = system: test: nixos-lib.runTest {
+ imports = [ test ];
+ hostPkgs = nixpkgsFor.${system};
+ defaults = {
+ nixpkgs.pkgs = nixpkgsFor.${system};
+ };
+ _module.args.nixpkgs = nixpkgs;
+ };
+
in {
# A Nixpkgs overlay that overrides the 'nix' and
@@ -460,6 +477,10 @@
src = self;
+ configureFlags = [
+ "CXXFLAGS=-I${lib.getDev pkgs.rapidcheck}/extras/gtest/include"
+ ];
+
enableParallelBuilding = true;
nativeBuildInputs = nativeBuildDeps;
@@ -478,49 +499,22 @@
};
# System tests.
- tests.remoteBuilds = import ./tests/remote-builds.nix {
- system = "x86_64-linux";
- inherit nixpkgs;
- overlay = self.overlays.default;
- };
+ tests.remoteBuilds = runNixOSTestFor "x86_64-linux" ./tests/nixos/remote-builds.nix;
- tests.nix-copy-closure = import ./tests/nix-copy-closure.nix {
- system = "x86_64-linux";
- inherit nixpkgs;
- overlay = self.overlays.default;
- };
+ tests.nix-copy-closure = runNixOSTestFor "x86_64-linux" ./tests/nixos/nix-copy-closure.nix;
- tests.nssPreload = (import ./tests/nss-preload.nix rec {
- system = "x86_64-linux";
- inherit nixpkgs;
- overlay = self.overlays.default;
- });
+ tests.nssPreload = runNixOSTestFor "x86_64-linux" ./tests/nixos/nss-preload.nix;
- tests.githubFlakes = (import ./tests/github-flakes.nix rec {
- system = "x86_64-linux";
- inherit nixpkgs;
- overlay = self.overlays.default;
- });
+ tests.githubFlakes = runNixOSTestFor "x86_64-linux" ./tests/nixos/github-flakes.nix;
- tests.sourcehutFlakes = (import ./tests/sourcehut-flakes.nix rec {
- system = "x86_64-linux";
- inherit nixpkgs;
- overlay = self.overlays.default;
- });
+ tests.sourcehutFlakes = runNixOSTestFor "x86_64-linux" ./tests/nixos/sourcehut-flakes.nix;
- tests.containers = (import ./tests/containers.nix rec {
- system = "x86_64-linux";
- inherit nixpkgs;
- overlay = self.overlays.default;
- });
+ tests.containers = runNixOSTestFor "x86_64-linux" ./tests/nixos/containers/containers.nix;
tests.setuid = nixpkgs.lib.genAttrs
["i686-linux" "x86_64-linux"]
- (system:
- import ./tests/setuid.nix rec {
- inherit nixpkgs system;
- overlay = self.overlays.default;
- });
+ (system: runNixOSTestFor system ./tests/nixos/setuid.nix);
+
# Make sure that nix-env still produces the exact same result
# on a particular version of Nixpkgs.
@@ -653,6 +647,7 @@
inherit system crossSystem;
overlays = [ self.overlays.default ];
};
+ inherit (nixpkgsCross) lib;
in with commonDeps { pkgs = nixpkgsCross; }; nixpkgsCross.stdenv.mkDerivation {
name = "nix-${version}";
@@ -665,7 +660,11 @@
nativeBuildInputs = nativeBuildDeps;
buildInputs = buildDeps ++ propagatedDeps;
- configureFlags = [ "--sysconfdir=/etc" "--disable-doc-gen" ];
+ configureFlags = [
+ "CXXFLAGS=-I${lib.getDev nixpkgsCross.rapidcheck}/extras/gtest/include"
+ "--sysconfdir=/etc"
+ "--disable-doc-gen"
+ ];
enableParallelBuilding = true;
diff --git a/src/libexpr/eval.cc b/src/libexpr/eval.cc
index 1828b8c2e..a48968656 100644
--- a/src/libexpr/eval.cc
+++ b/src/libexpr/eval.cc
@@ -519,6 +519,7 @@ EvalState::EvalState(
static_assert(sizeof(Env) <= 16, "environment must be <= 16 bytes");
/* Initialise the Nix expression search path. */
+ evalSettings.nixPath.setDefault(evalSettings.getDefaultNixPath());
if (!evalSettings.pureEval) {
for (auto & i : _searchPath) addToSearchPath(i);
for (auto & i : evalSettings.nixPath.get()) addToSearchPath(i);
@@ -2472,30 +2473,35 @@ std::ostream & operator << (std::ostream & str, const ExternalValueBase & v) {
EvalSettings::EvalSettings()
{
- auto var = getEnv("NIX_PATH");
- if (var) nixPath = parseNixPath(*var);
}
+/* impure => NIX_PATH or a default path
+ * restrict-eval => NIX_PATH
+ * pure-eval => empty
+ */
Strings EvalSettings::getDefaultNixPath()
{
- Strings res;
- auto add = [&](const Path & p, const std::string & s = std::string()) {
- if (pathExists(p)) {
- if (s.empty()) {
- res.push_back(p);
- } else {
- res.push_back(s + "=" + p);
- }
- }
- };
+ if (pureEval)
+ return {};
+
+ auto var = getEnv("NIX_PATH");
+ if (var) {
+ return parseNixPath(*var);
+ } else if (restrictEval) {
+ return {};
+ } else {
+ Strings res;
+ auto add = [&](const Path & p, const std::optional<std::string> & s = std::nullopt) {
+ if (pathExists(p))
+ res.push_back(s ? *s + "=" + p : p);
+ };
- if (!evalSettings.restrictEval && !evalSettings.pureEval) {
add(getHome() + "/.nix-defexpr/channels");
add(settings.nixStateDir + "/profiles/per-user/root/channels/nixpkgs", "nixpkgs");
add(settings.nixStateDir + "/profiles/per-user/root/channels");
- }
- return res;
+ return res;
+ }
}
bool EvalSettings::isPseudoUrl(std::string_view s)
diff --git a/src/libexpr/eval.hh b/src/libexpr/eval.hh
index e4d5906bd..2340ef67b 100644
--- a/src/libexpr/eval.hh
+++ b/src/libexpr/eval.hh
@@ -570,7 +570,7 @@ struct EvalSettings : Config
{
EvalSettings();
- static Strings getDefaultNixPath();
+ Strings getDefaultNixPath();
static bool isPseudoUrl(std::string_view s);
@@ -580,8 +580,15 @@ struct EvalSettings : Config
"Whether builtin functions that allow executing native code should be enabled."};
Setting<Strings> nixPath{
- this, getDefaultNixPath(), "nix-path",
- "List of directories to be searched for `<...>` file references."};
+ this, {}, "nix-path",
+ R"(
+ List of directories to be searched for `<...>` file references.
+
+ If [pure evaluation](#conf-pure-eval) is disabled,
+ this is initialised using the [`NIX_PATH`](@docroot@/command-ref/env-common.md#env-NIX_PATH)
+ environment variable, or, if it is unset and [restricted evaluation](#conf-restrict-eval)
+ is disabled, a default search path including the user's and `root`'s channels.
+ )"};
Setting<bool> restrictEval{
this, false, "restrict-eval",
diff --git a/src/libstore/build/local-derivation-goal.cc b/src/libstore/build/local-derivation-goal.cc
index 98f8cb061..8fdc9dce1 100644
--- a/src/libstore/build/local-derivation-goal.cc
+++ b/src/libstore/build/local-derivation-goal.cc
@@ -1517,7 +1517,7 @@ void LocalDerivationGoal::startDaemon()
try {
daemon::processConnection(store, from, to,
daemon::NotTrusted, daemon::Recursive,
- [&](Store & store) { store.createUser("nobody", 65535); });
+ [&](Store & store) {});
debug("terminated daemon connection");
} catch (SysError &) {
ignoreException();
@@ -2323,11 +2323,28 @@ DrvOutputs LocalDerivationGoal::registerOutputs()
buildUser ? std::optional(buildUser->getUIDRange()) : std::nullopt,
inodesSeen);
- debug("scanning for references for output '%s' in temp location '%s'", outputName, actualPath);
+ bool discardReferences = false;
+ if (auto structuredAttrs = parsedDrv->getStructuredAttrs()) {
+ if (auto udr = get(*structuredAttrs, "unsafeDiscardReferences")) {
+ settings.requireExperimentalFeature(Xp::DiscardReferences);
+ if (auto output = get(*udr, outputName)) {
+ if (!output->is_boolean())
+ throw Error("attribute 'unsafeDiscardReferences.\"%s\"' of derivation '%s' must be a Boolean", outputName, drvPath.to_string());
+ discardReferences = output->get<bool>();
+ }
+ }
+ }
- /* Pass blank Sink as we are not ready to hash data at this stage. */
- NullSink blank;
- auto references = scanForReferences(blank, actualPath, referenceablePaths);
+ StorePathSet references;
+ if (discardReferences)
+ debug("discarding references of output '%s'", outputName);
+ else {
+ debug("scanning for references for output '%s' in temp location '%s'", outputName, actualPath);
+
+ /* Pass blank Sink as we are not ready to hash data at this stage. */
+ NullSink blank;
+ references = scanForReferences(blank, actualPath, referenceablePaths);
+ }
outputReferencesIfUnregistered.insert_or_assign(
outputName,
diff --git a/src/libstore/daemon.cc b/src/libstore/daemon.cc
index 12596ba49..e2a7dab35 100644
--- a/src/libstore/daemon.cc
+++ b/src/libstore/daemon.cc
@@ -222,7 +222,8 @@ struct ClientSettings
else if (!hasSuffix(s, "/") && trusted.count(s + "/"))
subs.push_back(s + "/");
else
- warn("ignoring untrusted substituter '%s'", s);
+ warn("ignoring untrusted substituter '%s', you are not a trusted user.\n"
+ "Run `man nix.conf` for more information on the `substituters` configuration option.", s);
res = subs;
return true;
};
diff --git a/src/libstore/globals.hh b/src/libstore/globals.hh
index 7111def92..c3ccb5e11 100644
--- a/src/libstore/globals.hh
+++ b/src/libstore/globals.hh
@@ -570,11 +570,15 @@ public:
{"cache.nixos.org-1:6NCHdD59X431o0gWypbMrAURkbJ16ZPMQFGspcDShjY="},
"trusted-public-keys",
R"(
- A whitespace-separated list of public keys. When paths are copied
- from another Nix store (such as a binary cache), they must be
- signed with one of these keys. For example:
- `cache.nixos.org-1:6NCHdD59X431o0gWypbMrAURkbJ16ZPMQFGspcDShjY=
- hydra.nixos.org-1:CNHJZBh9K4tP3EKF6FkkgeVYsS3ohTl+oS0Qa8bezVs=`.
+ A whitespace-separated list of public keys.
+
+ At least one of the following condition must be met
+ for Nix to accept copying a store object from another
+ Nix store (such as a substituter):
+
+ - the store object has been signed using a key in the trusted keys list
+ - the [`require-sigs`](#conf-require-sigs) option has been set to `false`
+ - the store object is [output-addressed](@docroot@/glossary.md#gloss-output-addressed-store-object)
)",
{"binary-cache-public-keys"}};
@@ -670,13 +674,14 @@ public:
independently. Lower value means higher priority.
The default is `https://cache.nixos.org`, with a Priority of 40.
- Nix will copy a store path from a remote store only if one
- of the following is true:
+ At least one of the following conditions must be met for Nix to use
+ a substituter:
- - the store object is signed by one of the [`trusted-public-keys`](#conf-trusted-public-keys)
- the substituter is in the [`trusted-substituters`](#conf-trusted-substituters) list
- - the [`require-sigs`](#conf-require-sigs) option has been set to `false`
- - the store object is [output-addressed](@docroot@/glossary.md#gloss-output-addressed-store-object)
+ - the user calling Nix is in the [`trusted-users`](#conf-trusted-users) list
+
+ In addition, each store path should be trusted as described
+ in [`trusted-public-keys`](#conf-trusted-public-keys)
)",
{"binary-caches"}};
diff --git a/src/libstore/local-store.cc b/src/libstore/local-store.cc
index e55ccab84..c6f870dde 100644
--- a/src/libstore/local-store.cc
+++ b/src/libstore/local-store.cc
@@ -201,8 +201,6 @@ LocalStore::LocalStore(const Params & params)
throw SysError("could not set permissions on '%s' to 755", perUserDir);
}
- createUser(getUserName(), getuid());
-
/* Optionally, create directories and set permissions for a
multi-user install. */
if (getuid() == 0 && settings.buildUsersGroup != "") {
@@ -1844,20 +1842,6 @@ void LocalStore::signPathInfo(ValidPathInfo & info)
}
-void LocalStore::createUser(const std::string & userName, uid_t userId)
-{
- for (auto & dir : {
- fmt("%s/profiles/per-user/%s", stateDir, userName),
- fmt("%s/gcroots/per-user/%s", stateDir, userName)
- }) {
- createDirs(dir);
- if (chmod(dir.c_str(), 0755) == -1)
- throw SysError("changing permissions of directory '%s'", dir);
- if (chown(dir.c_str(), userId, getgid()) == -1)
- throw SysError("changing owner of directory '%s'", dir);
- }
-}
-
std::optional<std::pair<int64_t, Realisation>> LocalStore::queryRealisationCore_(
LocalStore::State & state,
const DrvOutput & id)
diff --git a/src/libstore/local-store.hh b/src/libstore/local-store.hh
index 06d36a7d5..a84eb7c26 100644
--- a/src/libstore/local-store.hh
+++ b/src/libstore/local-store.hh
@@ -281,8 +281,6 @@ private:
void signPathInfo(ValidPathInfo & info);
void signRealisation(Realisation &);
- void createUser(const std::string & userName, uid_t userId) override;
-
// XXX: Make a generic `Store` method
FixedOutputHash hashCAPath(
const FileIngestionMethod & method,
diff --git a/src/libstore/profiles.cc b/src/libstore/profiles.cc
index 3e4188188..b202351ce 100644
--- a/src/libstore/profiles.cc
+++ b/src/libstore/profiles.cc
@@ -280,16 +280,24 @@ std::string optimisticLockProfile(const Path & profile)
}
+Path profilesDir()
+{
+ auto profileRoot = getDataDir() + "/nix/profiles";
+ createDirs(profileRoot);
+ return profileRoot;
+}
+
+
Path getDefaultProfile()
{
Path profileLink = getHome() + "/.nix-profile";
try {
+ auto profile =
+ getuid() == 0
+ ? settings.nixStateDir + "/profiles/default"
+ : profilesDir() + "/profile";
if (!pathExists(profileLink)) {
- replaceSymlink(
- getuid() == 0
- ? settings.nixStateDir + "/profiles/default"
- : fmt("%s/profiles/per-user/%s/profile", settings.nixStateDir, getUserName()),
- profileLink);
+ replaceSymlink(profile, profileLink);
}
return absPath(readLink(profileLink), dirOf(profileLink));
} catch (Error &) {
diff --git a/src/libstore/profiles.hh b/src/libstore/profiles.hh
index 408ca039c..73667a798 100644
--- a/src/libstore/profiles.hh
+++ b/src/libstore/profiles.hh
@@ -68,6 +68,10 @@ void lockProfile(PathLocks & lock, const Path & profile);
rebuilt. */
std::string optimisticLockProfile(const Path & profile);
+/* Creates and returns the path to a directory suitable for storing the user’s
+ profiles. */
+Path profilesDir();
+
/* Resolve ~/.nix-profile. If ~/.nix-profile doesn't exist yet, create
it. */
Path getDefaultProfile();
diff --git a/src/libstore/store-api.hh b/src/libstore/store-api.hh
index 2d252db84..72517c6e4 100644
--- a/src/libstore/store-api.hh
+++ b/src/libstore/store-api.hh
@@ -653,9 +653,6 @@ public:
return toRealPath(printStorePath(storePath));
}
- virtual void createUser(const std::string & userName, uid_t userId)
- { }
-
/*
* Synchronises the options of the client with those of the daemon
* (a no-op when there’s no daemon)
diff --git a/src/libutil/error.hh b/src/libutil/error.hh
index 7d236028c..0ebeaba61 100644
--- a/src/libutil/error.hh
+++ b/src/libutil/error.hh
@@ -74,6 +74,8 @@ struct AbstractPos
virtual void print(std::ostream & out) const = 0;
std::optional<LinesOfCode> getCodeLines() const;
+
+ virtual ~AbstractPos() = default;
};
std::ostream & operator << (std::ostream & str, const AbstractPos & pos);
diff --git a/src/libutil/experimental-features.cc b/src/libutil/experimental-features.cc
index e0902971e..58d762ebb 100644
--- a/src/libutil/experimental-features.cc
+++ b/src/libutil/experimental-features.cc
@@ -16,6 +16,7 @@ std::map<ExperimentalFeature, std::string> stringifiedXpFeatures = {
{ Xp::ReplFlake, "repl-flake" },
{ Xp::AutoAllocateUids, "auto-allocate-uids" },
{ Xp::Cgroups, "cgroups" },
+ { Xp::DiscardReferences, "discard-references" },
};
const std::optional<ExperimentalFeature> parseExperimentalFeature(const std::string_view & name)
diff --git a/src/libutil/experimental-features.hh b/src/libutil/experimental-features.hh
index af775feb0..ac372e03e 100644
--- a/src/libutil/experimental-features.hh
+++ b/src/libutil/experimental-features.hh
@@ -25,6 +25,7 @@ enum struct ExperimentalFeature
ReplFlake,
AutoAllocateUids,
Cgroups,
+ DiscardReferences,
};
/**
diff --git a/src/libutil/tests/url.cc b/src/libutil/tests/url.cc
index c3b233797..e0c438b4d 100644
--- a/src/libutil/tests/url.cc
+++ b/src/libutil/tests/url.cc
@@ -99,6 +99,27 @@ namespace nix {
ASSERT_EQ(parsed, expected);
}
+ TEST(parseURL, parsesFilePlusHttpsUrl) {
+ auto s = "file+https://www.example.org/video.mp4";
+ auto parsed = parseURL(s);
+
+ ParsedURL expected {
+ .url = "file+https://www.example.org/video.mp4",
+ .base = "https://www.example.org/video.mp4",
+ .scheme = "file+https",
+ .authority = "www.example.org",
+ .path = "/video.mp4",
+ .query = (StringMap) { },
+ .fragment = "",
+ };
+
+ ASSERT_EQ(parsed, expected);
+ }
+
+ TEST(parseURL, rejectsAuthorityInUrlsWithFileTransportation) {
+ auto s = "file://www.example.org/video.mp4";
+ ASSERT_THROW(parseURL(s), Error);
+ }
TEST(parseURL, parseIPv4Address) {
auto s = "http://127.0.0.1:8080/file.tar.gz?download=fast&when=now#hello";
diff --git a/src/libutil/url.cc b/src/libutil/url.cc
index 5b7abeb49..4e43455e1 100644
--- a/src/libutil/url.cc
+++ b/src/libutil/url.cc
@@ -30,13 +30,13 @@ ParsedURL parseURL(const std::string & url)
auto & query = match[6];
auto & fragment = match[7];
- auto isFile = scheme.find("file") != std::string::npos;
+ auto transportIsFile = parseUrlScheme(scheme).transport == "file";
- if (authority && *authority != "" && isFile)
+ if (authority && *authority != "" && transportIsFile)
throw BadURL("file:// URL '%s' has unexpected authority '%s'",
url, *authority);
- if (isFile && path.empty())
+ if (transportIsFile && path.empty())
path = "/";
return ParsedURL{
diff --git a/src/libutil/util.cc b/src/libutil/util.cc
index 993dc1cb6..40faa4bf2 100644
--- a/src/libutil/util.cc
+++ b/src/libutil/util.cc
@@ -537,6 +537,16 @@ std::string getUserName()
return name;
}
+Path getHomeOf(uid_t userId)
+{
+ std::vector<char> buf(16384);
+ struct passwd pwbuf;
+ struct passwd * pw;
+ if (getpwuid_r(userId, &pwbuf, buf.data(), buf.size(), &pw) != 0
+ || !pw || !pw->pw_dir || !pw->pw_dir[0])
+ throw Error("cannot determine user's home directory");
+ return pw->pw_dir;
+}
Path getHome()
{
@@ -558,13 +568,7 @@ Path getHome()
}
}
if (!homeDir) {
- std::vector<char> buf(16384);
- struct passwd pwbuf;
- struct passwd * pw;
- if (getpwuid_r(geteuid(), &pwbuf, buf.data(), buf.size(), &pw) != 0
- || !pw || !pw->pw_dir || !pw->pw_dir[0])
- throw Error("cannot determine user's home directory");
- homeDir = pw->pw_dir;
+ homeDir = getHomeOf(geteuid());
if (unownedUserHomeDir.has_value() && unownedUserHomeDir != homeDir) {
warn("$HOME ('%s') is not owned by you, falling back to the one defined in the 'passwd' file ('%s')", *unownedUserHomeDir, *homeDir);
}
diff --git a/src/libutil/util.hh b/src/libutil/util.hh
index 9b149de80..266da0ae3 100644
--- a/src/libutil/util.hh
+++ b/src/libutil/util.hh
@@ -137,6 +137,9 @@ void deletePath(const Path & path, uint64_t & bytesFreed);
std::string getUserName();
+/* Return the given user's home directory from /etc/passwd. */
+Path getHomeOf(uid_t userId);
+
/* Return $HOME or the user's home directory from /etc/passwd. */
Path getHome();
diff --git a/src/nix-channel/nix-channel.cc b/src/nix-channel/nix-channel.cc
index cf52b03b4..263d85eea 100755
--- a/src/nix-channel/nix-channel.cc
+++ b/src/nix-channel/nix-channel.cc
@@ -1,9 +1,11 @@
+#include "profiles.hh"
#include "shared.hh"
#include "globals.hh"
#include "filetransfer.hh"
#include "store-api.hh"
#include "legacy.hh"
#include "fetchers.hh"
+#include "util.hh"
#include <fcntl.h>
#include <regex>
@@ -166,7 +168,7 @@ static int main_nix_channel(int argc, char ** argv)
nixDefExpr = home + "/.nix-defexpr";
// Figure out the name of the channels profile.
- profile = fmt("%s/profiles/per-user/%s/channels", settings.nixStateDir, getUserName());
+ profile = profilesDir() + "/channels";
enum {
cNone,
diff --git a/src/nix/daemon.cc b/src/nix/daemon.cc
index c527fdb0a..19fbbf155 100644
--- a/src/nix/daemon.cc
+++ b/src/nix/daemon.cc
@@ -248,7 +248,6 @@ static void daemonLoop()
querySetting("build-users-group", "") == "")
throw Error("if you run 'nix-daemon' as root, then you MUST set 'build-users-group'!");
#endif
- store.createUser(user, peer.uid);
});
exit(0);
diff --git a/src/nix/flake.cc b/src/nix/flake.cc
index 020c1b182..d2f68c37c 100644
--- a/src/nix/flake.cc
+++ b/src/nix/flake.cc
@@ -966,6 +966,7 @@ struct CmdFlakeArchive : FlakeCommand, MixJSON, MixDryRun
struct CmdFlakeShow : FlakeCommand, MixJSON
{
bool showLegacy = false;
+ bool showAllSystems = false;
CmdFlakeShow()
{
@@ -974,6 +975,11 @@ struct CmdFlakeShow : FlakeCommand, MixJSON
.description = "Show the contents of the `legacyPackages` output.",
.handler = {&showLegacy, true}
});
+ addFlag({
+ .longName = "all-systems",
+ .description = "Show the contents of outputs for all systems.",
+ .handler = {&showAllSystems, true}
+ });
}
std::string description() override
@@ -994,6 +1000,7 @@ struct CmdFlakeShow : FlakeCommand, MixJSON
auto state = getEvalState();
auto flake = std::make_shared<LockedFlake>(lockFlake());
+ auto localSystem = std::string(settings.thisSystem.get());
std::function<nlohmann::json(
eval_cache::AttrCursor & visitor,
@@ -1084,10 +1091,18 @@ struct CmdFlakeShow : FlakeCommand, MixJSON
|| (attrPath.size() == 3 && (attrPathS[0] == "checks" || attrPathS[0] == "packages" || attrPathS[0] == "devShells"))
)
{
- if (visitor.isDerivation())
- showDerivation();
- else
- throw Error("expected a derivation");
+ if (!showAllSystems && std::string(attrPathS[1]) != localSystem) {
+ if (!json)
+ logger->cout(fmt("%s " ANSI_WARNING "omitted" ANSI_NORMAL " (use '--all-systems' to show)", headerPrefix));
+ else {
+ logger->warn(fmt("%s omitted (use '--all-systems' to show)", concatStringsSep(".", attrPathS)));
+ }
+ } else {
+ if (visitor.isDerivation())
+ showDerivation();
+ else
+ throw Error("expected a derivation");
+ }
}
else if (attrPath.size() > 0 && attrPathS[0] == "hydraJobs") {
@@ -1106,6 +1121,12 @@ struct CmdFlakeShow : FlakeCommand, MixJSON
else {
logger->warn(fmt("%s omitted (use '--legacy' to show)", concatStringsSep(".", attrPathS)));
}
+ } else if (!showAllSystems && std::string(attrPathS[1]) != localSystem) {
+ if (!json)
+ logger->cout(fmt("%s " ANSI_WARNING "omitted" ANSI_NORMAL " (use '--all-systems' to show)", headerPrefix));
+ else {
+ logger->warn(fmt("%s omitted (use '--all-systems' to show)", concatStringsSep(".", attrPathS)));
+ }
} else {
if (visitor.isDerivation())
showDerivation();
diff --git a/src/nix/show-config.cc b/src/nix/show-config.cc
index 29944e748..3530584f9 100644
--- a/src/nix/show-config.cc
+++ b/src/nix/show-config.cc
@@ -9,15 +9,44 @@ using namespace nix;
struct CmdShowConfig : Command, MixJSON
{
+ std::optional<std::string> name;
+
+ CmdShowConfig() {
+ expectArgs({
+ .label = {"name"},
+ .optional = true,
+ .handler = {&name},
+ });
+ }
+
std::string description() override
{
- return "show the Nix configuration";
+ return "show the Nix configuration or the value of a specific setting";
}
Category category() override { return catUtility; }
void run() override
{
+ if (name) {
+ if (json) {
+ throw UsageError("'--json' is not supported when specifying a setting name");
+ }
+
+ std::map<std::string, Config::SettingInfo> settings;
+ globalConfig.getSettings(settings);
+ auto setting = settings.find(*name);
+
+ if (setting == settings.end()) {
+ throw Error("could not find setting '%1%'", *name);
+ } else {
+ const auto & value = setting->second.value;
+ logger->cout("%s", value);
+ }
+
+ return;
+ }
+
if (json) {
// FIXME: use appropriate JSON types (bool, ints, etc).
logger->cout("%s", globalConfig.toJSON().dump());
diff --git a/tests/check-refs.nix b/tests/check-refs.nix
index 9d90b0920..99d69a226 100644
--- a/tests/check-refs.nix
+++ b/tests/check-refs.nix
@@ -67,4 +67,11 @@ rec {
disallowedReferences = [test5];
};
+ test11 = makeTest 11 {
+ __structuredAttrs = true;
+ unsafeDiscardReferences.out = true;
+ outputChecks.out.allowedReferences = [];
+ buildCommand = ''echo ${dep} > "''${outputs[out]}"'';
+ };
+
}
diff --git a/tests/check-refs.sh b/tests/check-refs.sh
index 16bbabc40..65a72552a 100644
--- a/tests/check-refs.sh
+++ b/tests/check-refs.sh
@@ -40,3 +40,12 @@ nix-build -o $RESULT check-refs.nix -A test7
# test10 should succeed (no disallowed references).
nix-build -o $RESULT check-refs.nix -A test10
+
+if isDaemonNewer 2.12pre20230103; then
+ enableFeatures discard-references
+ restartDaemon
+
+ # test11 should succeed.
+ test11=$(nix-build -o $RESULT check-refs.nix -A test11)
+ [[ -z $(nix-store -q --references "$test11") ]]
+fi
diff --git a/tests/common.sh.in b/tests/common.sh.in
index 73c2d2309..74bbbc8ca 100644
--- a/tests/common.sh.in
+++ b/tests/common.sh.in
@@ -62,7 +62,7 @@ readLink() {
}
clearProfiles() {
- profiles="$NIX_STATE_DIR"/profiles
+ profiles="$HOME"/.local/share/nix/profiles
rm -rf $profiles
}
diff --git a/tests/config.sh b/tests/config.sh
index 3d0da3cef..723f575ed 100644
--- a/tests/config.sh
+++ b/tests/config.sh
@@ -51,3 +51,8 @@ exp_features=$(nix show-config | grep '^experimental-features' | cut -d '=' -f 2
[[ $prev != $exp_cores ]]
[[ $exp_cores == "4242" ]]
[[ $exp_features == "flakes nix-command" ]]
+
+# Test that it's possible to retrieve a single setting's value
+val=$(nix show-config | grep '^warn-dirty' | cut -d '=' -f 2 | xargs)
+val2=$(nix show-config warn-dirty)
+[[ $val == $val2 ]]
diff --git a/tests/export-graph.sh b/tests/export-graph.sh
index a1449b34e..4954a6cbc 100644
--- a/tests/export-graph.sh
+++ b/tests/export-graph.sh
@@ -4,7 +4,7 @@ clearStore
clearProfiles
checkRef() {
- nix-store -q --references $TEST_ROOT/result | grep -q "$1" || fail "missing reference $1"
+ nix-store -q --references $TEST_ROOT/result | grep -q "$1"'$' || fail "missing reference $1"
}
# Test the export of the runtime dependency graph.
diff --git a/tests/flakes/common.sh b/tests/flakes/common.sh
index c333733c2..9d79080cd 100644
--- a/tests/flakes/common.sh
+++ b/tests/flakes/common.sh
@@ -20,9 +20,13 @@ writeSimpleFlake() {
foo = import ./simple.nix;
default = foo;
};
+ packages.someOtherSystem = rec {
+ foo = import ./simple.nix;
+ default = foo;
+ };
# To test "nix flake init".
- legacyPackages.x86_64-linux.hello = import ./simple.nix;
+ legacyPackages.$system.hello = import ./simple.nix;
};
}
EOF
diff --git a/tests/flakes/init.sh b/tests/flakes/init.sh
index 36cb9956a..2d4c77ba1 100644
--- a/tests/flakes/init.sh
+++ b/tests/flakes/init.sh
@@ -41,8 +41,8 @@ cat > $templatesDir/trivial/flake.nix <<EOF
description = "A flake for building Hello World";
outputs = { self, nixpkgs }: {
- packages.x86_64-linux = rec {
- hello = nixpkgs.legacyPackages.x86_64-linux.hello;
+ packages.$system = rec {
+ hello = nixpkgs.legacyPackages.$system.hello;
default = hello;
};
};
diff --git a/tests/flakes/show.sh b/tests/flakes/show.sh
new file mode 100644
index 000000000..995de8dc3
--- /dev/null
+++ b/tests/flakes/show.sh
@@ -0,0 +1,39 @@
+source ./common.sh
+
+flakeDir=$TEST_ROOT/flake
+mkdir -p "$flakeDir"
+
+writeSimpleFlake "$flakeDir"
+cd "$flakeDir"
+
+
+# By default: Only show the packages content for the current system and no
+# legacyPackages at all
+nix flake show --json > show-output.json
+nix eval --impure --expr '
+let show_output = builtins.fromJSON (builtins.readFile ./show-output.json);
+in
+assert show_output.packages.someOtherSystem.default == {};
+assert show_output.packages.${builtins.currentSystem}.default.name == "simple";
+assert show_output.legacyPackages.${builtins.currentSystem} == {};
+true
+'
+
+# With `--all-systems`, show the packages for all systems
+nix flake show --json --all-systems > show-output.json
+nix eval --impure --expr '
+let show_output = builtins.fromJSON (builtins.readFile ./show-output.json);
+in
+assert show_output.packages.someOtherSystem.default.name == "simple";
+assert show_output.legacyPackages.${builtins.currentSystem} == {};
+true
+'
+
+# With `--legacy`, show the legacy packages
+nix flake show --json --legacy > show-output.json
+nix eval --impure --expr '
+let show_output = builtins.fromJSON (builtins.readFile ./show-output.json);
+in
+assert show_output.legacyPackages.${builtins.currentSystem}.hello.name == "simple";
+true
+'
diff --git a/tests/local.mk b/tests/local.mk
index 5ac1ede32..2aaaa67f9 100644
--- a/tests/local.mk
+++ b/tests/local.mk
@@ -17,6 +17,7 @@ nix_tests = \
fetchMercurial.sh \
gc-auto.sh \
user-envs.sh \
+ user-envs-migration.sh \
binary-cache.sh \
multiple-outputs.sh \
ca/build.sh \
@@ -113,6 +114,7 @@ nix_tests = \
store-ping.sh \
fetchClosure.sh \
completions.sh \
+ flakes/show.sh \
impure-derivations.sh \
path-from-hash-part.sh \
toString-path.sh
diff --git a/tests/nix_path.sh b/tests/nix_path.sh
index 2b222b4a1..d16fb4bb2 100644
--- a/tests/nix_path.sh
+++ b/tests/nix_path.sh
@@ -12,3 +12,8 @@ nix-instantiate --eval -E '<by-relative-path/simple.nix>' --restrict-eval
[[ $(nix-instantiate --find-file by-absolute-path/simple.nix) = $PWD/simple.nix ]]
[[ $(nix-instantiate --find-file by-relative-path/simple.nix) = $PWD/simple.nix ]]
+
+unset NIX_PATH
+
+[[ $(nix-instantiate --option nix-path by-relative-path=. --find-file by-relative-path/simple.nix) = "$PWD/simple.nix" ]]
+[[ $(NIX_PATH= nix-instantiate --option nix-path by-relative-path=. --find-file by-relative-path/simple.nix) = "$PWD/simple.nix" ]]
diff --git a/tests/containers.nix b/tests/nixos/containers/containers.nix
index a4856b2df..c8ee78a4a 100644
--- a/tests/containers.nix
+++ b/tests/nixos/containers/containers.nix
@@ -1,12 +1,7 @@
# Test whether we can run a NixOS container inside a Nix build using systemd-nspawn.
-{ nixpkgs, system, overlay }:
+{ lib, nixpkgs, ... }:
-with import (nixpkgs + "/nixos/lib/testing-python.nix") {
- inherit system;
- extraConfigurations = [ { nixpkgs.overlays = [ overlay ]; } ];
-};
-
-makeTest ({
+{
name = "containers";
nodes =
@@ -65,4 +60,4 @@ makeTest ({
host.succeed("[[ $(cat ./result/msg) = 'Hello World' ]]")
'';
-})
+}
diff --git a/tests/id-test.nix b/tests/nixos/containers/id-test.nix
index 8eb9d38f9..8eb9d38f9 100644
--- a/tests/id-test.nix
+++ b/tests/nixos/containers/id-test.nix
diff --git a/tests/systemd-nspawn.nix b/tests/nixos/containers/systemd-nspawn.nix
index 424436b3f..424436b3f 100644
--- a/tests/systemd-nspawn.nix
+++ b/tests/nixos/containers/systemd-nspawn.nix
diff --git a/tests/github-flakes.nix b/tests/nixos/github-flakes.nix
index a8b036b17..e4d347691 100644
--- a/tests/github-flakes.nix
+++ b/tests/nixos/github-flakes.nix
@@ -1,14 +1,9 @@
-{ nixpkgs, system, overlay }:
-
-with import (nixpkgs + "/nixos/lib/testing-python.nix") {
- inherit system;
- extraConfigurations = [ { nixpkgs.overlays = [ overlay ]; } ];
-};
-
+{ lib, config, nixpkgs, ... }:
let
+ pkgs = config.nodes.client.nixpkgs.pkgs;
# Generate a fake root CA and a fake api.github.com / github.com / channels.nixos.org certificate.
- cert = pkgs.runCommand "cert" { buildInputs = [ pkgs.openssl ]; }
+ cert = pkgs.runCommand "cert" { nativeBuildInputs = [ pkgs.openssl ]; }
''
mkdir -p $out
@@ -92,8 +87,6 @@ let
'';
in
-makeTest (
-
{
name = "github-flakes";
@@ -207,4 +200,4 @@ makeTest (
client.succeed("nix build nixpkgs#fuse --tarball-ttl 0")
'';
-})
+}
diff --git a/tests/nix-copy-closure.nix b/tests/nixos/nix-copy-closure.nix
index 2dc164ae4..66cbfb033 100644
--- a/tests/nix-copy-closure.nix
+++ b/tests/nixos/nix-copy-closure.nix
@@ -1,13 +1,16 @@
# Test ‘nix-copy-closure’.
-{ nixpkgs, system, overlay }:
+{ lib, config, nixpkgs, hostPkgs, ... }:
-with import (nixpkgs + "/nixos/lib/testing-python.nix") {
- inherit system;
- extraConfigurations = [ { nixpkgs.overlays = [ overlay ]; } ];
-};
+let
+ pkgs = config.nodes.client.nixpkgs.pkgs;
-makeTest (let pkgA = pkgs.cowsay; pkgB = pkgs.wget; pkgC = pkgs.hello; pkgD = pkgs.tmux; in {
+ pkgA = pkgs.cowsay;
+ pkgB = pkgs.wget;
+ pkgC = pkgs.hello;
+ pkgD = pkgs.tmux;
+
+in {
name = "nix-copy-closure";
nodes =
@@ -74,4 +77,4 @@ makeTest (let pkgA = pkgs.cowsay; pkgB = pkgs.wget; pkgC = pkgs.hello; pkgD = pk
# )
# client.succeed("nix-store --check-validity ${pkgC}")
'';
-})
+}
diff --git a/tests/nss-preload.nix b/tests/nixos/nss-preload.nix
index 5a6ff3f68..cef62e95b 100644
--- a/tests/nss-preload.nix
+++ b/tests/nixos/nss-preload.nix
@@ -1,11 +1,9 @@
-{ nixpkgs, system, overlay }:
-
-with import (nixpkgs + "/nixos/lib/testing-python.nix") {
- inherit system;
- extraConfigurations = [ { nixpkgs.overlays = [ overlay ]; } ];
-};
+{ lib, config, nixpkgs, ... }:
let
+
+ pkgs = config.nodes.client.nixpkgs.pkgs;
+
nix-fetch = pkgs.writeText "fetch.nix" ''
derivation {
# This derivation is an copy from what is available over at
@@ -41,9 +39,7 @@ let
'';
in
-makeTest (
-
-rec {
+{
name = "nss-preload";
nodes = {
@@ -122,4 +118,4 @@ rec {
nix-build ${nix-fetch} >&2
""")
'';
-})
+}
diff --git a/tests/remote-builds.nix b/tests/nixos/remote-builds.nix
index 9f88217fe..696cd2652 100644
--- a/tests/remote-builds.nix
+++ b/tests/nixos/remote-builds.nix
@@ -1,15 +1,9 @@
# Test Nix's remote build feature.
-{ nixpkgs, system, overlay }:
-
-with import (nixpkgs + "/nixos/lib/testing-python.nix") {
- inherit system;
- extraConfigurations = [ { nixpkgs.overlays = [ overlay ]; } ];
-};
-
-makeTest (
+{ config, lib, hostPkgs, ... }:
let
+ pkgs = config.nodes.client.nixpkgs.pkgs;
# The configuration of the remote builders.
builder =
@@ -75,7 +69,7 @@ in
# Create an SSH key on the client.
subprocess.run([
- "${pkgs.openssh}/bin/ssh-keygen", "-t", "ed25519", "-f", "key", "-N", ""
+ "${hostPkgs.openssh}/bin/ssh-keygen", "-t", "ed25519", "-f", "key", "-N", ""
], capture_output=True, check=True)
client.succeed("mkdir -p -m 700 /root/.ssh")
client.copy_from_host("key", "/root/.ssh/id_ed25519")
@@ -109,4 +103,4 @@ in
builder1.block()
client.succeed("nix-build ${expr nodes.client.config 4}")
'';
-})
+}
diff --git a/tests/setuid.nix b/tests/nixos/setuid.nix
index 6784615e4..2b66320dd 100644
--- a/tests/setuid.nix
+++ b/tests/nixos/setuid.nix
@@ -1,13 +1,12 @@
# Verify that Linux builds cannot create setuid or setgid binaries.
-{ nixpkgs, system, overlay }:
+{ lib, config, nixpkgs, ... }:
-with import (nixpkgs + "/nixos/lib/testing-python.nix") {
- inherit system;
- extraConfigurations = [ { nixpkgs.overlays = [ overlay ]; } ];
-};
+let
+ pkgs = config.nodes.machine.nixpkgs.pkgs;
-makeTest {
+in
+{
name = "setuid";
nodes.machine =
diff --git a/tests/sourcehut-flakes.nix b/tests/nixos/sourcehut-flakes.nix
index b77496ab6..a76fed020 100644
--- a/tests/sourcehut-flakes.nix
+++ b/tests/nixos/sourcehut-flakes.nix
@@ -1,12 +1,8 @@
-{ nixpkgs, system, overlay }:
-
-with import (nixpkgs + "/nixos/lib/testing-python.nix")
-{
- inherit system;
- extraConfigurations = [{ nixpkgs.overlays = [ overlay ]; }];
-};
+{ lib, config, hostPkgs, nixpkgs, ... }:
let
+ pkgs = config.nodes.sourcehut.nixpkgs.pkgs;
+
# Generate a fake root CA and a fake git.sr.ht certificate.
cert = pkgs.runCommand "cert" { buildInputs = [ pkgs.openssl ]; }
''
@@ -64,8 +60,6 @@ let
in
-makeTest (
-
{
name = "sourcehut-flakes";
@@ -164,4 +158,4 @@ makeTest (
client.succeed("nix build nixpkgs#fuse --tarball-ttl 0")
'';
- })
+}
diff --git a/tests/remote-store.sh b/tests/remote-store.sh
index 31210ab47..1ae126794 100644
--- a/tests/remote-store.sh
+++ b/tests/remote-store.sh
@@ -30,7 +30,3 @@ NIX_REMOTE= nix-store --dump-db > $TEST_ROOT/d2
cmp $TEST_ROOT/d1 $TEST_ROOT/d2
killDaemon
-
-user=$(whoami)
-[ -e $NIX_STATE_DIR/gcroots/per-user/$user ]
-[ -e $NIX_STATE_DIR/profiles/per-user/$user ]
diff --git a/tests/restricted.sh b/tests/restricted.sh
index 9bd16cf51..3b6ee2af1 100644
--- a/tests/restricted.sh
+++ b/tests/restricted.sh
@@ -17,6 +17,9 @@ nix-instantiate --restrict-eval --eval -E 'builtins.readDir ../src/nix-channel'
(! nix-instantiate --restrict-eval --eval -E 'let __nixPath = [ { prefix = "foo"; path = ./.; } ]; in <foo>')
nix-instantiate --restrict-eval --eval -E 'let __nixPath = [ { prefix = "foo"; path = ./.; } ]; in <foo>' -I src=.
+# no default NIX_PATH
+(unset NIX_PATH; ! nix-instantiate --restrict-eval --find-file .)
+
p=$(nix eval --raw --expr "builtins.fetchurl file://$(pwd)/restricted.sh" --impure --restrict-eval --allowed-uris "file://$(pwd)")
cmp $p restricted.sh
diff --git a/tests/user-envs-migration.sh b/tests/user-envs-migration.sh
new file mode 100644
index 000000000..467c28fbb
--- /dev/null
+++ b/tests/user-envs-migration.sh
@@ -0,0 +1,35 @@
+# Test that the migration of user environments
+# (https://github.com/NixOS/nix/pull/5226) does preserve everything
+
+source common.sh
+
+if isDaemonNewer "2.4pre20211005"; then
+ exit 99
+fi
+
+
+killDaemon
+unset NIX_REMOTE
+
+clearStore
+clearProfiles
+rm -rf ~/.nix-profile
+
+# Fill the environment using the older Nix
+PATH_WITH_NEW_NIX="$PATH"
+export PATH="$NIX_DAEMON_PACKAGE/bin:$PATH"
+
+nix-env -f user-envs.nix -i foo-1.0
+nix-env -f user-envs.nix -i bar-0.1
+
+# Migrate to the new profile dir, and ensure that everything’s there
+export PATH="$PATH_WITH_NEW_NIX"
+nix-env -q # Trigger the migration
+( [[ -L ~/.nix-profile ]] && \
+ [[ $(readlink ~/.nix-profile) == ~/.local/share/nix/profiles/profile ]] ) || \
+ fail "The nix profile should point to the new location"
+
+(nix-env -q | grep foo && nix-env -q | grep bar && \
+ [[ -e ~/.nix-profile/bin/foo ]] && \
+ [[ $(nix-env --list-generations | wc -l) == 2 ]]) ||
+ fail "The nix profile should have the same content as before the migration"