From 83708737d33d56f04bb69312166e2aa408202876 Mon Sep 17 00:00:00 2001 From: Martin Pywell Date: Mon, 15 Jul 2024 11:32:14 +0000 Subject: [PATCH] common: restore default disk backup behaviour In testing it was observed that the upstream disk API changes are excluding disks from Proxmox backup jobs by default (setting backup=0). This commit reinstates the behaviour of previous versions of this packer-plugin-proxmox where disks created by Packer are enabled for backup by default. A new ExcludeFromBackup disk field has been added to opt out of this behaviour. --- .web-docs/components/builder/clone/README.md | 3 + .web-docs/components/builder/iso/README.md | 3 + builder/proxmox/common/config.go | 3 + builder/proxmox/common/config.hcl2spec.go | 42 +++--- builder/proxmox/common/step_start_vm.go | 8 ++ builder/proxmox/common/step_start_vm_test.go | 123 +++++++++++++----- .../common/diskConfig-not-required.mdx | 3 + 7 files changed, 132 insertions(+), 53 deletions(-) diff --git a/.web-docs/components/builder/clone/README.md b/.web-docs/components/builder/clone/README.md index f40faa5b..48bae1b0 100644 --- a/.web-docs/components/builder/clone/README.md +++ b/.web-docs/components/builder/clone/README.md @@ -447,6 +447,9 @@ Example: - `asyncio` (string) - Configure Asynchronous I/O. Can be `native`, `threads`, or `io_uring`. Defaults to io_uring. +- `exclude_from_backup` (bool) - Exclude disk from Proxmox backup jobs + Defaults to false. + - `discard` (bool) - Relay TRIM commands to the underlying storage. Defaults to false. See the [Proxmox documentation](https://pve.proxmox.com/pve-docs/pve-admin-guide.html#qm_hard_disk_discard) diff --git a/.web-docs/components/builder/iso/README.md b/.web-docs/components/builder/iso/README.md index ab2685ac..7e0c679a 100644 --- a/.web-docs/components/builder/iso/README.md +++ b/.web-docs/components/builder/iso/README.md @@ -587,6 +587,9 @@ Example: - `asyncio` (string) - Configure Asynchronous I/O. Can be `native`, `threads`, or `io_uring`. Defaults to io_uring. +- `exclude_from_backup` (bool) - Exclude disk from Proxmox backup jobs + Defaults to false. + - `discard` (bool) - Relay TRIM commands to the underlying storage. Defaults to false. See the [Proxmox documentation](https://pve.proxmox.com/pve-docs/pve-admin-guide.html#qm_hard_disk_discard) diff --git a/builder/proxmox/common/config.go b/builder/proxmox/common/config.go index 8de53487..696a2a50 100644 --- a/builder/proxmox/common/config.go +++ b/builder/proxmox/common/config.go @@ -362,6 +362,9 @@ type diskConfig struct { // Configure Asynchronous I/O. Can be `native`, `threads`, or `io_uring`. // Defaults to io_uring. AsyncIO string `mapstructure:"asyncio"` + // Exclude disk from Proxmox backup jobs + // Defaults to false. + ExcludeFromBackup bool `mapstructure:"exclude_from_backup"` // Relay TRIM commands to the underlying storage. Defaults // to false. See the // [Proxmox documentation](https://pve.proxmox.com/pve-docs/pve-admin-guide.html#qm_hard_disk_discard) diff --git a/builder/proxmox/common/config.hcl2spec.go b/builder/proxmox/common/config.hcl2spec.go index 2a8fad88..93dd71df 100644 --- a/builder/proxmox/common/config.hcl2spec.go +++ b/builder/proxmox/common/config.hcl2spec.go @@ -333,16 +333,17 @@ func (*FlatNICConfig) HCL2Spec() map[string]hcldec.Spec { // FlatdiskConfig is an auto-generated flat version of diskConfig. // Where the contents of a field with a `mapstructure:,squash` tag are bubbled up. type FlatdiskConfig struct { - Type *string `mapstructure:"type" cty:"type" hcl:"type"` - StoragePool *string `mapstructure:"storage_pool" cty:"storage_pool" hcl:"storage_pool"` - StoragePoolType *string `mapstructure:"storage_pool_type" cty:"storage_pool_type" hcl:"storage_pool_type"` - Size *string `mapstructure:"disk_size" cty:"disk_size" hcl:"disk_size"` - CacheMode *string `mapstructure:"cache_mode" cty:"cache_mode" hcl:"cache_mode"` - DiskFormat *string `mapstructure:"format" cty:"format" hcl:"format"` - IOThread *bool `mapstructure:"io_thread" cty:"io_thread" hcl:"io_thread"` - AsyncIO *string `mapstructure:"asyncio" cty:"asyncio" hcl:"asyncio"` - Discard *bool `mapstructure:"discard" cty:"discard" hcl:"discard"` - SSD *bool `mapstructure:"ssd" cty:"ssd" hcl:"ssd"` + Type *string `mapstructure:"type" cty:"type" hcl:"type"` + StoragePool *string `mapstructure:"storage_pool" cty:"storage_pool" hcl:"storage_pool"` + StoragePoolType *string `mapstructure:"storage_pool_type" cty:"storage_pool_type" hcl:"storage_pool_type"` + Size *string `mapstructure:"disk_size" cty:"disk_size" hcl:"disk_size"` + CacheMode *string `mapstructure:"cache_mode" cty:"cache_mode" hcl:"cache_mode"` + DiskFormat *string `mapstructure:"format" cty:"format" hcl:"format"` + IOThread *bool `mapstructure:"io_thread" cty:"io_thread" hcl:"io_thread"` + AsyncIO *string `mapstructure:"asyncio" cty:"asyncio" hcl:"asyncio"` + ExcludeFromBackup *bool `mapstructure:"exclude_from_backup" cty:"exclude_from_backup" hcl:"exclude_from_backup"` + Discard *bool `mapstructure:"discard" cty:"discard" hcl:"discard"` + SSD *bool `mapstructure:"ssd" cty:"ssd" hcl:"ssd"` } // FlatMapstructure returns a new FlatdiskConfig. @@ -357,16 +358,17 @@ func (*diskConfig) FlatMapstructure() interface{ HCL2Spec() map[string]hcldec.Sp // The decoded values from this spec will then be applied to a FlatdiskConfig. func (*FlatdiskConfig) HCL2Spec() map[string]hcldec.Spec { s := map[string]hcldec.Spec{ - "type": &hcldec.AttrSpec{Name: "type", Type: cty.String, Required: false}, - "storage_pool": &hcldec.AttrSpec{Name: "storage_pool", Type: cty.String, Required: false}, - "storage_pool_type": &hcldec.AttrSpec{Name: "storage_pool_type", Type: cty.String, Required: false}, - "disk_size": &hcldec.AttrSpec{Name: "disk_size", Type: cty.String, Required: false}, - "cache_mode": &hcldec.AttrSpec{Name: "cache_mode", Type: cty.String, Required: false}, - "format": &hcldec.AttrSpec{Name: "format", Type: cty.String, Required: false}, - "io_thread": &hcldec.AttrSpec{Name: "io_thread", Type: cty.Bool, Required: false}, - "asyncio": &hcldec.AttrSpec{Name: "asyncio", Type: cty.String, Required: false}, - "discard": &hcldec.AttrSpec{Name: "discard", Type: cty.Bool, Required: false}, - "ssd": &hcldec.AttrSpec{Name: "ssd", Type: cty.Bool, Required: false}, + "type": &hcldec.AttrSpec{Name: "type", Type: cty.String, Required: false}, + "storage_pool": &hcldec.AttrSpec{Name: "storage_pool", Type: cty.String, Required: false}, + "storage_pool_type": &hcldec.AttrSpec{Name: "storage_pool_type", Type: cty.String, Required: false}, + "disk_size": &hcldec.AttrSpec{Name: "disk_size", Type: cty.String, Required: false}, + "cache_mode": &hcldec.AttrSpec{Name: "cache_mode", Type: cty.String, Required: false}, + "format": &hcldec.AttrSpec{Name: "format", Type: cty.String, Required: false}, + "io_thread": &hcldec.AttrSpec{Name: "io_thread", Type: cty.Bool, Required: false}, + "asyncio": &hcldec.AttrSpec{Name: "asyncio", Type: cty.String, Required: false}, + "exclude_from_backup": &hcldec.AttrSpec{Name: "exclude_from_backup", Type: cty.Bool, Required: false}, + "discard": &hcldec.AttrSpec{Name: "discard", Type: cty.Bool, Required: false}, + "ssd": &hcldec.AttrSpec{Name: "ssd", Type: cty.Bool, Required: false}, } return s } diff --git a/builder/proxmox/common/step_start_vm.go b/builder/proxmox/common/step_start_vm.go index 3fc85708..8775a98c 100644 --- a/builder/proxmox/common/step_start_vm.go +++ b/builder/proxmox/common/step_start_vm.go @@ -299,6 +299,10 @@ func generateProxmoxDisks(disks []diskConfig, isos []ISOsConfig, cloneSourceDisk case "K": size = proxmox.QemuDiskSize(tmpSize) } + backup := true + if disks[idx].ExcludeFromBackup { + backup = false + } switch disks[idx].Type { case "ide": @@ -311,6 +315,7 @@ func generateProxmoxDisks(disks []diskConfig, isos []ISOsConfig, cloneSourceDisk Format: proxmox.QemuDiskFormat(disks[idx].DiskFormat), Discard: disks[idx].Discard, EmulateSSD: disks[idx].SSD, + Backup: backup, }, } for { @@ -371,6 +376,7 @@ func generateProxmoxDisks(disks []diskConfig, isos []ISOsConfig, cloneSourceDisk Discard: disks[idx].Discard, EmulateSSD: disks[idx].SSD, IOThread: disks[idx].IOThread, + Backup: backup, }, } for { @@ -400,6 +406,7 @@ func generateProxmoxDisks(disks []diskConfig, isos []ISOsConfig, cloneSourceDisk Format: proxmox.QemuDiskFormat(disks[idx].DiskFormat), Discard: disks[idx].Discard, EmulateSSD: disks[idx].SSD, + Backup: backup, }, } for { @@ -429,6 +436,7 @@ func generateProxmoxDisks(disks []diskConfig, isos []ISOsConfig, cloneSourceDisk Format: proxmox.QemuDiskFormat(disks[idx].DiskFormat), Discard: disks[idx].Discard, IOThread: disks[idx].IOThread, + Backup: backup, }, } for { diff --git a/builder/proxmox/common/step_start_vm_test.go b/builder/proxmox/common/step_start_vm_test.go index 08346218..2c3a2731 100644 --- a/builder/proxmox/common/step_start_vm_test.go +++ b/builder/proxmox/common/step_start_vm_test.go @@ -510,14 +510,15 @@ func TestGenerateProxmoxDisks(t *testing.T) { "plain config, no special option set", []diskConfig{ { - Type: "scsi", - StoragePool: "local-lvm", - Size: "10G", - CacheMode: "none", - DiskFormat: "qcow2", - IOThread: false, - Discard: false, - SSD: false, + Type: "scsi", + StoragePool: "local-lvm", + Size: "10G", + CacheMode: "none", + DiskFormat: "qcow2", + IOThread: false, + Discard: false, + SSD: false, + ExcludeFromBackup: false, }, }, []ISOsConfig{}, @@ -535,6 +536,7 @@ func TestGenerateProxmoxDisks(t *testing.T) { Discard: false, EmulateSSD: false, IOThread: false, + Backup: true, }, }, }, @@ -545,14 +547,15 @@ func TestGenerateProxmoxDisks(t *testing.T) { "scsi + iothread, iothread should be true", []diskConfig{ { - Type: "scsi", - StoragePool: "local-lvm", - Size: "10G", - CacheMode: "none", - DiskFormat: "qcow2", - IOThread: true, - Discard: false, - SSD: false, + Type: "scsi", + StoragePool: "local-lvm", + Size: "10G", + CacheMode: "none", + DiskFormat: "qcow2", + IOThread: true, + Discard: false, + SSD: false, + ExcludeFromBackup: false, }, }, []ISOsConfig{}, @@ -570,6 +573,7 @@ func TestGenerateProxmoxDisks(t *testing.T) { Discard: false, EmulateSSD: false, IOThread: true, + Backup: true, }, }, }, @@ -580,14 +584,15 @@ func TestGenerateProxmoxDisks(t *testing.T) { "virtio + iothread, iothread should be true", []diskConfig{ { - Type: "virtio", - StoragePool: "local-lvm", - Size: "10G", - CacheMode: "none", - DiskFormat: "qcow2", - IOThread: true, - Discard: false, - SSD: false, + Type: "virtio", + StoragePool: "local-lvm", + Size: "10G", + CacheMode: "none", + DiskFormat: "qcow2", + IOThread: true, + Discard: false, + SSD: false, + ExcludeFromBackup: false, }, }, []ISOsConfig{}, @@ -605,6 +610,7 @@ func TestGenerateProxmoxDisks(t *testing.T) { Format: proxmox.QemuDiskFormat("qcow2"), Discard: false, IOThread: true, + Backup: true, }, }, }, @@ -614,15 +620,16 @@ func TestGenerateProxmoxDisks(t *testing.T) { "asyncio is native", []diskConfig{ { - Type: "virtio", - StoragePool: "local-lvm", - Size: "10G", - CacheMode: "none", - DiskFormat: "qcow2", - AsyncIO: "native", - IOThread: true, - Discard: false, - SSD: false, + Type: "virtio", + StoragePool: "local-lvm", + Size: "10G", + CacheMode: "none", + DiskFormat: "qcow2", + AsyncIO: "native", + IOThread: true, + Discard: false, + SSD: false, + ExcludeFromBackup: false, }, }, []ISOsConfig{}, @@ -640,6 +647,42 @@ func TestGenerateProxmoxDisks(t *testing.T) { Format: proxmox.QemuDiskFormat("qcow2"), Discard: false, IOThread: true, + Backup: true, + }, + }, + }, + }, + }, + { + "exclude disk from backup", + []diskConfig{ + { + Type: "virtio", + StoragePool: "local-lvm", + Size: "10G", + CacheMode: "none", + DiskFormat: "qcow2", + IOThread: true, + Discard: false, + SSD: false, + ExcludeFromBackup: true, + }, + }, + []ISOsConfig{}, + &proxmox.QemuStorages{ + Ide: &proxmox.QemuIdeDisks{}, + Sata: &proxmox.QemuSataDisks{}, + Scsi: &proxmox.QemuScsiDisks{}, + VirtIO: &proxmox.QemuVirtIODisks{ + Disk_0: &proxmox.QemuVirtIOStorage{ + Disk: &proxmox.QemuVirtIODisk{ + SizeInKibibytes: 10485760, + Storage: "local-lvm", + Cache: proxmox.QemuDiskCache("none"), + Format: proxmox.QemuDiskFormat("qcow2"), + Discard: false, + IOThread: true, + Backup: false, }, }, }, @@ -723,6 +766,7 @@ func TestGenerateProxmoxDisks(t *testing.T) { Cache: proxmox.QemuDiskCache("none"), Format: proxmox.QemuDiskFormat("qcow2"), Discard: false, + Backup: true, }, }, Disk_1: &proxmox.QemuIdeStorage{ @@ -732,6 +776,7 @@ func TestGenerateProxmoxDisks(t *testing.T) { Cache: proxmox.QemuDiskCache("none"), Format: proxmox.QemuDiskFormat("qcow2"), Discard: false, + Backup: true, }, }, }, @@ -743,6 +788,7 @@ func TestGenerateProxmoxDisks(t *testing.T) { Cache: proxmox.QemuDiskCache("none"), Format: proxmox.QemuDiskFormat("qcow2"), Discard: false, + Backup: true, }, }, Disk_1: &proxmox.QemuSataStorage{ @@ -752,6 +798,7 @@ func TestGenerateProxmoxDisks(t *testing.T) { Cache: proxmox.QemuDiskCache("none"), Format: proxmox.QemuDiskFormat("qcow2"), Discard: false, + Backup: true, }, }, }, @@ -764,6 +811,7 @@ func TestGenerateProxmoxDisks(t *testing.T) { Format: proxmox.QemuDiskFormat("qcow2"), Discard: false, IOThread: true, + Backup: true, }, }, Disk_1: &proxmox.QemuScsiStorage{ @@ -774,6 +822,7 @@ func TestGenerateProxmoxDisks(t *testing.T) { Format: proxmox.QemuDiskFormat("qcow2"), Discard: false, IOThread: true, + Backup: true, }, }, }, @@ -786,6 +835,7 @@ func TestGenerateProxmoxDisks(t *testing.T) { Format: proxmox.QemuDiskFormat("qcow2"), Discard: false, IOThread: true, + Backup: true, }, }, Disk_1: &proxmox.QemuVirtIOStorage{ @@ -796,6 +846,7 @@ func TestGenerateProxmoxDisks(t *testing.T) { Format: proxmox.QemuDiskFormat("qcow2"), Discard: false, IOThread: true, + Backup: true, }, }, }, @@ -868,6 +919,7 @@ func TestGenerateProxmoxDisks(t *testing.T) { Cache: proxmox.QemuDiskCache("none"), Format: proxmox.QemuDiskFormat("qcow2"), Discard: false, + Backup: true, }, }, Disk_1: &proxmox.QemuIdeStorage{ @@ -877,6 +929,7 @@ func TestGenerateProxmoxDisks(t *testing.T) { Cache: proxmox.QemuDiskCache("none"), Format: proxmox.QemuDiskFormat("qcow2"), Discard: false, + Backup: true, }, }, Disk_2: &proxmox.QemuIdeStorage{ @@ -886,6 +939,7 @@ func TestGenerateProxmoxDisks(t *testing.T) { Cache: proxmox.QemuDiskCache("none"), Format: proxmox.QemuDiskFormat("qcow2"), Discard: false, + Backup: true, }, }, }, @@ -897,6 +951,7 @@ func TestGenerateProxmoxDisks(t *testing.T) { Cache: proxmox.QemuDiskCache("none"), Format: proxmox.QemuDiskFormat("qcow2"), Discard: false, + Backup: true, }, }, Disk_1: &proxmox.QemuSataStorage{ @@ -906,6 +961,7 @@ func TestGenerateProxmoxDisks(t *testing.T) { Cache: proxmox.QemuDiskCache("none"), Format: proxmox.QemuDiskFormat("qcow2"), Discard: false, + Backup: true, }, }, Disk_2: &proxmox.QemuSataStorage{ @@ -926,6 +982,7 @@ func TestGenerateProxmoxDisks(t *testing.T) { Format: proxmox.QemuDiskFormat("qcow2"), Discard: false, IOThread: true, + Backup: true, }, }, }, diff --git a/docs-partials/builder/proxmox/common/diskConfig-not-required.mdx b/docs-partials/builder/proxmox/common/diskConfig-not-required.mdx index bbd36df3..7e880550 100644 --- a/docs-partials/builder/proxmox/common/diskConfig-not-required.mdx +++ b/docs-partials/builder/proxmox/common/diskConfig-not-required.mdx @@ -28,6 +28,9 @@ - `asyncio` (string) - Configure Asynchronous I/O. Can be `native`, `threads`, or `io_uring`. Defaults to io_uring. +- `exclude_from_backup` (bool) - Exclude disk from Proxmox backup jobs + Defaults to false. + - `discard` (bool) - Relay TRIM commands to the underlying storage. Defaults to false. See the [Proxmox documentation](https://pve.proxmox.com/pve-docs/pve-admin-guide.html#qm_hard_disk_discard)