Commit Graph
282 Commits
Author SHA1 Message Date
eldritch horrorsandRaito Bezarius 469cb4218d libstore: don't default build-dir to temp-dir
if a build directory is accessible to other users it is possible to
smuggle data in and out of build directories. usually this ins only
a build purity problem, but in combination with other issues it can
be used to break out of a build sandbox. to prevent this we default
to using a subdirectory of nixStateDir (which is more restrictive).

Fixes CVE-2025-52991.

Change-Id: Iacfc9b50534de158618c815f9fb99d7dae1be4d0
2025-06-24 10:50:03 +00:00
Alois Wohlschlagerandeldritch horrors e62b7236e8 libstore/gc: fix auto-GC blocking indefinitely during evaluation
The first auto-GC request would not be registered as a waiter due to a logic
error. As a result, if that request was synchronous (as happens during
evaluation) it would be stuck forever waiting on a promise that will never be
fulfilled.
Register also the first request properly so that it is notified and unblocked
again when the GC has finished. Also add a test verifying that auto-GC
triggering during evaluation will not get stuck.

Fixes: https://git.lix.systems/lix-project/lix/issues/844
Change-Id: I157afdc737415261e48d6d01d46c586a2927a1ad
(cherry picked from commit 4505bfac8e)
2025-06-03 12:09:32 +00:00
Tom HubrechtandLix Systems Gerrit 885dde9c3d Merge "libstore: Show illegal path references in fixed-outputs derivations" into main 2025-05-08 20:19:15 +00:00
a8da0df671 libstore: Show illegal path references in fixed-outputs derivations
This allows debugging the errors by pinpointing the offenders, instead
of trying to blindly guess what could have possibly gone wrong.

The wording has been improved to better explain the failure.

Closes #530

Co-authored-by: Ben Millwood <thebenmachine+git@gmail.com>
Change-Id: I84ba5d2d81e5d1867f53bd3bc80e615cab9fe274
2025-05-08 20:23:12 +02:00
eldritch horrors 2059ccaad3 libexpr: remove positions from primops
they're always noPos and have caused quite some confusion.

fixes #781

Change-Id: I15d4210b1aab6ef5d1caabe2e10b45cf98cc4d47
2025-05-02 10:57:15 +00:00
eldritch horrors bdebc3797b cmd/libexpr: don't determinePos in value-to-json
it's not useful. nix-instantiate will always point to the wrong location
because "at the toplevel" is not a position we can point to. all nesting
conversions will point to strange places: the *original* definition of a
lambda value (or partial applications thereof), or nowhere at all (since
only lambda values can have their positions determined in the formatter)

Change-Id: I56bd9e1cf3cae11b4198f148a141ca758e4fe8ac
2025-04-27 17:38:57 +00:00
eldritch horrors eb0280f715 libexpr: add set-to-string error frame
this is much more useful than a frame pointing to the set but claiming
it as a function being called. if the function is actually at fault we
will now point to its attribute, although the position may be slightly
wrong if __toString was defined from set updates or builtin functions.

Change-Id: Ib3eb237a276d94426d9c6fc0e26eea72382d34a2
2025-04-27 11:01:22 +00:00
Raito Bezarius 5ca168f6f2 chore: drop experimental feature recursive-nix
This was discussed as part of https://git.lix.systems/lix-project/lix/issues/767
with a one month long comment period.

This commit removes the recursive-nix feature from Lix. It has seen
limited usage and is difficult to stabilize, especially on non-Linux
systems where its behavior is underspecified.

Maintaining this feature complicates core work on the store, as we must
account for the potential presence of the daemon in the sandbox, adding
unnecessary complexity. Additionally, its inclusion in the
platform-independent local store creates risks for non-Linux platforms.

For more details on this removal, refer to the release note entry or the
issue entry.

Change-Id: I9137202f563c0a317f9c5da79cd9fd07d801427a
Signed-off-by: Raito Bezarius <raito@lix.systems>
2025-04-25 17:09:01 +02:00
2b22dae1ba lixexpr: Declutter error traces
Now that we can correctly point to all expressions, we can remove
redundant intermediate traces to reduce clutter.

Co-authored-by: eldritch horrors <pennae@lix.systems>
Co-authored-by: Raito Bezarius <raito@lix.systems>
Change-Id: I3e9d7c1c7a6599a8e68302448bbb961d051002b7
2025-04-24 20:44:57 +02:00
piegames abb8ad29c0 repl: Always use parser, allow trailing ; in assignments
We now properly shell out to the parser instead of hacking stuff
together with a regex. Stuff we get for free by doing this:

- Optional trailing semicolon
- Declaring nested attribute sets
- String identifiers, and future proofing for eventual grammar
improvements to identifiers
- Dynamic attributes

Change-Id: Ibf1ad815e5e27caf162df05ea5ba5b1b4955d9c9
2025-04-21 20:19:25 +02:00
helle 2238f7a8ab Replace existing external command/custom sub command tests with functional2 tests
This removes the bash dependency issue that the previous test had, the
tests are translated roughly 1 to 1 and do not address any of the TOD
list items.

Closes #800, also superceeds I81817b9fe4a5eeb019f7e04b5a60e091bbde26b2

Change-Id: Ie440cd0a602d4ca4a48edcaf517b7358ec572710
2025-04-19 20:09:44 +02:00
Commentator2.0 fb0ef6ca6b Made parser warnings use Error info
no other warn calls were found, which have position information

Change-Id: If9773b86a756e5b2e4096d3f6b3a5114bfed5bee
2025-04-08 10:21:53 +02:00
eldritch horrors 8d8bb60796 treewide: lint against non-lix exceptions
we generally do not want to catch or throw these. catching them to print
and discard is fine, tests are largely exempt, and cases in which we can
be certain where the exception came from are also fine to *catch*. we'll
try to never *throw* (or rethrow) these if possible though because doing
so will make it impossible to construct async traces for the exceptions.

Change-Id: I3b71c32ecd16afc2246c946472f5629a1fa31f2c
2025-04-06 12:14:38 +02:00
Maximilian BoschandLix Systems Gerrit d169c092fc Merge "fetchers: don't consider a path locked if a rev is specified" into main 2025-03-29 18:51:45 +00:00
Jade Lovelace b22bee91f5 fix!: file type flake inputs are always recursive hashed
Well that is a mess. I don't like breaking derivation compatibility,
but I like non-deterministic evaluation much less.

We can break compat if we own up to it, which this does.

Fixes: https://git.lix.systems/lix-project/lix/issues/750

Change-Id: Ic9e2407393f1d42c2be604f80b4aa11bc872bc23
2025-03-21 13:19:15 -07:00
Maximilian Bosch 62fb98ae55 fetchers: don't consider a path locked if a rev is specified
It's possible to put a path into the store in pure mode by pretending
it's locked like this:

    $ echo 'lalala' > testfile
    $ nix eval --expr '(builtins.fetchTree { path = "/home/ma27/testfile"; rev = "0000000000000000000000000000000000000000"; type = "path"; })'
    { lastModified = 1723656303; lastModifiedDate = "20240814172503"; narHash = "sha256-hOMY06A0ohaaCLwnhpZIMoAqi/8kG2vk30NRiqi0dfc="; outPath = "/nix/store/lhfz259iipmv9ky995rml8018jvriynh-source"; rev = "0000000000000000000000000000000000000000"; shortRev = "0000000"; }
    $ cat /nix/store/lhfz259iipmv9ky995rml8018jvriynh-source
    lalala

There was a fix in CppNix[1], but Puck noted that it's breaking
backwards-compatibility because

> [...] a github fetch with a fully specified rev is no longer considered "locked"
> this is for "purity" reasons, but it breaks any existing flake.nix files

I tried a way smaller correctness fix here:

* Each scheme can denote whether a `rev` is enough to consider itself
  locked.
* If a `rev` is given and the scheme is OK with just a `rev` to be
  locked, the input is marked as locked.

For `path` this is not the case anymore, i.e. it requires a NAR hash to
be locked down.

[1] https://github.com/nixos/nix/commit/071dd2b3a4e6c0b2106f1b6f14ec26e153d97446

Change-Id: Ibbbf4733c82bcfa1c24dfe099a896d8aaecd81cc
2025-03-20 13:17:34 +00:00
Jade Lovelace ed7c89790e fix: do not test non-presence of flakes from a subdirectory of lix src
Yeah, we could have seen that one coming, it's kind of on the nose,
really.

Fixes: https://git.lix.systems/lix-project/lix/issues/748
Change-Id: I9e89f73ed89105338343fdecd615e398fc758e89
2025-03-18 12:40:10 -07:00
jadeandLix Systems Gerrit 6e6ff58272 Merge "feat!: remove experimental repl-flakes" into main 2025-03-18 16:02:55 +00:00
jadeandLix Systems Gerrit ea4cf48879 Merge "post-build-hook: don't emit config settings that aren't overridden" into main 2025-03-17 23:31:32 +00:00
KFearsandJade Lovelace 2c21882767 feat!: remove experimental repl-flakes
This is a backport of CppNix PR 10299

Fixes #557

Change-Id: I848e8c5af4bde09afba053a5911fbbd54004fbb8
2025-03-17 16:01:53 -07:00
Jade Lovelace 523965697d post-build-hook: don't emit config settings that aren't overridden
This is a redesign from 9b1f3cbc13 where
this was introduced.

I deleted the AbstractConfig::toKeyValue since it was conspicuously and
obviously broken for two years since 450e5ec618.
I asked myself if anyone was using it, given that it only emitted
settings that were aliases (broken!), and found that nobody used it.

The motivation for this change is the same for only emitting overridden
settings to the protocol: the nix inside there may not be able to parse
our defaults, as is the case of CppNix since the consensual
accept-flake-config was added to Lix.

Fixes: https://git.lix.systems/lix-project/lix/issues/739
Change-Id: Ib9874a52137f1f22220c25bcfa2425a4802509c7
2025-03-17 15:25:52 -07:00
Jade Lovelace adf45deeca plugins: support nix_plugin_entry, do some minor reworks
Plugins are already allowed to fail to load, let's be even more tolerant
of them failing to load by ignoring inaccessible ones with a warning.

This change also significantly reworks the docs for plugins.

This is a tiny extremely partial backport of the C API at
https://github.com/NixOS/nix/pull/8699.

Fixes: https://git.lix.systems/lix-project/lix/issues/740
CC: https://git.lix.systems/lix-project/lix/issues/359

Change-Id: If4ee20c3daaf26c8184a415eef3e20ca5b5e7aef
2025-03-16 16:43:54 -07:00
ZitroneandGerrit Code Review 85a140accb Merge "libexpr: show all missing and unexpected arguments instead of just one" into main 2025-03-11 21:54:32 +00:00
Zitrone f6c4034e2f libexpr: show all missing and unexpected arguments instead of just one
also only give suggestions for unused arguments

Change-Id: Iae8e72defbbe2571a803dfd7216745b39848ccb2
2025-03-11 20:21:24 +01:00
Linus Heckemann 29b07611b8 gc: allow continuing deletion even if some paths are still live
This adds a gcTryDeleteSpecific operation. This is similar to
gcDeleteSpecific, but will not fail if any of the given paths cannot
be deleted. Paths that could not be deleted are reported in the new
`kept` field of struct GCResults.

This also changes the behaviour of gcDeleteSpecific, such that it will
now continue deleting paths even if it fails to delete one along the
way, and only throw an error once deletion of all the given paths has
been attempted. This seems reasonable to me, because it makes its
behaviour somewhat less surprising -- previously, if some paths were
deletable and others weren't, the deletable ones would be deleted iff
they preceded the live ones in lexical sort order.

This also fixes a regression introduced in
8614cf1334, whereby nix-store --delete
failed to delete paths if they had any dependents -- even if none of
the dependents had GC roots.

The gcTryDeleteSpecific operation is surfaced via additional flags for
the `nix store delete` and `nix-store --delete` commands.

This makes custom garbage-collection logic a lot easier to implement
and experiment with:

- Paths known to be large can be thrown at `nix store delete` without
  having to manually filter out those that are still reachable from a
  root, e.g.
  `nix store delete /nix/store/*mbrola-voices*`

- The --delete-closure option allows extending this to paths that are
  not large themselves but do have a large closure size, e.g.
  `nix store delete /nix/store/*nixos-system-gamingpc*`
  Having an option for this is not strictly necessary, but convenient
  because it doesn't require the user to add an extra `nix-store
  -qR` (or `nix path-info -r`) into their command, nor to rewrite
  their command to use `--stdin` if the closure ends up too large to
  fit on a command line.

- Other heuristics like atime-based deletion can be applied more
  easily, because `nix store delete` once again takes over the task of
  working out which paths can't be deleted.

Change-Id: If345407fe7b11bdb3a8fdc04b0d56c32ab3d5928
2025-03-11 14:10:32 +01:00
Linus HeckemannandGerrit Code Review 423a343937 Merge "libstore/gc: restore deletion of referrers" into main 2025-03-09 21:41:49 +00:00
Linus Heckemann d6c871eb2d libstore/gc: restore deletion of referrers
Fixes: 8614cf1334
Fixes #495

Change-Id: I4d8d655c6254786ba1222a5b37551c68d9e370ee
2025-03-09 22:15:12 +01:00
Ersei Saggi 7928669ef9 Detect if in Nix3 shell
This replicates behaviour found in the Nix2 commands, where IN_NIX_SHELL
is set. This is for shells to determine whether they are inside of a
Nix3 shell, and set a custom prompt accordingly.

For example, Fish's Tide prompt framework checks for that environment
variable and displays it in the prompt, indicating that the shell is in
a Nix environment.

This is not new behaviour, and the old Nix2 commands set the variable.

If the shell that is created is a "pure" shell, ie --ignore-environment
is passed, then IN_NIX_SHELL will be set to "pure". However, "nix
develop" will always create an impure environment.

Replicated from my Nix PR: https://github.com/NixOS/nix/pull/8885

Change-Id: I695cdc336f76541940a302835124fe7d8f7f39b2
Signed-off-by: Ersei Saggi <vcs@ersei.net>
2025-03-07 07:45:08 -05:00
Raito BezariusandGerrit Code Review 271f0e2507 Merge "libexpr: fix checkSourcePath purity regression" into main 2025-03-03 02:00:35 +00:00
eldritch horrors 820c9bdaf5 libstore: don't abort when flat-importing non-files
fixes #705

Change-Id: I3be20235006425dd3bb6156510d021699f05b9ba
2025-03-02 17:37:12 +00:00
Alois Wohlschlager 9d99a7c2cf libexpr: fix checkSourcePath purity regression
Starting with commit 0dbfa7b26e access would also
be allowed to ancestors of allowed paths. This is (ironically) a significant
purity regression, since several users of the purity checks will themselves
assume that arbitrary descent is allowed. For example, `builtins.readDir` and
`builtins.path` could now refer to the filesystem root, breaking purity
entirely in the latter case by allowing to read arbitrary files. Restore the
previous behaviour of only allowing access to explicitly allowed paths.

Change-Id: Ie64180733ab735da9873255e1ccbf95ba7c9161c
2025-03-02 18:30:30 +01:00
piegames 65ce95d381 libexpr: Deprecate NUL bytes in strings
I absolutely want to go back to allowing them, I am strongly of the
opinion that nothing should be special about NUL in a string, but this
will have to wait until at least the GC rewrite, so for now the least I
can do is to disarm this gun.

Change-Id: Id14b6037bc8b274c6c60ad970b1c74d436fb62a7
2025-02-28 16:17:17 +01:00
piegames e38ad66ef7 libexpr: Deprecate CR and CRLF line endings
They are broken beyond repair, and barring a language version revision
this is our only option besides doing nothing about it.

Change-Id: I25fa4f032ca9b5ca67356946bcd889289583592e
2025-02-28 16:17:17 +01:00
Andrew Hamon 2bdac6b7ec feat: add a --priority flag to nix-env --install
Backport of https://github.com/NixOS/nix/pull/12275

nix-env can read priorities from a derivations meta attributes, but this
only works when installing a nix expression.

nix-env can also install bare store paths, however meta attributes are
not readable in that case. This means that a store path can not be
installed with a specific priority.

Some cases where it is advantageous to install a store path: a remote
host following a `nix copy`, or any time you want to save some
evaluation time and happen to already know the store path.

This PR addresses this shortcoming by adding a --priority flag to
nix-env --install.

Change-Id: Ibd9365d0058820a9c2aeecc909b81a0410d5764b
2025-02-26 19:11:39 -08:00
Raito BezariusandGerrit Code Review d037b9e102 Merge "libexpr: rectify filtering logic for filter builtins under chroot stores" into main 2025-02-27 01:37:13 +00:00
62ee2aea29 libexpr: rectify filtering logic for filter builtins under chroot stores
Under chroot or diverted store setups, the filtering logic of
`builtins.filterSource` and `builtins.path` (which shares the same filtering
logic as `filterSource`) would incorrectly pass physical paths to the
filter function instead of logical store paths.

This caused actual breakage in nixpkgs when the `lib.fileset` library was
introduced. Due to this unresolved bug in Nix, the library was forbidden
from use: <https://github.com/NixOS/nixpkgs/pull/369694>.

To the best of our knowledge, this bug has existed since CppNix 2.3.

The existing tests were strengthened to cover these cases, but
additional testing may be required, particularly regarding symlink
handling.

References: https://github.com/NixOS/nix/pull/12512 (CppNix fix to the
problem using "union" abstractions).

Co-authored-by: Raito Bezarius <raito@lix.systems>
Co-authored-by: Alois Wohlschlager <alois1@gmx-topmail.de>
Co-authored-by: eldritch horrors <pennae@lix.systems>
Signed-off-by: Raito Bezarius <raito@lix.systems>
Change-Id: Iaf6ca8c506eeca145393ce100c64db12178daa62
2025-02-27 00:26:48 +01:00
Jade Lovelace 29f5ce07db fix: flakes now obey --eval-system
This required changing an excessive number of places since flakes code
is a delicious bowl of copy pasta.

I didn't change all of the usage sites since some of them run things on
the local machine and you actually want it to be the real system there.

Nevertheless, we probably should have the daemon do something much
different when it receives a `system` setting:
https://git.lix.systems/lix-project/lix/issues/694

Fixes: https://git.lix.systems/lix-project/lix/issues/692
Fixes: https://git.lix.systems/lix-project/lix/issues/673
Fixes: https://github.com/NixOS/nix/issues/11359
Change-Id: I55e696c09794d2520b60238a84829c98fcad7ccc
2025-02-26 12:05:07 -08:00
piegames 0928d4d87a flakes: Make checkOverlay less strict
I'm sorry but checking the name of the function arguments to be "final"
and "prev" is just absurd. That's like worst of
type-checking-meets-static-analysis. And the error message of the second
`throw` was not even good, as it mixed all three failure cases together.

Change-Id: Id4244171123dd8a228be71ce9f04d8e9f647c111
2025-02-24 12:54:48 +01:00
Raito BezariusandGerrit Code Review 43b0902390 Merge "feat: add support for external lix- prefixed commands in the CLI" into main 2025-02-24 10:51:27 +00:00
Raito Bezarius 5f50741ce9 feat: add support for external lix- prefixed commands in the CLI
This feature allows calling external binaries starting with `lix-` as
subcommands directly within the `lix` CLI, similar to how Git handles
external commands.

For example, a binary named `lix-example` can now be invoked using `lix
example`.

This change opens up the possibility for broader community-driven
extensions of the Lix CLI, offering flexibility that Flakes has somewhat
restricted by centralizing certain features around its own model of
dependency management.

By enabling users to introduce custom subcommands, we encourage
experimentation and diverse workflows, addressing the needs of those who
seek more modular, feature-rich approaches to package management and
system configuration beyond what Flakes currently offers [1] [2] [3].

This adds `lix` as a new binary to be able to use this feature.

[1]: https://github.com/nmattia/niv
[2]: https://github.com/andir/npins
[3]: https://github.com/nikstur/lon

Change-Id: Ic6344424a6a46fc9fb30432f00e21c3509659f8a
Signed-off-by: Raito Bezarius <raito@lix.systems>
2025-02-23 15:24:28 +01:00
Jade Lovelace c9b2e8b1d9 fix: pre-build-hook did not run when useChroot == false
It turns out there is actually some history here.
Eight years ago, in 7f5b750b40, the
pre-build-hook condition got changed to check that useChroot is true
(which we will put down as "eelco making a mistake" because it makes no
sense) and that this->drv was a Derivation (as opposed to a
BasicDerivation as would be the case if the derivation was not present
on disk). The intent of this change was that pre-build-hook would not
run when the derivation doesn't exist, so that some hydras would not
explode.

However, this broke later when both cases became Derivation such that
AFAICT it will always run it if useChroot is true, which is absolutely
not the intended behaviour, but it is a reasonable interpretation as
well, just inconvenient for certain pre-build-hook usages.

So, I think the safest and most compatible behaviour is to run the
pre-build-hook but not guarantee that the derivation actually exists on
disk, since it already didn't run in many cases. Maybe the more correct
way is to actually write out the derivation if we are running a
pre-build-hook, but post-build-hook has exactly the same situation and
it's expected, so idk.

Fixes: https://git.lix.systems/lix-project/lix/issues/674
Change-Id: I75b828ae2a07ab373f44083507eb243459bd081d
2025-02-17 16:05:06 -08:00
Robert HensingandLinus Heckemann 66da3fd63f libstore: more precise origin info for strange structured logs
Robert made these improvements on the PR that cherry-picked
e55cd3beea /
https://gerrit.lix.systems/c/lix/+/2057
from Lix into CppNix:
https://github.com/NixOS/nix/pull/11921

Push log source description out of libutil and report build hook @nix warning correctly

(cherry picked from commit 03d4bfd852dce9a050f984e887c887a43581796c)

test: Move unusual-logging to run only in logging test case

(cherry picked from commit 1421420e862434321c46511a3152016e443dd479)

Remove redundant warning: prefix from structured build log warning

(cherry picked from commit f3c722cab24f7a0de8c3573d25e91749f4f16234)
Change-Id: I7da99046f2a41b3c58e62351119bc89bcc25a703
2025-02-16 14:15:36 +01:00
eldritch horrors ecfda8abe2 libstore: asyncify openStore
Change-Id: Ia152bfd2014851590328e732f434dff6695304bd
2025-02-08 12:45:15 +00:00
alois31andGerrit Code Review 8553adbb41 Merge "libfetchers/mercurial: handle "evil refs" gracefully" into main 2025-02-04 17:40:32 +00:00
Rebecca Turner c263070d37 Fix crash in debugger mode using with
Fixes this crash (#592):

    $ nix repl --debugger
    Lix 2.92.0-dev-pre20241120-66f6dbd debugger
    Type :? for help.
    nix-repl> let x = 4; in __seq x (with x; (x: builtins.break x) 1)
    info: breakpoint reached

    [1]    949722 segmentation fault (core dumped)  nix repl --debugger

Change-Id: I13c72941dc325ff984dcce2a84c01c89b1c552af
2025-02-03 15:22:50 -08:00
Dusk Banks 6a583136b7 libexpr: fix --debugger --ignore-try
a65e9e5828 did not inform `tryEval` that
(as far as it's concerned) `state.debug` moved to `state.errors.debug`
and changed types. this resulted in the REPL erroneously coming up, that
REPL having a non-debug state, and segfaulting after that REPL exited.

it's probably good that `state.debug` isn't mutated by `--ignore-try`
anymore.

Change-Id: I1918e93edacd626452aa423fc2eb825080738835
Fixes: a65e9e5828 ("libexpr: extract eval error creation into new type")
Signed-off-by: Dusk Banks <me@bb010g.com>
2025-01-30 18:46:14 -08:00
piegames f8a592713d repl: Allow :env outside of debug mode
Printing the current variables plus staticBaseEnv is useful

Change-Id: Ide8bc26c1c6b4ec0b1d68767994ddac8891a649f
2025-01-28 09:37:01 +01:00
piegames f324574265 libexpr: Track position information in all expressions
Change-Id: Ied79381a917a715cdd8816d6f9df527289217dfb
2025-01-27 20:49:25 +01:00
piegames d0361e9467 libexpr: Unify literal expressions as ExprLiteral
Change-Id: Ifc0f1e27b46803fa2175801ed7d3d108896c8259
2025-01-27 20:49:25 +01:00
Alois Wohlschlager a2daf4e774 libfetchers/mercurial: handle "evil refs" gracefully
If a revision is specified in a way that looks like a commit hash, Lix expects
that it actually is a commit hash. Unlike Git, Mercurial will fall back to
bookmarks, tags and branches with the specified name when a commit with the
specified hash does not exist. Previously, an assertion failure would be thrown
due to the resulting commit hash mismatch. Tell Mercurial to only take commit
hashes into account, whose non-existence is then handled gracefully.

Change-Id: I98bf020187575f3cf8176831da85872d066c4d95
2025-01-26 11:22:03 +01:00