From 411ad21fd89be66c0a987eb0d2bdb98a795ea3c7 Mon Sep 17 00:00:00 2001 From: Joe Topjian Date: Thu, 14 Jul 2016 15:29:31 +0000 Subject: [PATCH] provider/openstack: Fixing boot volume interference This commit fixes the situation where instances with both a bootable volume and attached block storage volumes were reporting an inconsistent state. --- .../resource_openstack_compute_instance_v2.go | 25 ++++++++--- ...urce_openstack_compute_instance_v2_test.go | 41 +++++++++++++++++++ 2 files changed, 60 insertions(+), 6 deletions(-) diff --git a/builtin/providers/openstack/resource_openstack_compute_instance_v2.go b/builtin/providers/openstack/resource_openstack_compute_instance_v2.go index 7f1b8f9bc..4edd512e0 100644 --- a/builtin/providers/openstack/resource_openstack_compute_instance_v2.go +++ b/builtin/providers/openstack/resource_openstack_compute_instance_v2.go @@ -1436,12 +1436,25 @@ func getVolumeAttachments(computeClient *gophercloud.ServiceClient, d *schema.Re return err } - vols := make([]map[string]interface{}, len(attachments)) - for i, attachment := range attachments { - vols[i] = make(map[string]interface{}) - vols[i]["id"] = attachment.ID - vols[i]["volume_id"] = attachment.VolumeID - vols[i]["device"] = attachment.Device + var vols []map[string]interface{} + for _, attachment := range attachments { + // ignore the volume if it is attached as a root device + rootDevFound := false + for _, rootDev := range []string{"/dev/vda", "/dev/xda", "/dev/sda", "/dev/xvda"} { + if attachment.Device == rootDev { + rootDevFound = true + } + } + + if rootDevFound { + continue + } + + vol := make(map[string]interface{}) + vol["id"] = attachment.ID + vol["volume_id"] = attachment.VolumeID + vol["device"] = attachment.Device + vols = append(vols, vol) } log.Printf("[INFO] Volume attachments: %v", vols) d.Set("volume", vols) diff --git a/builtin/providers/openstack/resource_openstack_compute_instance_v2_test.go b/builtin/providers/openstack/resource_openstack_compute_instance_v2_test.go index cc87bf707..6e1f9c422 100644 --- a/builtin/providers/openstack/resource_openstack_compute_instance_v2_test.go +++ b/builtin/providers/openstack/resource_openstack_compute_instance_v2_test.go @@ -388,6 +388,47 @@ func TestAccComputeV2Instance_bootFromVolumeImage(t *testing.T) { }) } +func TestAccComputeV2Instance_bootFromVolumeImageWithAttachedVolume(t *testing.T) { + var instance servers.Server + var testAccComputeV2Instance_bootFromVolumeImageWithAttachedVolume = fmt.Sprintf(` + resource "openstack_blockstorage_volume_v1" "volume_1" { + name = "volume_1" + size = 1 + } + + resource "openstack_compute_instance_v2" "instance_1" { + name = "instance_1" + security_groups = ["default"] + block_device { + uuid = "%s" + source_type = "image" + volume_size = 2 + boot_index = 0 + destination_type = "volume" + delete_on_termination = true + } + + volume { + volume_id = "${openstack_blockstorage_volume_v1.volume_1.id}" + } + }`, + os.Getenv("OS_IMAGE_ID")) + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckComputeV2InstanceDestroy, + Steps: []resource.TestStep{ + resource.TestStep{ + Config: testAccComputeV2Instance_bootFromVolumeImageWithAttachedVolume, + Check: resource.ComposeTestCheckFunc( + testAccCheckComputeV2InstanceExists(t, "openstack_compute_instance_v2.instance_1", &instance), + ), + }, + }, + }) +} + func TestAccComputeV2Instance_bootFromVolumeVolume(t *testing.T) { var instance servers.Server var testAccComputeV2Instance_bootFromVolumeVolume = fmt.Sprintf(`