Using nixos-generators in a flake with customFormats

Hi everyone,

I’m trying to generate VM-Images with nixos-generators. Because I want to have finer control, I want to use customFormats, but I can’t get it to work. I’m fairly new to Nix and Flakes, therefore it is probably some stupid mistake I’m making. Any advice is appreciated, thank you all in advance.

flake.nix

{
  inputs = {
    nixpkgs.url = "nixpkgs/nixos-23.05";
    nixos-generators = {
      url = "github:nix-community/nixos-generators";
      inputs.nixpkgs.follows = "nixpkgs";
    };
    qcow2_imp = {
      url = "../modules/qcow2.nix";
      flake = false;
    };
  };
  outputs = { self, nixpkgs, nixos-generators, qcow2_imp, ... }: 
  {
    packages.x86_64-linux = {
      vbox = nixos-generators.nixosGenerate {
        system = "x86_64-linux";
        format = "virtualbox";
      };
      qemu = nixos-generators.nixosGenerate {
        system = "x86_64-linux";
        format = "qcow2";
        customFormats = { qcow2 = qcow2_imp; };
      };
      hyperv = nixos-generators.nixosGenerate {
        system = "x86_64-linux";
        format = "hyperv";
      };
      default = self.packages.x86_64-linux.vbox;
    };
  };
}

qcow2.nix (copied from the examples on github)

{
  config,
  lib,
  pkgs,
  modulesPath,
  ...
}: {
  # for virtio kernel drivers
  imports = [
    "${toString modulesPath}/profiles/qemu-guest.nix"
  ];

  fileSystems."/" = {
    device = "/dev/disk/by-label/nixos";
    autoResize = true;
    fsType = "ext4";
  };

  boot.growPartition = true;
  boot.kernelParams = ["console=ttyS0"];
  boot.loader.grub.device =
    if (pkgs.stdenv.system == "x86_64-linux")
    then (lib.mkDefault "/dev/vda")
    else (lib.mkDefault "nodev");

  boot.loader.grub.efiSupport = lib.mkIf (pkgs.stdenv.system != "x86_64-linux") (lib.mkDefault true);
  boot.loader.grub.efiInstallAsRemovable = lib.mkIf (pkgs.stdenv.system != "x86_64-linux") (lib.mkDefault true);
  boot.loader.timeout = 0;

  system.build.qcow = import "${toString modulesPath}/../lib/make-disk-image.nix" {
    inherit lib config pkgs;
    diskSize = 8192;
    format = "qcow2";
    partitionTableType = "hybrid";
  };

  formatAttr = "qcow2";
  fileExtension = ".qcow2";
}

error message

warning: Git tree '/home/kakn/Dokumente/Repositories/reproducibledevenvironments' is dirty
warning: updating lock file '/home/kakn/Dokumente/Repositories/reproducibledevenvironments/base-config/flake.lock':
• Updated input 'qcow2_imp':
    'path:/nix/store/8pxxvq5g97q16fys82x2qvysgwdcjaxc-source/modules/qcow2.nix?lastModified=1&narHash=sha256-LiqQe/qigVi6Otl%2BY2gL3/Wc/4vFyHMVrg862rvnCiE%3D' (1970-01-01)
  → 'path:/nix/store/2q02n99779d96939mm1anra5vi4zc709-source/modules/qcow2.nix?lastModified=1&narHash=sha256-LiqQe/qigVi6Otl%2BY2gL3/Wc/4vFyHMVrg862rvnCiE%3D' (1970-01-01)
warning: Git tree '/home/kakn/Dokumente/Repositories/reproducibledevenvironments' is dirty
error:
       … while evaluating the attribute 'config.system.build."${(image).config.formatAttr}"'

         at /nix/store/c8aplaf4cij0zr4bca19y1k2vi9qhslz-source/lib/modules.nix:326:9:

          325|         options = checked options;
          326|         config = checked (removeAttrs config [ "_module" ]);
             |         ^
          327|         _module = checked (config._module);

       … while calling the 'seq' builtin

         at /nix/store/c8aplaf4cij0zr4bca19y1k2vi9qhslz-source/lib/modules.nix:326:18:

          325|         options = checked options;
          326|         config = checked (removeAttrs config [ "_module" ]);
             |                  ^
          327|         _module = checked (config._module);

       (stack trace truncated; use '--show-trace' to show the full trace)

       error: The option `lastModified' does not exist. Definition values:
       - In `/nix/store/c8aplaf4cij0zr4bca19y1k2vi9qhslz-source/flake.nix': 1

is this checked into a public git repo any where ,

so i can git clone and try and reproduce.

Sadly I can’t share the full repository, but I put the involved files into a public GitHub repository, the error is the same, so you should be able to reproduce it. Thank you for your help!

https://github.com/kknoepfle/reproducible_environments/tree/main

1 Like

thats a shame, as nixos is reproducible, being able to reproduce problems…

that’s one of biggest hurdles about customer success engineering…

The ‘reproducer’ is the key, snippets and code that cannot evaluate or be realised, is of limited use.

However, for the those cases , commercial support is available.

I can reproduce it with the shared repo, and the following command :

% cd base-config && nix build .#packages.x86_64-linux.qemu
warning: creating lock file '/home/user/reproducible_environments/base-config/flake.lock'
warning: Git tree '/home/user/reproducible_environments' is dirty
error:
       … while evaluating the attribute 'config.system.build."${(image).config.formatAttr}"'

         at /nix/store/w8lqwhvjx7q0xqpmzyi82j5ka2iqkhxf-source/lib/modules.nix:326:9:

          325|         options = checked options;
          326|         config = checked (removeAttrs config [ "_module" ]);
             |         ^
          327|         _module = checked (config._module);

       … while calling the 'seq' builtin

         at /nix/store/w8lqwhvjx7q0xqpmzyi82j5ka2iqkhxf-source/lib/modules.nix:326:18:

          325|         options = checked options;
          326|         config = checked (removeAttrs config [ "_module" ]);
             |                  ^
          327|         _module = checked (config._module);

       (stack trace truncated; use '--show-trace' to show the full trace)

       error: The option `lastModified' does not exist. Definition values:
       - In `/nix/store/w8lqwhvjx7q0xqpmzyi82j5ka2iqkhxf-source/flake.nix': 1

here is a patch to you git, with these changes it worked for me:

iff --git a/base-config/flake.nix b/base-config/flake.nix
index 54e7861..09bb6db 100644
--- a/base-config/flake.nix
+++ b/base-config/flake.nix
@@ -20,7 +20,7 @@
       qemu = nixos-generators.nixosGenerate {
         system = "x86_64-linux";
         format = "qcow2";
-        customFormats = { qcow2 = qcow2_imp; };
+        customFormats = { qcow2.imports = [ qcow2_imp.outPath ]; };
       };
       hyperv = nixos-generators.nixosGenerate {
         system = "x86_64-linux";
diff --git a/modules/qcow2.nix b/modules/qcow2.nix
index 115c8a1..a2abd1d 100644
--- a/modules/qcow2.nix
+++ b/modules/qcow2.nix
@@ -27,7 +27,7 @@
   boot.loader.grub.efiInstallAsRemovable = lib.mkIf (pkgs.stdenv.system != "x86_64-linux") (lib.mkDefault true);
   boot.loader.timeout = 0;

-  system.build.qcow = import "${toString modulesPath}/../lib/make-disk-image.nix" {
+  system.build.qcow2 = import "${toString modulesPath}/../lib/make-disk-image.nix" {
     inherit lib config pkgs;
     diskSize = 8192;
     format = "qcow2";
3 Likes

Works for me, many thanks !

Now I’ll try to understand why the change was needed.

Works for me too, thank you!