Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(vm): fixed startup / shutdown behaviour on HA clusters #508

Merged
merged 7 commits into from
Aug 21, 2023
40 changes: 25 additions & 15 deletions proxmoxtf/resource/vm.go
Original file line number Diff line number Diff line change
Expand Up @@ -1600,7 +1600,22 @@ func deleteIdeDrives(ctx context.Context, vmAPI *vms.Client, itf1 string, itf2 s
return nil
}

// Shutdown the VM.
// Start the VM, then wait for it to actually start; it may not be started immediately if running in HA mode.
func vmStart(ctx context.Context, vmAPI *vms.Client, d *schema.ResourceData) diag.Diagnostics {
tflog.Debug(ctx, "Starting VM")

startVMTimeout := d.Get(mkResourceVirtualEnvironmentVMTimeoutStartVM).(int)

e := vmAPI.StartVM(ctx, startVMTimeout)
if e != nil {
return diag.FromErr(e)
}

return diag.FromErr(vmAPI.WaitForVMState(ctx, "running", startVMTimeout, 1))
}

// Shutdown the VM, then wait for it to actually shut down (it may not be shut down immediately if
// running in HA mode).
func vmShutdown(ctx context.Context, vmAPI *vms.Client, d *schema.ResourceData) diag.Diagnostics {
tflog.Debug(ctx, "Shutting down VM")

Expand All @@ -1615,7 +1630,7 @@ func vmShutdown(ctx context.Context, vmAPI *vms.Client, d *schema.ResourceData)
return diag.FromErr(e)
}

return nil
return diag.FromErr(vmAPI.WaitForVMState(ctx, "stopped", shutdownTimeout, 1))
}

func vmCreateClone(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
Expand Down Expand Up @@ -1928,6 +1943,7 @@ func vmCreateClone(ctx context.Context, d *schema.ResourceData, m interface{}) d
tflog.Trace(ctx, fmt.Sprintf("CloudInit IDE interface is '%s'", initializationInterface))

const cdromCloudInitEnabled = true

cdromCloudInitFileID := fmt.Sprintf("%s:cloudinit", initializationDatastoreID)
cdromCloudInitMedia := "cdrom"
ideDevices[initializationInterface] = vms.CustomStorageDevice{
Expand Down Expand Up @@ -2750,10 +2766,8 @@ func vmCreateStart(ctx context.Context, d *schema.ResourceData, m interface{}) d
vmAPI := api.Node(nodeName).VM(vmID)

// Start the virtual machine and wait for it to reach a running state before continuing.
startVMTimeout := d.Get(mkResourceVirtualEnvironmentVMTimeoutStartVM).(int)
err = vmAPI.StartVM(ctx, startVMTimeout)
if err != nil {
return diag.FromErr(err)
if diags := vmStart(ctx, vmAPI, d); diags != nil {
return diags
}

if reboot {
Expand Down Expand Up @@ -3499,6 +3513,7 @@ func vmReadCustom(
vmStatus *vms.GetStatusResponseData,
) diag.Diagnostics {
config := m.(proxmoxtf.ProviderConfiguration)

api, err := config.GetClient()
if err != nil {
return diag.FromErr(err)
Expand Down Expand Up @@ -5444,11 +5459,8 @@ func vmUpdate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.D
if (d.HasChange(mkResourceVirtualEnvironmentVMStarted) || stoppedBeforeUpdate) && !bool(template) {
started := d.Get(mkResourceVirtualEnvironmentVMStarted).(bool)
if started {
startVMTimeout := d.Get(mkResourceVirtualEnvironmentVMTimeoutStartVM).(int)

e = vmAPI.StartVM(ctx, startVMTimeout)
if e != nil {
return diag.FromErr(e)
if diags := vmStart(ctx, vmAPI, d); diags != nil {
return diags
}
} else {
if e := vmShutdown(ctx, vmAPI, d); e != nil {
Expand Down Expand Up @@ -5605,10 +5617,8 @@ func vmUpdateDiskLocationAndSize(
}

if shutdownForDisksRequired && started && !template {
startVMTimeout := d.Get(mkResourceVirtualEnvironmentVMTimeoutStartVM).(int)
err = vmAPI.StartVM(ctx, startVMTimeout)
if err != nil {
return diag.FromErr(err)
if diags := vmStart(ctx, vmAPI, d); diags != nil {
return diags
}

// This concludes an equivalent of a reboot, avoid doing another.
Expand Down