Skip to content
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

Flake support #68897

Merged
merged 39 commits into from Feb 10, 2020
Merged

Flake support #68897

merged 39 commits into from Feb 10, 2020

Conversation

@edolstra
Copy link
Member

@edolstra edolstra commented Sep 16, 2019

Motivation for this change

This PR:

  • Adds a flake.nix file to Nixpkgs, making Nixpkgs usable from other flakes.
  • Adds flake support to nixos-rebuild, enabling hermetic NixOS builds.
  • Adds flake support to nixos-container.

A typical NixOS system configuration flake looks like this:

{
  edition = 201909;

  outputs = { self, nixpkgs, dwarffs, hydra }: rec {

    nixosConfigurations.my-server = nixpkgs.lib.nixosSystem {
      system = "x86_64-linux";
      modules =
        [ dwarffs.nixosModules.dwarffs
          nixpkgs.nixosModules.notDetected
          hydra.nixosModules.hydra
          { system.configurationRevision = self.rev;
            /* typical configuration.nix stuff follows */
          }
        ];
    };

  };
}

which can be installed by doing

# nixos-rebuild switch --flake /path/to/flake --config my-server

(--config defaults to the host name so it can usually be omitted).

The option system.configurationRevision tracks the revision of the top-level flake. This allows the entire configuration to be reproduced reliably. In a running system, it can be queried using nixos-version:

$ nixos-version --json | jq -r .configurationRevision
2c475bc41c13e7a9ae5c16b6c10d8d328cd07ee7

Note: NIX_PATH is unavailable in flake-based builds. In particular this means that

imports = [ <nixpkgs/nixos/modules/installer/scan/not-detected.nix> ];

in hardware-configuration.nix no longer works. Instead you have to use

modules = [ nixpkgs.nixosModules.notDetected ];

nixos-container also supports flakes. For example, the following command creates a container that serves the NixOS homepage:

$ nixos-container create homepage --flake nixos-homepage 
$ nixos-container start homepage 
$ curl http://$(nixos-container show-ip homepage)

TODO: add flake support to nixos-install, add tests.

Things done
  • Tested using sandboxing (nix.useSandbox on NixOS, or option sandbox in nix.conf on non-NixOS)
  • Built on platform(s)
    • NixOS
    • macOS
    • other Linux distributions
  • Tested via one or more NixOS test(s) if existing and applicable for the change (look inside nixos/tests)
  • Tested compilation of all pkgs that depend on this change using nix-shell -p nix-review --run "nix-review wip"
  • Tested execution of all binary files (usually in ./result/bin/)
  • Determined the impact on package closure size (by running nix path-info -S before and after)
  • Ensured that relevant documentation is up to date
  • Fits CONTRIBUTING.md.
Notify maintainers

cc @

flake.nix Outdated

outputs = { self }:
let
pkgs = import ./. { system = "x86_64-linux"; };

This comment has been minimized.

@flokli

flokli Sep 16, 2019
Contributor

does this mean we currently can't use the nixpkgs flake from any non-x86 system?

This comment has been minimized.

@edolstra

edolstra Sep 19, 2019
Author Member

Not from the nix command line. You can call it from other flakes with a non-x86_64-linux system argument though.

This comment has been minimized.

@matthewbauer

matthewbauer Sep 26, 2019
Member

Can't we use builtins.currentSystem?

This comment has been minimized.

@jD91mZM2

jD91mZM2 Jan 15, 2020
Member

Nope, not in pure evaluation mode.

$ nix eval "(builtins.currentSystem)"
error: attribute 'currentSystem' missing, at (string):1:2
$ nix eval --impure "(builtins.currentSystem)"
"x86_64-linux"
@arianvp
Copy link
Member

@arianvp arianvp commented Sep 17, 2019

I myself had a slightly different take on nixos-rebuild in the presence of flakes which I am using here: https://github.com/arianvp/nixos-stuff/blob/master/deployments.nix#L15-L46 (Though I'm still implementing the flake part, but the idea of calling lib.nixosSystem inside your package definition is the same to what I am doing).

The idea is that you ou can do:

nix run github:arianvp/nixos-stuff:deployments.arianvp-me -c deploy [switch|boot|test] [target*]

or in two steps:

nix build github:arianvp/nixos-stuff:deployments.arianvp-me
./result/deploy switch

# or deploy remotely
./result/deploy switch  root@arianvp.me

E.g. a nixos flake returns a nixos-rebuild-like command that can be called instead of having nixos-rebuild call nix build. Kind of an inversion of control thing.

Would such a thing be more ergonomic? It would also mean you don't need nixos-rebuild on your computer to be able to deploy a nixos derivation. (Because nixos-rebuild doesn't seem to be exposed as a package in nixpkgs. so I do this so I can deploy nixos servers from my non-nixos machines)

Of course this is a bit of a backwards incompatible change, but we could also keep the old nixos-rebuild for non-flake deployments, and use this "design pattern" for flake-like deployments.

What do you think?

@edolstra
Copy link
Member Author

@edolstra edolstra commented Sep 19, 2019

@arianvp Well, you already don't need nixos-rebuild since you can build the top-level system derivation and then run its switch-to-configuration script, e.g.

$ nix build .:nixosConfigurations.vyr.config.system.build.toplevel
$ ./result/bin/switch-to-configuration test

which is just what nixos-rebuild does.

Edit: or indeed

$ nix run .:nixosConfigurations.vyr.config.system.build.toplevel -c switch-to-configuration test

as you suggested.

@edolstra
Copy link
Member Author

@edolstra edolstra commented Sep 19, 2019

Update: added flake support to nixos-container.

@arianvp
Copy link
Member

@arianvp arianvp commented Sep 19, 2019

Well and you have to nix-env --set it right? Would there be a way to do that in one step?

@edolstra edolstra force-pushed the edolstra:master branch from 71a1b42 to 0a4dd6e Sep 23, 2019
flake.nix Outdated Show resolved Hide resolved
flake.nix Outdated
legacyPackages = pkgs;

nixosModules = {
notDetected = ./nixos/modules/installer/scan/not-detected.nix;

This comment has been minimized.

@matthewbauer

matthewbauer Sep 26, 2019
Member

Why include this?

This comment has been minimized.

@jtojnar

jtojnar Oct 17, 2019
Contributor

Note: NIX_PATH is unavailable in flake-based builds.


Should we add other modules as well? For example, I use the following imports on my server:

<nixpkgs/nixos/modules/profiles/minimal.nix>
<nixpkgs/nixos/modules/virtualisation/container-config.nix>
<nixpkgs/nixos/modules/installer/cd-dvd/channel.nix>
@edolstra edolstra force-pushed the edolstra:master branch 2 times, most recently from 1028bb3 to 4a4e146 Oct 8, 2019
@edolstra edolstra force-pushed the edolstra:master branch from d4a07f0 to 153ca08 Oct 23, 2019
@edolstra edolstra force-pushed the edolstra:master branch from 153ca08 to 015c9ec Nov 6, 2019
@nixos-discourse
Copy link

@nixos-discourse nixos-discourse commented Nov 11, 2019

This pull request has been mentioned on NixOS Discourse. There might be relevant details there:

https://discourse.nixos.org/t/building-nixos-system-with-nix-build-and-a-channel-specifier/4747/2

And also --refresh and --no-net.
@edolstra edolstra changed the title [WIP] Flake support Flake support Feb 5, 2020
@edolstra edolstra force-pushed the edolstra:master branch from a6ca3f4 to c089308 Feb 5, 2020
Copy link
Contributor

@yorickvP yorickvP left a comment

Would be happy to see this merged. However, I'm afraid that the FIXME's in here will never get fixed once this is merged. We depend on the nixos-rebuild re'execing currently, so that fixme would be a blocker for moving to flakes for us, personally.

# Re-execute nixos-rebuild from the Nixpkgs tree.
if [ -z "$_NIXOS_REBUILD_REEXEC" -a -n "$canRun" -a -z "$fast" ]; then
# FIXME: get nixos-rebuild from $flake.

This comment has been minimized.

@yorickvP

yorickvP Feb 6, 2020
Contributor

This is important for my workflow

This comment has been minimized.

@edolstra

edolstra Feb 10, 2020
Author Member

The re-exec is fundamentally broken anyway, since it tries to build nixos-rebuild with the old Nix. (The code to upgrade Nix happens later.) We could do nix build $flake#nixosConfigurations.$flakeAttr.config.system.build.nixos-rebuild but I don't think it's useful currently.

nixos/modules/installer/tools/nixos-rebuild.sh Outdated Show resolved Hide resolved
@@ -296,7 +347,8 @@ prebuiltNix() {

remotePATH=

if [ -n "$buildNix" ]; then
# FIXME: get nix from the flake.

This comment has been minimized.

@yorickvP

yorickvP Feb 6, 2020
Contributor

FIXME: get nix from the flake.

(defined $configFile && $configFile ne "")) {
writeNixOSConfig $nixosConfigFile;
# Unless overriden on the command line, rebuild the flake recorded
# in the container config file. FIXME: read the container config

This comment has been minimized.

@yorickvP

yorickvP Feb 6, 2020
Contributor

fixme: read the container config in a more sensible way

Copy link
Contributor

@yorickvP yorickvP left a comment

^

if [[ -z $flake ]]; then
pathToConfig="$(nixBuild '<nixpkgs/nixos>' -A vm -k "${extraBuildFlags[@]}")"
else
echo "TODO: not implemented" >&2

This comment has been minimized.

@yorickvP

yorickvP Feb 6, 2020
Contributor

todo: not implemented

This comment has been minimized.

@yorickvP

yorickvP Feb 10, 2020
Contributor

Not supporting nixos vm builds will ensure limited flake adoption.

This comment has been minimized.

@edolstra

edolstra Feb 10, 2020
Author Member

I haven't used build-vm in years.

This comment has been minimized.

@yorickvP

yorickvP Feb 10, 2020
Contributor

I use it almost all the time, to do integration tests of modules. It's fairly prominent in the documentation and one of nixos's selling points.

This comment has been minimized.

@edolstra

edolstra Feb 10, 2020
Author Member

Sure, but nixos-rebuild build-vm is just a wrapper around nix build. It doesn't do anything you couldn't otherwise do.

This comment has been minimized.

@worldofpeace

worldofpeace Feb 10, 2020
Member

I've used build-vm to test the many many PRs that I've reviewed, merged, and tested. It's a very very useful tool for me.

This comment has been minimized.

@worldofpeace

worldofpeace Feb 11, 2020
Member

Do you mean people can just do?

nix run vm -f '<nixpkgs/nixos>' --arg configuration "$PWD/configuration.nix" -c run-nixos-vm
if [[ -z $flake ]]; then
pathToConfig="$(nixBuild '<nixpkgs/nixos>' -A vmWithBootLoader -k "${extraBuildFlags[@]}")"
else
echo "TODO: not implemented" >&2

This comment has been minimized.

@yorickvP

yorickvP Feb 6, 2020
Contributor

todo: not implemented

@alyssais
Copy link
Member

@alyssais alyssais commented Feb 6, 2020

I feel very conflicted about making this change now, when not only have we still not decided on the format for flake.nix, but the RFC seems to have been stalled for months…

edolstra added 5 commits Feb 7, 2020
"master" is not a valid SHA-1 commit hash, and it's not even
necessarily the branch used. 'nixos-version --revision' now returns an
error if the commit hash is not known.
@edolstra
Copy link
Member Author

@edolstra edolstra commented Feb 10, 2020

Well and you have to nix-env --set it right? Would there be a way to do that in one step?

Yes, you can do nix build --profile /nix/var/nix/profiles/system $flake#nixosConfigurations.$hostname.config.system.build.toplevel to do the build and the profile update in one step.

Copy link
Member

@FRidh FRidh left a comment

I would like to know how we deal on the stable with changes to e.g. the Flake format. Can it be relied on being stable during the lifetime of 20.03, or is it consider experimental? Probably needs a release note either way, clarifying this.

flake.nix Show resolved Hide resolved
@edolstra edolstra requested review from Infinisil and nbp as code owners Feb 10, 2020
@edolstra
Copy link
Member Author

@edolstra edolstra commented Feb 10, 2020

I've added a note that it's experimental (so it shouldn't be relied on).

@edolstra edolstra merged commit 0e6ceb8 into NixOS:master Feb 10, 2020
@arianvp
Copy link
Member

@arianvp arianvp commented Feb 13, 2020

Nixpkgs.lib.nixosSystem already exists as pkgs.nixos
It's confusing to have both. Can we remove one of the two?

Iirc nixpkgs.nixos is explicitly mentioned in our documentation too

I already noted this in November. But no reply. Could we still address this?

@edolstra
Copy link
Member Author

@edolstra edolstra commented Feb 13, 2020

Ideally we would remove pkgs.nixos, since it's not a package, but I don't want to make incompatible changes since this is all experimental.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.