github.com/gophercloud/gophercloud@v1.11.0/internal/acceptance/openstack/compute/v2/bootfromvolume_test.go (about) 1 //go:build acceptance || compute || bootfromvolume 2 // +build acceptance compute bootfromvolume 3 4 package v2 5 6 import ( 7 "testing" 8 9 "github.com/gophercloud/gophercloud/internal/acceptance/clients" 10 blockstorage "github.com/gophercloud/gophercloud/internal/acceptance/openstack/blockstorage/v2" 11 "github.com/gophercloud/gophercloud/internal/acceptance/tools" 12 "github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/bootfromvolume" 13 "github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/volumeattach" 14 th "github.com/gophercloud/gophercloud/testhelper" 15 ) 16 17 func TestBootFromImage(t *testing.T) { 18 clients.RequireLong(t) 19 20 client, err := clients.NewComputeV2Client() 21 th.AssertNoErr(t, err) 22 23 choices, err := clients.AcceptanceTestChoicesFromEnv() 24 th.AssertNoErr(t, err) 25 26 blockDevices := []bootfromvolume.BlockDevice{ 27 { 28 BootIndex: 0, 29 DeleteOnTermination: true, 30 DestinationType: bootfromvolume.DestinationLocal, 31 SourceType: bootfromvolume.SourceImage, 32 UUID: choices.ImageID, 33 }, 34 } 35 36 server, err := CreateBootableVolumeServer(t, client, blockDevices) 37 th.AssertNoErr(t, err) 38 defer DeleteServer(t, client, server) 39 40 tools.PrintResource(t, server) 41 42 th.AssertEquals(t, server.Image["id"], choices.ImageID) 43 } 44 45 func TestBootFromNewVolume(t *testing.T) { 46 clients.RequireLong(t) 47 48 client, err := clients.NewComputeV2Client() 49 th.AssertNoErr(t, err) 50 51 choices, err := clients.AcceptanceTestChoicesFromEnv() 52 th.AssertNoErr(t, err) 53 54 // minimum required microversion for getting volume tags is 2.70 55 // https://docs.openstack.org/nova/latest/reference/api-microversion-history.html#id64 56 client.Microversion = "2.70" 57 58 tagName := "tag1" 59 blockDevices := []bootfromvolume.BlockDevice{ 60 { 61 DeleteOnTermination: true, 62 DestinationType: bootfromvolume.DestinationVolume, 63 SourceType: bootfromvolume.SourceImage, 64 UUID: choices.ImageID, 65 VolumeSize: 2, 66 Tag: tagName, 67 }, 68 } 69 70 server, err := CreateBootableVolumeServer(t, client, blockDevices) 71 th.AssertNoErr(t, err) 72 defer DeleteServer(t, client, server) 73 74 attachPages, err := volumeattach.List(client, server.ID).AllPages() 75 th.AssertNoErr(t, err) 76 77 attachments, err := volumeattach.ExtractVolumeAttachments(attachPages) 78 th.AssertNoErr(t, err) 79 80 tools.PrintResource(t, server) 81 tools.PrintResource(t, attachments) 82 attachmentTag := *attachments[0].Tag 83 th.AssertEquals(t, attachmentTag, tagName) 84 85 if server.Image != nil { 86 t.Fatalf("server image should be nil") 87 } 88 89 th.AssertEquals(t, len(attachments), 1) 90 91 // TODO: volumes_attached extension 92 } 93 94 func TestBootFromExistingVolume(t *testing.T) { 95 clients.RequireLong(t) 96 97 computeClient, err := clients.NewComputeV2Client() 98 th.AssertNoErr(t, err) 99 100 blockStorageClient, err := clients.NewBlockStorageV3Client() 101 th.AssertNoErr(t, err) 102 103 volume, err := blockstorage.CreateVolumeFromImage(t, blockStorageClient) 104 th.AssertNoErr(t, err) 105 106 tools.PrintResource(t, volume) 107 108 blockDevices := []bootfromvolume.BlockDevice{ 109 { 110 DeleteOnTermination: true, 111 DestinationType: bootfromvolume.DestinationVolume, 112 SourceType: bootfromvolume.SourceVolume, 113 UUID: volume.ID, 114 }, 115 } 116 117 server, err := CreateBootableVolumeServer(t, computeClient, blockDevices) 118 th.AssertNoErr(t, err) 119 defer DeleteServer(t, computeClient, server) 120 121 attachPages, err := volumeattach.List(computeClient, server.ID).AllPages() 122 th.AssertNoErr(t, err) 123 124 attachments, err := volumeattach.ExtractVolumeAttachments(attachPages) 125 th.AssertNoErr(t, err) 126 127 tools.PrintResource(t, server) 128 tools.PrintResource(t, attachments) 129 130 if server.Image != nil { 131 t.Fatalf("server image should be nil") 132 } 133 134 th.AssertEquals(t, len(attachments), 1) 135 th.AssertEquals(t, attachments[0].VolumeID, volume.ID) 136 // TODO: volumes_attached extension 137 } 138 139 func TestBootFromMultiEphemeralServer(t *testing.T) { 140 clients.RequireLong(t) 141 142 client, err := clients.NewComputeV2Client() 143 th.AssertNoErr(t, err) 144 145 choices, err := clients.AcceptanceTestChoicesFromEnv() 146 th.AssertNoErr(t, err) 147 148 blockDevices := []bootfromvolume.BlockDevice{ 149 { 150 BootIndex: 0, 151 DestinationType: bootfromvolume.DestinationLocal, 152 DeleteOnTermination: true, 153 SourceType: bootfromvolume.SourceImage, 154 UUID: choices.ImageID, 155 VolumeSize: 5, 156 }, 157 { 158 BootIndex: -1, 159 DestinationType: bootfromvolume.DestinationLocal, 160 DeleteOnTermination: true, 161 GuestFormat: "ext4", 162 SourceType: bootfromvolume.SourceBlank, 163 VolumeSize: 1, 164 }, 165 { 166 BootIndex: -1, 167 DestinationType: bootfromvolume.DestinationLocal, 168 DeleteOnTermination: true, 169 GuestFormat: "ext4", 170 SourceType: bootfromvolume.SourceBlank, 171 VolumeSize: 1, 172 }, 173 } 174 175 server, err := CreateMultiEphemeralServer(t, client, blockDevices) 176 th.AssertNoErr(t, err) 177 defer DeleteServer(t, client, server) 178 179 tools.PrintResource(t, server) 180 } 181 182 func TestAttachNewVolume(t *testing.T) { 183 clients.RequireLong(t) 184 185 client, err := clients.NewComputeV2Client() 186 th.AssertNoErr(t, err) 187 188 choices, err := clients.AcceptanceTestChoicesFromEnv() 189 th.AssertNoErr(t, err) 190 191 blockDevices := []bootfromvolume.BlockDevice{ 192 { 193 BootIndex: 0, 194 DeleteOnTermination: true, 195 DestinationType: bootfromvolume.DestinationLocal, 196 SourceType: bootfromvolume.SourceImage, 197 UUID: choices.ImageID, 198 }, 199 { 200 BootIndex: 1, 201 DeleteOnTermination: true, 202 DestinationType: bootfromvolume.DestinationVolume, 203 SourceType: bootfromvolume.SourceBlank, 204 VolumeSize: 2, 205 }, 206 } 207 208 server, err := CreateBootableVolumeServer(t, client, blockDevices) 209 th.AssertNoErr(t, err) 210 defer DeleteServer(t, client, server) 211 212 attachPages, err := volumeattach.List(client, server.ID).AllPages() 213 th.AssertNoErr(t, err) 214 215 attachments, err := volumeattach.ExtractVolumeAttachments(attachPages) 216 th.AssertNoErr(t, err) 217 218 tools.PrintResource(t, server) 219 tools.PrintResource(t, attachments) 220 221 th.AssertEquals(t, server.Image["id"], choices.ImageID) 222 th.AssertEquals(t, len(attachments), 1) 223 224 // TODO: volumes_attached extension 225 } 226 227 func TestAttachExistingVolume(t *testing.T) { 228 clients.RequireLong(t) 229 230 computeClient, err := clients.NewComputeV2Client() 231 th.AssertNoErr(t, err) 232 233 blockStorageClient, err := clients.NewBlockStorageV3Client() 234 th.AssertNoErr(t, err) 235 236 choices, err := clients.AcceptanceTestChoicesFromEnv() 237 th.AssertNoErr(t, err) 238 239 volume, err := blockstorage.CreateVolume(t, blockStorageClient) 240 th.AssertNoErr(t, err) 241 242 blockDevices := []bootfromvolume.BlockDevice{ 243 { 244 BootIndex: 0, 245 DeleteOnTermination: true, 246 DestinationType: bootfromvolume.DestinationLocal, 247 SourceType: bootfromvolume.SourceImage, 248 UUID: choices.ImageID, 249 }, 250 { 251 BootIndex: 1, 252 DeleteOnTermination: true, 253 DestinationType: bootfromvolume.DestinationVolume, 254 SourceType: bootfromvolume.SourceVolume, 255 UUID: volume.ID, 256 }, 257 } 258 259 server, err := CreateBootableVolumeServer(t, computeClient, blockDevices) 260 th.AssertNoErr(t, err) 261 defer DeleteServer(t, computeClient, server) 262 263 attachPages, err := volumeattach.List(computeClient, server.ID).AllPages() 264 th.AssertNoErr(t, err) 265 266 attachments, err := volumeattach.ExtractVolumeAttachments(attachPages) 267 th.AssertNoErr(t, err) 268 269 tools.PrintResource(t, server) 270 tools.PrintResource(t, attachments) 271 272 th.AssertEquals(t, server.Image["id"], choices.ImageID) 273 th.AssertEquals(t, len(attachments), 1) 274 th.AssertEquals(t, attachments[0].VolumeID, volume.ID) 275 276 // TODO: volumes_attached extension 277 } 278 279 func TestBootFromNewCustomizedVolume(t *testing.T) { 280 if testing.Short() { 281 t.Skip("Skipping test that requires server creation in short mode.") 282 } 283 284 client, err := clients.NewComputeV2Client() 285 if err != nil { 286 t.Fatalf("Unable to create a compute client: %v", err) 287 } 288 289 choices, err := clients.AcceptanceTestChoicesFromEnv() 290 if err != nil { 291 t.Fatal(err) 292 } 293 294 blockDevices := []bootfromvolume.BlockDevice{ 295 { 296 DeleteOnTermination: true, 297 DestinationType: bootfromvolume.DestinationVolume, 298 SourceType: bootfromvolume.SourceImage, 299 UUID: choices.ImageID, 300 VolumeSize: 2, 301 DeviceType: "disk", 302 DiskBus: "virtio", 303 }, 304 } 305 306 server, err := CreateBootableVolumeServer(t, client, blockDevices) 307 if err != nil { 308 t.Fatalf("Unable to create server: %v", err) 309 } 310 defer DeleteServer(t, client, server) 311 312 tools.PrintResource(t, server) 313 }