nixpkgs/nixos/modules/virtualisation/proxmox-image.nix

198 lines
6.2 KiB
Nix

{ config, pkgs, lib, ... }:
with lib;
{
options.proxmox = {
qemuConf = {
# essential configs
boot = mkOption {
type = types.str;
default = "";
example = "order=scsi0;net0";
description = lib.mdDoc ''
Default boot device. PVE will try all devices in its default order if this value is empty.
'';
};
scsihw = mkOption {
type = types.str;
default = "virtio-scsi-pci";
example = "lsi";
description = lib.mdDoc ''
SCSI controller type. Must be one of the supported values given in
<https://pve.proxmox.com/wiki/Qemu/KVM_Virtual_Machines>
'';
};
virtio0 = mkOption {
type = types.str;
default = "local-lvm:vm-9999-disk-0";
example = "ceph:vm-123-disk-0";
description = lib.mdDoc ''
Configuration for the default virtio disk. It can be used as a cue for PVE to autodetect the target sotrage.
This parameter is required by PVE even if it isn't used.
'';
};
ostype = mkOption {
type = types.str;
default = "l26";
description = lib.mdDoc ''
Guest OS type
'';
};
cores = mkOption {
type = types.ints.positive;
default = 1;
description = lib.mdDoc ''
Guest core count
'';
};
memory = mkOption {
type = types.ints.positive;
default = 1024;
description = lib.mdDoc ''
Guest memory in MB
'';
};
# optional configs
name = mkOption {
type = types.str;
default = "nixos-${config.system.nixos.label}";
description = lib.mdDoc ''
VM name
'';
};
net0 = mkOption {
type = types.commas;
default = "virtio=00:00:00:00:00:00,bridge=vmbr0,firewall=1";
description = lib.mdDoc ''
Configuration for the default interface. When restoring from VMA, check the
"unique" box to ensure device mac is randomized.
'';
};
serial0 = mkOption {
type = types.str;
default = "socket";
example = "/dev/ttyS0";
description = lib.mdDoc ''
Create a serial device inside the VM (n is 0 to 3), and pass through a host serial device (i.e. /dev/ttyS0),
or create a unix socket on the host side (use qm terminal to open a terminal connection).
'';
};
agent = mkOption {
type = types.bool;
apply = x: if x then "1" else "0";
default = true;
description = lib.mdDoc ''
Expect guest to have qemu agent running
'';
};
};
qemuExtraConf = mkOption {
type = with types; attrsOf (oneOf [ str int ]);
default = {};
example = literalExpression ''{
cpu = "host";
onboot = 1;
}'';
description = lib.mdDoc ''
Additional options appended to qemu-server.conf
'';
};
filenameSuffix = mkOption {
type = types.str;
default = config.proxmox.qemuConf.name;
example = "999-nixos_template";
description = lib.mdDoc ''
Filename of the image will be vzdump-qemu-''${filenameSuffix}.vma.zstd.
This will also determine the default name of the VM on restoring the VMA.
Start this value with a number if you want the VMA to be detected as a backup of
any specific VMID.
'';
};
};
config = let
cfg = config.proxmox;
cfgLine = name: value: ''
${name}: ${builtins.toString value}
'';
cfgFile = fileName: properties: pkgs.writeTextDir fileName ''
# generated by NixOS
${lib.concatStrings (lib.mapAttrsToList cfgLine properties)}
#qmdump#map:virtio0:drive-virtio0:local-lvm:raw:
'';
in {
system.build.VMA = import ../../lib/make-disk-image.nix {
name = "proxmox-${cfg.filenameSuffix}";
postVM = let
# Build qemu with PVE's patch that adds support for the VMA format
vma = (pkgs.qemu_kvm.override {
alsaSupport = false;
pulseSupport = false;
sdlSupport = false;
jackSupport = false;
gtkSupport = false;
vncSupport = false;
smartcardSupport = false;
spiceSupport = false;
ncursesSupport = false;
libiscsiSupport = false;
tpmSupport = false;
numaSupport = false;
seccompSupport = false;
guestAgentSupport = false;
}).overrideAttrs ( super: rec {
version = "7.0.0";
src = pkgs.fetchurl {
url= "https://download.qemu.org/qemu-${version}.tar.xz";
sha256 = "sha256-9rN1x5UfcoQCeYsLqrsthkeMpT1Eztvvq74cRr9G+Dk=";
};
patches = [
(pkgs.fetchpatch {
url =
let
rev = "1976ca460796f28447b41e3618e5c1e234035dd5";
path = "debian/patches/pve/0026-PVE-Backup-add-vma-backup-format-code.patch";
in "https://git.proxmox.com/?p=pve-qemu.git;a=blob_plain;hb=${rev};f=${path}";
hash = "sha256-2Dz+ceTwrcyYYxi76RtyY3v15/2pwGcDhFuoZWlgbjc=";
})
];
buildInputs = super.buildInputs ++ [ pkgs.libuuid ];
});
in
''
${vma}/bin/vma create "vzdump-qemu-${cfg.filenameSuffix}.vma" \
-c ${cfgFile "qemu-server.conf" (cfg.qemuConf // cfg.qemuExtraConf)}/qemu-server.conf drive-virtio0=$diskImage
rm $diskImage
${pkgs.zstd}/bin/zstd "vzdump-qemu-${cfg.filenameSuffix}.vma"
mv "vzdump-qemu-${cfg.filenameSuffix}.vma.zst" $out/
mkdir -p $out/nix-support
echo "file vma $out/vzdump-qemu-${cfg.filenameSuffix}.vma.zst" >> $out/nix-support/hydra-build-products
'';
format = "raw";
inherit config lib pkgs;
};
boot = {
growPartition = true;
kernelParams = [ "console=ttyS0" ];
loader.grub.device = lib.mkDefault "/dev/vda";
loader.timeout = 0;
initrd.availableKernelModules = [ "uas" "virtio_blk" "virtio_pci" ];
};
fileSystems."/" = {
device = "/dev/disk/by-label/nixos";
autoResize = true;
fsType = "ext4";
};
services.qemuGuest.enable = lib.mkDefault true;
};
}