github.com/sneal/packer@v0.5.2/builder/openstack/step_create_image.go (about) 1 package openstack 2 3 import ( 4 "fmt" 5 "github.com/mitchellh/multistep" 6 "github.com/mitchellh/packer/packer" 7 "github.com/rackspace/gophercloud" 8 "log" 9 "time" 10 ) 11 12 type stepCreateImage struct{} 13 14 func (s *stepCreateImage) Run(state multistep.StateBag) multistep.StepAction { 15 csp := state.Get("csp").(gophercloud.CloudServersProvider) 16 config := state.Get("config").(config) 17 server := state.Get("server").(*gophercloud.Server) 18 ui := state.Get("ui").(packer.Ui) 19 20 // Create the image 21 ui.Say(fmt.Sprintf("Creating the image: %s", config.ImageName)) 22 createOpts := gophercloud.CreateImage{ 23 Name: config.ImageName, 24 } 25 imageId, err := csp.CreateImage(server.Id, createOpts) 26 if err != nil { 27 err := fmt.Errorf("Error creating image: %s", err) 28 state.Put("error", err) 29 ui.Error(err.Error()) 30 return multistep.ActionHalt 31 } 32 33 // Set the Image ID in the state 34 ui.Say(fmt.Sprintf("Image: %s", imageId)) 35 state.Put("image", imageId) 36 37 // Wait for the image to become ready 38 ui.Say("Waiting for image to become ready...") 39 if err := WaitForImage(csp, imageId); err != nil { 40 err := fmt.Errorf("Error waiting for image: %s", err) 41 state.Put("error", err) 42 ui.Error(err.Error()) 43 return multistep.ActionHalt 44 } 45 46 return multistep.ActionContinue 47 } 48 49 func (s *stepCreateImage) Cleanup(multistep.StateBag) { 50 // No cleanup... 51 } 52 53 // WaitForImage waits for the given Image ID to become ready. 54 func WaitForImage(csp gophercloud.CloudServersProvider, imageId string) error { 55 for { 56 image, err := csp.ImageById(imageId) 57 if err != nil { 58 return err 59 } 60 61 if image.Status == "ACTIVE" { 62 return nil 63 } 64 65 log.Printf("Waiting for image creation status: %s (%d%%)", image.Status, image.Progress) 66 time.Sleep(2 * time.Second) 67 } 68 }