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