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