Commit Graph
18488 Commits
Author SHA1 Message Date
Raito Bezarius 91867941fa libstore/s3: sign payloads if the request demands it
This fixes problems with S3 implementations that have mandatory payload
signing, e.g. Garage v2, AWS S3 itself, etc.

The problem manifested itself when the AWS SDK threw some error codes 99
(NETWORK_CONNECTION) with no messages and retried until it finally came
to a moment where the state machinery decided to send a
`Transfer-Encoding` header in a `Content-Encoding`/`Content-Length`-set
request with signed headers (even though payload signing is disabled),
causing the server to reject the transfer and crash the copy.

I did not debug super far what went wrong in AWS SDK, but I can confirm
this change makes transfers possible to finish with Garage v2.

Change-Id: Icc9e6a9f2afb0d760cf2d1e27816decd385a1d85
Signed-off-by: Raito Bezarius <raito@lix.systems>
2025-10-31 20:01:14 +01:00
Commentator2.0 9ed75192ec tests/functional2: fix crash on empty nix.nix([]) calls on darwin
Calling `nix.nix` with an empty argument list, would crash on darwin due
to a Index Out Of Range Error, as the build="auto" functionallity would
try to access the first element of the provided arguments (second
element at the place of call) resulting in a crash

Change-Id: Ia678109808b3f75a30182114baa421cedaa8759b
2025-10-30 18:53:11 +00:00
Raito Bezarius 95f15cf94f libstore/binary-cache: default to zstd for compression
libarchive's xz offers single threaded xz compression which is very slow
and provides ~10-20Mbps compression speed in addition to maxing a core.

In exchange, it achieves optimal compression ratios among all our
compression methods.

Nonetheless, xz prevent the saturation of 1Gbps+ connections and slow
down significantly decompression for end users. As these connections and
faster hardware is becoming prevalent for cache servers and clients, we
offer to default to zstd.

Lix is a "compress once, decompress many times" application. To avoid
incurring a high penalty to end users very sensitive to compress ratio
(very slow Internet connections), we dampen the consequences of
switching to zstd by increasing the default zstd level to 12.

On one example, xz will compress a 4.4GB file to 632MB, zstd on 12 will
compress it to 775MB, that is a ~18 % increase over the optimal xz
compression. zstd took 18 seconds to produce this file.

Increasing to level 14 leads to a 773MB file while taking 37s.
Increasing to level 16 leads to 735MB file while taking 66s.

Finally, xz took 77s, so a 50 % reduction in time taken to compress in
exchange of an increase of 18 % of the compressed size.

This change will reduce issues encountered in #945 but is probably not
the root cause.

References:

- https://discourse.nixos.org/t/switch-cache-nixos-org-to-zstd-to-fix-slow-nixos-updates-nix-downloads/23961

Change-Id: I7beda2bf2c1fed146dcb797b8f85dc290c486ab2
Signed-off-by: Raito Bezarius <raito@lix.systems>
2025-10-30 15:10:10 +01:00
eldritch horrors 047aad9992 libstore: fix s3 promise fulfiller lifetimes
if a promise for an async s3 operation is cancelled is inner fulfiller
will be destroyed, but the s3 operation may still be running. once the
operation finished and attempted to fulfill the promise we'd segfault.

Change-Id: I603c75d6cc39a1aee465b3ceee06b638f7f7f596
2025-10-30 13:57:15 +01:00
Raito Bezarius 1f08eaeb55 doc/manual: provide more information about Pasta and its shortcomings
As we saw actual users running into them throughout the debugging of
#920 and #1014.

It's best to document and point end users to this so they can take
measures for themselves.

Change-Id: I7d08407f4354055bf65fc6dd7d1624c5a9304402
Signed-off-by: Raito Bezarius <raito@lix.systems>
2025-10-30 00:04:21 +01:00
Raito Bezarius 480c8e52b6 libstore/linux/pasta: always list an IPv4 & IPv6 nameserver
Fixes #1014.

Address family detection is performed by Pasta, we influence Pasta into
enabling dual stack by listing both an IPv4 & IPv6.

Change-Id: I4121e0eae7d5185c287957106adc36edf3f82a40
Signed-off-by: Raito Bezarius <raito@lix.systems>
2025-10-29 21:44:12 +00:00
Raito Bezariusandeldritch horrors 12b87538e3 lix/nix-shell: cleanup of shell directories happens in Lix itself
Instead of letting inner shell perform the cleanup, we will fork/execvp
and finish the work ourselves. Once an interruption arrives, we wait
again and return the exit status code of the inner shell.

This idea was suggested by eldritch horrors.

Fixes #1020.

Co-authored-by: eldritch horrors <pennae@lix.systems>
Change-Id: Id38af7ac33874aa1c4b7ca9c6123e3cbd8c3cd8c
Signed-off-by: Raito Bezarius <raito@lix.systems>
2025-10-29 20:13:23 +01:00
Raito Bezarius f6d723b22f lix/main: return the legacy command statuses
This was forgotten which should have been part of 64b9247f.

Change-Id: I3cf83d8699f2c1963ce530bbea6a511075202a79
Signed-off-by: Raito Bezarius <raito@lix.systems>
2025-10-29 18:53:00 +01:00
Raito Bezarius 64b9427f98 legacy/nix-build: return exit codes
Legacy commands "main function" will now return an exit code.
Fun fact: `main_nix_build` was the only one not returning integers
already.

Change-Id: Ia43a16c3c3fb9a670e8889aefc4ee9b6528a7df4
Signed-off-by: Raito Bezarius <raito@lix.systems>
2025-10-28 20:38:39 +01:00
Raito Bezarius 56b4ed3908 libmain/main: propagate status codes via return values for mainWrapped
This also prevent `legacy` to return nothing as it's void.

Change-Id: Ic797544a59b04b41ad9e1c46af4cad3a1cb6fdc8
Signed-off-by: Raito Bezarius <raito@lix.systems>
2025-10-28 20:38:39 +01:00
eldritch horrors 2c176afa7a libutil: don't allow interactive runProgram2
realistically only runProgram is ever called for interactive reasons,
and even those calls seem to be rather ill-advised in many cases. the
chance of multiple interactive processes interfering with each other,
whether for input or for output, must be very low to make this in any
way reasonable: if e.g. git calls ssh for multiple fetched inputs and
ssh requests passphrases for both we can otherwise not guarantee that
*any* input is routed correctly. misrouted output is merely annoying.

Change-Id: I794e3fdf0a3238cb9292003a89ac267f0de7a939
2025-10-28 11:53:33 +00:00
Qyriad 9523446901 libexpr/libutil: summarize derivations in stack traces regardless of --show-trace
Eval errors will now print a simple, no frills chain of involved
derivations at the bottom. For example, trying to evaluate
`pkgs.xonsh.override { python3 = pkgs.python2; }` has the usual

Package ‘python-2.7.18.8’ in /nix/store/9v6qa656sq3xc58vkxslqy646p0ajj61-source/pkgs/development/interpreters/python/cpython/2.7/default.nix:398 is marked as insecure, refusing to evaluate.

message, but now also includes the following:

       note: trace involved the following derivations:
       derivation 'xonsh-0.19.9'
       derivation 'python2.7-xonsh-0.19.9'
       derivation 'python2.7-setuptools-44.0.0'

To give the user information about why the erroring derivation was
involved in the first place.

We would like more structured information in the future, but this should
still be a significant improvement.

Change-Id: Icf6da52abd0a043cfb63943bf0b0c160c21ee59e
2025-10-27 20:28:27 +01:00
Commentator2.0 73c019c57b tests/functional2/lang: allow adding requiring of global assets like config.nix
Change-Id: Ia740b91fb3d18f7d01c0d551196b71e7f3e46384
2025-10-27 17:07:47 +01:00
Qyriad 836caf1173 libutil: add concepts for constraining iterables ("ranges")
Change-Id: I5d75abb9d3713a3fab863666786aa8d38cc93dbd
2025-10-27 13:16:29 +01:00
Qyriad b8462562f2 libutil: allow moving Trace into Error
`pushTrace` now move-constructs or copy-constructs, instead of always
copy-constructing.

Change-Id: Ie5f02643e98b7a6c1adbe58b0d46d9e116eba28e
2025-10-27 13:14:50 +01:00
eldritch horrors 18efc848fe libstore: move curl-multi wrapper into own class
the wrapper is needed by transfer streams to restart a failed transfer
if desired. curlFileTransfer itself is more of a fancy handler for the
thread we're dedicating to curl io handling. the thread will stay with
the multi handle for now because quit handling needs to stay there. we
could have CurlMulti keep only a flag, but that does not help us much.

Change-Id: I99550f0bbb635b75898ca7260f08275df86050e3
2025-10-23 22:52:09 +00:00
eldritch horrors b460a7a38b libstore: move curlFileTransfer::TransferItem up
we have anonymous namespaces and no other scoping requirements, we can
move it out. this will also make it easier to move *other* things out,
such as the transport streams and all the shared multi state handling.

Change-Id: Iafa1eaeb69e096e98c4667f0531b17d5fe7c78a6
2025-10-24 00:16:15 +02:00
eldritch horrors 253ed1cc05 libstore: abort all transfers when shutting down curl thread
waiting for them to finish leaves us prone to deadlocking, e.g. if some
active transfers is blocked and hasn't been destroyed before our thread
was asked to exit. aborting transfers is the safer option here; even if
we cause use after frees we'll at least have a crash, not hang forever.

Change-Id: I333dcced810e8a85e2ded1f377962a0176798098
2025-10-22 17:36:21 +00:00
Raito Bezarius e0d2fa89d3 libstore/build: resolve symlinks beneath settings.caFile
This behavior existed before I32f8b5ce20fe9b6a911768114c92f95fc886cc07
was introduced.

It was remarked in
https://gerrit.lix.systems/c/lix/+/3765/comment/1ff0b2b7_ae67ab1b/.

Change-Id: I7a72e7c36c6043a6c2cb8cab57ad45a552d5e2b6
Signed-off-by: Raito Bezarius <raito@lix.systems>
2025-10-22 13:23:48 +00:00
Alois Wohlschlager 7a0b8834a4 Reapply "functional2: fix in the development shell"
This reverts commit 3ef7e0711b.

Change-Id: I5b76d2c2e9b0dd669818c7218493d3e76a6a6964
2025-10-22 07:41:46 +02:00
Alois Wohlschlager 0e0853cc70 functional2: handle unset or empty BUILD_TEST_SHELL properly
If BUILD_TEST_SHELL is not set or empty, None or the empty string respectively
should not make it into the PATH. Ensure this property.

Change-Id: I4ce9b0c06c407b465308b63b9cb64e7d6a6a6964
2025-10-22 07:41:46 +02:00
eldritch horrors 5346b2bc68 libstore: simplify worker child handling a bit
we no longer need the optional wrapping.

Change-Id: I742cca23753c6e0a97ada0b301bb42f442803ea8
2025-10-20 12:43:22 +00:00
eldritch horrors 31b6eb2786 libstore: convert build-hook logging to rpc
Change-Id: I0c20f89de113dce6032c93a32e9fcd43b4478f55
2025-10-20 12:43:22 +00:00
eldritch horrors 5b7ed433d6 libutil: add logging rpc definitions
this is still somewhat experimental and should be considered in flux. we
will have to nail down a logger interface once we start moving the store
protocol to rpc, but until we do that we can use build hooks to test it.

Change-Id: Id20cd346c9520f45871799c31b0af040adde56ef
2025-10-20 12:43:22 +00:00
eldritch horrors 2d2cd7ac03 libutil: always rethrow kj::CanceledException
the fiber runtime requires this for correctness.

Change-Id: I5ebc6a046596403e86cebaa95962053ff7813877
2025-10-20 12:43:22 +00:00
eldritch horrors bab44b870e libstore: handle log size limiting in only one place
extracting the size-specific log handling into a new sink deduplicates
the size-limiting code and lets us clean up the derivation goal a bit:
a number of log-related fields we kept only because previous ownership
semantics were a lot more ad-hoc can be moved into the new sink class.

Change-Id: Ie770a276597c84f9d928a9624c0f0de86adfe815
2025-10-20 12:43:22 +00:00
eldritch horrors 4b9723a23f libstore: DerivationGoal::{handleChildOutput -> wrapChildHandler}
we'll want to remove handleRawChildStream from DerivationGoal, but the
timeout handling is still important. the wrapper is thus useful, but a
more generic way to pass it a promise to do the handling is necessary.

Change-Id: I55bf041d51e4f8a8b8291deae053423d06724329
2025-10-20 12:43:22 +00:00
eldritch horrors b02a66d13e libstore: simplify hook instance handling
we never need the connection or the rpc client directly after the hook
is constructed, only the hook instance rpc object. wrapping them using
kj primitives makes this more explicit and prevents destruction errors

Change-Id: I7e0b14d7e365c2e001273e04c0e741ba4afb12f2
2025-10-20 12:43:08 +00:00
eldritch horrors 6c416ff2ca libstore: make build hook exit status reusable
this makes it possible to wait for the hook to exit in one place,
process its exit status for some purpose, and later process it in
another place for a different purpose. rpc will need this to shut
down a hook cleanly after the hook has completed its assignments.

Change-Id: I5af2d5aac4b02a0a200d720d0e6f0b5df5496aaf
2025-10-19 16:09:32 +00:00
eldritch horrors 7e171a4abe libstore: localize act, builderActivities
only LocalDerivationGoal needs these, and once the child is done
running (or is begin torn down) we can just destroy all of them.

Change-Id: Id4d9f0105aaf33d6736c435bb891d3f9af8e7894
2025-10-18 21:33:54 +00:00
eldritch horrors 0365d17d7e libutil: disallow implicit ref downcasts
wtf?

Change-Id: I3dbce7052e72525c9430efb0f5090b168db04750
2025-10-18 21:33:54 +00:00
eldritch horrors 641769414b libutil: add a timed wait to async mutex
wrapping the wait in a timeout at the call site is insufficient because
a timeout would not relock the mutex and leave the raii object invalid.

Change-Id: I0be2aaf6b3c9966070fb0f1deaab048765fd7af3
2025-10-18 21:33:54 +00:00
Commentator2.0 2541db5321 tests/functional2/lang: fix expected skip message
it seems like pytest is updating the message printed when skipping a set
due to no parametrization
which leads to breakage on staging-next.
this commit changes the expected message to allow both old and new skip
message

Change-Id: I34d11ad84d7075911d8229fbc89889bb880a27c9
2025-10-18 17:19:01 +02:00
Commentator2.0 0ac71ea1cc tests/functional2/lang: fix wrong unused file error for generic test group collection
Change-Id: I1c548fcebe45d2a6621987091e3a852b8a9b5765
2025-10-18 11:24:00 +00:00
Commentator2.0 4fcfdc66fe tests/functional2: migrate debugger.sh
Change-Id: I82c5b739db09530ff216c91608be2f70a2036e11
2025-10-18 11:23:43 +00:00
helle e8d281eac6 doc: information at the use-cgroups option on conflicts it can give
as discussed on Zulip and with Lunaphied

Change-Id: I7c6b3e7994c1e7961033e3daf509c81348927baf
2025-10-18 09:51:36 +00:00
K900 6e2edbff93 flake: only apply the monotonic clocks patch to capnp<1.2.0
1.2.0 already includes it so building on unstable fails.

Change-Id: Iefa49203c371e5bab164c06b9da6f89a89ce7cfe
2025-10-18 12:04:06 +03:00
eldritch horrors a55fe35dac apply capnp patches again
This partially reverts commit f68233ec43.

while more modern capnp in *does* have the build system changes, it
does *not* have the patches. and those patches are rather important
to us; the clock patch because our CI machiens don't behave the way
capnp expect and the nodiscard patch because it *is* a bugsquasher.

Change-Id: Ic273777f09fd8e5e7001f815db8998dae2dd7b88
2025-10-17 19:21:17 +00:00
EmilyandQyriad 6ea1d8e37e libstore: use makeTempSiblingPath in replaceValidPath
Change-Id: I6a6a69641a3b4e6fdd076faac44dc314e6cc057e
2025-10-17 18:41:58 +00:00
EmilyandQyriad 39ebb982ea libutil: add makeTempSiblingPath helper
The prospective callers of this should probably be doing something
smarter or more abstracted to begin with, but this is useful as an
incremental improvement for call sites with existing `makeTempPath`
logic in the face of filename length limits.

Change-Id: I6a6a69644292f5bbf984a1df90192e06c6022b53
2025-10-17 18:41:58 +00:00
EmilyandQyriad d9eead0eac tests: add fetchTarball test for symlink temporary directories
Change-Id: I6a6a6964dfe85b5ee4f66b8c442fe448c7c5c87c
2025-10-17 18:41:58 +00:00
Qyriad 013d5e54e9 libstore: fix non-awaited calls to optimisePath()
LocalStore::optimisePath() was made asynchronous in 38b75b736¹, but we
lost warnings for not awaiting kj::Promise in f68233ec4², since our
capnproto no longer has the [[nodiscard]] patch.

[1]: 38b75b7367
[2]: f68233ec43

Change-Id: I2363396949f40dd43eae08cc76be9ede6b488cf7
2025-10-17 18:41:43 +00:00
eldritch horrors 20ba2b49fb testing: mock ssh during nix-copy prompt test
we don't need full ssh, we only need to know something makes it onto the terminal.

Change-Id: Ic31808e10e1b876b35d0dbdeee0b5ede7b5b9883
2025-10-17 15:13:37 +02:00
eldritch horrors ab9dddfb7a libutil: wrap async kj exceptions as errors
this is important for rpc error reporting: if the peer disconnects we
want to throw a useful error that can e.g. let pending builds finish,
not kill the entire process because kj errors are non-lix exceptions.

Change-Id: I41ebe10ad7fd65d886238ce52eeca1fa243b1bb2
2025-10-17 11:33:00 +00:00
eldritch horrors 21d7cb8e1c libstore: initialize build hooks via rpc
this removes another file descriptor from the build hook. we are now
using only rpc to communicate between build hook and daemon, setting
the stage for a future world in which we don't even need build hooks

Change-Id: I706d9d3f2a420abd42fc7762c205931a45d3c8c5
2025-10-17 11:33:00 +00:00
eldritch horrors 9b886e2acf libstore: remove unused DerivationGoal::machineName
interpolation of the remote store name into activity text is now done in
the build hook, so we no longer need to send it back to the daemon. this
also reduces the dependency of the daemon on how *exactly* remote builds
are done a little bit, and maybe in time we can make these fully opaque.

Change-Id: Ie51c4f2cd107350fec4ad0a8ef83621ed86db6a2
2025-10-17 11:33:00 +00:00
eldritch horrors 711ad52776 libstore: move logSize into each log handler
there's no need for this to be an instance variable of the goals.

Change-Id: Iaa315e8b5d8649d8eb3c3fedc387c0f0c48945fc
2025-10-17 11:33:00 +00:00
eldritch horrors 645a0533eb libstore: move sandbox log handling to LocalDerivationGoal
only local builds can now have a builderOutFD, remote builds only log
via json streams. these two kinds of logs have different requirements
and each is only needed by its respective build kind. splitting these
apart thus makes sense, though ideally we'd also split DerivationGoal
into a RemoteDerivationGoal to clean up the rest, but that will wait.

Change-Id: Ib577537266d1160355ab9c44b4604ebda87a7d04
2025-10-17 11:33:00 +00:00
eldritch horrors a824877d45 libstore: don't treat legacy ssh like a sandbox
treat it like ssh-ng instead, and have the build hook do the translation
of ssh stdout to the json log message steam the derivaiton goal can use.
since the ssh-ng path also handles all store urls that aren't legacy ssh
we now have a single logging system that handles every remote build kind
equally, without requiring fd passing into the build hook. this is later
required to rpc-ify the log stream emitted by build hooks to the daemon.

Change-Id: Ifb522eb8a9745029050f16b1b3b3601a6ddac748
2025-10-17 11:33:00 +00:00
Alois Wohlschlager ac8209404c nix-eval-jobs: estimate memory usage using the heap size
When the maximum memory size is chosen too large (relative to the free memory
usage), so that the evaluation workers don't fit into the free memory, they
will start being swapped out. Further increase in memory usage will not be
reflected in the RSS, so they will not exit, and instead fill up all swap too
until the system runs out of memory.

The BDW-GC keeps track of its heap size, including any parts of it that may be
swapped out. For this reason it does not suffer from a similar problem. While
not all memory usage by the evaluation worker is accounted for by the GC, a
simple affine model for the overhead works reasonably well in practice. The
specific parameter values were determined using nixpkgs evaluation, and appear
to work quite well also for somewhat different workloads (like the `hydraJobs`
of Lix, which include a bunch of NixOS system configurations). So this is what
gets used.

When Lix is configured without the BDW-GC, of course this approach cannot be
used. In this case the old strategy is retained.

Change-Id: I6cb5f0a9b4ceda9dd14be165dda108cd6a6a6964
2025-10-16 15:22:54 +00:00