From 4f1a0c94883ffc556c4b07080c96f2cc30d51d01 Mon Sep 17 00:00:00 2001 From: Marshall Ford Date: Tue, 23 Jan 2024 16:19:30 -0600 Subject: [PATCH] adds wait_for_shutoff to resource_libvirt_domain --- libvirt/domain.go | 13 +++++++++++++ libvirt/resource_libvirt_domain.go | 29 +++++++++++++++++++++++++++++ website/docs/r/domain.html.markdown | 1 + 3 files changed, 43 insertions(+) diff --git a/libvirt/domain.go b/libvirt/domain.go index f9881527c..6282ecf1b 100644 --- a/libvirt/domain.go +++ b/libvirt/domain.go @@ -871,3 +871,16 @@ func destroyDomainByUserRequest(virConn *libvirt.Libvirt, d *schema.ResourceData return nil } + +func waitForDomainShutoff(virConn *libvirt.Libvirt, domain libvirt.Domain) resource.StateRefreshFunc { + return func() (interface{}, string, error) { + state, _, err := virConn.DomainGetState(domain, 0) + if err != nil { + return nil, "", err + } + if libvirt.DomainState(state) == libvirt.DomainShutoff { + return domain, "SHUTOFF", nil + } + return domain, "NOT-SHUTOFF", err + } +} diff --git a/libvirt/resource_libvirt_domain.go b/libvirt/resource_libvirt_domain.go index c287f3245..7b51fe159 100644 --- a/libvirt/resource_libvirt_domain.go +++ b/libvirt/resource_libvirt_domain.go @@ -15,6 +15,7 @@ import ( libvirt "github.com/digitalocean/go-libvirt" "github.com/dmacvicar/terraform-provider-libvirt/libvirt/helper/suppress" "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" "libvirt.org/go/libvirtxml" ) @@ -41,6 +42,7 @@ func resourceLibvirtDomain() *schema.Resource { Timeouts: &schema.ResourceTimeout{ //nolint:gomnd Create: schema.DefaultTimeout(5 * time.Minute), + Delete: schema.DefaultTimeout(5 * time.Minute), }, Schema: map[string]*schema.Schema{ "name": { @@ -101,6 +103,13 @@ func resourceLibvirtDomain() *schema.Resource { }, }, }, + "wait_for_shutoff": { + Type: schema.TypeBool, + Optional: true, + Default: false, + ForceNew: false, + Required: false, + }, "running": { Type: schema.TypeBool, Optional: true, @@ -1118,6 +1127,26 @@ func resourceLibvirtDomainDelete(ctx context.Context, d *schema.ResourceData, me return diag.Errorf("couldn't get info about domain: %s", err) } + if d.Get("wait_for_shutoff").(bool) && libvirt.DomainState(state) == libvirt.DomainRunning { + log.Printf("[DEBUG] Shutting down libvirt_domain") + if err := virConn.DomainShutdown(domain); err != nil { + return diag.Errorf("couldn't shutdown libvirt domain: %s", err) + } + + stateConf := &resource.StateChangeConf{ + Pending: []string{"NOT-SHUTOFF"}, + Target: []string{"SHUTOFF"}, + Refresh: waitForDomainShutoff(virConn, domain), + Timeout: d.Timeout(schema.TimeoutDelete), + Delay: resourceStateDelay, + } + _, err = stateConf.WaitForStateContext(ctx) + if err != nil { + return diag.Errorf("error waiting for domain to reach SHUTOFF state: %s", err) + } + state = int32(libvirt.DomainShutoff) + } + if state == int32(libvirt.DomainRunning) || state == int32(libvirt.DomainPaused) { if err := virConn.DomainDestroy(domain); err != nil { return diag.Errorf("couldn't destroy libvirt domain: %s", err) diff --git a/website/docs/r/domain.html.markdown b/website/docs/r/domain.html.markdown index 777b4b3c3..5ec173874 100644 --- a/website/docs/r/domain.html.markdown +++ b/website/docs/r/domain.html.markdown @@ -34,6 +34,7 @@ The following arguments are supported: will be created. * `memory` - (Optional) The amount of memory in MiB. If not specified the domain will be created with 512 MiB of memory be used. +* `wait_for_shutoff` - (Optional) Use `true` to shutoff instance before destroying. Allows guest VM to shutdown gracefully. If not specified `false` is assumed. * `running` - (Optional) Use `false` to turn off the instance. If not specified, true is assumed and the instance, if stopped, will be started at next apply. * `disk` - (Optional) An array of one or more disks to attach to the domain. The