mirror of
https://github.com/bpg/terraform-provider-proxmox.git
synced 2025-06-29 18:21:10 +00:00
fix(vm): vga
block defaults handling during create / clone (#1732)
* fix(vm): fix `vga` block defaults handling during create / clone Signed-off-by: Pavel Boldyrev <627562+bpg@users.noreply.github.com> * fix: formatting Signed-off-by: Pavel Boldyrev <627562+bpg@users.noreply.github.com> * fix: acc test failure due to skip 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:
parent
4d89d3484b
commit
c992dfc1f3
5
.gitignore
vendored
5
.gitignore
vendored
@ -46,5 +46,6 @@ id_rsa.pub
|
||||
# Binary
|
||||
terraform-provider-proxmox*
|
||||
|
||||
# .vscode
|
||||
.vscode/settings.json
|
||||
# VScode / Cursor
|
||||
.vscode/settings.json
|
||||
.cursorrules
|
||||
|
11
.vscode/launch.json
vendored
11
.vscode/launch.json
vendored
@ -1,12 +1,21 @@
|
||||
{
|
||||
"version": "0.2.0",
|
||||
"configurations": [
|
||||
{
|
||||
"name": "Run Acceptance Tests",
|
||||
"type": "go",
|
||||
"request": "launch",
|
||||
"mode": "test",
|
||||
"program": "${workspaceFolder}/fwprovider/test",
|
||||
"envFile": "${workspaceFolder}/testacc.env",
|
||||
"args": ["-test.v", "-test.timeout", "120s"]
|
||||
},
|
||||
{
|
||||
"name": "Debug Acceptance Tests",
|
||||
"type": "go",
|
||||
"request": "launch",
|
||||
"mode": "test",
|
||||
"program": "${workspaceFolder}/fwprovider/tests",
|
||||
"program": "${workspaceFolder}/fwprovider/test",
|
||||
"envFile": "${workspaceFolder}/testacc.env",
|
||||
"args": ["-debug", "-test.v", "-test.timeout", "120s"]
|
||||
|
||||
|
8
.vscode/settings.example.json
vendored
8
.vscode/settings.example.json
vendored
@ -127,6 +127,14 @@
|
||||
]
|
||||
}
|
||||
],
|
||||
"psi-header.lang-config": [
|
||||
{
|
||||
"language": "go",
|
||||
"ignoreLines": [
|
||||
"//go:build"
|
||||
]
|
||||
}
|
||||
],
|
||||
"makefile.configureOnOpen": false,
|
||||
"go.buildFlags": ["-tags=all"],
|
||||
"gopls": { "build.buildFlags": ["-tags=all"] }
|
||||
|
@ -311,7 +311,7 @@ func TestAccResourceStandardRepoValidInput(t *testing.T) {
|
||||
// PUT /api2/json/nodes/{node}/apt/repositories with handle = "no-subscription" will create a new
|
||||
// entry in /etc/apt/sources.list on each call :/
|
||||
SkipFunc: func() (bool, error) {
|
||||
return true, fmt.Errorf("skipped due to API limitation: PUT request creates new entry on each call")
|
||||
return true, nil
|
||||
},
|
||||
Config: te.RenderConfig(`
|
||||
resource "proxmox_virtual_environment_apt_standard_repository" "test" {
|
||||
@ -337,8 +337,10 @@ func TestAccResourceStandardRepoValidInput(t *testing.T) {
|
||||
|
||||
// Test the "ImportState" implementation.
|
||||
{
|
||||
// PUT /api2/json/nodes/{node}/apt/repositories with handle = "no-subscription" will create a new
|
||||
// entry in /etc/apt/sources.list on each call :/
|
||||
SkipFunc: func() (bool, error) {
|
||||
return true, fmt.Errorf("skipped due to API limitation: PUT request creates new entry on each call")
|
||||
return true, nil
|
||||
},
|
||||
ImportState: true,
|
||||
ImportStateId: fmt.Sprintf("%s,no-subscription", strings.ToLower(te.NodeName)),
|
||||
|
@ -9,7 +9,6 @@
|
||||
package test
|
||||
|
||||
import (
|
||||
"math/rand"
|
||||
"regexp"
|
||||
"testing"
|
||||
|
||||
@ -73,18 +72,16 @@ func TestAccResourceVM(t *testing.T) {
|
||||
}),
|
||||
),
|
||||
}}},
|
||||
{
|
||||
"empty node_name", []resource.TestStep{{
|
||||
Config: te.RenderConfig(`
|
||||
{"empty node_name", []resource.TestStep{{
|
||||
Config: te.RenderConfig(`
|
||||
resource "proxmox_virtual_environment_vm" "test_empty_node_name" {
|
||||
node_name = ""
|
||||
started = false
|
||||
}`),
|
||||
ExpectError: regexp.MustCompile(`expected "node_name" to not be an empty string, got `),
|
||||
}},
|
||||
},
|
||||
{
|
||||
"protection", []resource.TestStep{{
|
||||
ExpectError: regexp.MustCompile(`expected "node_name" to not be an empty string, got `),
|
||||
}}},
|
||||
{"protection", []resource.TestStep{
|
||||
{
|
||||
Config: te.RenderConfig(`
|
||||
resource "proxmox_virtual_environment_vm" "test_vm4" {
|
||||
node_name = "{{.NodeName}}"
|
||||
@ -110,10 +107,10 @@ func TestAccResourceVM(t *testing.T) {
|
||||
"protection": "false",
|
||||
}),
|
||||
),
|
||||
}},
|
||||
},
|
||||
{
|
||||
"update cpu block", []resource.TestStep{{
|
||||
},
|
||||
}},
|
||||
{"update cpu block", []resource.TestStep{
|
||||
{
|
||||
Config: te.RenderConfig(`
|
||||
resource "proxmox_virtual_environment_vm" "test_vm5" {
|
||||
node_name = "{{.NodeName}}"
|
||||
@ -143,10 +140,10 @@ func TestAccResourceVM(t *testing.T) {
|
||||
"cpu.0.sockets": "1",
|
||||
}),
|
||||
),
|
||||
}},
|
||||
},
|
||||
{
|
||||
"set cpu.architecture as non root is not supported", []resource.TestStep{{
|
||||
},
|
||||
}},
|
||||
{"set cpu.architecture as non root is not supported", []resource.TestStep{
|
||||
{
|
||||
Config: te.RenderConfig(`
|
||||
resource "proxmox_virtual_environment_vm" "test_cpu_arch" {
|
||||
node_name = "{{.NodeName}}"
|
||||
@ -157,8 +154,8 @@ func TestAccResourceVM(t *testing.T) {
|
||||
}`, WithAPIToken()),
|
||||
ExpectError: regexp.MustCompile(`can only be set by the root account`),
|
||||
},
|
||||
{
|
||||
Config: te.RenderConfig(`
|
||||
{
|
||||
Config: te.RenderConfig(`
|
||||
resource "proxmox_virtual_environment_vm" "template" {
|
||||
node_name = "{{.NodeName}}"
|
||||
started = false
|
||||
@ -166,11 +163,11 @@ func TestAccResourceVM(t *testing.T) {
|
||||
architecture = "x86_64"
|
||||
}
|
||||
}`, WithRootUser()),
|
||||
Destroy: false,
|
||||
}},
|
||||
},
|
||||
{
|
||||
"update memory block", []resource.TestStep{{
|
||||
Destroy: false,
|
||||
},
|
||||
}},
|
||||
{"update memory block", []resource.TestStep{
|
||||
{
|
||||
Config: te.RenderConfig(`
|
||||
resource "proxmox_virtual_environment_vm" "test_vm6" {
|
||||
node_name = "{{.NodeName}}"
|
||||
@ -200,10 +197,39 @@ func TestAccResourceVM(t *testing.T) {
|
||||
"memory.0.dedicated": "1024",
|
||||
}),
|
||||
),
|
||||
}},
|
||||
},
|
||||
{
|
||||
"update vga block", []resource.TestStep{{
|
||||
},
|
||||
}},
|
||||
{"create vga block", []resource.TestStep{
|
||||
{
|
||||
Config: te.RenderConfig(`
|
||||
resource "proxmox_virtual_environment_vm" "test_vm" {
|
||||
node_name = "{{.NodeName}}"
|
||||
started = false
|
||||
}`),
|
||||
Check: resource.ComposeTestCheckFunc(
|
||||
ResourceAttributes("proxmox_virtual_environment_vm.test_vm", map[string]string{
|
||||
"vga.#": "0",
|
||||
}),
|
||||
),
|
||||
}, {
|
||||
Config: te.RenderConfig(`
|
||||
resource "proxmox_virtual_environment_vm" "test_vm" {
|
||||
node_name = "{{.NodeName}}"
|
||||
started = false
|
||||
vga {
|
||||
type = "virtio-gl"
|
||||
clipboard = "vnc"
|
||||
}
|
||||
}`),
|
||||
Check: resource.ComposeTestCheckFunc(
|
||||
ResourceAttributes("proxmox_virtual_environment_vm.test_vm", map[string]string{
|
||||
"vga.#": "1",
|
||||
}),
|
||||
),
|
||||
},
|
||||
}},
|
||||
{"update vga block", []resource.TestStep{
|
||||
{
|
||||
Config: te.RenderConfig(`
|
||||
resource "proxmox_virtual_environment_vm" "test_vm" {
|
||||
node_name = "{{.NodeName}}"
|
||||
@ -253,10 +279,10 @@ func TestAccResourceVM(t *testing.T) {
|
||||
"vga.0.clipboard": "",
|
||||
}),
|
||||
),
|
||||
}},
|
||||
},
|
||||
{
|
||||
"update watchdog block", []resource.TestStep{{
|
||||
},
|
||||
}},
|
||||
{"update watchdog block", []resource.TestStep{
|
||||
{
|
||||
Config: te.RenderConfig(`
|
||||
resource "proxmox_virtual_environment_vm" "test_vm" {
|
||||
node_name = "{{.NodeName}}"
|
||||
@ -309,8 +335,8 @@ func TestAccResourceVM(t *testing.T) {
|
||||
"watchdog.0.action": "reset",
|
||||
}),
|
||||
),
|
||||
}},
|
||||
},
|
||||
},
|
||||
}},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
@ -498,8 +524,9 @@ func TestAccResourceVMNetwork(t *testing.T) {
|
||||
}),
|
||||
),
|
||||
}}},
|
||||
{"network device disconnected", []resource.TestStep{{
|
||||
Config: te.RenderConfig(`
|
||||
{"network device disconnected", []resource.TestStep{
|
||||
{
|
||||
Config: te.RenderConfig(`
|
||||
resource "proxmox_virtual_environment_vm" "test_vm_network2" {
|
||||
node_name = "{{.NodeName}}"
|
||||
started = false
|
||||
@ -508,14 +535,14 @@ func TestAccResourceVMNetwork(t *testing.T) {
|
||||
bridge = "vmbr0"
|
||||
}
|
||||
}`),
|
||||
Check: resource.ComposeTestCheckFunc(
|
||||
ResourceAttributes("proxmox_virtual_environment_vm.test_vm_network2", map[string]string{
|
||||
"network_device.0.bridge": "vmbr0",
|
||||
"network_device.0.disconnected": "false",
|
||||
}),
|
||||
),
|
||||
}, {
|
||||
Config: te.RenderConfig(`
|
||||
Check: resource.ComposeTestCheckFunc(
|
||||
ResourceAttributes("proxmox_virtual_environment_vm.test_vm_network2", map[string]string{
|
||||
"network_device.0.bridge": "vmbr0",
|
||||
"network_device.0.disconnected": "false",
|
||||
}),
|
||||
),
|
||||
}, {
|
||||
Config: te.RenderConfig(`
|
||||
resource "proxmox_virtual_environment_vm" "test_vm_network2" {
|
||||
node_name = "{{.NodeName}}"
|
||||
started = false
|
||||
@ -525,13 +552,14 @@ func TestAccResourceVMNetwork(t *testing.T) {
|
||||
disconnected = true
|
||||
}
|
||||
}`),
|
||||
Check: resource.ComposeTestCheckFunc(
|
||||
ResourceAttributes("proxmox_virtual_environment_vm.test_vm_network2", map[string]string{
|
||||
"network_device.0.bridge": "vmbr0",
|
||||
"network_device.0.disconnected": "true",
|
||||
}),
|
||||
),
|
||||
}}},
|
||||
Check: resource.ComposeTestCheckFunc(
|
||||
ResourceAttributes("proxmox_virtual_environment_vm.test_vm_network2", map[string]string{
|
||||
"network_device.0.bridge": "vmbr0",
|
||||
"network_device.0.disconnected": "true",
|
||||
}),
|
||||
),
|
||||
},
|
||||
}},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
@ -552,9 +580,6 @@ func TestAccResourceVMClone(t *testing.T) {
|
||||
}
|
||||
|
||||
te := InitEnvironment(t)
|
||||
te.AddTemplateVars(map[string]interface{}{
|
||||
"TemplateVMID": 100000 + rand.Intn(99999),
|
||||
})
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
@ -564,8 +589,8 @@ func TestAccResourceVMClone(t *testing.T) {
|
||||
Config: te.RenderConfig(`
|
||||
resource "proxmox_virtual_environment_vm" "template" {
|
||||
node_name = "{{.NodeName}}"
|
||||
vm_id = {{.TemplateVMID}}
|
||||
started = false
|
||||
template = true
|
||||
cpu {
|
||||
architecture = "x86_64"
|
||||
}
|
||||
@ -578,6 +603,25 @@ func TestAccResourceVMClone(t *testing.T) {
|
||||
}
|
||||
}`, WithRootUser()),
|
||||
}}},
|
||||
{"clone no vga block", []resource.TestStep{{
|
||||
Config: te.RenderConfig(`
|
||||
resource "proxmox_virtual_environment_vm" "template" {
|
||||
node_name = "{{.NodeName}}"
|
||||
started = false
|
||||
}
|
||||
resource "proxmox_virtual_environment_vm" "clone" {
|
||||
node_name = "{{.NodeName}}"
|
||||
started = false
|
||||
clone {
|
||||
vm_id = proxmox_virtual_environment_vm.template.vm_id
|
||||
}
|
||||
}`),
|
||||
Check: resource.ComposeTestCheckFunc(
|
||||
ResourceAttributes("proxmox_virtual_environment_vm.clone", map[string]string{
|
||||
"vga.#": "0",
|
||||
}),
|
||||
),
|
||||
}}},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
|
@ -1398,15 +1398,6 @@ func VM() *schema.Resource {
|
||||
Type: schema.TypeList,
|
||||
Description: "The VGA configuration",
|
||||
Optional: true,
|
||||
DefaultFunc: func() (interface{}, error) {
|
||||
return []interface{}{
|
||||
map[string]interface{}{
|
||||
mkVGAClipboard: dvVGAClipboard,
|
||||
mkVGAMemory: dvVGAMemory,
|
||||
mkVGAType: dvVGAType,
|
||||
},
|
||||
}, nil
|
||||
},
|
||||
Elem: &schema.Resource{
|
||||
Schema: map[string]*schema.Schema{
|
||||
mkVGAClipboard: {
|
||||
@ -2128,11 +2119,7 @@ func vmCreateClone(ctx context.Context, d *schema.ResourceData, m interface{}) d
|
||||
}
|
||||
|
||||
if len(vga) > 0 {
|
||||
vgaDevice, err := vmGetVGADeviceObject(d)
|
||||
if err != nil {
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
|
||||
vgaDevice := vmGetVGADeviceObject(d)
|
||||
updateBody.VGADevice = vgaDevice
|
||||
}
|
||||
|
||||
@ -2531,10 +2518,7 @@ func vmCreateCustom(ctx context.Context, d *schema.ResourceData, m interface{})
|
||||
tabletDevice := types.CustomBool(d.Get(mkTabletDevice).(bool))
|
||||
template := types.CustomBool(d.Get(mkTemplate).(bool))
|
||||
|
||||
vgaDevice, err := vmGetVGADeviceObject(d)
|
||||
if err != nil {
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
vgaDevice := vmGetVGADeviceObject(d)
|
||||
|
||||
vmIDUntyped, hasVMID := d.GetOk(mkVMID)
|
||||
vmID := vmIDUntyped.(int)
|
||||
@ -3320,39 +3304,33 @@ func vmGetTagsString(d *schema.ResourceData) string {
|
||||
return strings.Join(sanitizedTags, ";")
|
||||
}
|
||||
|
||||
func vmGetVGADeviceObject(d *schema.ResourceData) (*vms.CustomVGADevice, error) {
|
||||
resource := VM()
|
||||
func vmGetVGADeviceObject(d *schema.ResourceData) *vms.CustomVGADevice {
|
||||
vga := d.Get(mkVGA).([]interface{})
|
||||
if len(vga) > 0 && vga[0] != nil {
|
||||
vgaBlock := vga[0].(map[string]interface{})
|
||||
vgaClipboard := vgaBlock[mkVGAClipboard].(string)
|
||||
vgaMemory := vgaBlock[mkVGAMemory].(int)
|
||||
|
||||
vgaBlock, err := structure.GetSchemaBlock(
|
||||
resource,
|
||||
d,
|
||||
[]string{mkVGA},
|
||||
0,
|
||||
true,
|
||||
)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error getting VGA block: %w", err)
|
||||
vgaType := vgaBlock[mkVGAType].(string)
|
||||
|
||||
vgaDevice := &vms.CustomVGADevice{}
|
||||
|
||||
if vgaClipboard != "" {
|
||||
vgaDevice.Clipboard = &vgaClipboard
|
||||
}
|
||||
|
||||
if vgaMemory > 0 {
|
||||
vgaDevice.Memory = ptr.Ptr(int64(vgaMemory))
|
||||
}
|
||||
|
||||
if vgaType != "" {
|
||||
vgaDevice.Type = &vgaType
|
||||
}
|
||||
|
||||
return vgaDevice
|
||||
}
|
||||
|
||||
vgaClipboard := vgaBlock[mkVGAClipboard].(string)
|
||||
vgaMemory := vgaBlock[mkVGAMemory].(int)
|
||||
vgaType := vgaBlock[mkVGAType].(string)
|
||||
|
||||
vgaDevice := &vms.CustomVGADevice{}
|
||||
|
||||
if vgaClipboard != "" {
|
||||
vgaDevice.Clipboard = &vgaClipboard
|
||||
}
|
||||
|
||||
if vgaMemory > 0 {
|
||||
vgaDevice.Memory = ptr.Ptr(int64(vgaMemory))
|
||||
}
|
||||
|
||||
if vgaType != "" {
|
||||
vgaDevice.Type = &vgaType
|
||||
}
|
||||
|
||||
return vgaDevice, nil
|
||||
return nil
|
||||
}
|
||||
|
||||
func vmRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
|
||||
@ -4420,9 +4398,9 @@ func vmReadCustom(
|
||||
vga[mkVGAType] = *vmConfig.VGADevice.Type
|
||||
}
|
||||
} else {
|
||||
vga[mkVGAClipboard] = ""
|
||||
vga[mkVGAMemory] = 0
|
||||
vga[mkVGAType] = ""
|
||||
vga[mkVGAClipboard] = dvVGAClipboard
|
||||
vga[mkVGAMemory] = dvVGAMemory
|
||||
vga[mkVGAType] = dvVGAType
|
||||
}
|
||||
|
||||
currentVGA := d.Get(mkVGA).([]interface{})
|
||||
@ -5306,11 +5284,7 @@ func vmUpdate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.D
|
||||
|
||||
// Prepare the new VGA configuration.
|
||||
if d.HasChange(mkVGA) {
|
||||
updateBody.VGADevice, e = vmGetVGADeviceObject(d)
|
||||
if e != nil {
|
||||
return diag.FromErr(e)
|
||||
}
|
||||
|
||||
updateBody.VGADevice = vmGetVGADeviceObject(d)
|
||||
rebootRequired = true
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user