nixos/proxmox-image: init (#144013)

Co-authored-by: Sandro <sandro.jaeckel@gmail.com>

authored by illustris Sandro and committed by GitHub 8d197bff dd1edacb

+169
+169
nixos/modules/virtualisation/proxmox-image.nix
···
··· 1 + { config, pkgs, lib, ... }: 2 + 3 + with lib; 4 + 5 + { 6 + options.proxmox = { 7 + qemuConf = { 8 + # essential configs 9 + boot = mkOption { 10 + type = types.str; 11 + default = ""; 12 + example = "order=scsi0;net0"; 13 + description = '' 14 + Default boot device. PVE will try all devices in its default order if this value is empty. 15 + ''; 16 + }; 17 + scsihw = mkOption { 18 + type = types.str; 19 + default = "virtio-scsi-pci"; 20 + example = "lsi"; 21 + description = '' 22 + SCSI controller type. Must be one of the supported values given in 23 + <link xlink:href="https://pve.proxmox.com/wiki/Qemu/KVM_Virtual_Machines"/> 24 + ''; 25 + }; 26 + virtio0 = mkOption { 27 + type = types.str; 28 + default = "local-lvm:vm-9999-disk-0"; 29 + example = "ceph:vm-123-disk-0"; 30 + description = '' 31 + Configuration for the default virtio disk. It can be used as a cue for PVE to autodetect the target sotrage. 32 + This parameter is required by PVE even if it isn't used. 33 + ''; 34 + }; 35 + ostype = mkOption { 36 + type = types.str; 37 + default = "l26"; 38 + description = '' 39 + Guest OS type 40 + ''; 41 + }; 42 + cores = mkOption { 43 + type = types.ints.positive; 44 + default = 1; 45 + description = '' 46 + Guest core count 47 + ''; 48 + }; 49 + memory = mkOption { 50 + type = types.ints.positive; 51 + default = 1024; 52 + description = '' 53 + Guest memory in MB 54 + ''; 55 + }; 56 + 57 + # optional configs 58 + name = mkOption { 59 + type = types.str; 60 + default = "nixos-${config.system.nixos.label}"; 61 + description = '' 62 + VM name 63 + ''; 64 + }; 65 + net0 = mkOption { 66 + type = types.commas; 67 + default = "virtio=00:00:00:00:00:00,bridge=vmbr0,firewall=1"; 68 + description = '' 69 + Configuration for the default interface. When restoring from VMA, check the 70 + "unique" box to ensure device mac is randomized. 71 + ''; 72 + }; 73 + serial0 = mkOption { 74 + type = types.str; 75 + default = "socket"; 76 + example = "/dev/ttyS0"; 77 + description = '' 78 + Create a serial device inside the VM (n is 0 to 3), and pass through a host serial device (i.e. /dev/ttyS0), 79 + or create a unix socket on the host side (use qm terminal to open a terminal connection). 80 + ''; 81 + }; 82 + agent = mkOption { 83 + type = types.bool; 84 + apply = x: if x then "1" else "0"; 85 + default = true; 86 + description = '' 87 + Expect guest to have qemu agent running 88 + ''; 89 + }; 90 + }; 91 + qemuExtraConf = mkOption { 92 + type = with types; attrsOf (oneOf [ str int ]); 93 + default = {}; 94 + example = literalExpression ''{ 95 + cpu = "host"; 96 + onboot = 1; 97 + }''; 98 + description = '' 99 + Additional options appended to qemu-server.conf 100 + ''; 101 + }; 102 + filenameSuffix = mkOption { 103 + type = types.str; 104 + default = config.proxmox.qemuConf.name; 105 + example = "999-nixos_template"; 106 + description = '' 107 + Filename of the image will be vzdump-qemu-''${filenameSuffix}.vma.zstd. 108 + This will also determine the default name of the VM on restoring the VMA. 109 + Start this value with a number if you want the VMA to be detected as a backup of 110 + any specific VMID. 111 + ''; 112 + }; 113 + }; 114 + 115 + config = let 116 + cfg = config.proxmox; 117 + cfgLine = name: value: '' 118 + ${name}: ${builtins.toString value} 119 + ''; 120 + cfgFile = fileName: properties: pkgs.writeTextDir fileName '' 121 + # generated by NixOS 122 + ${lib.concatStrings (lib.mapAttrsToList cfgLine properties)} 123 + #qmdump#map:virtio0:drive-virtio0:local-lvm:raw: 124 + ''; 125 + in { 126 + system.build.VMA = import ../../lib/make-disk-image.nix { 127 + name = "proxmox-${cfg.filenameSuffix}"; 128 + postVM = let 129 + # Build qemu with PVE's patch that adds support for the VMA format 130 + vma = pkgs.qemu_kvm.overrideAttrs ( super: { 131 + patches = let 132 + rev = "cc707c362ea5c8d832aac270d1ffa7ac66a8908f"; 133 + path = "debian/patches/pve/0025-PVE-Backup-add-vma-backup-format-code.patch"; 134 + vma-patch = pkgs.fetchpatch { 135 + url = "https://git.proxmox.com/?p=pve-qemu.git;a=blob_plain;hb=${rev};f=${path}"; 136 + sha256 = "1z467xnmfmry3pjy7p34psd5xdil9x0apnbvfz8qbj0bf9fgc8zf"; 137 + }; 138 + in super.patches ++ [ vma-patch ]; 139 + buildInputs = super.buildInputs ++ [ pkgs.libuuid ]; 140 + }); 141 + in 142 + '' 143 + ${vma}/bin/vma create "vzdump-qemu-${cfg.filenameSuffix}.vma" \ 144 + -c ${cfgFile "qemu-server.conf" (cfg.qemuConf // cfg.qemuExtraConf)}/qemu-server.conf drive-virtio0=$diskImage 145 + rm $diskImage 146 + ${pkgs.zstd}/bin/zstd "vzdump-qemu-${cfg.filenameSuffix}.vma" 147 + mv "vzdump-qemu-${cfg.filenameSuffix}.vma.zst" $out/ 148 + ''; 149 + format = "raw"; 150 + inherit config lib pkgs; 151 + }; 152 + 153 + boot = { 154 + growPartition = true; 155 + kernelParams = [ "console=ttyS0" ]; 156 + loader.grub.device = lib.mkDefault "/dev/vda"; 157 + loader.timeout = 0; 158 + initrd.availableKernelModules = [ "uas" "virtio_blk" "virtio_pci" ]; 159 + }; 160 + 161 + fileSystems."/" = { 162 + device = "/dev/disk/by-label/nixos"; 163 + autoResize = true; 164 + fsType = "ext4"; 165 + }; 166 + 167 + services.qemuGuest.enable = lib.mkDefault true; 168 + }; 169 + }