github.phpd.cn/hashicorp/packer@v1.3.2/builder/openstack/step_detach_volume.go (about) 1 package openstack 2 3 import ( 4 "context" 5 "fmt" 6 7 "github.com/gophercloud/gophercloud/openstack/blockstorage/extensions/volumeactions" 8 "github.com/hashicorp/packer/helper/multistep" 9 "github.com/hashicorp/packer/packer" 10 ) 11 12 type StepDetachVolume struct { 13 UseBlockStorageVolume bool 14 } 15 16 func (s *StepDetachVolume) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { 17 // Proceed only if block storage volume is used. 18 if !s.UseBlockStorageVolume { 19 return multistep.ActionContinue 20 } 21 22 config := state.Get("config").(*Config) 23 ui := state.Get("ui").(packer.Ui) 24 25 blockStorageClient, err := config.blockStorageV3Client() 26 if err != nil { 27 err = fmt.Errorf("Error initializing block storage client: %s", err) 28 state.Put("error", err) 29 return multistep.ActionHalt 30 } 31 32 volume := state.Get("volume_id").(string) 33 ui.Say(fmt.Sprintf("Detaching volume %s (volume id: %s)", config.VolumeName, volume)) 34 if err := volumeactions.Detach(blockStorageClient, volume, volumeactions.DetachOpts{}).ExtractErr(); err != nil { 35 err = fmt.Errorf("Error detaching block storage volume: %s", err) 36 state.Put("error", err) 37 return multistep.ActionHalt 38 } 39 40 // Wait for volume to become available. 41 ui.Say(fmt.Sprintf("Waiting for volume %s (volume id: %s) to become available...", config.VolumeName, volume)) 42 if err := WaitForVolume(blockStorageClient, volume); err != nil { 43 err := fmt.Errorf("Error waiting for volume: %s", err) 44 state.Put("error", err) 45 ui.Error(err.Error()) 46 return multistep.ActionHalt 47 } 48 49 return multistep.ActionContinue 50 } 51 52 func (s *StepDetachVolume) Cleanup(multistep.StateBag) { 53 // No cleanup. 54 }