-
-
Notifications
You must be signed in to change notification settings - Fork 1.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Rename nixosConfigurations to configurations.<system> #10291
base: master
Are you sure you want to change the base?
Conversation
ea06cef
to
4df697d
Compare
This change makes it possible to define cross-compiled configurations. We add `configurations` attribute because changing `nixosConfigurations.<name>` to `nixosConfigurations.<system>.<name>` is a breaking change, i.e. we cannot efficiently differentiate between two schemas. Limitations: - Using this reliably requires content-addressed derivations (that are curently available as an experimental feature). - Even with content-addressed derivations, a lot of work has to be done in NixOS/Nixpkgs so that `build ≠ host` does not change the output. While not directly related, also keep in mind that NixOS configurations currently support only a single host platform. That is, the resulting system contains executables and bootloader only for a single CPU architecture. E.g. it is not possible to install systemd-boot with [per-architecture boot entries] to boot the configuration for the specific CPU architecture. [per-architecture boot entries]: https://uapi-group.org/specifications/specs/boot_loader_specification/#boot-loader-entries
4df697d
to
bf448de
Compare
The attribute name should include "nixos" to distinguish it from other types of configurations (e.g. home-manager configurations). Maybe However, I'm not really convinced that this is needed. Unlike (say) packages, a NixOS configuration is always for a particular machine and therefore a particular system type, and it's not very likely that users will want to query what configurations are available for a system type.
I'm not sure how this helps with cross-compilation. It's not even clear whether "system" denotes the target or build system. And we should probably come up with a general scheme for cross-compilation first (e.g. to support
Other than CA derivations reducing binary cache storage if the cross-build produces the exact same result as the non-cross-build, I don't see how CA derivations are needed? |
To keep every bit of the configuration identical down to the store paths. For example, Go compiler binary input would be different on macOS and Linux, but the output of the compiler is the same for a given platform (GOOS/GOARCH/etc). With CA derivations, the following derivation output should result in identical store paths, even if bash input from stdenv differs between systems:
NixOS module system already has
This is not for a particular system type, this is built from a system (as in localSystem, not crossSystem).
The system denotes build system, just like with all other system-dependent flake attributes.
I’m not really sure how this is supposed to look. I’ve never really had a problem with cross-compiling packages from flakes. We can already define For example, a flake defined for
You can even have Similar structure applies to the |
Local and cross are kinda bad terminology. I'd recommend the GNU and Nixpkgs terminology
When both are set, What you're proposing also differs from Home Manager, which also uses the automatic CA does not mean we should make the build platform a parameter Even if CA works and the expressions are close to perfect, a cross compiled result is weaker than a natively built one, because far fewer tests will run. |
Local and cross are kinda bad terminologyAgreed, just to be clear:
System is not reflected in schemaI’d argue that configurations.<system> is a recorded decision, and that is currently not reflected in the schema. Deploying such configurations right now is a bit awkward— The proposed schema makes this decision explicit and for most use cases the migration path is simply There is also an unintended but positive side effect when substituters have (full or part of) the configuration cached. With # From aarch64-linux to x86_64-linux, cached configuration, no --fast flag
nixos-rebuild test --verbose --target-host machine --flake .#machine
Exec from Python:
I understand that technically this is a bug in
So, if the configuration isn’t defined to be built from a given system, they’d get an error that it does not exist. <system> becomes ambiguousI don’t think it does. This is simply a string that is passed to the builtins.derivation Actual use w.r.t. derivation output depends on the top-level attribute, e.g. for Far fewer tests will runNixOS/Nixpkgs has infrastructure for running integration tests under VM and running commands with an emulator. For example, for Go packages:
Currently cross-compilation is closer to a second-class citizen in Nixpkgs, but that shouldn’t be the status quo. Sure, not all packages can be updated to run tests when cross-compiling, but I’d like to emphasize that a lot actually can. |
Edit: this behavior is mandated by the standard 🤷
|
What's needed to push this forward :P |
I've made some progress on one of the side-issues, which needs review: Other than that, we seem to disagree on a fundamental issue, which is whether cross compilation is an issue that must be decided in the flake or on the CLI. Maybe there's a middle ground, but IMO this is more of a NixOS issue anyway has this been discussed in the Nixpkgs issue tracker? Something like nixosConfigurations.my-system = lib.nixosSystem {
modules = [
{ nixpkgs.buildPlatforms = [ "x86_64-linux" "aarch64-darwin" ]; }
./configuration.nix
];
}; Then the NixOS can then lazily call itself for all the build platforms using
To be honest, this is a bit convoluted, because we can't specify something like this yet: nix build --expr '{flake, name, buildSystem}: let ... in toplevel' \
--argflake flake $flakeref \
--argstr name $(hostname) \
--argstr buildSystem $(nix eval --impure --expr "builtins.currentSystem") Also, we don't have an implementation for caching such an evaluation either, but considering that these arguments could all be made part of the cache key, I don't see any blocking issues for this. Note also that when |
Motivation
Deprecates
nixosConfigurations
in favor ofconfigurations.<system>
output (where system is semantically equivalent tobuiltins.currentSystem
, that is, system used for realisation, similar topackages
and other flake outputs that contains derivations).See also #6257
Context
This change makes it possible to define cross-compiled configurations. We add
configurations
attribute because changingnixosConfigurations.<name>
tonixosConfigurations.<system>.<name>
it’s harder to implement in a non-breaking manner and alsoconfigurations
(as implemented) is not limited to NixOS configurations (usingclass
attribute).Limitations:
build ≠ host
does not change the output.While not directly related, also keep in mind that NixOS configurations currently support only a single host platform. That is, the resulting system contains executables and bootloader only for a single CPU architecture. E.g. it is not possible to install systemd-boot with per-architecture boot entries to boot the configuration for the specific CPU architecture.
Nixpkgs branch (no PR yet): NixOS/nixpkgs@master...tie:nixpkgs:nixos-rebuild-system-attr
Nixpkgs-side support above is implemented by making uniform flake URI handling across NixOS tools (
nixos-rebuild
,nixos-install
,nixos-container
) usingnixos-config-flake-uri
tool. The tool also handles multiple output formats and escaping (e.g. fornixos-rebuild repl
motd expression).In particular, all NixOS flake-aware tool will have support for absolute attribute paths, adding a transition path from the old schema, for example:
That said, we can also add a flag to
nixos-config-flake-uri
to evaluate the flake and check attribute path from URI fragment againstnixosConfigurations
(nix eval --apply to check attribute existence).Regarding scoping configurations under
system
attribute:I don’t think that’s been discussed in a separate issue, although there is nix-community/home-manager#2161, #6257 (comment) and a quote from #8665:
While I agree that configuration must be built reproducibly, that does not mean that it has to be built one way only. If it really can’t be cross-compiled to an identical package, then the flake shouldn’t define other system attributes (e.g.
packages
has similar semantics), and/or use absolute attribute path to be confident that a particular configuration is built. Despite some bugs (and assuming content-addressed derivations), it should be possible to cross-compile an entire configuration that is bit-wise identical to the native build.Note that #6257 suggests
configurations.<class>
scheme. While this makes querying configurations of a particular class arguably more efficient, I don’t see much practical value. Tools likenixos-rebuild
don’t list configurations (and there is little reason to do so) andnix flake show
(as implemented in this PR) printsclass
value (if it exists). Finally, and perhaps most importantly,configurations.<system>
is consistent withpackages
,check
,apps
, etc.Priorities and Process
Add 👍 to pull requests you find important.
The Nix maintainer team uses a GitHub project board to schedule and track reviews.