Skip to content
This repository was archived by the owner on Aug 1, 2023. It is now read-only.

Commit 74d0736

Browse files
author
Jamie Hannaford
committed
Merge pull request #489 from feiskyer/blockstoragev2-volumes
[rfr] Add volumes part of blockstorage v2 API
2 parents 116a4d7 + e028916 commit 74d0736

File tree

20 files changed

+1745
-0
lines changed

20 files changed

+1745
-0
lines changed
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
// The extensions package contains acceptance tests for the Openstack Cinder V2 extensions service.
2+
3+
package extensions
Lines changed: 149 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,149 @@
1+
// +build acceptance blockstorage
2+
3+
package extensions
4+
5+
import (
6+
"os"
7+
"testing"
8+
9+
"github.com/rackspace/gophercloud"
10+
"github.com/rackspace/gophercloud/openstack"
11+
"github.com/rackspace/gophercloud/openstack/blockstorage/v2/extensions/volumeactions"
12+
"github.com/rackspace/gophercloud/openstack/blockstorage/v2/volumes"
13+
th "github.com/rackspace/gophercloud/testhelper"
14+
)
15+
16+
func newClient(t *testing.T) (*gophercloud.ServiceClient, error) {
17+
ao, err := openstack.AuthOptionsFromEnv()
18+
th.AssertNoErr(t, err)
19+
20+
client, err := openstack.AuthenticatedClient(ao)
21+
th.AssertNoErr(t, err)
22+
23+
return openstack.NewBlockStorageV2(client, gophercloud.EndpointOpts{
24+
Region: os.Getenv("OS_REGION_NAME"),
25+
})
26+
}
27+
28+
func TestVolumeAttach(t *testing.T) {
29+
client, err := newClient(t)
30+
th.AssertNoErr(t, err)
31+
32+
t.Logf("Creating volume")
33+
cv, err := volumes.Create(client, &volumes.CreateOpts{
34+
Size: 1,
35+
Name: "blockv2-volume",
36+
}).Extract()
37+
th.AssertNoErr(t, err)
38+
39+
defer func() {
40+
err = volumes.WaitForStatus(client, cv.ID, "available", 60)
41+
th.AssertNoErr(t, err)
42+
43+
t.Logf("Deleting volume")
44+
err = volumes.Delete(client, cv.ID).ExtractErr()
45+
th.AssertNoErr(t, err)
46+
}()
47+
48+
err = volumes.WaitForStatus(client, cv.ID, "available", 60)
49+
th.AssertNoErr(t, err)
50+
51+
instanceID := os.Getenv("OS_INSTANCE_ID")
52+
if instanceID == "" {
53+
t.Fatal("Environment variable OS_INSTANCE_ID is required")
54+
}
55+
56+
t.Logf("Attaching volume")
57+
err = volumeactions.Attach(client, cv.ID, &volumeactions.AttachOpts{
58+
MountPoint: "/mnt",
59+
Mode: "rw",
60+
InstanceUUID: instanceID,
61+
}).ExtractErr()
62+
th.AssertNoErr(t, err)
63+
64+
err = volumes.WaitForStatus(client, cv.ID, "in-use", 60)
65+
th.AssertNoErr(t, err)
66+
67+
t.Logf("Detaching volume")
68+
err = volumeactions.Detach(client, cv.ID).ExtractErr()
69+
th.AssertNoErr(t, err)
70+
}
71+
72+
func TestVolumeReserve(t *testing.T) {
73+
client, err := newClient(t)
74+
th.AssertNoErr(t, err)
75+
76+
t.Logf("Creating volume")
77+
cv, err := volumes.Create(client, &volumes.CreateOpts{
78+
Size: 1,
79+
Name: "blockv2-volume",
80+
}).Extract()
81+
th.AssertNoErr(t, err)
82+
83+
defer func() {
84+
err = volumes.WaitForStatus(client, cv.ID, "available", 60)
85+
th.AssertNoErr(t, err)
86+
87+
t.Logf("Deleting volume")
88+
err = volumes.Delete(client, cv.ID).ExtractErr()
89+
th.AssertNoErr(t, err)
90+
}()
91+
92+
err = volumes.WaitForStatus(client, cv.ID, "available", 60)
93+
th.AssertNoErr(t, err)
94+
95+
t.Logf("Reserving volume")
96+
err = volumeactions.Reserve(client, cv.ID).ExtractErr()
97+
th.AssertNoErr(t, err)
98+
99+
err = volumes.WaitForStatus(client, cv.ID, "attaching", 60)
100+
th.AssertNoErr(t, err)
101+
102+
t.Logf("Unreserving volume")
103+
err = volumeactions.Unreserve(client, cv.ID).ExtractErr()
104+
th.AssertNoErr(t, err)
105+
106+
err = volumes.WaitForStatus(client, cv.ID, "available", 60)
107+
th.AssertNoErr(t, err)
108+
}
109+
110+
func TestVolumeConns(t *testing.T) {
111+
client, err := newClient(t)
112+
th.AssertNoErr(t, err)
113+
114+
t.Logf("Creating volume")
115+
cv, err := volumes.Create(client, &volumes.CreateOpts{
116+
Size: 1,
117+
Name: "blockv2-volume",
118+
}).Extract()
119+
th.AssertNoErr(t, err)
120+
121+
defer func() {
122+
err = volumes.WaitForStatus(client, cv.ID, "available", 60)
123+
th.AssertNoErr(t, err)
124+
125+
t.Logf("Deleting volume")
126+
err = volumes.Delete(client, cv.ID).ExtractErr()
127+
th.AssertNoErr(t, err)
128+
}()
129+
130+
err = volumes.WaitForStatus(client, cv.ID, "available", 60)
131+
th.AssertNoErr(t, err)
132+
133+
connOpts := &volumeactions.ConnectorOpts{
134+
IP: "127.0.0.1",
135+
Host: "stack",
136+
Initiator: "iqn.1994-05.com.redhat:17cf566367d2",
137+
Multipath: false,
138+
Platform: "x86_64",
139+
OSType: "linux2",
140+
}
141+
142+
t.Logf("Initializing connection")
143+
_, err = volumeactions.InitializeConnection(client, cv.ID, connOpts).Extract()
144+
th.AssertNoErr(t, err)
145+
146+
t.Logf("Terminating connection")
147+
err = volumeactions.TerminateConnection(client, cv.ID, connOpts).ExtractErr()
148+
th.AssertNoErr(t, err)
149+
}
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
// The v2 package contains acceptance tests for the Openstack Cinder V2 service.
2+
3+
package v2
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
// +build acceptance blockstorage
2+
3+
package v2
4+
5+
import (
6+
"os"
7+
"testing"
8+
9+
"github.com/rackspace/gophercloud"
10+
"github.com/rackspace/gophercloud/openstack"
11+
"github.com/rackspace/gophercloud/openstack/blockstorage/v2/volumes"
12+
"github.com/rackspace/gophercloud/pagination"
13+
th "github.com/rackspace/gophercloud/testhelper"
14+
)
15+
16+
func newClient(t *testing.T) (*gophercloud.ServiceClient, error) {
17+
ao, err := openstack.AuthOptionsFromEnv()
18+
th.AssertNoErr(t, err)
19+
20+
client, err := openstack.AuthenticatedClient(ao)
21+
th.AssertNoErr(t, err)
22+
23+
return openstack.NewBlockStorageV2(client, gophercloud.EndpointOpts{
24+
Region: os.Getenv("OS_REGION_NAME"),
25+
})
26+
}
27+
28+
func TestVolumes(t *testing.T) {
29+
client, err := newClient(t)
30+
th.AssertNoErr(t, err)
31+
32+
cv, err := volumes.Create(client, &volumes.CreateOpts{
33+
Size: 1,
34+
Name: "blockv2-volume",
35+
}).Extract()
36+
th.AssertNoErr(t, err)
37+
defer func() {
38+
err = volumes.WaitForStatus(client, cv.ID, "available", 60)
39+
th.AssertNoErr(t, err)
40+
err = volumes.Delete(client, cv.ID).ExtractErr()
41+
th.AssertNoErr(t, err)
42+
}()
43+
44+
_, err = volumes.Update(client, cv.ID, &volumes.UpdateOpts{
45+
Name: "blockv2-updated-volume",
46+
}).Extract()
47+
th.AssertNoErr(t, err)
48+
49+
v, err := volumes.Get(client, cv.ID).Extract()
50+
th.AssertNoErr(t, err)
51+
t.Logf("Got volume: %+v\n", v)
52+
53+
if v.Name != "blockv2-updated-volume" {
54+
t.Errorf("Unable to update volume: Expected name: blockv2-updated-volume\nActual name: %s", v.Name)
55+
}
56+
57+
err = volumes.List(client, &volumes.ListOpts{Name: "blockv2-updated-volume"}).EachPage(func(page pagination.Page) (bool, error) {
58+
vols, err := volumes.ExtractVolumes(page)
59+
th.CheckEquals(t, 1, len(vols))
60+
return true, err
61+
})
62+
th.AssertNoErr(t, err)
63+
}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
// Package volumeactions provides information and interaction with volumes in the
2+
// OpenStack Block Storage service. A volume is a detachable block storage
3+
// device, akin to a USB hard drive. It can only be attached to one instance at
4+
// a time.
5+
package volumeactions

0 commit comments

Comments
 (0)