1
1
Fork 0
mirror of https://github.com/NixOS/nix.git synced 2025-11-15 23:12:44 +01:00
Commit graph

5066 commits

Author SHA1 Message Date
Eelco Dolstra
c7603c61c8 Mark tmpDir as const 2025-09-03 20:17:42 +02:00
Eelco Dolstra
2fe629c5d4 Fix deadlock in SSHMaster::addCommonSSHOpts()
When useMaster is true, startMaster() acquires the state lock, then
calls isMasterRunning(), which calls addCommonSSHOpts(), which tries
to acquire the state lock again, causing a deadlock.

The solution is to move tmpDir out of the state. It doesn't need to be
there in the first place because it never changes.
2025-09-03 17:49:24 +02:00
Jörg Thalheim
a0ce514769
Merge pull request #13866 from obsidiansystems/more-derivation-builder-cleanup
Even more `DerivationBuilder` cleanup
2025-09-01 20:35:16 +02:00
Jörg Thalheim
0d300112fa
Merge pull request #13862 from obsidiansystems/build-failure-content-vs-presentation
Properly separater builder failure content and presentation
2025-09-01 20:25:50 +02:00
Jörg Thalheim
de7f137f31
Merge pull request #13860 from obsidiansystems/derivation-building-resources-code-cleanup
Derivation building resources code cleanup
2025-09-01 20:22:30 +02:00
Jörg Thalheim
dc29cdf66d
Merge pull request #13858 from obsidiansystems/no-more-defered-exception
Get rid of `delayedException` in `DerivationBuilder`
2025-09-01 20:11:51 +02:00
Sergei Zimmerman
e548700010
lib{store,fetchers}: Pass URLs specified directly verbatim to FileTransferRequest
The URL should not be normalized before handing it off to cURL, because
builtin fetchers like fetchTarball/fetchurl are expected to work with
arbitrary URLs, that might not be RFC3986 compliant. For those cases
Nix should not normalize URLs, though validation is fine. ParseURL and
cURL are supposed to match the set of acceptable URLs, since they implement
the same RFC.
2025-09-01 02:22:23 +03:00
Sergei Zimmerman
e1c9bc0ef6
libstore: Get rid of allocations in printString, allocate 2K bytes on the stack
Looking at perf:

   0.21 │       push   %rbp
   0.99 │       mov    %rsp,%rbp
        │       push   %r15
   0.25 │       push   %r14
        │       push   %r13
   0.49 │       push   %r12
   0.66 │       push   %rbx
   1.23 │       lea    -0x10000(%rsp),%r11
   0.23 │ 15:   sub    $0x1000,%rsp
   1.01 │       orq    $0x0,(%rsp)
  59.12 │       cmp    %r11,%rsp
   0.27 │     ↑ jne    15

Seems like 64K is too much to have on the stack for each invocation, considering
that only a minuscule number of allocations are actually larger than 4K.

There's actually no good reason this function should use so much stack space. Or
use small_string at all. Everything can be done in small chunks that don't require
any memory allocations and use up 2K bytes on the stack.

This patch also adds a microbenchmark for tracking the unparsing performance. Here
are the results for this change:

(Before)

BM_UnparseRealDerivationFile/hello         7275 ns         7247 ns        96093 bytes_per_second=232.136Mi/s
BM_UnparseRealDerivationFile/firefox      40538 ns        40376 ns        17327 bytes_per_second=378.534Mi/s

(After)

BM_UnparseRealDerivationFile/hello         3228 ns         3218 ns       215671 bytes_per_second=522.775Mi/s
BM_UnparseRealDerivationFile/firefox      39724 ns        39584 ns        17617 bytes_per_second=386.101Mi/s

This translates into nice evaluation performance improvements (compared to 18c3d2348f):

Benchmark 1: GC_INITIAL_HEAP_SIZE=8G old-nix/bin/nix-instantiate ../nixpkgs -A nixosTests.gnome --readonly-mode
  Time (mean ± σ):      3.111 s ±  0.021 s    [User: 2.513 s, System: 0.580 s]
  Range (min … max):    3.083 s …  3.143 s    10 runs

Benchmark 2: GC_INITIAL_HEAP_SIZE=8G result/bin/nix-instantiate ../nixpkgs -A nixosTests.gnome --readonly-mode
  Time (mean ± σ):      3.037 s ±  0.038 s    [User: 2.461 s, System: 0.558 s]
  Range (min … max):    2.960 s …  3.086 s    10 runs
2025-08-31 00:48:37 +03:00
John Ericson
a8c4cfae26 DerivationBuildingGoal::done* restore outputLocks.unlock()
This was accidentally removed in
169033001d.
2025-08-29 17:49:11 -04:00
John Ericson
d7ed86ceb1 Move deleting redirected outputs in to cleanupBuild
It is only done in the `force = true` case, and the only
`cleanupBuild(true)` call is right after where it used to be, so this
has the exact same behavior as before.
2025-08-29 16:10:25 -04:00
John Ericson
76125f8eb1 Get rid of Finally in DerivationBuilderImpl::unprepareBuild
Calling `reset` on this `std::optional` field of `DerivationBuilderImpl`
is also what the (automatically created) destructor of
`DerivationBuilderImpl` will do. We should be making sure that the
derivation builder is cleaned up by the goal anyways, and if we do that,
then this `Finally` is no longer needed.
2025-08-29 13:22:36 -04:00
Jörg Thalheim
0d006aedd6
Merge pull request #13854 from obsidiansystems/register-outputs-slight-simplify
Simplify handling of statuses for build errors
2025-08-29 07:20:55 +02:00
John Ericson
8825bfa7fe Properly separater builer failure content and presentation
Before, had a very ugly `appendLogTailErrorMsg` callback. Now, we
instead have a `fixupBuilderFailureErrorMessage` that is just used by
`DerivationBuildingGoal`, and `DerivationBuilder` just returns the raw
data needed by this.
2025-08-28 22:17:15 -04:00
John Ericson
47cae1f72b
Merge pull request #13850 from obsidiansystems/factor-out-drv-env-desugar
Factor out a new `DesugaredEnv` from `DerivationBuildingGoal`
2025-08-28 17:10:48 -04:00
John Ericson
53c31c8b29 Factor out a new DesugaredEnv from DerivationBuildingGoal
Now we have better separation of the core logic --- an integral part of
the store layer spec even --- from the goal mechanism and other
minutiae.

Co-authored-by: Jeremy Kolb <kjeremy@gmail.com>
2025-08-28 16:45:45 -04:00
Jörg Thalheim
c436b7a32a
Fix ParsedURL handling of %2F in URL paths
See the new extensive doxygen in `url.hh`.
This fixes fetching gitlab: flakes.

Paths are now stored as a std::vector of individual path
segments, which can themselves contain path separators '/' (%2F).
This is necessary to make the Gitlab's /projects/ API work.

Co-authored-by: John Ericson <John.Ericson@Obsidian.Systems>
Co-authored-by: Sergei Zimmerman <sergei@zimmerman.foo>
2025-08-28 22:20:04 +03:00
John Ericson
3e0b1705c1 Move markContentsGood to after DerivationBuilder finishes
I think this should be fine for repairing. If anything, it is better,
because it would be weird to "mark and output good" only for it to then
fail output checks.
2025-08-28 14:54:11 -04:00
Sergei Zimmerman
c2782d7b84
Merge pull request #13853 from obsidiansystems/no-old-debugging-aid
Revert "Add a crude tracing mechansim for the build results"
2025-08-28 21:18:10 +03:00
John Ericson
bde745cb3f Move killChild call from ~DerivationBuildingGoal to ~DerivationBuilder
Sadly we cannot unexpose `DerivationBuilder::killChild` yet, because
`DerivationBuildingGoal` calls it elsewhere, but we can at least haave a
better division of labor between the two destructors.
2025-08-28 14:01:24 -04:00
John Ericson
c632c823ce Take DerivationBuilder::pid private 2025-08-28 14:01:20 -04:00
John Ericson
4388e3dcb5 Create DerivationBuilder::killChild
Then the derivation building goal doesn't need to snoop around as much.
2025-08-28 14:01:17 -04:00
John Ericson
49da508f46 Write a destructor for DerivationBuilderImpl
This allows `DerivationBuildingGoal` to know less.
2025-08-28 14:01:14 -04:00
John Ericson
557bbe969e Combine cleanupBuild and deleteTmpDir
It's hard to tell if I changed any behavior, but if I did, I think I
made it better, because now we explicitly move stuff out of the chroot
(if we were going to) before trying to delete the chroot.
2025-08-28 14:01:11 -04:00
John Ericson
4db6bf96b7 Give DerivationBuilderImpl::cleanupBuild bool arg
Do this to match `DerivationBuilder::deleteTmpDir`, which we'll want to
combine it with next.

Also chenge one caller from `deleteTmpDir(true)` to `cleanupBuild(true)`
now that this is done, because it will not make a difference.

This should be a pure refactor with no behavioral change.
2025-08-28 14:01:08 -04:00
John Ericson
8dd289099c Simplify DerivationGoal::unprepareBuild::diskFull
We only need it defined in the narrower scope
2025-08-28 14:01:05 -04:00
John Ericson
374f8e79a1 DerivationBuilderImpl::unprepareBuild Just throw error
Aftet the previous simplifications, there is no reason to catch the
error and immediately return it with a `std::variant` --- just let the
caller catch it instead.
2025-08-28 14:00:35 -04:00
John Ericson
0b85b023d8 Get rid of delayedException in DerivationBuilder
Instead of that funny business, the fixed output checks are not put in
`checkOutputs`, with the other (newer) output checks, where they also
better belong. The control flow is reworked (with comments!) so that
`checkOutputs` also runs in the `bmCheck` case.

Not only does this preserve existing behavior of `bmCheck`
double-checking fixed output hashes with less tricky code, it also makes
`bmCheck` better by also double-checking the other output checks, rather
than just assuming they pass if the derivation is deterministic.
2025-08-28 11:44:18 -04:00
John Ericson
ff961fd9e2 Get rid of DerivationBuilder::note*Mismatch
It's fine to set these worker flags a little later in the control flow,
since we'll be sure to reach those points in the error cases. And doing
that is much nicer than having these tangled callbacks.

I originally made the callbacks to meticulously recreate the exact
behavior which I didn't quite understand. Now, thanks to cleaning up the
error handling, I do understand what is going on, so I can be confident
that this change is safe to make.
2025-08-28 11:44:18 -04:00
John Ericson
169033001d Simplify handling of statuses for build errors
Instead of passing them around separately, or doing finicky logic in a
try-catch block to recover them, just make `BuildError` always contain a
status, and make it the thrower's responsibility to set it. This is much
more simple and explicit.

Once that change is done, split the `done` functions of `DerivationGoal`
and `DerivationBuildingGoal` into separate success and failure
functions, which ends up being easier to understand and hardly any
duplication.

Also, change the handling of failures in resolved cases to use
`BuildResult::DependencyFailed` and a new message. This is because the
underlying derivation will also get its message printed --- which is
good, because in general the resolved derivation is not unique. One dyn
drv test had to be updated, but CA (and dyn drv) is experimental, so I
do not mind.

Finally, delete `SubstError` because it is unused.
2025-08-27 20:05:06 -04:00
John Ericson
0590b13156 Revert "Add a crude tracing mechansim for the build results"
The commit says it was added for CA testing --- manual I assume, since
there is no use of this in the test suite. I don't think we need it any
more, and I am not sure whether it was ever supposed to have made it to
`master` either.

This reverts commit 2eec2f765a.
2025-08-27 19:36:02 -04:00
Bernardo Meurer Costa
241abcca86
refactor(libstore/http-binary-cache-store): pragma once 2025-08-27 21:13:59 +00:00
John Ericson
d1bdaef04e Factor out checkOutputs
We currently just use this during the build of a derivation, but there is no
reason we wouldn't want to use it elsewhere, e.g. to check the outputs
of someone else's build after the fact.

Moreover, I like pulling things out of `DerivationBuilder` that are
simple and don't need access to all that state. While
`DerivationBuilder` is unix-only, this refactor also make the code more
portable "for free".

The header is private, at Eelco's request.
2025-08-27 16:25:46 -04:00
John Ericson
6c8f5ef9f7
Merge pull request #13802 from obsidiansystems/post-build-hook-later
Move `runPostBuildHook` out of `DerivationBuilder`
2025-08-27 15:48:05 -04:00
John Ericson
f4a0161cb1 Create StringSet DerivationBuilderParams::systemFeatures
Do this to avoid checking "system features" from the store config
directly, because we rather not have `DerivationBuilder` depend on
`Store`.
2025-08-27 12:38:15 -04:00
John Ericson
f5f9e32f54 No more DerivationBuilderParams: constructor!
I am not sure how/why this started working. C++23?
2025-08-27 11:40:02 -04:00
John Ericson
e82210b3b2 Implement parseURLRelative, use in HttpBinaryCacheStore
This allows us to replace some very hacky and not correct string
concatentation in `HttpBinaryCacheStore`. It will especially be useful
with #13752, when today's hacks started to cause problems in practice,
not just theory.

Also make `fixGitURL` returned a `ParsedURL`.
2025-08-26 19:45:10 -04:00
John Ericson
0250d50df3 Move runPostBuildHook out of DerivationBuilder
It is suppposed to be "post build" not "during the build" after all. Its
location now matches that for the hook case (see elsewhere in
`DerivationdBuildingGoal`).

It was in a try-catch before, and now it isn't, but I believe that it is
impossible for it to throw `BuildError`, which is sufficient for this
code motion to be correct.
2025-08-25 18:29:24 -04:00
Robert Hensing
c1e2396d58
Merge pull request #13826 from xokdvium/sqlite-zfs-hack
SQLite: fsync db.sqlite-shm before opening the database
2025-08-26 00:05:40 +02:00
Eelco Dolstra
e492c64c8e
SQLite: fsync db.sqlite-shm before opening the database
This is a workaround for https://github.com/NixOS/nix/issues/13515
(opening the SQLite DB randomly taking a couple of seconds on ZFS).

(cherry picked from commit a7fceb5eec)
2025-08-26 00:42:18 +03:00
John Ericson
e4e8a615fa ParsedS3URL::toHttpsUrl Slight optimize
I didn't want to block that PR on further code review while I figured
out these new (to us) C++23 goodies.
2025-08-25 16:53:39 -04:00
Bernardo Meurer Costa
5985d67906
feat(libstore/s3): add toHttpsUrl
This is extracted from the work in #13752
2025-08-25 18:48:19 +00:00
John Ericson
3e86d75c9d Make more URLs parsed, most notably FileTransferRequest::url
Trying to gradually replace the use of strings with better types in ways
that makes sense.
2025-08-22 12:42:48 -04:00
John Ericson
72a548ed6a Limit to lenient parsing of non-standard URLs only where needed
This allows us to put `parseURL` in more spots without furthering
technical debt.
2025-08-22 12:37:37 -04:00
Eelco Dolstra
615b10cb44
Merge pull request #13800 from NixOS/concurrent-eval-cache
Use WAL mode for SQLite cache databases
2025-08-21 11:42:15 +02:00
John Ericson
4c76db8e7c Make sure settings.sandboxedPaths is closed outside DerivationBuilder
This is a nicer separation of concerns --- `DerivationBuilder` just
mounts the extra paths you tell it too, and the outside world is
responsible for making sure those extra paths make sense.

Since the closure only depends on global settings, and not
per-derivation information, we also have the option of moving this up
further and caching it across all local builds. (I only just realized
this after having done this refactor. I am not doing that change at this
time, however.)
2025-08-20 18:49:11 -04:00
John Ericson
1d3ddb21fa Further consolidate environment variable processing outside DerivationBuilder
Now, `DerivationBuilder` only concerns itself with `finalEnv` and
`extraFiles`, in straightforward unconditional code. All the fancy
desugaring logic is consolidated in `DerivationBuildingGoal`.

We should better share the pulled-out logic with `nix-shell`/`nix
develop`, which would fill in some missing features, arguably fixing
bugs.
2025-08-20 16:54:17 -04:00
John Ericson
e3c74f5a13 Desugar structured attrs, "export reference graph" outside DerivationBuilder
I think this is a better separation of concerns. `DerivationBuilder`
doesn't need to to the final, query-heavy details about how these things
are constructed. It just operates on the level of "simple, stupid" files
and environment variables.
2025-08-20 16:54:17 -04:00
John Ericson
92b10cf3f5 DerivationBuilderImpl::writeStructuredAttrs remove a rewrite
As much as I prefer rewriting the parsed rather than unparsed JSON for
elegance, this gets in the way of the separation of concerns that I am
trying to do.

As a practical matter, any rewriting that this did will also be done by
the second round of rewriting that remains below, so removing this code
should have no effect.
2025-08-20 16:54:17 -04:00
John Ericson
2767ae35d9 Deduplicate "export reference graph" logic a bit
The first part on `drvOptions.exportReferencesGraph` is the same in both
cases. It is just how the information is finally rendered that is
different.
2025-08-20 16:54:17 -04:00
John Ericson
a712445a7a Make Settings::sandboxPaths well-typed
Parsing logic is moved from `DerivationBuilder`, where is doesn't
belong, to `Settings` itself, where it does.
2025-08-20 16:24:37 -04:00