0
0
mirror of https://github.com/bpg/terraform-provider-proxmox.git synced 2025-06-30 02:31:10 +00:00

feat(vm): deprecate enabled attribute on cdrom/disk devices (#1746)

* feat(vm): deprecate `enabled` attribute on `cdrom`/`disk` devices

Signed-off-by: Pavel Boldyrev <627562+bpg@users.noreply.github.com>

* docs(vm): update CDROM configuration terminology and deprecation note

Improve documentation for virtual machine CD-ROM configuration by:
- Correcting capitalization of "CD-ROM"
- Clarifying deprecation note for `enabled` attribute

Signed-off-by: Pavel Boldyrev <627562+bpg@users.noreply.github.com>

---------

Signed-off-by: Pavel Boldyrev <627562+bpg@users.noreply.github.com>
This commit is contained in:
Pavel Boldyrev 2025-02-07 22:50:57 -05:00 committed by GitHub
parent bf9c496f29
commit 5f003143f8
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
8 changed files with 58 additions and 91 deletions

View File

@ -142,12 +142,13 @@ output "ubuntu_vm_public_key" {
- `seabios` - SeaBIOS. - `seabios` - SeaBIOS.
- `boot_order` - (Optional) Specify a list of devices to boot from in the order - `boot_order` - (Optional) Specify a list of devices to boot from in the order
they appear in the list (defaults to `[]`). they appear in the list (defaults to `[]`).
- `cdrom` - (Optional) The CDROM configuration. - `cdrom` - (Optional) The CD-ROM configuration.
- `enabled` - (Optional) Whether to enable the CDROM drive (defaults - `enabled` - (Optional) Whether to enable the CD-ROM drive (defaults
to `false`). to `false`). *Deprecated*. The attribute will be removed in the next version of the provider.
Set `file_id` to `none` to leave the CD-ROM drive empty.
- `file_id` - (Optional) A file ID for an ISO file (defaults to `cdrom` as - `file_id` - (Optional) A file ID for an ISO file (defaults to `cdrom` as
in the physical drive). Use `none` to leave the CDROM drive empty. in the physical drive). Use `none` to leave the CD-ROM drive empty.
- `interface` - (Optional) A hardware interface to connect CDROM drive to, - `interface` - (Optional) A hardware interface to connect CD-ROM drive to,
must be `ideN` (defaults to `ide3`). Note that `q35` machine type only must be `ideN` (defaults to `ide3`). Note that `q35` machine type only
supports `ide0` and `ide2`. supports `ide0` and `ide2`.
- `clone` - (Optional) The cloning configuration. - `clone` - (Optional) The cloning configuration.

View File

@ -90,7 +90,6 @@ resource "proxmox_virtual_environment_vm" "example_template" {
name = "terraform-provider-proxmox-example-template" name = "terraform-provider-proxmox-example-template"
cdrom { cdrom {
enabled = true
file_id = "none" file_id = "none"
} }

View File

@ -23,36 +23,15 @@ func TestAccResourceVMCDROM(t *testing.T) {
name string name string
steps []resource.TestStep steps []resource.TestStep
}{ }{
{"default no cdrom", []resource.TestStep{ {"default no cdrom", []resource.TestStep{{
{ Config: te.RenderConfig(`
Config: te.RenderConfig(`
resource "proxmox_virtual_environment_vm" "test_cdrom" { resource "proxmox_virtual_environment_vm" "test_cdrom" {
node_name = "{{.NodeName}}" node_name = "{{.NodeName}}"
started = false started = false
name = "test-cdrom" name = "test-cdrom"
}`), }`),
Check: NoResourceAttributesSet("proxmox_virtual_environment_vm.test_cdrom", []string{"cdrom.#"}), Check: NoResourceAttributesSet("proxmox_virtual_environment_vm.test_cdrom", []string{"cdrom.#"}),
}, }}},
}},
{"default cdrom", []resource.TestStep{
{
Config: te.RenderConfig(`
resource "proxmox_virtual_environment_vm" "test_cdrom" {
node_name = "{{.NodeName}}"
started = false
name = "test-cdrom"
cdrom {
enabled = true
}
}`),
Check: ResourceAttributes("proxmox_virtual_environment_vm.test_cdrom", map[string]string{
"cdrom.0.enabled": "true",
}),
},
{
RefreshState: true,
},
}},
{"none cdrom", []resource.TestStep{ {"none cdrom", []resource.TestStep{
{ {
Config: te.RenderConfig(` Config: te.RenderConfig(`
@ -61,12 +40,10 @@ func TestAccResourceVMCDROM(t *testing.T) {
started = false started = false
name = "test-cdrom" name = "test-cdrom"
cdrom { cdrom {
enabled = true
file_id = "none" file_id = "none"
} }
}`), }`),
Check: ResourceAttributes("proxmox_virtual_environment_vm.test_cdrom", map[string]string{ Check: ResourceAttributes("proxmox_virtual_environment_vm.test_cdrom", map[string]string{
"cdrom.0.enabled": "true",
"cdrom.0.file_id": "none", "cdrom.0.file_id": "none",
}), }),
}, },
@ -74,6 +51,36 @@ func TestAccResourceVMCDROM(t *testing.T) {
RefreshState: true, RefreshState: true,
}, },
}}, }},
{"enable cdrom", []resource.TestStep{
{
Config: te.RenderConfig(`
resource "proxmox_virtual_environment_vm" "test_cdrom" {
node_name = "{{.NodeName}}"
started = false
name = "test-cdrom"
cdrom {
file_id = "none"
}
}`),
Check: ResourceAttributes("proxmox_virtual_environment_vm.test_cdrom", map[string]string{
"cdrom.0.file_id": "none",
}),
},
{
Config: te.RenderConfig(`
resource "proxmox_virtual_environment_vm" "test_cdrom" {
node_name = "{{.NodeName}}"
started = false
name = "test-cdrom"
cdrom {
file_id = "cdrom"
}
}`),
Check: ResourceAttributes("proxmox_virtual_environment_vm.test_cdrom", map[string]string{
"cdrom.0.file_id": "cdrom",
}),
},
}},
} }
for _, tt := range tests { for _, tt := range tests {

View File

@ -45,7 +45,6 @@ type CustomStorageDevice struct {
Size *types.DiskSize `json:"size,omitempty" url:"size,omitempty"` Size *types.DiskSize `json:"size,omitempty" url:"size,omitempty"`
SSD *types.CustomBool `json:"ssd,omitempty" url:"ssd,omitempty,int"` SSD *types.CustomBool `json:"ssd,omitempty" url:"ssd,omitempty,int"`
DatastoreID *string `json:"-" url:"-"` DatastoreID *string `json:"-" url:"-"`
Enabled bool `json:"-" url:"-"`
FileID *string `json:"-" url:"-"` FileID *string `json:"-" url:"-"`
} }
@ -358,8 +357,6 @@ func (d *CustomStorageDevice) UnmarshalJSON(b []byte) error {
} }
} }
d.Enabled = true
return nil return nil
} }
@ -379,7 +376,8 @@ func (d CustomStorageDevices) Filter(fn func(*CustomStorageDevice) bool) CustomS
// EncodeValues converts a CustomStorageDevices array to multiple URL values. // EncodeValues converts a CustomStorageDevices array to multiple URL values.
func (d CustomStorageDevices) EncodeValues(_ string, v *url.Values) error { func (d CustomStorageDevices) EncodeValues(_ string, v *url.Values) error {
for s, d := range d { for s, d := range d {
if d.Enabled { // Explicitly skip disks which have FileID set, so it won't be encoded in "Create" or "Update" operations.
if d.FileID == nil || *d.FileID == "" {
if err := d.EncodeValues(s, v); err != nil { if err := d.EncodeValues(s, v); err != nil {
return fmt.Errorf("error encoding storage device %s: %w", s, err) return fmt.Errorf("error encoding storage device %s: %w", s, err)
} }

View File

@ -32,7 +32,6 @@ func TestCustomStorageDevice_UnmarshalJSON(t *testing.T) {
want: &CustomStorageDevice{ want: &CustomStorageDevice{
Cache: ptr.Ptr("writeback"), Cache: ptr.Ptr("writeback"),
Discard: ptr.Ptr("on"), Discard: ptr.Ptr("on"),
Enabled: true,
FileVolume: "local-lvm:vm-2041-disk-0", FileVolume: "local-lvm:vm-2041-disk-0",
IOThread: types.CustomBool(true).Pointer(), IOThread: types.CustomBool(true).Pointer(),
Size: ds8gig, Size: ds8gig,
@ -44,7 +43,6 @@ func TestCustomStorageDevice_UnmarshalJSON(t *testing.T) {
line: `"nfs:2041/vm-2041-disk-0.raw,discard=ignore,ssd=1,iothread=1,size=8G"`, line: `"nfs:2041/vm-2041-disk-0.raw,discard=ignore,ssd=1,iothread=1,size=8G"`,
want: &CustomStorageDevice{ want: &CustomStorageDevice{
Discard: ptr.Ptr("ignore"), Discard: ptr.Ptr("ignore"),
Enabled: true,
FileVolume: "nfs:2041/vm-2041-disk-0.raw", FileVolume: "nfs:2041/vm-2041-disk-0.raw",
Format: ptr.Ptr("raw"), Format: ptr.Ptr("raw"),
IOThread: types.CustomBool(true).Pointer(), IOThread: types.CustomBool(true).Pointer(),

View File

@ -106,8 +106,6 @@ type CreateRequestBody struct {
// AddCustomStorageDevice adds a custom storage device to the create request body. // AddCustomStorageDevice adds a custom storage device to the create request body.
func (b *CreateRequestBody) AddCustomStorageDevice(iface string, device CustomStorageDevice) { func (b *CreateRequestBody) AddCustomStorageDevice(iface string, device CustomStorageDevice) {
device.Enabled = true
if b.CustomStorageDevices == nil { if b.CustomStorageDevices == nil {
b.CustomStorageDevices = make(CustomStorageDevices, 1) b.CustomStorageDevices = make(CustomStorageDevices, 1)
} }

View File

@ -162,9 +162,7 @@ func GetDiskDeviceObjects(
diskDeviceObjects := vms.CustomStorageDevices{} diskDeviceObjects := vms.CustomStorageDevices{}
for _, diskEntry := range diskDevices { for _, diskEntry := range diskDevices {
diskDevice := &vms.CustomStorageDevice{ diskDevice := &vms.CustomStorageDevice{}
Enabled: true,
}
block := diskEntry.(map[string]interface{}) block := diskEntry.(map[string]interface{})
datastoreID, _ := block[mkDiskDatastoreID].(string) datastoreID, _ := block[mkDiskDatastoreID].(string)
@ -202,11 +200,6 @@ func GetDiskDeviceObjects(
fileFormat = dvDiskFileFormat fileFormat = dvDiskFileFormat
} }
// Explicitly disable the disk, so it won't be encoded in "Create" or "Update" operations.
if fileID != "" {
diskDevice.Enabled = false
}
if pathInDatastore != "" { if pathInDatastore != "" {
if datastoreID != "" { if datastoreID != "" {
diskDevice.FileVolume = fmt.Sprintf("%s:%s", datastoreID, pathInDatastore) diskDevice.FileVolume = fmt.Sprintf("%s:%s", datastoreID, pathInDatastore)

View File

@ -419,7 +419,6 @@ func VM() *schema.Resource {
DefaultFunc: func() (interface{}, error) { DefaultFunc: func() (interface{}, error) {
return []interface{}{ return []interface{}{
map[string]interface{}{ map[string]interface{}{
mkCDROMEnabled: dvCDROMEnabled,
mkCDROMFileID: dvCDROMFileID, mkCDROMFileID: dvCDROMFileID,
mkCDROMInterface: dvCDROMInterface, mkCDROMInterface: dvCDROMInterface,
}, },
@ -432,6 +431,8 @@ func VM() *schema.Resource {
Description: "Whether to enable the CDROM drive", Description: "Whether to enable the CDROM drive",
Optional: true, Optional: true,
Default: dvCDROMEnabled, Default: dvCDROMEnabled,
Deprecated: "Remove this attribute's configuration as it is no longer used and the attribute will " +
"be removed in the next version of the provider. Set `file_id` to `none` to leave the CDROM drive empty.",
}, },
mkCDROMFileID: { mkCDROMFileID: {
Type: schema.TypeString, Type: schema.TypeString,
@ -1908,7 +1909,6 @@ func vmCreateClone(ctx context.Context, d *schema.ResourceData, m interface{}) d
if len(cdrom) > 0 && cdrom[0] != nil { if len(cdrom) > 0 && cdrom[0] != nil {
cdromBlock := cdrom[0].(map[string]interface{}) cdromBlock := cdrom[0].(map[string]interface{})
cdromEnabled := cdromBlock[mkCDROMEnabled].(bool)
cdromFileID := cdromBlock[mkCDROMFileID].(string) cdromFileID := cdromBlock[mkCDROMFileID].(string)
cdromInterface := cdromBlock[mkCDROMInterface].(string) cdromInterface := cdromBlock[mkCDROMInterface].(string)
@ -1919,7 +1919,6 @@ func vmCreateClone(ctx context.Context, d *schema.ResourceData, m interface{}) d
cdromMedia := "cdrom" cdromMedia := "cdrom"
ideDevices[cdromInterface] = &vms.CustomStorageDevice{ ideDevices[cdromInterface] = &vms.CustomStorageDevice{
Enabled: cdromEnabled,
FileVolume: cdromFileID, FileVolume: cdromFileID,
Media: &cdromMedia, Media: &cdromMedia,
} }
@ -1990,12 +1989,9 @@ func vmCreateClone(ctx context.Context, d *schema.ResourceData, m interface{}) d
tflog.Trace(ctx, fmt.Sprintf("CloudInit IDE interface is '%s'", initializationInterface)) tflog.Trace(ctx, fmt.Sprintf("CloudInit IDE interface is '%s'", initializationInterface))
const cdromCloudInitEnabled = true
cdromCloudInitFileID := fmt.Sprintf("%s:cloudinit", initializationDatastoreID) cdromCloudInitFileID := fmt.Sprintf("%s:cloudinit", initializationDatastoreID)
cdromCloudInitMedia := "cdrom" cdromCloudInitMedia := "cdrom"
ideDevices[initializationInterface] = &vms.CustomStorageDevice{ ideDevices[initializationInterface] = &vms.CustomStorageDevice{
Enabled: cdromCloudInitEnabled,
FileVolume: cdromCloudInitFileID, FileVolume: cdromCloudInitFileID,
Media: &cdromCloudInitMedia, Media: &cdromCloudInitMedia,
} }
@ -2349,29 +2345,23 @@ func vmCreateCustom(ctx context.Context, d *schema.ResourceData, m interface{})
bios := d.Get(mkBIOS).(string) bios := d.Get(mkBIOS).(string)
cdromBlock, err := structure.GetSchemaBlock( cdromFileID := ""
resource, cdromInterface := ""
d,
[]string{mkCDROM}, cdrom := d.Get(mkCDROM).([]interface{})
0, if len(cdrom) > 0 {
true, cdromBlock := cdrom[0].(map[string]interface{})
) cdromFileID = cdromBlock[mkCDROMFileID].(string)
if err != nil { cdromInterface = cdromBlock[mkCDROMInterface].(string)
return diag.FromErr(err)
if cdromFileID == "" {
cdromFileID = "cdrom"
}
} }
cdromEnabled := cdromBlock[mkCDROMEnabled].(bool)
cdromFileID := cdromBlock[mkCDROMFileID].(string)
cdromInterface := cdromBlock[mkCDROMInterface].(string)
cdromCloudInitEnabled := false
cdromCloudInitFileID := "" cdromCloudInitFileID := ""
cdromCloudInitInterface := "" cdromCloudInitInterface := ""
if cdromFileID == "" {
cdromFileID = "cdrom"
}
cpuBlock, err := structure.GetSchemaBlock( cpuBlock, err := structure.GetSchemaBlock(
resource, resource,
d, d,
@ -2447,7 +2437,6 @@ func vmCreateCustom(ctx context.Context, d *schema.ResourceData, m interface{})
initializationBlock := initialization[0].(map[string]interface{}) initializationBlock := initialization[0].(map[string]interface{})
initializationDatastoreID := initializationBlock[mkInitializationDatastoreID].(string) initializationDatastoreID := initializationBlock[mkInitializationDatastoreID].(string)
cdromCloudInitEnabled = true
cdromCloudInitFileID = fmt.Sprintf("%s:cloudinit", initializationDatastoreID) cdromCloudInitFileID = fmt.Sprintf("%s:cloudinit", initializationDatastoreID)
cdromCloudInitInterface = initializationBlock[mkInitializationInterface].(string) cdromCloudInitInterface = initializationBlock[mkInitializationInterface].(string)
@ -2543,7 +2532,7 @@ func vmCreateCustom(ctx context.Context, d *schema.ResourceData, m interface{})
} }
var bootOrderConverted []string var bootOrderConverted []string
if cdromEnabled { if cdromInterface != "" {
bootOrderConverted = []string{cdromInterface} bootOrderConverted = []string{cdromInterface}
} }
@ -2585,7 +2574,6 @@ func vmCreateCustom(ctx context.Context, d *schema.ResourceData, m interface{})
if cdromCloudInitInterface != "" { if cdromCloudInitInterface != "" {
diskDeviceObjects[cdromCloudInitInterface] = &vms.CustomStorageDevice{ diskDeviceObjects[cdromCloudInitInterface] = &vms.CustomStorageDevice{
Enabled: cdromCloudInitEnabled,
FileVolume: cdromCloudInitFileID, FileVolume: cdromCloudInitFileID,
Media: &ideDevice2Media, Media: &ideDevice2Media,
} }
@ -2593,7 +2581,6 @@ func vmCreateCustom(ctx context.Context, d *schema.ResourceData, m interface{})
if cdromInterface != "" { if cdromInterface != "" {
diskDeviceObjects[cdromInterface] = &vms.CustomStorageDevice{ diskDeviceObjects[cdromInterface] = &vms.CustomStorageDevice{
Enabled: cdromEnabled,
FileVolume: cdromFileID, FileVolume: cdromFileID,
Media: &ideDevice2Media, Media: &ideDevice2Media,
} }
@ -3000,7 +2987,6 @@ func vmGetEfiDiskAsStorageDevice(d *schema.ResourceData, disk []interface{}) (*v
id := "0" id := "0"
storageDevice = &vms.CustomStorageDevice{ storageDevice = &vms.CustomStorageDevice{
Enabled: true,
FileVolume: efiDisk.FileVolume, FileVolume: efiDisk.FileVolume,
Format: efiDisk.Format, Format: efiDisk.Format,
DatastoreID: &id, DatastoreID: &id,
@ -3054,7 +3040,6 @@ func vmGetTPMStateAsStorageDevice(d *schema.ResourceData, disk []interface{}) *v
if tpmState != nil { if tpmState != nil {
id := "0" id := "0"
storageDevice = &vms.CustomStorageDevice{ storageDevice = &vms.CustomStorageDevice{
Enabled: true,
FileVolume: tpmState.FileVolume, FileVolume: tpmState.FileVolume,
DatastoreID: &id, DatastoreID: &id,
} }
@ -3541,7 +3526,6 @@ func vmReadCustom(
cdromBlock := map[string]interface{}{} cdromBlock := map[string]interface{}{}
if len(clone) == 0 || len(currentCDROM) > 0 { if len(clone) == 0 || len(currentCDROM) > 0 {
cdromBlock[mkCDROMEnabled] = cdromIDEDevice.Enabled
cdromBlock[mkCDROMFileID] = cdromIDEDevice.FileVolume cdromBlock[mkCDROMFileID] = cdromIDEDevice.FileVolume
cdromBlock[mkCDROMInterface] = currentInterface cdromBlock[mkCDROMInterface] = currentInterface
@ -3551,10 +3535,6 @@ func vmReadCustom(
if currentBlock[mkCDROMFileID] == "" { if currentBlock[mkCDROMFileID] == "" {
cdromBlock[mkCDROMFileID] = "" cdromBlock[mkCDROMFileID] = ""
} }
if currentBlock[mkCDROMEnabled] == false {
cdromBlock[mkCDROMEnabled] = false
}
} }
cdrom[0] = cdromBlock cdrom[0] = cdromBlock
@ -4923,7 +4903,6 @@ func vmUpdate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.D
return diag.FromErr(err) return diag.FromErr(err)
} }
cdromEnabled := cdromBlock[mkCDROMEnabled].(bool)
cdromFileID := cdromBlock[mkCDROMFileID].(string) cdromFileID := cdromBlock[mkCDROMFileID].(string)
cdromInterface := cdromBlock[mkCDROMInterface].(string) cdromInterface := cdromBlock[mkCDROMInterface].(string)
@ -4944,10 +4923,6 @@ func vmUpdate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.D
} }
} }
if !cdromEnabled && cdromFileID == "" {
del = append(del, cdromInterface)
}
if cdromFileID == "" { if cdromFileID == "" {
cdromFileID = "cdrom" cdromFileID = "cdrom"
} }
@ -4955,7 +4930,6 @@ func vmUpdate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.D
cdromMedia := "cdrom" cdromMedia := "cdrom"
updateBody.AddCustomStorageDevice(cdromInterface, vms.CustomStorageDevice{ updateBody.AddCustomStorageDevice(cdromInterface, vms.CustomStorageDevice{
Enabled: cdromEnabled,
FileVolume: cdromFileID, FileVolume: cdromFileID,
Media: &cdromMedia, Media: &cdromMedia,
}) })
@ -5124,7 +5098,6 @@ func vmUpdate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.D
} }
updateBody.AddCustomStorageDevice(initializationInterface, vms.CustomStorageDevice{ updateBody.AddCustomStorageDevice(initializationInterface, vms.CustomStorageDevice{
Enabled: true,
FileVolume: fileVolume, FileVolume: fileVolume,
Media: &cdromMedia, Media: &cdromMedia,
}) })