mirror of
https://github.com/bpg/terraform-provider-proxmox.git
synced 2025-07-01 02:52:58 +00:00
feat(vm): add support for vga.clipboard
, virtio-gl
type (#1326)
Signed-off-by: Pavel Boldyrev <627562+bpg@users.noreply.github.com>
This commit is contained in:
parent
1c6b9e4935
commit
32de050605
@ -527,11 +527,10 @@ output "ubuntu_vm_public_key" {
|
|||||||
- `timeout_stop_vm` - (Optional) Timeout for stopping a VM in seconds (defaults
|
- `timeout_stop_vm` - (Optional) Timeout for stopping a VM in seconds (defaults
|
||||||
to 300).
|
to 300).
|
||||||
- `vga` - (Optional) The VGA configuration.
|
- `vga` - (Optional) The VGA configuration.
|
||||||
- `enabled` - (Optional) Whether to enable the VGA device (defaults
|
|
||||||
to `true`).
|
|
||||||
- `memory` - (Optional) The VGA memory in megabytes (defaults to `16`).
|
- `memory` - (Optional) The VGA memory in megabytes (defaults to `16`).
|
||||||
- `type` - (Optional) The VGA type (defaults to `std`).
|
- `type` - (Optional) The VGA type (defaults to `std`).
|
||||||
- `cirrus` - Cirrus (deprecated since QEMU 2.2).
|
- `cirrus` - Cirrus (deprecated since QEMU 2.2).
|
||||||
|
- `none` - No VGA device.
|
||||||
- `qxl` - SPICE.
|
- `qxl` - SPICE.
|
||||||
- `qxl2` - SPICE Dual Monitor.
|
- `qxl2` - SPICE Dual Monitor.
|
||||||
- `qxl3` - SPICE Triple Monitor.
|
- `qxl3` - SPICE Triple Monitor.
|
||||||
@ -542,7 +541,9 @@ output "ubuntu_vm_public_key" {
|
|||||||
- `serial3` - Serial Terminal 3.
|
- `serial3` - Serial Terminal 3.
|
||||||
- `std` - Standard VGA.
|
- `std` - Standard VGA.
|
||||||
- `virtio` - VirtIO-GPU.
|
- `virtio` - VirtIO-GPU.
|
||||||
|
- `virtio-gl` - VirtIO-GPU with 3D acceleration (VirGL). VirGL support needs some extra libraries that aren’t installed by default. See the [Proxmox documentation](https://pve.proxmox.com/pve-docs/pve-admin-guide.html#qm_virtual_machines_settings) section 10.2.8.for more information.
|
||||||
- `vmware` - VMware Compatible.
|
- `vmware` - VMware Compatible.
|
||||||
|
- `clipboard` - (Optional) Enable VNC clipboard by setting to `vnc`. See the [Proxmox documentation](https://pve.proxmox.com/pve-docs/pve-admin-guide.html#qm_virtual_machines_settings) section 10.2.8.for more information.
|
||||||
- `vm_id` - (Optional) The VM identifier.
|
- `vm_id` - (Optional) The VM identifier.
|
||||||
- `hook_script_file_id` - (Optional) The identifier for a file containing a hook script (needs to be executable).
|
- `hook_script_file_id` - (Optional) The identifier for a file containing a hook script (needs to be executable).
|
||||||
|
|
||||||
|
@ -162,6 +162,41 @@ func TestAccResourceVM(t *testing.T) {
|
|||||||
),
|
),
|
||||||
}},
|
}},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"update vga block", []resource.TestStep{{
|
||||||
|
Config: te.RenderConfig(`
|
||||||
|
resource "proxmox_virtual_environment_vm" "test_vm" {
|
||||||
|
node_name = "{{.NodeName}}"
|
||||||
|
started = false
|
||||||
|
|
||||||
|
vga {
|
||||||
|
type = "none"
|
||||||
|
}
|
||||||
|
}`),
|
||||||
|
Check: resource.ComposeTestCheckFunc(
|
||||||
|
ResourceAttributes("proxmox_virtual_environment_vm.test_vm", map[string]string{
|
||||||
|
"vga.0.type": "none",
|
||||||
|
}),
|
||||||
|
),
|
||||||
|
}, {
|
||||||
|
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.0.type": "virtio-gl",
|
||||||
|
"vga.0.clipboard": "vnc",
|
||||||
|
}),
|
||||||
|
),
|
||||||
|
}},
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, tt := range tests {
|
for _, tt := range tests {
|
||||||
|
@ -185,8 +185,9 @@ type CustomUSBDevices []CustomUSBDevice
|
|||||||
|
|
||||||
// CustomVGADevice handles QEMU VGA device parameters.
|
// CustomVGADevice handles QEMU VGA device parameters.
|
||||||
type CustomVGADevice struct {
|
type CustomVGADevice struct {
|
||||||
Memory *int `json:"memory,omitempty" url:"memory,omitempty"`
|
Clipboard *string `json:"clipboard,omitempty" url:"memory,omitempty"`
|
||||||
Type *string `json:"type,omitempty" url:"type,omitempty"`
|
Memory *int `json:"memory,omitempty" url:"memory,omitempty"`
|
||||||
|
Type *string `json:"type,omitempty" url:"type,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// CustomVirtualIODevice handles QEMU VirtIO device parameters.
|
// CustomVirtualIODevice handles QEMU VirtIO device parameters.
|
||||||
@ -1242,6 +1243,10 @@ func (r CustomUSBDevices) EncodeValues(key string, v *url.Values) error {
|
|||||||
func (r CustomVGADevice) EncodeValues(key string, v *url.Values) error {
|
func (r CustomVGADevice) EncodeValues(key string, v *url.Values) error {
|
||||||
var values []string
|
var values []string
|
||||||
|
|
||||||
|
if r.Clipboard != nil {
|
||||||
|
values = append(values, fmt.Sprintf("clipboard=%s", *r.Clipboard))
|
||||||
|
}
|
||||||
|
|
||||||
if r.Memory != nil {
|
if r.Memory != nil {
|
||||||
values = append(values, fmt.Sprintf("memory=%d", *r.Memory))
|
values = append(values, fmt.Sprintf("memory=%d", *r.Memory))
|
||||||
}
|
}
|
||||||
@ -2038,6 +2043,9 @@ func (r *CustomVGADevice) UnmarshalJSON(b []byte) error {
|
|||||||
r.Type = &v[0]
|
r.Type = &v[0]
|
||||||
} else if len(v) == 2 {
|
} else if len(v) == 2 {
|
||||||
switch v[0] {
|
switch v[0] {
|
||||||
|
case "clipboard":
|
||||||
|
r.Clipboard = &v[1]
|
||||||
|
|
||||||
case "memory":
|
case "memory":
|
||||||
m, err := strconv.Atoi(v[1])
|
m, err := strconv.Atoi(v[1])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -228,6 +228,7 @@ func VGAMemoryValidator() schema.SchemaValidateDiagFunc {
|
|||||||
func VGATypeValidator() schema.SchemaValidateDiagFunc {
|
func VGATypeValidator() schema.SchemaValidateDiagFunc {
|
||||||
return validation.ToDiagFunc(validation.StringInSlice([]string{
|
return validation.ToDiagFunc(validation.StringInSlice([]string{
|
||||||
"cirrus",
|
"cirrus",
|
||||||
|
"none",
|
||||||
"qxl",
|
"qxl",
|
||||||
"qxl2",
|
"qxl2",
|
||||||
"qxl3",
|
"qxl3",
|
||||||
@ -238,6 +239,7 @@ func VGATypeValidator() schema.SchemaValidateDiagFunc {
|
|||||||
"serial3",
|
"serial3",
|
||||||
"std",
|
"std",
|
||||||
"virtio",
|
"virtio",
|
||||||
|
"virtio-gl",
|
||||||
"vmware",
|
"vmware",
|
||||||
}, false))
|
}, false))
|
||||||
}
|
}
|
||||||
|
@ -124,7 +124,7 @@ const (
|
|||||||
dvTimeoutShutdownVM = 1800
|
dvTimeoutShutdownVM = 1800
|
||||||
dvTimeoutStartVM = 1800
|
dvTimeoutStartVM = 1800
|
||||||
dvTimeoutStopVM = 300
|
dvTimeoutStopVM = 300
|
||||||
dvVGAEnabled = true
|
dvVGAClipboard = ""
|
||||||
dvVGAMemory = 16
|
dvVGAMemory = 16
|
||||||
dvVGAType = "std"
|
dvVGAType = "std"
|
||||||
dvSCSIHardware = "virtio-scsi-pci"
|
dvSCSIHardware = "virtio-scsi-pci"
|
||||||
@ -271,6 +271,7 @@ const (
|
|||||||
mkHostUSBDeviceMapping = "mapping"
|
mkHostUSBDeviceMapping = "mapping"
|
||||||
mkHostUSBDeviceUSB3 = "usb3"
|
mkHostUSBDeviceUSB3 = "usb3"
|
||||||
mkVGA = "vga"
|
mkVGA = "vga"
|
||||||
|
mkVGAClipboard = "clipboard"
|
||||||
mkVGAEnabled = "enabled"
|
mkVGAEnabled = "enabled"
|
||||||
mkVGAMemory = "memory"
|
mkVGAMemory = "memory"
|
||||||
mkVGAType = "type"
|
mkVGAType = "type"
|
||||||
@ -1388,19 +1389,29 @@ func VM() *schema.Resource {
|
|||||||
DefaultFunc: func() (interface{}, error) {
|
DefaultFunc: func() (interface{}, error) {
|
||||||
return []interface{}{
|
return []interface{}{
|
||||||
map[string]interface{}{
|
map[string]interface{}{
|
||||||
mkVGAEnabled: dvVGAEnabled,
|
mkVGAClipboard: dvVGAClipboard,
|
||||||
mkVGAMemory: dvVGAMemory,
|
mkVGAMemory: dvVGAMemory,
|
||||||
mkVGAType: dvVGAType,
|
mkVGAType: dvVGAType,
|
||||||
},
|
},
|
||||||
}, nil
|
}, nil
|
||||||
},
|
},
|
||||||
Elem: &schema.Resource{
|
Elem: &schema.Resource{
|
||||||
Schema: map[string]*schema.Schema{
|
Schema: map[string]*schema.Schema{
|
||||||
|
mkVGAClipboard: {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Description: "Enable clipboard support. Set to `vnc` to enable clipboard support for VNC.",
|
||||||
|
Optional: true,
|
||||||
|
Default: dvVGAClipboard,
|
||||||
|
ValidateDiagFunc: validation.ToDiagFunc(validation.StringInSlice([]string{
|
||||||
|
"vnc",
|
||||||
|
}, true)),
|
||||||
|
},
|
||||||
mkVGAEnabled: {
|
mkVGAEnabled: {
|
||||||
Type: schema.TypeBool,
|
Type: schema.TypeBool,
|
||||||
|
Deprecated: "The `enabled` attribute is deprecated and will be removed in a future release. " +
|
||||||
|
"Use type `none` instead.",
|
||||||
Description: "Whether to enable the VGA device",
|
Description: "Whether to enable the VGA device",
|
||||||
Optional: true,
|
Optional: true,
|
||||||
Default: dvVGAEnabled,
|
|
||||||
},
|
},
|
||||||
mkVGAMemory: {
|
mkVGAMemory: {
|
||||||
Type: schema.TypeInt,
|
Type: schema.TypeInt,
|
||||||
@ -3335,24 +3346,22 @@ func vmGetVGADeviceObject(d *schema.ResourceData) (*vms.CustomVGADevice, error)
|
|||||||
return nil, fmt.Errorf("error getting VGA block: %w", err)
|
return nil, fmt.Errorf("error getting VGA block: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
vgaEnabled := types.CustomBool(vgaBlock[mkAgentEnabled].(bool))
|
vgaClipboard := vgaBlock[mkVGAClipboard].(string)
|
||||||
vgaMemory := vgaBlock[mkVGAMemory].(int)
|
vgaMemory := vgaBlock[mkVGAMemory].(int)
|
||||||
vgaType := vgaBlock[mkVGAType].(string)
|
vgaType := vgaBlock[mkVGAType].(string)
|
||||||
|
|
||||||
vgaDevice := &vms.CustomVGADevice{}
|
vgaDevice := &vms.CustomVGADevice{}
|
||||||
|
|
||||||
if vgaEnabled {
|
if vgaClipboard != "" {
|
||||||
if vgaMemory > 0 {
|
vgaDevice.Clipboard = &vgaClipboard
|
||||||
vgaDevice.Memory = &vgaMemory
|
}
|
||||||
}
|
|
||||||
|
|
||||||
|
if vgaMemory > 0 {
|
||||||
|
vgaDevice.Memory = &vgaMemory
|
||||||
|
}
|
||||||
|
|
||||||
|
if vgaType != "" {
|
||||||
vgaDevice.Type = &vgaType
|
vgaDevice.Type = &vgaType
|
||||||
} else {
|
|
||||||
vgaType = "none"
|
|
||||||
|
|
||||||
vgaDevice = &vms.CustomVGADevice{
|
|
||||||
Type: &vgaType,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return vgaDevice, nil
|
return vgaDevice, nil
|
||||||
@ -4413,29 +4422,23 @@ func vmReadCustom(
|
|||||||
vga := map[string]interface{}{}
|
vga := map[string]interface{}{}
|
||||||
|
|
||||||
if vmConfig.VGADevice != nil {
|
if vmConfig.VGADevice != nil {
|
||||||
vgaEnabled := true
|
if vmConfig.VGADevice.Clipboard != nil {
|
||||||
|
vga[mkVGAClipboard] = *vmConfig.VGADevice.Clipboard
|
||||||
if vmConfig.VGADevice.Type != nil {
|
} else {
|
||||||
vgaEnabled = *vmConfig.VGADevice.Type != "none"
|
vga[mkVGAClipboard] = dvVGAClipboard
|
||||||
}
|
}
|
||||||
|
|
||||||
vga[mkVGAEnabled] = vgaEnabled
|
|
||||||
|
|
||||||
if vmConfig.VGADevice.Memory != nil {
|
if vmConfig.VGADevice.Memory != nil {
|
||||||
vga[mkVGAMemory] = *vmConfig.VGADevice.Memory
|
vga[mkVGAMemory] = *vmConfig.VGADevice.Memory
|
||||||
} else {
|
} else {
|
||||||
vga[mkVGAMemory] = 0
|
vga[mkVGAMemory] = dvVGAMemory
|
||||||
}
|
}
|
||||||
|
|
||||||
if vgaEnabled {
|
if vmConfig.VGADevice.Type != nil {
|
||||||
if vmConfig.VGADevice.Type != nil {
|
vga[mkVGAType] = *vmConfig.VGADevice.Type
|
||||||
vga[mkVGAType] = *vmConfig.VGADevice.Type
|
|
||||||
} else {
|
|
||||||
vga[mkVGAType] = ""
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
vga[mkVGAEnabled] = true
|
vga[mkVGAClipboard] = ""
|
||||||
vga[mkVGAMemory] = 0
|
vga[mkVGAMemory] = 0
|
||||||
vga[mkVGAType] = ""
|
vga[mkVGAType] = ""
|
||||||
}
|
}
|
||||||
@ -4447,7 +4450,7 @@ func vmReadCustom(
|
|||||||
err := d.Set(mkVGA, []interface{}{vga})
|
err := d.Set(mkVGA, []interface{}{vga})
|
||||||
diags = append(diags, diag.FromErr(err)...)
|
diags = append(diags, diag.FromErr(err)...)
|
||||||
case len(currentVGA) > 0 ||
|
case len(currentVGA) > 0 ||
|
||||||
vga[mkVGAEnabled] != dvVGAEnabled ||
|
vga[mkVGAClipboard] != dvVGAClipboard ||
|
||||||
vga[mkVGAMemory] != dvVGAMemory ||
|
vga[mkVGAMemory] != dvVGAMemory ||
|
||||||
vga[mkVGAType] != dvVGAType:
|
vga[mkVGAType] != dvVGAType:
|
||||||
err := d.Set(mkVGA, []interface{}{vga})
|
err := d.Set(mkVGA, []interface{}{vga})
|
||||||
|
Loading…
Reference in New Issue
Block a user