Implemented stop_before_destroy behavior

Docs and acceptance test included
This commit is contained in:
Dmytro Aleksandrov 2016-06-15 22:26:18 +03:00 committed by Dmytro Aleksandrov
parent 20bb0b352a
commit c32d152495
3 changed files with 61 additions and 1 deletions

View File

@ -18,6 +18,7 @@ import (
"github.com/rackspace/gophercloud/openstack/compute/v2/extensions/keypairs"
"github.com/rackspace/gophercloud/openstack/compute/v2/extensions/schedulerhints"
"github.com/rackspace/gophercloud/openstack/compute/v2/extensions/secgroups"
"github.com/rackspace/gophercloud/openstack/compute/v2/extensions/startstop"
"github.com/rackspace/gophercloud/openstack/compute/v2/extensions/tenantnetworks"
"github.com/rackspace/gophercloud/openstack/compute/v2/extensions/volumeattach"
"github.com/rackspace/gophercloud/openstack/compute/v2/flavors"
@ -318,6 +319,11 @@ func resourceComputeInstanceV2() *schema.Resource {
},
Set: resourceComputeInstancePersonalityHash,
},
"stop_before_destroy": &schema.Schema{
Type: schema.TypeBool,
Optional: true,
Default: false,
},
},
}
}
@ -808,6 +814,27 @@ func resourceComputeInstanceV2Delete(d *schema.ResourceData, meta interface{}) e
return fmt.Errorf("Error creating OpenStack compute client: %s", err)
}
if d.Get("stop_before_destroy").(bool) {
err = startstop.Stop(computeClient, d.Id()).ExtractErr()
if err != nil {
log.Printf("[WARN] Error stopping OpenStack instance: %s", err)
} else {
stopStateConf := &resource.StateChangeConf{
Pending: []string{"ACTIVE"},
Target: []string{"SHUTOFF"},
Refresh: ServerV2StateRefreshFunc(computeClient, d.Id()),
Timeout: 3 * time.Minute,
Delay: 10 * time.Second,
MinTimeout: 3 * time.Second,
}
log.Printf("[DEBUG] Waiting for instance (%s) to stop", d.Id())
_, err = stopStateConf.WaitForState()
if err != nil {
log.Printf("[WARN] Error waiting for instance (%s) to stop: %s, proceeding to delete", d.Id(), err)
}
}
}
err = servers.Delete(computeClient, d.Id()).ExtractErr()
if err != nil {
return fmt.Errorf("Error deleting OpenStack server: %s", err)
@ -817,7 +844,7 @@ func resourceComputeInstanceV2Delete(d *schema.ResourceData, meta interface{}) e
log.Printf("[DEBUG] Waiting for instance (%s) to delete", d.Id())
stateConf := &resource.StateChangeConf{
Pending: []string{"ACTIVE"},
Pending: []string{"ACTIVE", "SHUTOFF"},
Target: []string{"DELETED"},
Refresh: ServerV2StateRefreshFunc(computeClient, d.Id()),
Timeout: 30 * time.Minute,

View File

@ -840,3 +840,31 @@ func testAccCheckComputeV2InstanceInstanceIDsDoNotMatch(
return nil
}
}
func TestAccComputeV2Instance_stop_before_destroy(t *testing.T) {
var instance servers.Server
var testAccComputeV2Instance_stop_before_destroy = fmt.Sprintf(`
resource "openstack_compute_instance_v2" "foo" {
name = "terraform-test"
security_groups = ["default"]
network {
uuid = "%s"
}
stop_before_destroy = true
}`,
os.Getenv("OS_NETWORK_ID"))
resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
CheckDestroy: testAccCheckComputeV2InstanceDestroy,
Steps: []resource.TestStep{
resource.TestStep{
Config: testAccComputeV2Instance_stop_before_destroy,
Check: resource.ComposeTestCheckFunc(
testAccCheckComputeV2InstanceExists(t, "openstack_compute_instance_v2.foo", &instance),
),
},
},
})
}

View File

@ -264,6 +264,11 @@ The following arguments are supported:
defining one or more files and their contents. The personality structure
is described below.
* `stop_before_destroy` - (Optional) Whether to try stop instance gracefully
before destroying it, thus giving chance for guest OS daemons to stop correctly.
If instance doesn't stop within timeout, it will be destroyed anyway.
The `network` block supports:
* `uuid` - (Required unless `port` or `name` is provided) The network UUID to