We at the Lix team are proud to announce our sixth major release, version 2.95 “Kakigōri”.
This release focuses on long-awaited bugfixes, quality-of-life improvements, documentation, performance improvements and continued integration of Lix with the Cap’n’Proto remote procedure call runtime to replace the previous bespoke implementation.
Kakigōri is a Japanese shaved ice dessert flavored with syrup and a sweetener, often condensed milk.
Lix is a Nix implementation focused on reliability, predictability, friendliness, developed by a community of people from around the world. We have long term plans to incrementally evolve Nix to work in more places, to make it more reliable and secure, and to update the language and semantics to correct past mistakes and reduce errors, all the while providing an amazing tooling experience.
Upgrading from CppNix or previous Lix versions
WARNING: We do not recommend to use nix upgrade-nix, please follow the instructions in https://lix.systems/install/ with the Lix’s upgrade shell script.
The upgrade procedure depends on how you installed Lix or CppNix, and is fully described in the Lix installation guide.
If you are using Lix from nixpkgs on NixOS, you just need to upgrade your nixpkgs once the upgrade pull request has passed through the build farm into your channel; no other action is required.
If you want to help us test the next version of Lix, consider running main by following the beta guide.
Changes
Lix 2.95 builds on the work from Lix 2.94 in improving the daemon and language to make room for future evolution.
In this release Lix has fixed a number of long-running bugs, and we intend to continue this trend. We aim to have only very few longstanding bugs remaining by the time we hit Lix 3.0.
Here is a tasting menu of changes in Lix 2.95 that we think are the most exciting. This is by no means a complete list, otherwise this post would be huge. If you’re interested in the full list, please refer to the release notes.
News from RPC
RPC work is ongoing behind the scenes. Lix 2.95 ships with internal changes required to create multiple daemon sockets with different protocols on each, and we intend to make use of this to expose new protocols as they become ready.
Previous releases confirmed that using Cap’n’Proto is feasible, and we’ve gained experience exchanging information between Lix and its helper programs via Cap’n’Proto RPC mechanisms. In the 2.96 development cycle we will build on this knowledge to add a new—experimental, for now—RPC protocol for connections to the local daemon. As we gain confidence in our implementation we also want to enable this protocol for remote builds, and ultimately replace the ssh:// and ssh-ng:// remote store URI schemes.
Flakes go arctic
Lix 2.94 has frozen Flakes, and 2.95 has used this freeze to take the first few steps towards extracting Flakes from Lix core into a plugin. The extraction is proving much more difficult than expected due to many interdependencies between Flakes behaviors, the CLI parser and its quirks, the configuration system, and how deeply engrained Flakes are in the current design of Lix itself.
We have made some progress nonetheless, but we are still far from done. We aim to not only extract Flakes from the core code, but to also make it possible for other projects to use the same mechanisms to add their own, Flakes-like, interfaces to Lix. Why should nix build not be able to understand npins-based repositories? It should! And with a plugin, it will be able to. Eventually. Once the snow melts.
Breaking changes
A significant amount of technical debt has been cleared to allow safer evolution of Lix.
More deprecations of old language features
The Nix language is replete with features that by now are mostly problematic, such as merges of
recsets (which sometimes did not create rec sets!), dynamic attributes inrecsets (which never behaved as one would have expected), warnings for probable tokenization issues (which mean[ 00.123 ]is a list with two elements), and many more.Lix strives to improve the language in an incremental fashion with minimal disruption to existing uses, and we are working with Nixpkgs contributors to achieve this goal. Lix 2.95 should not produce any deprecation warnings or errors when evaluating up-to-date Nixpkgs expressions, and all warnings can be disabled if fixing them is not possible immediately.
Many thanks to piegames, rootile (Rutile), and eldritch horrors.
Daemon cache directory moved
Previously the daemon stored its caches in
/root/.cache/nix, now it stores them in/var/cache/nix. Storing caches in the root user home directory was never truly intentional, and never all that configurable either. Lix now respects system settings (such as set by systemd when settingCacheDirectoryon the daemon unit) instead.Many thanks to Raito Bezarius.
fetch-closureexperimental feature removed, andbuiltins.fetchClosurewith itSince Lix removed CA derivations most of the inner workings of
fetchClosurehave become inaccessible, and the remainder was largely not an improvement over existing features (such importing store derivation). We’ve removed it to lighten the maintenance burden.Many thanks to just1602.
New features
builtins.warnis now available to emit warnings during expression evaluation, and two new optionsdebugger-on-warnandabort-on-warnlet you debug why warnings happen, or turn them into errors for all your CI needs.Many thanks to Emilia Bopp and Qyriad.
log-formatcan now be set innix.conf, and nix3 CLI commands default to printing logs instead of discarding them. No morenix build -L / --log-format multiline-with-logs!Many thanks to Qyriad.
a better remote builder configuration mechanism
Remote builders can be configured with TOML now! The old format is still supported, but we encourage all users to adopt the new format since it is clearer, more usable, and much more extensible.
Many thanks to rootile (Rutile) and Qyriad.
Improvements
Flakes untrusted settings questions are less obnoxious
Any time a flake asks to apply settings it now asks for all of them at once first, with a list of settings it requested. You can accept or reject all settings at once, or handle each setting individually.
Many thanks to isabelroses, Raito Bezarius and eldritch horrors.
keep-env-derivationsis now supported by the nix3 CLIThis feature has been available for the nix2 CLI for a long time. The nix3 CLI now also supports it.
Many thanks to Raito Bezarius.
nix-shellandnix shellprovide nesting depth informationMuch like the
SHLVLenvironment variable we all know and love (which counts how many shells deep you currently are),nix-shellandnix shellnow expose aNIX_SHELL_LEVELvariable that does the same thing for nix shell environments.Many thanks to Tom Hubrecht.
The REPL pretty-prints derivations as attribute sets with limited depth now instead of printing only the store derivation path. This makes it much easier to inspect derivations in the REPL.
Many thanks to Lunaphied.
improved build sandbox launch mechanisms
Sandboxed builds are now much faster to launch on Linux, up to 80%! Whether (and how much) improvements you will see depends greatly on what kind of derivation graph you build. Graphs with many
runCommandderivations (like NixOS systems) are likely to see a noticeable improvement. Larger graphs see disproportionately larger absolute savings.Many thanks to eldritch horrors.
Miscellanea
daemons are fully socket-activated on Linux now
As mentioned in the intro, daemons now use socket activation with instanced units instead of a single, global system daemon. This is required to make the
cgroupsexperimental feature work well and allows much better monitoring of individual connections even without advanced monitoring features built into Lix itself. Care must be taken during upgrades to ensure thatnix-daemon@.serviceis available, otherwise daemon connections will fail.Many thanks to eldritch horrors.
And all the rest
Many more changes and improvements have gone into Lix 2.95. The list is much too long to even summarize here; a great deal of work has gone into making Lix 2.95 one of our best releases to date.
Known issues
- 2.95.0 can break your development shells if they make use of
nixConfigandnix print-dev-env, upgrade to 2.95.1. - 2.95.0 static builds are unable to build anything, upgrade to 2.95.1.
What is planned for the future?
Flakes
As mentioned before, Lix is freezing the Flakes feature set to extract it into an isolated plugin.
The Flakes implementation in Lix consist of two main parts:
libfetchers: infrastructure for fetching and interacting with source trees, including thefetchTreebuiltin.- CLI surface:
nix3commands and flake-specific hooks (the installables).
Our first extraction effort focuses on moving Flakes-specific code from the Lix core into plugins, such as the search path logic that resolves flake: URIs.
Next we will gradually remove Flakes-related logic from nix3 commands while ensuring that commands not compatible with plugins are handled safely. Once the CLI can operate without Flakes it will remain useful only for certain --file or --expr use cases unless some plugin that extends the CLI is loaded.
To restore CLI functionality, plugins can:
- register new installables (syntax elements that can be parsed into Nix values), e.g. file-based, inline expression, or flake-based. We will introduce infrastructure for this purpose.
- add CLI flags and commands when Flakes is present. The current
nix3CLI parser has design limitations, and 2.96 will invest in a new parser, possibly using Rust.
Once these functionalities are stabilized, Flakes can be offered as a plugin. Users who wish to continue using Flakes will be able to enable them in their profile manager of choice, e.g. by specifying
lix.plugins = ps: [ ps.flakes_v1 ];
Versioning plugins allows future improvements while maintaining backward compatibility. Challenges remain, such as versioning Flakes itself. We encourage the community to participate in solving these issues.
The next target after this is reworking will be libfetchers and redefining its role in Lix, in cooperation with our RPC efforts.
News from Rust integration
Lix has historically included Rust in limited ways, such as the statically linked lix-doc. In 2.95, we pushed FFI capabilities further.
Two very important things happened during 2.95 cycle:
- We introduced
rust-monocrate: a Rust component inside Lix capable of calling C++ or C APIs, or being called from C++ via the C ABI. - Library unification: we’ve merged all our shared libraries into a single, big, library to simplify Meson integration with Rust.
Experiments with cxx are underway to evaluate its suitability for upcoming changes, such as rewriting the CLI parser and config system in Rust.
In the future we want to use Rust more and more in our codebase, first for user-facing changes where the better library ecosystem of the Rust world can have the most immediate impact, and for reliability of isolated small components (such as tarball decompression).
Ongoing stabilization goals
Lix has several experimental features. Our focus is on first stabilizing those most critical for Lix itself.
Extended attribute support in the sandbox
During the 2.95 cycle we allowed extended attributes in the sandbox while preventing derivation outputs from writing them. This enabled testing UNIX ACLs for daemon sockets.
Testing showed that extended attribute support in the sandbox is impractical. Many programs assume access to more UIDs than the default three (nobody, nixbld, root) is possible and fail if this is not the case. Supporting extended attributes also requires uid-range for these programs, which is not yet feasible in standard sandboxes.
We still intend to make extended attributes available in the build sandbox but will be putting this effort on the back burner to resolve its dependencies first.
auto-allocate-uids and the uid-range system feature
auto-allocate-uids provides a way to assign a range of UIDs in the sandbox and exposes the uid-range system feature.
Previously tied to cgroups for safe sandbox cleanup, auto-allocate-uids now relies on stable cgroups support and will no longer work if cgroups are not also enabled. Linux lacks a standard API for allocating many UIDs, but systemd offers systemd-nsresourced, which can provide delegated UIDs safely.
Stabilizing auto-allocate-uids will require systemd-nsresourced which is being worked on in NixOS.
cgroups experimental feature
Using cgroups correctly is complex due to a lack of standard APIs. Container engines often don’t delegate cgroups according to any standard, creating UX issues.
When Lix runs without a daemon, sandboxing and cgroup delegation become tricky. Users can recover via systemd-run or --no-use-cgroups, but some software assumes direct store access and needs code adjustments.
Stabilization depends on resolving these UX challenges and improving compatibility with container engines.
Want to help Lix? Consider donating to Lix!
Following Lix integration in AFNix, Lix now has an Open Collective and can receive donations.
We run infrastructure across x86_64-linux, aarch64-linux, and aarch64-darwin. Some of it is in-kind and sponsored. Current costs are around 100€/month.
If you value self-hosting and benefit from Lix, please consider donating. Every contribution helps sustain the project.
Credits
Thanks, as always, to the following groups:
The large community who beta tested the upcoming release by running
mainin production since the 2.95 branch-off. We really appreciate having immediate feedback on our work and the trust of running main alongside us means a lot to us. We know we tested the patience of some of you, we thank you for that.If you want to run Lix main yourself, see the beta guide for details.
Everyone who contributed by filing bugs and giving us feedback on Matrix.
All the first time contributors who made their first contributions to a Nix implementation in Lix. We are eternally grateful to everyone who helped us out on the numerous important but tedious issues.
All the contributors who have helped us with the backlog of bugs.
The CppNix contributors and CppNix team, without whom we would not have this software, and who wrote some of the improvements ported into this release.
Onwards and upwards for the next release. We look forward to continuing to work together with everyone to build a better foundation for the evolution of Nix.