mirror of
https://github.com/bpg/terraform-provider-proxmox.git
synced 2025-08-22 19:38:35 +00:00
fix(vm): race condition on reboot causing inconsistent VM state (#1911)
Signed-off-by: Pavel Boldyrev <627562+bpg@users.noreply.github.com>
This commit is contained in:
parent
ce5cc746f9
commit
7fd190aaeb
@ -300,6 +300,25 @@ func (c *Client) RebuildCloudInitDisk(ctx context.Context) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// RebootVMAndWaitForRunning reboots a virtual machine and waits for it to be running.
|
||||||
|
func (c *Client) RebootVMAndWaitForRunning(ctx context.Context, rebootTimeoutSec int) error {
|
||||||
|
// We add 3 seconds padding to the timeout to account for retries and delays down the callstack.
|
||||||
|
ctx, cancel := context.WithTimeout(ctx, time.Duration(rebootTimeoutSec+3)*time.Second)
|
||||||
|
defer cancel()
|
||||||
|
|
||||||
|
err := c.RebootVM(
|
||||||
|
ctx,
|
||||||
|
&RebootRequestBody{
|
||||||
|
Timeout: &rebootTimeoutSec,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return c.WaitForVMStatus(ctx, "running")
|
||||||
|
}
|
||||||
|
|
||||||
// RebootVM reboots a virtual machine.
|
// RebootVM reboots a virtual machine.
|
||||||
func (c *Client) RebootVM(ctx context.Context, d *RebootRequestBody) error {
|
func (c *Client) RebootVM(ctx context.Context, d *RebootRequestBody) error {
|
||||||
taskID, err := c.RebootVMAsync(ctx, d)
|
taskID, err := c.RebootVMAsync(ctx, d)
|
||||||
|
@ -2865,14 +2865,8 @@ func vmCreateStart(ctx context.Context, d *schema.ResourceData, m interface{}) d
|
|||||||
if reboot {
|
if reboot {
|
||||||
rebootTimeoutSec := d.Get(mkTimeoutReboot).(int)
|
rebootTimeoutSec := d.Get(mkTimeoutReboot).(int)
|
||||||
|
|
||||||
err := vmAPI.RebootVM(
|
if e := vmAPI.RebootVMAndWaitForRunning(ctx, rebootTimeoutSec); e != nil {
|
||||||
ctx,
|
return diag.FromErr(e)
|
||||||
&vms.RebootRequestBody{
|
|
||||||
Timeout: &rebootTimeoutSec,
|
|
||||||
},
|
|
||||||
)
|
|
||||||
if err != nil {
|
|
||||||
return diag.FromErr(err)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3544,7 +3538,16 @@ func vmReadCustom(
|
|||||||
return diag.FromErr(e)
|
return diag.FromErr(e)
|
||||||
}
|
}
|
||||||
|
|
||||||
diags := vmReadPrimitiveValues(d, vmConfig, vmStatus)
|
var diags diag.Diagnostics
|
||||||
|
|
||||||
|
if !d.Get(mkTemplate).(bool) {
|
||||||
|
// we shouldn't be updating this attribute at read. Instead, the current status should be captured
|
||||||
|
// in a separate computed attribute. To be addressed in v1.0
|
||||||
|
err := d.Set(mkStarted, vmStatus.Status == "running")
|
||||||
|
diags = append(diags, diag.FromErr(err)...)
|
||||||
|
}
|
||||||
|
|
||||||
|
diags = append(diags, vmReadPrimitiveValues(d, vmConfig)...)
|
||||||
if diags.HasError() {
|
if diags.HasError() {
|
||||||
return diags
|
return diags
|
||||||
}
|
}
|
||||||
@ -4695,7 +4698,6 @@ func vmReadCustom(
|
|||||||
func vmReadPrimitiveValues(
|
func vmReadPrimitiveValues(
|
||||||
d *schema.ResourceData,
|
d *schema.ResourceData,
|
||||||
vmConfig *vms.GetResponseData,
|
vmConfig *vms.GetResponseData,
|
||||||
vmStatus *vms.GetStatusResponseData,
|
|
||||||
) diag.Diagnostics {
|
) diag.Diagnostics {
|
||||||
var diags diag.Diagnostics
|
var diags diag.Diagnostics
|
||||||
|
|
||||||
@ -4829,11 +4831,6 @@ func vmReadPrimitiveValues(
|
|||||||
diags = append(diags, diag.FromErr(err)...)
|
diags = append(diags, diag.FromErr(err)...)
|
||||||
}
|
}
|
||||||
|
|
||||||
if !d.Get(mkTemplate).(bool) {
|
|
||||||
err = d.Set(mkStarted, vmStatus.Status == "running")
|
|
||||||
diags = append(diags, diag.FromErr(err)...)
|
|
||||||
}
|
|
||||||
|
|
||||||
currentTabletDevice := d.Get(mkTabletDevice).(bool)
|
currentTabletDevice := d.Get(mkTabletDevice).(bool)
|
||||||
|
|
||||||
if len(clone) == 0 || !currentTabletDevice {
|
if len(clone) == 0 || !currentTabletDevice {
|
||||||
@ -5804,14 +5801,8 @@ func vmUpdateDiskLocationAndSize(
|
|||||||
if vmStatus.Status != "stopped" {
|
if vmStatus.Status != "stopped" {
|
||||||
rebootTimeoutSec := d.Get(mkTimeoutReboot).(int)
|
rebootTimeoutSec := d.Get(mkTimeoutReboot).(int)
|
||||||
|
|
||||||
err := vmAPI.RebootVM(
|
if e := vmAPI.RebootVMAndWaitForRunning(ctx, rebootTimeoutSec); e != nil {
|
||||||
ctx,
|
return diag.FromErr(e)
|
||||||
&vms.RebootRequestBody{
|
|
||||||
Timeout: &rebootTimeoutSec,
|
|
||||||
},
|
|
||||||
)
|
|
||||||
if err != nil {
|
|
||||||
return diag.FromErr(err)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user