Skip to content

Commit a084896

Browse files
authored
Merge pull request #1513 from Tinyblargon/qemu-power-state
Feat: Qemu power state
2 parents 0ddc5f6 + e38fab2 commit a084896

14 files changed

Lines changed: 183 additions & 148 deletions

File tree

docs/examples/pxe_example.tf

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ resource "proxmox_vm_qemu" "pxe-example" {
3737
kvm = true
3838
memory = 2048
3939
onboot = false
40-
vm_state = "running"
40+
power_state = "running"
4141
os_type = "Linux 5.x - 2.6 Kernel"
4242
qemu_os = "l26"
4343
scsihw = "virtio-scsi-pci"

docs/resources/vm_qemu.md

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -101,8 +101,7 @@ The following arguments are supported in the top level resource block.
101101
| `efidisk` | `nested` | | The configuration for the EFI disk, see [EFI Disk Block](#efi-disk-block) section.|
102102
| `start_at_node_boot` | `bool` | `false` | Whether the guest should start automatically when the Proxmox node boots.|
103103
| `startup_shutdown` | `nested` | | Startup and shutdown configuration of the guest, see [Startup and Shutdown Reference](#startup-and-shutdown-reference).|
104-
| `vm_state` | `string` | `"running"` | The desired state of the VM, options are `running`, `stopped` and `started`. Do note that `started` will only start the vm on creation and won't fully manage the power state unlike `running` and `stopped` do. |
105-
| `oncreate` | `bool` | `true` | Whether to have the VM startup after the VM is created (deprecated, use `vm_state` instead) |
104+
| `power_state` | `string` | `"running"` | Power state of the guest, can be `"running"` or `"stopped"`.|
106105
| `protection` | `bool` | `false` | Enable/disable the VM protection from being removed. The default value of `false` indicates the VM is removable. |
107106
| `tablet` | `bool` | `true` | Enable/disable the USB tablet device. This device is usually needed to allow absolute mouse positioning with VNC. |
108107
| `boot` | `str` | | The boot order for the VM. For example: `order=scsi0;ide2;net0`. The deprecated `legacy=` syntax is no longer supported. See the `boot` option in the [Proxmox manual](https://pve.proxmox.com/wiki/Manual:_qm.conf#_options) for more information. |

go.mod

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ module github.com/Telmate/terraform-provider-proxmox/v2
33
go 1.24.9
44

55
require (
6-
github.com/Telmate/proxmox-api-go v0.0.0-20260405210716-af179791a625
6+
github.com/Telmate/proxmox-api-go v0.0.0-20260423201259-0eeefb930bb2
77
github.com/google/uuid v1.6.0
88
github.com/hashicorp/go-cty v1.5.0
99
github.com/hashicorp/terraform-plugin-sdk/v2 v2.38.2

go.sum

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@ github.com/Microsoft/go-winio v0.6.2 h1:F2VQgta7ecxGYO8k3ZZz3RS8fVIXVxONVUPlNERo
44
github.com/Microsoft/go-winio v0.6.2/go.mod h1:yd8OoFMLzJbo9gZq8j5qaps8bJ9aShtEA8Ipt1oGCvU=
55
github.com/ProtonMail/go-crypto v1.2.0 h1:+PhXXn4SPGd+qk76TlEePBfOfivE0zkWFenhGhFLzWs=
66
github.com/ProtonMail/go-crypto v1.2.0/go.mod h1:9whxjD8Rbs29b4XWbB8irEcE8KHMqaR2e7GWU1R+/PE=
7-
github.com/Telmate/proxmox-api-go v0.0.0-20260405210716-af179791a625 h1:F0YfK9eN0dIfa3bz3ZRklsihsuHj8yaxHbIe7JVKnGM=
8-
github.com/Telmate/proxmox-api-go v0.0.0-20260405210716-af179791a625/go.mod h1:HGPbpwiVsrpYYuQAygnnU04ZdGLYc8fdP9qhJIBw2Bg=
7+
github.com/Telmate/proxmox-api-go v0.0.0-20260423201259-0eeefb930bb2 h1:VVMmJjr9NmuekozPo3/XTdcgQZsXgGayA0eVYI1zb8g=
8+
github.com/Telmate/proxmox-api-go v0.0.0-20260423201259-0eeefb930bb2/go.mod h1:HGPbpwiVsrpYYuQAygnnU04ZdGLYc8fdP9qhJIBw2Bg=
99
github.com/agext/levenshtein v1.2.3 h1:YB2fHEn0UJagG8T1rrWknE3ZQzWM06O8AMAatNn7lmo=
1010
github.com/agext/levenshtein v1.2.3/go.mod h1:JEDfjyjHDjOF/1e4FlBE/PkbqA9OfWu2ki2W0IB5558=
1111
github.com/apparentlymart/go-textseg/v12 v12.0.0/go.mod h1:S/4uRK2UtaQttw1GenVJEynmyUenKwP++x/+DdGV/Ec=

proxmox/Internal/resource/guest/powerstate/schema.go

Lines changed: 19 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -9,27 +9,28 @@ import (
99
const (
1010
Root = "power_state"
1111

12+
Default string = enumRunning
13+
1214
enumRunning = "running"
1315
enumStopped = "stopped"
1416
)
1517

16-
func Schema() *schema.Schema {
17-
return &schema.Schema{
18-
Type: schema.TypeString,
19-
Optional: true,
20-
Default: enumRunning,
21-
ValidateDiagFunc: func(i any, path cty.Path) diag.Diagnostics {
22-
if v, ok := i.(string); ok {
23-
switch v {
24-
case enumRunning, enumStopped:
25-
return nil
26-
}
27-
}
28-
return diag.Diagnostics{
29-
diag.Diagnostic{
30-
Detail: "the power state must be either '" + enumRunning + "' or '" + enumStopped + "'",
31-
Summary: "invalid power state",
32-
Severity: diag.Error},
18+
func Schema(s schema.Schema) *schema.Schema {
19+
s.Type = schema.TypeString
20+
s.Optional = true
21+
s.ValidateDiagFunc = func(i any, path cty.Path) diag.Diagnostics {
22+
if v, ok := i.(string); ok {
23+
switch v {
24+
case enumRunning, enumStopped:
25+
return nil
3326
}
34-
}}
27+
}
28+
return diag.Diagnostics{
29+
diag.Diagnostic{
30+
Detail: "the power state must be either '" + enumRunning + "' or '" + enumStopped + "'",
31+
Summary: "invalid power state",
32+
Severity: diag.Error},
33+
}
34+
}
35+
return &s
3536
}
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
package powerstate
2+
3+
import (
4+
"github.com/hashicorp/go-cty/cty"
5+
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
6+
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
7+
)
8+
9+
const (
10+
LegacyRoot = "vm_state"
11+
12+
legacyEnumStarted = "started"
13+
)
14+
15+
func SchemaLegacy() *schema.Schema {
16+
return &schema.Schema{
17+
Type: schema.TypeString,
18+
Deprecated: "Use " + Root + " instead",
19+
Description: "The state of the VM (" + enumRunning + ", " + legacyEnumStarted + ", " + enumStopped + ")",
20+
Optional: true,
21+
ConflictsWith: []string{Root},
22+
ValidateDiagFunc: func(i any, path cty.Path) diag.Diagnostics {
23+
if v, ok := i.(string); ok {
24+
switch v {
25+
case enumRunning, enumStopped, legacyEnumStarted:
26+
return nil
27+
}
28+
}
29+
return diag.Diagnostics{
30+
diag.Diagnostic{
31+
Detail: LegacyRoot + " must be one of '" + enumRunning + "', '" + enumStopped + "', '" + legacyEnumStarted + "'",
32+
Summary: "invalid " + LegacyRoot,
33+
Severity: diag.Error},
34+
}
35+
},
36+
DiffSuppressFunc: func(k, old, new string, d *schema.ResourceData) bool {
37+
return new == legacyEnumStarted
38+
}}
39+
}

proxmox/Internal/resource/guest/powerstate/sdk.go

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,17 +2,28 @@ package powerstate
22

33
import (
44
pveSDK "github.com/Telmate/proxmox-api-go/proxmox"
5+
"github.com/Telmate/terraform-provider-proxmox/v2/proxmox/Internal/util"
56
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
67
)
78

8-
func SDK(d *schema.ResourceData) *pveSDK.PowerState {
9-
switch d.Get(Root).(string) {
9+
const (
10+
LegacyFalse LegacyEnum = 0
11+
LegacyCreate LegacyEnum = 1
12+
LegacyUpdate LegacyEnum = 2
13+
)
14+
15+
type LegacyEnum uint8
16+
17+
func SDK(legacy LegacyEnum, d *schema.ResourceData) *pveSDK.PowerState {
18+
v, ok := d.GetOk(Root)
19+
if !ok && legacy > LegacyFalse {
20+
return sdkLegacy(d)
21+
}
22+
switch v.(string) {
1023
case enumRunning:
11-
state := pveSDK.PowerStateRunning
12-
return &state
24+
return util.Pointer(pveSDK.PowerStateRunning)
1325
case enumStopped:
14-
state := pveSDK.PowerStateStopped
15-
return &state
26+
return util.Pointer(pveSDK.PowerStateStopped)
1627
default:
1728
return nil
1829
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
package powerstate
2+
3+
import (
4+
pveSDK "github.com/Telmate/proxmox-api-go/proxmox"
5+
"github.com/Telmate/terraform-provider-proxmox/v2/proxmox/Internal/util"
6+
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
7+
)
8+
9+
func sdkLegacy(d *schema.ResourceData) *pveSDK.PowerState {
10+
v, ok := d.GetOk(LegacyRoot)
11+
if !ok {
12+
return util.Pointer(pveSDK.PowerStateRunning)
13+
}
14+
switch v.(string) {
15+
case enumRunning:
16+
return util.Pointer(pveSDK.PowerStateRunning)
17+
case enumStopped:
18+
return util.Pointer(pveSDK.PowerStateStopped)
19+
default:
20+
return nil
21+
}
22+
}

proxmox/Internal/resource/guest/powerstate/terraform.go

Lines changed: 22 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,30 @@ import (
55
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
66
)
77

8-
func Terraform(state pveSDK.PowerState, d *schema.ResourceData) {
9-
switch state {
8+
func Terraform(config pveSDK.PowerState, legacy bool, d *schema.ResourceData) {
9+
if _, ok := d.GetOk(Root); ok {
10+
d.Set(Root, terraform(config))
11+
if legacy {
12+
terraformLegacyClear(d)
13+
}
14+
return
15+
}
16+
if legacy {
17+
if _, ok := d.GetOk(LegacyRoot); ok {
18+
terraformLegacy(config,d)
19+
return
20+
}
21+
}
22+
d.Set(Root, terraform(config))
23+
}
24+
25+
func terraform(config pveSDK.PowerState) string {
26+
switch config {
1027
case pveSDK.PowerStateRunning:
11-
d.Set(Root, enumRunning)
28+
return enumRunning
1229
case pveSDK.PowerStateStopped:
13-
d.Set(Root, enumStopped)
30+
return enumStopped
1431
default:
15-
d.Set(Root, "")
32+
return ""
1633
}
1734
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
package powerstate
2+
3+
import (
4+
pveSDK "github.com/Telmate/proxmox-api-go/proxmox"
5+
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
6+
)
7+
8+
func terraformLegacy(config pveSDK.PowerState, d *schema.ResourceData) {
9+
d.Set(LegacyRoot, terraform(config))
10+
}
11+
12+
func terraformLegacyClear(d *schema.ResourceData) {
13+
if _, ok := d.GetOk(LegacyRoot); ok {
14+
d.Set(LegacyRoot, nil)
15+
}
16+
}

0 commit comments

Comments
 (0)