From 8d197bffd80e21f34c3f52379d93a565444ea189 Mon Sep 17 00:00:00 2001 From: illustris Date: Sun, 7 Nov 2021 20:32:54 +0530 Subject: [PATCH] nixos/proxmox-image: init (#144013) Co-authored-by: Sandro --- .../modules/virtualisation/proxmox-image.nix | 169 ++++++++++++++++++ 1 file changed, 169 insertions(+) create mode 100644 nixos/modules/virtualisation/proxmox-image.nix diff --git a/nixos/modules/virtualisation/proxmox-image.nix b/nixos/modules/virtualisation/proxmox-image.nix new file mode 100644 index 00000000000..c537d5aed44 --- /dev/null +++ b/nixos/modules/virtualisation/proxmox-image.nix @@ -0,0 +1,169 @@ +{ config, pkgs, lib, ... }: + +with lib; + +{ + options.proxmox = { + qemuConf = { + # essential configs + boot = mkOption { + type = types.str; + default = ""; + example = "order=scsi0;net0"; + description = '' + 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 = '' + SCSI controller type. Must be one of the supported values given in + + ''; + }; + virtio0 = mkOption { + type = types.str; + default = "local-lvm:vm-9999-disk-0"; + example = "ceph:vm-123-disk-0"; + description = '' + 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 = '' + Guest OS type + ''; + }; + cores = mkOption { + type = types.ints.positive; + default = 1; + description = '' + Guest core count + ''; + }; + memory = mkOption { + type = types.ints.positive; + default = 1024; + description = '' + Guest memory in MB + ''; + }; + + # optional configs + name = mkOption { + type = types.str; + default = "nixos-${config.system.nixos.label}"; + description = '' + VM name + ''; + }; + net0 = mkOption { + type = types.commas; + default = "virtio=00:00:00:00:00:00,bridge=vmbr0,firewall=1"; + description = '' + 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 = '' + 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 = '' + Expect guest to have qemu agent running + ''; + }; + }; + qemuExtraConf = mkOption { + type = with types; attrsOf (oneOf [ str int ]); + default = {}; + example = literalExpression ''{ + cpu = "host"; + onboot = 1; + }''; + description = '' + Additional options appended to qemu-server.conf + ''; + }; + filenameSuffix = mkOption { + type = types.str; + default = config.proxmox.qemuConf.name; + example = "999-nixos_template"; + description = '' + 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.overrideAttrs ( super: { + patches = let + rev = "cc707c362ea5c8d832aac270d1ffa7ac66a8908f"; + path = "debian/patches/pve/0025-PVE-Backup-add-vma-backup-format-code.patch"; + vma-patch = pkgs.fetchpatch { + url = "https://git.proxmox.com/?p=pve-qemu.git;a=blob_plain;hb=${rev};f=${path}"; + sha256 = "1z467xnmfmry3pjy7p34psd5xdil9x0apnbvfz8qbj0bf9fgc8zf"; + }; + in super.patches ++ [ vma-patch ]; + 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/ + ''; + 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; + }; +}