Conflicting bootloader settings in /virtualisation/proxmox-lxc.nix

I am having trouble with conflicting bootloader options. In my flake I want to generate separate nix configs for bare metal machines and for Proxmox LXCs.

I have written two modules, each hidden behind enable options:

bare metal bootloader.nix
{ config, lib, ... }:

let
  cfg = config.my.system.bootloader;
in
{
  options = {
    my.system.bootloader = {
      enable = lib.mkOption {
        type = lib.types.bool;
        default = false;
        description = "Enable bootloader settings";
      };
    };
  };

  config = lib.mkIf cfg.enable {
    boot.loader.systemd-boot.enable = true;
    boot.loader.systemd-boot.graceful = true;
    boot.loader.systemd-boot.configurationLimit = 45;
    boot.loader.efi.canTouchEfiVariables = true;
  };
}
proxmox-lxc.nix
{ config, pkgs, lib, modulesPath, ... }:

let
  cfg = config.my.system.proxmox-lxc;
in
{
  options = {
    my.system.proxmox-lxc = {
      enable = lib.mkOption {
        type = lib.types.bool;
        default = false;
        description = "Enable proxmox-lxc settings";
      };
    };
  };

  imports = [ (modulesPath + "/virtualisation/proxmox-lxc.nix") ];

  config = lib.mkIf cfg.enable {

    boot.isContainer = true;

    # Suppress these units, since they do not work inside LXC
    systemd.suppressedSystemUnits = [
      "dev-mqueue.mount"
      "sys-kernel-debug.mount"
      "sys-fs-fuse-connections.mount"
    ];
  };
}

Both default to disabled and I would only enable one at a time. Unfortunately I can’t even rebuild with both modules staged and disabled in my repo. This is the error I receive:

nixos rebuild error
error:
       … while calling the 'head' builtin
         at /nix/store/52hnnvpyni1n79ra4rqxdcswmd2w3823-source/lib/attrsets.nix:1534:13:
         1533|           if length values == 1 || pred here (elemAt values 1) (head values) then
         1534|             head values
             |             ^
         1535|           else

       … while evaluating the attribute 'value'
         at /nix/store/52hnnvpyni1n79ra4rqxdcswmd2w3823-source/lib/modules.nix:992:7:
          991|     // {
          992|       value = addErrorContext "while evaluating the option `${showOption loc}':" value;
             |       ^
          993|       inherit (res.defsFinal') highestPrio;

       … while evaluating the option `system.build.toplevel':

       … while evaluating definitions from `/nix/store/52hnnvpyni1n79ra4rqxdcswmd2w3823-source/nixos/modules/system/activation/top-level.nix':

       … while evaluating the option `system.systemBuilderArgs':

       … while evaluating definitions from `/nix/store/52hnnvpyni1n79ra4rqxdcswmd2w3823-source/nixos/modules/system/activation/top-level.nix':

       … while evaluating the option `system.build.installBootLoader':

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

       error: The option `system.build.installBootLoader' is defined multiple times while it's expected to be unique.
       Only one bootloader can be enabled at a time. This requirement has not
       been checked until NixOS 22.05. Earlier versions defaulted to the last
       definition. Change your configuration to enable only one bootloader.

       Definition values:
       - In `/nix/store/52hnnvpyni1n79ra4rqxdcswmd2w3823-source/nixos/modules/system/boot/loader/init-script/init-script.nix': <derivation init-script-builder.sh>
       - In `/nix/store/52hnnvpyni1n79ra4rqxdcswmd2w3823-source/nixos/modules/system/boot/loader/systemd-boot/systemd-boot.nix': <derivation install-systemd-boot.sh>
       Use `lib.mkForce value` or `lib.mkDefault value` to change the priority on any of these definitions.

My troubleshooting indicates that this is caused by the import of /virtualisation/proxmox-lxc.nix. The error disappears when I comment out the import of that external module, but that’s equivalent to commenting out my own module.

As I understand it, imports must be separate to config and therefore cannot be hidden behind a conditional lib.mkIf cfg.enable.

So how can I import /virtualisation/proxmox-lxc.nix for my Proxmox LXC hosts without conflicting with boot settings for bare metal machines? i.e. how can I have both of these modules in my repo simultaneously?

It looks like this issue was encountered and fixed by others: nixos/proxmox-lxc: allow importing module without activation by Silver-Golden · Pull Request #267764 · NixOS/nixpkgs · GitHub

The proxmox-lxc.nix module in nixpkgs is wrapped in an enabling option of its own, proxmoxLXC.enable.

I have now set that to default off:
proxmoxLXC.enable = lib.mkDefault false;

… which allows the nixpkgs module to be imported without being automatically enabled and causing nixos-rebuild to fail in a bootloader conflict.

When I need to configure an LXC, I can use proxmoxLXC.enable = true; to override the default.

1 Like