// WaitForImage waits for the given Image ID to become ready. func WaitForImage(client *gophercloud.ServiceClient, imageId string) error { maxNumErrors := 10 numErrors := 0 for { image, err := images.Get(client, imageId).Extract() if err != nil { errCode, ok := err.(*gophercloud.ErrUnexpectedResponseCode) if ok && (errCode.Actual == 500 || errCode.Actual == 404) { numErrors++ if numErrors >= maxNumErrors { log.Printf("[ERROR] Maximum number of errors (%d) reached; failing with: %s", numErrors, err) return err } log.Printf("[ERROR] %d error received, will ignore and retry: %s", errCode.Actual, err) time.Sleep(2 * time.Second) continue } return err } if image.Status == "ACTIVE" { return nil } log.Printf("Waiting for image creation status: %s (%d%%)", image.Status, image.Progress) time.Sleep(2 * time.Second) } }
func TestGetImage(t *testing.T) { th.SetupHTTP() defer th.TeardownHTTP() th.Mux.HandleFunc("/images/12345678", func(w http.ResponseWriter, r *http.Request) { th.TestMethod(t, r, "GET") th.TestHeader(t, r, "X-Auth-Token", fake.TokenID) w.Header().Add("Content-Type", "application/json") fmt.Fprintf(w, ` { "image": { "status": "ACTIVE", "updated": "2014-09-23T12:54:56Z", "id": "f3e4a95d-1f4f-4989-97ce-f3a1fb8c04d7", "OS-EXT-IMG-SIZE:size": 476704768, "name": "F17-x86_64-cfntools", "created": "2014-09-23T12:54:52Z", "minDisk": 0, "progress": 100, "minRam": 0 } } `) }) actual, err := images.Get(fake.ServiceClient(), "12345678").Extract() if err != nil { t.Fatalf("Unexpected error from Get: %v", err) } expected := &images.Image{ Status: "ACTIVE", Updated: "2014-09-23T12:54:56Z", ID: "f3e4a95d-1f4f-4989-97ce-f3a1fb8c04d7", Name: "F17-x86_64-cfntools", Created: "2014-09-23T12:54:52Z", MinDisk: 0, Progress: 100, MinRAM: 0, } if !reflect.DeepEqual(expected, actual) { t.Errorf("Expected %#v, but got %#v", expected, actual) } }
func TestImagesGet(t *testing.T) { client, err := clients.NewComputeV2Client() if err != nil { t.Fatalf("Unable to create a compute: client: %v", err) } choices, err := clients.AcceptanceTestChoicesFromEnv() if err != nil { t.Fatal(err) } image, err := images.Get(client, choices.ImageID).Extract() if err != nil { t.Fatalf("Unable to get image information: %v", err) } PrintImage(t, *image) }
func setImageInformation(computeClient *gophercloud.ServiceClient, server *servers.Server, d *schema.ResourceData) error { // If block_device was used, an Image does not need to be specified, unless an image/local // combination was used. This emulates normal boot behavior. Otherwise, ignore the image altogether. if vL, ok := d.GetOk("block_device"); ok { needImage := false for _, v := range vL.([]interface{}) { vM := v.(map[string]interface{}) if vM["source_type"] == "image" && vM["destination_type"] == "local" { needImage = true } } if !needImage { d.Set("image_id", "Attempt to boot from volume - no image supplied") return nil } } imageId := server.Image["id"].(string) if imageId != "" { d.Set("image_id", imageId) if image, err := images.Get(computeClient, imageId).Extract(); err != nil { if _, ok := err.(gophercloud.ErrDefault404); ok { // If the image name can't be found, set the value to "Image not found". // The most likely scenario is that the image no longer exists in the Image Service // but the instance still has a record from when it existed. d.Set("image_name", "Image not found") return nil } return err } else { d.Set("image_name", image.Name) } } return nil }