How can I specify boot device with a flake?

I’ve installed the system with nixos-anywhere and since it doesn’t leave a trace of its config, I’m trying to do it manually with a flake that I push with nixos-rebuild.

BASHY $ nixos-rebuild switch --fast --flake .#default --target-host root@10.0.0.72 --build-host root@10.0.0.72
building the system configuration...
warning: you did not specify '--add-root'; the result might be removed by the garbage collector
updating GRUB 2 menu...
installing the GRUB 2 boot loader on /dev/disk/by-id/ata-Samsung_SSD_980_1TB_S64ANS0W304164P...
Installing for i386-pc platform.
Installation finished. No error reported.
installing the GRUB 2 boot loader into /boot...
Installing for x86_64-efi platform.
/nix/store/1bfclcsrmv9a4w1mmfk5szn9axiji0ss-grub-2.12-rc1/sbin/grub-install: error: /boot doesn't look like an EFI partition.
/nix/store/75qbm0iq2qdc5kkijmyymf3mzswjivrc-install-grub.pl: installation of GRUB EFI into /boot failed: No such file or directory
warning: error(s) occurred while switching to the new configuration

I’m not really sure what it’s looking for.
In my config I specify:

  fileSystems."/" =
    { device = "/dev/disk/by-uuid/f2204226-1a14-49f5-ad79-08857f12b59a";
      fsType = "ext4";
    };

  fileSystems."/boot" = {
    device = "/dev/disk/by-label/disk-main-ESP";
    fsType = "vfat";
  };


  boot.loader.grub.enable = true;
  boot.loader.grub.device = "/dev/disk/by-id/ata-Samsung_SSD_980_1TB_S64ANS0W304164P";
  #boot.loader.grub.useOSProber = false;

Here are my partitions

blkid
/dev/sda3: UUID="f2204226-1a14-49f5-ad79-08857f12b59a" BLOCK_SIZE="4096" TYPE="ext4" PARTLABEL="disk-main-root" PARTUUID="3b99b026-3294-4c0c-bdb1-24a160d8f1b5"
/dev/sda2: PARTLABEL="disk-main-boot" PARTUUID="ca6bf32c-c209-44f5-afe5-d609afe3d1f2"
/dev/sda1: UUID="AC8D-AAD4" BLOCK_SIZE="512" TYPE="vfat" PARTLABEL="disk-main-ESP" PARTUUID="5316ef3b-5869-464e-9f15-78afb71e5ffd"

Is your boot partition actually mounted to /boot?

No, it’s not.

I’m not sure if it should or shouldn’t

[root@nixos:~]# ls /mnt/sda1/
background.png  converted-font.pf2  EFI  grub  kernels
[root@nixos:~]# ls /boot/
background.png  converted-font.pf2  grub

If I look at the SSD:

[root@nixos:~]# fdisk  -l
Disk /dev/sda: 931.51 GiB, 1000204886016 bytes, 1953525168 sectors
Disk model: SSK Storage
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: gpt
Disk identifier: 0DE29D59-964C-410A-BF7A-FD62933CB8C9

Device       Start        End    Sectors  Size Type
/dev/sda1     2048    1050623    1048576  512M EFI System
/dev/sda2  1050624    1052671       2048    1M BIOS boot
/dev/sda3  1052672 1953523711 1952471040  931G Linux filesystem

Yep, it should be, as in you need to mount it.

nixos-rebuild isn’t really made for an initial installation. I’d recommend ssh-ing into the host and following the installation guide.

If your problem is that you need to boot an installer on a VPS type thing, consider trying nixos-anywhere again and just sharing what went wrong so we can help.

Hmm, that seemed to work;) Thanks.

I manually mounted /dev/sda1 on /boot

, but how I am supposed to know that this is what I should do? After nixos-anywhere, is there any way to know the config I must use in a flake to update the system?

Also, why isn’t nixos-rebuild the proper tool here? I don’t want to log in with SSH, cause I want to manage everything from a single workstation.

I also use labels now, so there’s no confusion:

  fileSystems."/" =
    { device = "/dev/disk/by-partlabel/disk-main-root";
      fsType = "ext4";
    };

  fileSystems."/boot" = {
    device = "/dev/disk/by-partlabel/disk-main-ESP";
    fsType = "vfat";
  };

I guessed given lots of knowledge of both NixOS and generally how Linux works, combined with some ability to parse error messages, and got lucky.

There was no way to know, you were half-following two different installation methods and something broke, no documentation could have helped you at that point - ultimately no guide can help you if you’re not following it.

Normally you run nixos-anywhere something like this:

nix run github:nix-community/nixos-anywhere -- --flake '.#myconfig' nixos@fec0::5054:ff:fe12:3456

In this case, you’d use myconfig (from .#myconfig). Ideally, the hostname of the machine you’re deploying to matches the name of the configuration - if so, nixos-rebuild will automatically use the configuration that matches the hostname.

Note that to update, you will need to run nix flake update before nixos-rebuild.

Because as far as you told me, there should have been no running NixOS system on the remote yet. Trying to run nixos-rebuild should have resulted in an error telling you to create a nix store, and various other things NixOS needs to be able to even use nixos-rebuild.

It didn’t because you had a half-completed nixos-anywhere installation, and got somewhat lucky that it was far enough along that you could use nixos-rebuild with a quick manual fix.

The “correct” way of doing it would have been to only use nixos-anywhere and fully complete the installation if you didn’t want to manually SSH into the remote.

As a side note, nixos-anywhere also just uses SSH to log into the remote and runs a script more or less equal to what you would otherwise do manually, so there’s no real difference between these approaches besides convenience.

Out of interest, since you’re using nixos-anywhere, any reason you’re not letting disko do this for you? This may have been where you went wrong in the first place.

I do use disko, as part of the nixos-anywhere step.

I think it’s a little unclear how I did this. Let me try to explain;)

  1. Create a live ISO and fire up a workstation with this ISO.
  2. run nixos-anywhere with disko against this workstation and reboot.
  3. run nixos-rebuild against this workstation.

Now everything is up and all is perfect;) I’m using a flake that I push from my main station.

I’m not sure if this is the proper procedure, but I finally got something working, so I’m happy for the moment;). Thanks.

1 Like

Ah! I see - yes, in that case what went wrong is that you specified the fileSystems at all. As the disko documentation mentions, you’re expected to generate your initial config with --no-filesystems, and then import your disko config.

The disko config will then configure your fileSystems according to how nixos-anywhere partitioned your disks at installation time. This should make your /boot actually show up at boot time.

If you manually set the filesystems instead, and presumably have a typo or such in there, naturally nixos-rebuild won’t be able to write to a partition that wasn’t mounted (and not marked as needed for boot).

Otherwise the procedure was absolutely correct, it’s just your config that was broken.

ok, I see

I should do

imports =
 [ # Include the results of the hardware scan.
   ./hardware-configuration.nix
   "${builtins.fetchTarball "https://github.com/nix-community/disko/archive/master.tar.gz"}/module.nix"
   ./disko-config.nix
 ];

, but then I get:

error: in pure evaluation mode, 'fetchTarball' requires a 'sha256' argument

Is it not meant for a flake, then?

You want to use something like:

{ flake-inputs, ... }: {
  imports = [ 
    # Include the results of the hardware scan.
    ./hardware-configuration.nix
    flake-inputs.disko.nixosModules.disko
    ./disko-config.nix
   ];
}

See this blog post for some hints on how to achieve that: Getting inputs to modules in a nix-flake | NobbZ' Blog

ok, great; now a new error;)

BASHY $ nixos-rebuild switch --fast --flake .#default --target-host root@10.0.0.72 --build-host root@10.0.0.72
building the system configuration...
error: undefined variable 'flake-inputs'

       at /nix/store/bvyrprz3k3sf7jn9yhh3l9b06fg6684h-source/configuration.nix:4:6:

            3|     ./hardware-configuration.nix
            4|      flake-inputs.disko.nixosModules.disko
             |      ^
            5|      /home/b0ef/proj/2024-01-29.tlater-for-thaldor/disk-mbr.nix
(use '--show-trace' to show detailed location information)

Seems I need something more. Just pasting it here, while I try to read that link you sent. It can’t be science rockets;)

ok, I’m stuck;)

I’m can’t find any references to “flake-inputs”.

I tried inputs, but then I got some kind of infinite loop;)

What error do you get? The full set of files should look something like:

# flake.nix
{
  inputs.nixpkgs.url = "github:nixos/nixpkgs?ref=nixpkgs-unstable";
  inputs.example.url = "github:nobbz/example";
  outputs = {self, nixpkgs, example}@inputs: {
    nixosSystem.nixos = nixpkgs.lib.nixosSystem {
      system = "x86_64-linux";
      specialArgs = {inherit inputs;};
      modules = [
        ./configuration.nix
      ];
    };
  };
}
# configuration.nix
{ inputs, ... }: {
  imports = [ 
    # Include the results of the hardware scan.
    ./hardware-configuration.nix
    inputs.disko.nixosModules.disko
    ./disko-config.nix
   ];
}

Assuming your disko stuff is in configuration.nix of course, your actual file names may vary.

I have flake.nix

{ inputs.nixpkgs.url = "github:NixOS/nixpkgs/23.11";

  outputs = { nixpkgs, ... }: {
    nixosConfigurations.default = nixpkgs.lib.nixosSystem {
      system = "x86_64-linux";

      modules = [ ./configuration.nix ];
    };
  };
}

top part of configuration.nix

{ modulesPath, config, lib, pkgs, inputs, ... }: {
  imports = [
    ./hardware-configuration.nix
    inputs.disko.nixosModules.disko	
     /home/b0ef/proj/2024-01-29.tlater-for-thaldor/disk-mbr.nix
  ];

Error is:

error: infinite recursion encountered

Yep, just change:

diff --git a/a.nix b/b.nix
index 0b90f4d..2cd9665 100644
--- a/a.nix
+++ b/b.nix
@@ -1,9 +1,9 @@
 { inputs.nixpkgs.url = "github:NixOS/nixpkgs/23.11";
 
-  outputs = { nixpkgs, ... }: {
+  outputs = { nixpkgs, ... } @ inputs: {
     nixosConfigurations.default = nixpkgs.lib.nixosSystem {
       system = "x86_64-linux";
-
+      specialArgs = {inherit inputs;};
       modules = [ ./configuration.nix ];
     };
   };
}

That error is probably caused by your other files.

Ok, getting closer. I can feel it in the air.

error: attribute 'disko' missing

flake.nix

{ inputs.nixpkgs.url = "github:NixOS/nixpkgs/23.11";

  outputs = { nixpkgs, ... } @ inputs: {
    nixosConfigurations.default = nixpkgs.lib.nixosSystem {
      system = "x86_64-linux";

      specialArgs = {inherit inputs;};
      modules = [ ./configuration.nix ];
    };
  };
}

top part of configuration.nix

{ modulesPath, config, lib, pkgs, inputs, ... }: {
  imports = [
    ./hardware-configuration.nix
    inputs.disko.nixosModules.disko	
     /home/b0ef/proj/2024-01-29.tlater-for-thaldor/disk-mbr.nix
  ];

Right, yeah, of course you need to add disko to your flake inputs as well:

diff --git a/b.nix b/c.nix
index 2cd9665..2d3ab33 100644
--- a/b.nix
+++ b/c.nix
@@ -1,4 +1,11 @@
-{ inputs.nixpkgs.url = "github:NixOS/nixpkgs/23.11";
+{
+  inputs = {
+    nixpkgs.url = "github:NixOS/nixpkgs/nixos-23.11";
+    disko = {
+      url = "github:nix-community/disko";
+      inputs.nixpkgs.follows = "nixpkgs";
+    };
+  };
 
   outputs = { nixpkgs, ... } @ inputs: {
     nixosConfigurations.default = nixpkgs.lib.nixosSystem {
1 Like

Silly me;) Yup, you made it;)

Thanks a bunch. This deserves a steak and pepper sauce.

I’m poor, so what’s your crypto address and I’ll send you a pizza?:wink:

Hah, appreciate the sentiment, but please donate to the foundation instead if you want to show appreciation: Donate | Nix & NixOS

Helps me too, and ultimately benefits us all :wink:

2 Likes