Flake to create a simple SD image for RPI4 (cross)

Like not having ZFS enabled in installers by default? :slight_smile: It was done like that for a long time and enabling it was actually pretty easy for users who needed it.

I think it’s good to have by default. Just should be easier to make one without it.

But that’s way harder currently since supportedFilesystems is a list “interface”, so you need to force it with another list that contains all except zfs (where you need to figure out what all means). Maybe we could expand it to a record like supportedFilesystems.zfs.enabled but that again is non-trivial backwards incompatible change affecting all NixOS users.

Right but what I just said is that it should be easier.

And you don’t have to do it as you described. I linked a module before that does it more easily.

Anyway this isn’t the thread to discuss how the ISO modules in nixpkgs should be changed.

If ZFS is something common for NixOS users, then I agree with just having the support for ZFS enabled, however it also installs and runs a daemon (zfs-zed). Which is only really necessary for systems that actually use ZFS. So therefore I would rather have zfs not enabled by default, if it requires an additional process, or have the process optional.

It’s only there by default within the installer. If you install a system without using ZFS, then ZFS won’t be in your system, even if it was in the installer.

Reading the module it suggests exactly the same thing so that is something to consider.

I agree, I might just file a PR some day.

Where in my flake do I explicitly use the installer? I just want to create a minimal sd-card image for rpi4.

Ah, my bad. The SD card modules are based on the installer modules, because it’s sort of meant to be a starting point. Flash the SD card with this “installation medium”, and then update the system to your actual preferred config. Or at least that was the original design.

nixos-generator has the sd-aarch64-installer format, which I don’t use.

Ah, I see. Ok the sd-aarch64 non-installer format still ends up including a fair amount of extra stuff, if you follow the imports from here. It’s very much not a minimal config, like it probably should be.

Eventually those imports lead you here, which is where the dependency on ZFS (and several other file systems) comes from.

1 Like

Thanks! I read the first link already (I have posted it in this thread before), and was very surprised how raspberry pi specific it is. I would have expected something much more general to the whole aarch64 platform. This stuff I would have expected in nixos-hardware.nixosModules.raspberry-pi-4.

The second link, I haven’t found before, but it does add a lot of unnecessary stuff. Is there a way to remove that include from my flake?

I guess I could just try implementing my own format…

That’s not really possible. ARM doesn’t have any kind of standard boot mechanism across boards, except for EBBR which is (mostly) only adopted on servers. See: Planning for a better NixOS on ARM (and other non-x86_64 systems)

You can probably add it to the disabledModules list (note, that section is titled “replace modules”, but you don’t actually have to provide a replacement).

1 Like

Well that is what the nixos-hardware is for, I thought. I was surprised that the sdcard format also had aarch64 in its name.

I think calling the format “sdcard” is probably a misnomer. There’s nothing special about SD cards; if it was platform agnostic, the format would work on any kind of block device. Realistically, it’s the rpi format. And yes, if you read the post I linked, we would very much like to remove the sd-image things from NixOS and keep these device-specific configurations in nixos-hardware.

1 Like

I tried this:

boot.zfs.enabled = nixpkgs.lib.mkDefault false;

And got the same issue:

$ nix build .#packages.aarch64-linux.sdcard
error: The option `boot.zfs.enabled' is read-only, but it's set multiple times. Definition values:
       - In `/nix/store/kcmipm57ph9bpzz8bs80iiijiwbyzwy3-source/nixos/modules/tasks/filesystems/zfs.nix': true
       - In `/nix/store/kcmipm57ph9bpzz8bs80iiijiwbyzwy3-source/flake.nix': false
(use '--show-trace' to show detailed location information)

I also tried:

boot.supportedFilesystems = [ "ext4" ];

which didn’t trigger a rebuild, so it probably didn’t have any effect.

I answered both of those questions above. boot.zfs.enabled is readonly because it is merely indicative of whether ZFS is in supportedFilesystems, not prescriptive. Some of the installer modules do a kind of silly hack to cut ZFS out. You can copy that same trick. What you tried didn’t work because modules are merged and added, so you simply added ext4. You would have to mkForce that option to the exact list that you want. The silly hack in the installer modules is easier. I would like for this to be easier.

1 Like

But also, did you try the disabledModules idea I mentioned?

I think I saw that trick (hack) before, but I didn’t understand what it is doing.

I copied it now, and it a rebuild is happening, so it seems like it might work.

I haven’t gotten to the disableModules yet. Just wanted to start testing suggestions in chronological order :wink:

disableModules seems to work and is probably the nicest way to minimize the image.

For posterity sake, here is the full flake.nix, for a minimal system:

{
  description = "Base system for raspberry pi 4";
  inputs = {
    nixpkgs.url = "nixpkgs/nixos-unstable";
    nixos-generators = {
      url = "github:nix-community/nixos-generators";
      inputs.nixpkgs.follows = "nixpkgs";
    };
  };

  outputs = { self, nixpkgs, nixos-generators, ... }: 
  {
    nixosModules = {
      system = {
        #boot.zfs.enabled = false; # error: The option `boot.zfs.enabled' is read-only, but it's set multiple times.
        #boot.zfs.enabled = nixpkgs.lib.mkDefault false; # error: The option `boot.zfs.enabled' is read-only, but it's set multiple times.
        #boot.supportedFilesystems = [ "ext4" ]; # Does not have any effect, because it only adds `ext4`, not deletes anything else from the array.

        # Copied from https://github.com/NixOS/nixpkgs/blob/f3565a2c088883636f198550eac349ed82c6a2b3/nixos/modules/installer/sd-card/sd-image-aarch64-new-kernel-no-zfs-installer.nix#L6 "
        # This works, however it is a hack:
        # Makes `availableOn` fail for zfs, see <nixos/modules/profiles/base.nix>.
        # This is a workaround since we cannot remove the `"zfs"` string from `supportedFilesystems`.
        # The proper fix would be to make `supportedFilesystems` an attrset with true/false which we
        # could then `lib.mkForce false`
        #nixpkgs.overlays = [(final: super: {
        #  zfs = super.zfs.overrideAttrs(_: {
        #    meta.platforms = [];
        #  });
        #})];

        # Disabling the whole `profiles/base.nix` module, which is responsible
        # for adding ZFS and a bunch of other unnecessary programs:
        disabledModules = [
          "profiles/base.nix"
        ];

        system.stateVersion = "23.11";
      };
      users = {
        users.users = {
          admin = {
            password = "admin";
            isNormalUser = true;
            extraGroups = [ "wheel" ];
          };
        };
      };
    };

    packages.aarch64-linux = {
      sdcard = nixos-generators.nixosGenerate {
        system = "aarch64-linux";
        format = "sd-aarch64";
        modules = [
          self.nixosModules.system
          self.nixosModules.users
        ];
      };
    };
  };
}
3 Likes