github.com/vnpaycloud-console/gophercloud/v2@v2.0.5/internal/acceptance/openstack/image/v2/imageservice.go (about) 1 // Package v2 contains common functions for creating image resources 2 // for use in acceptance tests. See the `*_test.go` files for example usages. 3 package v2 4 5 import ( 6 "context" 7 "io" 8 "net/http" 9 "os" 10 "testing" 11 12 "github.com/vnpaycloud-console/gophercloud/v2" 13 "github.com/vnpaycloud-console/gophercloud/v2/internal/acceptance/tools" 14 "github.com/vnpaycloud-console/gophercloud/v2/openstack/image/v2/imagedata" 15 "github.com/vnpaycloud-console/gophercloud/v2/openstack/image/v2/imageimport" 16 "github.com/vnpaycloud-console/gophercloud/v2/openstack/image/v2/images" 17 "github.com/vnpaycloud-console/gophercloud/v2/openstack/image/v2/tasks" 18 th "github.com/vnpaycloud-console/gophercloud/v2/testhelper" 19 ) 20 21 // CreateEmptyImage will create an image, but with no actual image data. 22 // An error will be returned if an image was unable to be created. 23 func CreateEmptyImage(t *testing.T, client *gophercloud.ServiceClient) (*images.Image, error) { 24 var image *images.Image 25 26 name := tools.RandomString("ACPTTEST", 16) 27 t.Logf("Attempting to create image: %s", name) 28 29 protected := false 30 visibility := images.ImageVisibilityPrivate 31 createOpts := &images.CreateOpts{ 32 Name: name, 33 ContainerFormat: "bare", 34 DiskFormat: "qcow2", 35 MinDisk: 0, 36 MinRAM: 0, 37 Protected: &protected, 38 Visibility: &visibility, 39 Properties: map[string]string{ 40 "architecture": "x86_64", 41 }, 42 Tags: []string{"foo", "bar", "baz"}, 43 } 44 45 image, err := images.Create(context.TODO(), client, createOpts).Extract() 46 if err != nil { 47 return image, err 48 } 49 50 newImage, err := images.Get(context.TODO(), client, image.ID).Extract() 51 if err != nil { 52 return image, err 53 } 54 55 t.Logf("Created image %s: %#v", name, newImage) 56 57 th.CheckEquals(t, newImage.Name, name) 58 th.CheckEquals(t, newImage.Properties["architecture"], "x86_64") 59 return newImage, nil 60 } 61 62 // DeleteImage deletes an image. 63 // A fatal error will occur if the image failed to delete. This works best when 64 // used as a deferred function. 65 func DeleteImage(t *testing.T, client *gophercloud.ServiceClient, image *images.Image) { 66 err := images.Delete(context.TODO(), client, image.ID).ExtractErr() 67 if err != nil { 68 t.Fatalf("Unable to delete image %s: %v", image.ID, err) 69 } 70 71 t.Logf("Deleted image: %s", image.ID) 72 } 73 74 // ImportImageURL contains an URL of a test image that can be imported. 75 const ImportImageURL = "http://download.cirros-cloud.net/0.4.0/cirros-0.4.0-x86_64-disk.img" 76 77 // CreateTask will create a task to import the CirrOS image. 78 // An error will be returned if a task couldn't be created. 79 func CreateTask(t *testing.T, client *gophercloud.ServiceClient, imageURL string) (*tasks.Task, error) { 80 t.Logf("Attempting to create an Image service import task with image: %s", imageURL) 81 opts := tasks.CreateOpts{ 82 Type: "import", 83 Input: map[string]any{ 84 "image_properties": map[string]any{ 85 "container_format": "bare", 86 "disk_format": "raw", 87 }, 88 "import_from_format": "raw", 89 "import_from": imageURL, 90 }, 91 } 92 task, err := tasks.Create(context.TODO(), client, opts).Extract() 93 if err != nil { 94 return nil, err 95 } 96 97 newTask, err := tasks.Get(context.TODO(), client, task.ID).Extract() 98 if err != nil { 99 return nil, err 100 } 101 102 return newTask, nil 103 } 104 105 // GetImportInfo will retrieve Import API information. 106 func GetImportInfo(t *testing.T, client *gophercloud.ServiceClient) (*imageimport.ImportInfo, error) { 107 t.Log("Attempting to get the Image service Import API information") 108 importInfo, err := imageimport.Get(context.TODO(), client).Extract() 109 if err != nil { 110 return nil, err 111 } 112 113 return importInfo, nil 114 } 115 116 // StageImage will stage local image file to the referenced remote queued image. 117 func StageImage(t *testing.T, client *gophercloud.ServiceClient, filepath, imageID string) error { 118 imageData, err := os.Open(filepath) 119 if err != nil { 120 return err 121 } 122 defer imageData.Close() 123 124 return imagedata.Stage(context.TODO(), client, imageID, imageData).ExtractErr() 125 } 126 127 // DownloadImageFileFromURL will download an image from the specified URL and 128 // place it into the specified path. 129 func DownloadImageFileFromURL(t *testing.T, url, filepath string) error { 130 file, err := os.Create(filepath) 131 if err != nil { 132 return err 133 } 134 defer file.Close() 135 136 t.Logf("Attempting to download image from %s", url) 137 resp, err := http.Get(url) 138 if err != nil { 139 return err 140 } 141 defer resp.Body.Close() 142 143 size, err := io.Copy(file, resp.Body) 144 if err != nil { 145 return err 146 } 147 148 t.Logf("Downloaded image with size of %d bytes in %s", size, filepath) 149 return nil 150 } 151 152 // DeleteImageFile will delete local image file. 153 func DeleteImageFile(t *testing.T, filepath string) { 154 err := os.Remove(filepath) 155 if err != nil { 156 t.Fatalf("Unable to delete image file %s", filepath) 157 } 158 159 t.Logf("Successfully deleted image file %s", filepath) 160 } 161 162 // ImportImage will import image data from the remote source to the Image service. 163 func ImportImage(t *testing.T, client *gophercloud.ServiceClient, imageID string) error { 164 importOpts := imageimport.CreateOpts{ 165 Name: imageimport.WebDownloadMethod, 166 URI: ImportImageURL, 167 } 168 169 t.Logf("Attempting to import image data for %s from %s", imageID, importOpts.URI) 170 return imageimport.Create(context.TODO(), client, imageID, importOpts).ExtractErr() 171 }