Unable to nixos-rebuid switch during flake migration

I want to switch to a full flake based system as it fulfills the only problem I had with nixos: mixing nixpkgs with my personal projects in a reproducible and traceable way.

I followed Eelco’s blog post Nix Flakes, Part 3: Managing NixOS systems. I already had my configuration.nix working so my flake.nix looks like this:

{
  inputs.nixpkgs.url = "github:NixOS/nixpkgs/nixos-20.03";

  outputs = { self, nixpkgs }: {
    nixosConfigurations.container = nixpkgs.lib.nixosSystem {
      system = "x86_64-linux";
      modules = [ ./configuration.nix ];
    };
  };
}

If I try to rebuild my system though, something is missing:

[dan@thinkpad:/etc/nixos]$ nixos-rebuild switch --flake /etc/nixos
building the system configuration...
error: flake 'git+file:///etc/nixos?ref=main&rev=d1656f817efa24fb3ec11e7a58ab082fb2298688' does not provide attribute 'packages.x86_64-linux.nixosConfigurations."thinkpad".config.system.build.toplevel', 'legacyPackages.x86_64-linux.nixosConfigurations."thinkpad".config.system.build.toplevel' or 'nixosConfigurations."thinkpad".config.system.build.toplevel'

Why is it happening? :slight_smile:

1 Like

Too much copy-pasting w/o thinking :grinning_face_with_smiling_eyes: here I’m defining the container configuration, I want to build one for the “thinkpad” machine instead. Changing that solves it.

As usual, saying things out loud solves most of the problems. I’m keeping this post here for reference! Thanks and cheers to everyone reading.

2 Likes

do you have you system flake on github , or some other git ‘platform’. It always nice to see more flakes.

Hey @nixinator, here it is https://github.com/dmorn/nixos-configuration !

I got stuck again, this time a boot-loader issue:

sudo nixos-rebuild switch --flake /etc/nixos
warning: Git tree '/etc/nixos' is dirty
building the system configuration...
warning: Git tree '/etc/nixos' is dirty
updating systemd-boot from (249.7) to (249.5)
Skipping "/boot/EFI/systemd/systemd-bootx64.efi", since a newer boot loader version exists already.
Skipping "/boot/EFI/BOOT/BOOTX64.EFI", since a newer boot loader version exists already.
Traceback (most recent call last):
  File "/nix/store/kl48p3k468d8ypp882gj2ndz98z7wdgx-systemd-boot", line 314, in <module>
    main()
  File "/nix/store/kl48p3k468d8ypp882gj2ndz98z7wdgx-systemd-boot", line 267, in main
    subprocess.check_call(["/nix/store/n7shnc1xmriya9djkcvzibw9f6paahxy-systemd-249.5/bin/bootctl", "--path=/boot", "update"])
  File "/nix/store/rppr9s436950i1dlzknbmz40m2xqqnxc-python3-3.9.9/lib/python3.9/subprocess.py", line 373, in check_call
    raise CalledProcessError(retcode, cmd)
subprocess.CalledProcessError: Command '['/nix/store/n7shnc1xmriya9djkcvzibw9f6paahxy-systemd-249.5/bin/bootctl', '--path=/boot', 'update']' returned non-zero exit status 1.
warning: error(s) occurred while switching to the new configuration

Any ideas on this one? I mean, I understand the error message but I don’t get it!

https://github.com/NixOS/nixpkgs/issues/152795

1 Like

systemd-boot started causing problems a few months ago. After some time, I gave up on it and switched to GRUB.

You should simply be able to get around this by running nixos-rebuild switch with --install-bootloader.

3 Likes

I picked branch github:NixOS/nixpkgs/staging-next which mentioned this behaviour and it fixed the issue indeed. I’m on flakes now :smiley: Thanks @matthewcroughan for the suggestion though.

OK stuck on another one in the transition. In the Nix Flakes, Part 3: Managing NixOS systems post, it is suggested to set

nix.registry.nixpkgs.flake = nixpkgs;

To have flakes use the system’s pinned set of packages by default. If I do it though in my configuration.nix, using the pkgs passed as module parameter, I get

[dan@thinkpad:/etc/nixos]$ sudo nixos-rebuild switch --flake '.#'
[sudo] password for dan:
warning: Git tree '/etc/nixos' is dirty
building the system configuration...
warning: Git tree '/etc/nixos' is dirty
error: attribute 'outPath' missing

       at /nix/store/vmzh4cjf7pa8sq06cj5j7l73g5nk3pir-source/nixos/modules/services/misc/nix-daemon.nix:542:27:

          541|                 ({ type = "path";
          542|                    path = config.flake.outPath;
             |                           ^
          543|                  } // lib.filterAttrs
(use '--show-trace' to show detailed location information)

Any clues? In general, I find it difficult to discover what nix has to offer, i.e. what options are available, what attributes functions expect. This is of course due to the fact that I’m new to this environment and I’m still learning how to move in the documentation; nevertheless, if you have suggestions also on this regard, you’re welcome :wink:

In my flake, I have a common.nix that I import, which looks like this:

{ config, pkgs, lib, inputs, ...}:
{
  nix = {
    extraOptions =
      let empty_registry = builtins.toFile "empty-flake-registry.json" ''{"flakes":[],"version":2}''; in
      ''
        experimental-features = nix-command flakes
        flake-registry = ${empty_registry}
      '';
    registry.nixpkgs.flake = inputs.nixpkgs;
    nixPath = [ "nixpkgs=${inputs.nixpkgs}" ];
  };
}

It will:

  1. Force nix-shell and all of the old Nix tools to use the Nixpkgs in your flake’s input.
  2. Force nix shell to do the same in nix shell nixpkgs#hello for example.
  3. Disable the registry from having impure behavior, like fetching the latest nixpkgs when you say nix-build nixpkgs#hello for example. Otherwise it’s kind of annoying in the same way that nix-channels are.

If you want to do this, you need to make sure that your nixosConfigurations in your flake have specialArgs = { inherit inputs; }; and that your flake’s outputs argument set is able to be referenced by the name inputs using the @ syntax of Nix, like this:

{
  inputs = {
    nixpkgs.url = "github:nixos/nixpkgs/nixos-21.11";
  };
  outputs = { self, nixpkgs, ... }@inputs: {
    nixosConfigurations = {
      myMachine = nixpkgs.lib.nixosSystem {
        system = "x86_64-linux";
        modules = [
          (import ./hosts/myMachine/configuration.nix)
          (import ./common.nix)
        ];
        specialArgs = { inherit inputs; };
      };
  };
}

In this example, specialArgs = { inherit inputs; } allows the (import ./common.nix) in modules to use the word inputs to access the nixpkgs defined in outputs = { self, nixpkgs, ... }@inputs:.

3 Likes