Skip to content

Commit 90b8ab5

Browse files
committed
Merge pull request #407 from ycombinator/bfv
Boot from volume support
2 parents 8107e3c + 6832be7 commit 90b8ab5

File tree

6 files changed

+191
-6
lines changed

6 files changed

+191
-6
lines changed

docs/userguide/Compute/Server.md

Lines changed: 43 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,9 @@ RAX-SI:image_schedule|If scheduled images enabled or not. If the value is TRUE,
4747

4848
## Create server
4949

50-
There are a few parameter requirements when creating a server:
50+
### Using an image
51+
52+
There are a few parameter requirements when creating a server using an image:
5153

5254
* **name** - needs to be a string;
5355
- **flavor** - a `OpenCloud\Compute\Resource\Flavor` object, that is populated with the values of a real API flavor;
@@ -86,13 +88,52 @@ try {
8688

8789
It's always best to be defensive when executing functionality over HTTP; you can achieve this best by wrapping calls in a try/catch block. It allows you to debug your failed operations in a graceful and efficient manner.
8890

91+
### Using a bootable volume
92+
93+
There are a few parameter requirements when creating a server using a bootable volume:
94+
95+
* **name** - needs to be a string;
96+
* **flavor** - a `OpenCloud\Compute\Resource\Flavor` object, that is populated with the values of a real API flavor;
97+
* **volume** - a `OpenCloud\Volume\Resource\Volume` object, that is populated with the values of a real API volume;
98+
99+
Firstly we need to find our flavor and volume using their IDs.
100+
101+
```php
102+
$volumeService = $client->volumeService();
103+
$bootableVolume = $volumeService->volume('<ID OF A BOOTABLE VOLUME>');
104+
$flavor = $compute->flavor('<ID OF A FLAVOR>');
105+
```
106+
107+
Now we're ready to create our instance:
108+
109+
```php
110+
use OpenCloud\Compute\Constants\Network;
111+
112+
$server = $compute->server();
113+
114+
try {
115+
$response = $server->create(array(
116+
'name' => 'My lovely server',
117+
'volume' => $bootableVolume,
118+
'flavor' => $flavor
119+
));
120+
} catch (\Guzzle\Http\Exception\BadResponseException $e) {
121+
// No! Something failed. Let's find out:
122+
echo $e->getRequest() . PHP_EOL . PHP_EOL;
123+
echo $e->getResponse();
124+
}
125+
```
126+
127+
It's always best to be defensive when executing functionality over HTTP; you can achieve this best by wrapping calls in a try/catch block. It allows you to debug your failed operations in a graceful and efficient manner.
128+
89129
### Create parameters
90130

91131
Name|Description|Type|Required
92132
---|---|---|---
93133
name|The server name. The name that you specify in a create request becomes the initial host name of the server. After the server is built, if you change the server name in the API or change the host name directly, the names are not kept in sync.|string|Yes
94134
flavor|A populated `OpenCloud\Compute\Resource\Flavor` object representing your chosen flavor|object|Yes
95-
image|A populated `OpenCloud\Compute\Resource\Image` object representing your chosen image|object|Yes
135+
image|A populated `OpenCloud\Compute\Resource\Image` object representing your chosen image|object|No, if volume is specified
136+
volume|A populated `OpenCloud\Volume\Resource\Volume` object representing your chosen bootable volume|object|No, if image is specified
96137
OS-DCF:diskConfig|The disk configuration value. You can use two options: `AUTO` or `MANUAL`. <br><br>`AUTO` means the server is built with a single partition the size of the target flavor disk. The file system is automatically adjusted to fit the entire partition. This keeps things simple and automated. `AUTO` is valid only for images and servers with a single partition that use the EXT3 file system. This is the default setting for applicable Rackspace base images.<br><br>`MANUAL` means the server is built using whatever partition scheme and file system is in the source image. If the target flavor disk is larger, the remaining disk space is left unpartitioned. This enables images to have non-EXT3 file systems, multiple partitions, and so on, and enables you to manage the disk configuration.|string|No
97138
networks|An array of populated `OpenCloud\Compute\Resource\Network` objects that indicate which networks your instance resides in.|array|No
98139
metadata|An array of arbitrary data (key-value pairs) that adds additional meaning to your server.|array|No

lib/OpenCloud/Compute/Resource/Server.php

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,13 @@ class Server extends NovaResource implements HasPtrRecordsInterface
7676
*/
7777
public $image;
7878

79+
/**
80+
* The bootable volume for this server.
81+
*
82+
* @var Volume
83+
*/
84+
public $volume;
85+
7986
/**
8087
* The Flavor for this server.
8188
*
@@ -649,6 +656,17 @@ protected function createJson()
649656
$server->metadata = $this->metadata->toArray();
650657
}
651658

659+
// Boot from volume
660+
if ($this->volume instanceof Volume) {
661+
$server->block_device_mapping_v2 = array();
662+
$server->block_device_mapping_v2[] = (object) array(
663+
'source_type' => 'volume',
664+
'destination_type' => 'volume',
665+
'uuid' => $this->volume->id,
666+
'boot_index' => 0
667+
);
668+
}
669+
652670
// Networks
653671
if (is_array($this->networks) && count($this->networks)) {
654672

lib/OpenCloud/Volume/Resource/Volume.php

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -38,10 +38,6 @@ class Volume extends PersistentResource
3838
public $attachments = array();
3939
public $created_at;
4040
public $source_volid;
41-
42-
/**
43-
* OpenStack only
44-
*/
4541
public $imageRef;
4642
public $bootable;
4743

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
<?php
2+
3+
/*
4+
* Copyright 2014 Rackspace US, Inc.
5+
*
6+
* Licensed under the Apache License, Version 2.0 (the "License");
7+
* you may not use this file except in compliance with the License.
8+
* You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing, software
13+
* distributed under the License is distributed on an "AS IS" BASIS,
14+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
* See the License for the specific language governing permissions and
16+
* limitations under the License.
17+
*/
18+
19+
/**
20+
* Pre-requisites:
21+
*
22+
* Prior to running this script, you must setup the following environment variables:
23+
* - RAX_USERNAME: Your Rackspace Cloud Account Username,
24+
* - RAX_API_KEY: Your Rackspace Cloud Account API Key,
25+
* - RAX_REGION: Rackspace Cloud region in which to create server; e.g.: DFW,
26+
* - RAX_BOOTABLE_VOLUME_ID: ID of bootable volume in Rackspace Cloud region, and
27+
* - RAX_FLAVOR_ID: ID of a compute flavor (performance or higher) in the Rackspace Cloud; e.g.: performance1-1.
28+
*
29+
* - You have an existing keypair. For this script, it will be called 'my_keypair'
30+
* but this will change depending on what you called yours.
31+
*/
32+
33+
require __DIR__ . '/../../vendor/autoload.php';
34+
35+
use OpenCloud\Rackspace;
36+
use Guzzle\Http\Exception\BadResponseException;
37+
38+
// 1. Instantiate a Rackspace client.
39+
$client = new Rackspace(Rackspace::US_IDENTITY_ENDPOINT, array(
40+
'username' => getenv('RAX_USERNAME'),
41+
'apiKey' => getenv('RAX_API_KEY')
42+
));
43+
44+
// 2. Create Compute service
45+
$region = getenv('RAX_REGION');
46+
$computeService = $client->computeService(null, $region);
47+
$volumeService = $client->volumeService(null, $region);
48+
49+
// 3. Get empty server
50+
$server = $computeService->server();
51+
52+
// 4. Select bootable volume
53+
$bootableVolume = $volumeService->volume(getenv('RAX_BOOTABLE_VOLUME_ID'));
54+
55+
// 5. Select a hardware flavor
56+
$flavor = $computeService->flavor(getenv('RAX_FLAVOR_ID'));
57+
58+
// 6. Create
59+
try {
60+
$response = $server->create(array(
61+
'name' => 'My server created from a bootable volume',
62+
'volume' => $bootableVolume,
63+
'flavor' => $flavor
64+
));
65+
} catch (BadResponseException $e) {
66+
// No! Something failed. Let's find out:
67+
echo $e->getRequest() . PHP_EOL . PHP_EOL;
68+
echo $e->getResponse();
69+
}

samples/Compute/list_servers.php

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
<?php
2+
/**
3+
* Copyright 2012-2014 Rackspace US, Inc.
4+
*
5+
* Licensed under the Apache License, Version 2.0 (the "License");
6+
* you may not use this file except in compliance with the License.
7+
* You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
18+
//
19+
// Pre-requisites:
20+
// * Prior to running this script, you must setup the following environment variables:
21+
// * RAX_USERNAME: Your Rackspace Cloud Account Username, and
22+
// * RAX_API_KEY: Your Rackspace Cloud Account API Key, and
23+
//
24+
25+
require __DIR__ . '/../../vendor/autoload.php';
26+
use OpenCloud\Rackspace;
27+
28+
// 1. Instantiate a Rackspace client.
29+
$client = new Rackspace(Rackspace::US_IDENTITY_ENDPOINT, array(
30+
'username' => getenv('RAX_USERNAME'),
31+
'apiKey' => getenv('RAX_API_KEY')
32+
));
33+
34+
// 2. Obtain a Compute service object from the client.
35+
$region = 'DFW';
36+
$computeService = $client->computeService(null, $region);
37+
38+
// 3. Get the list of servers.
39+
$serverList = $computeService->serverList();
40+
41+
foreach ($serverList as $server) {
42+
echo str_repeat("-", 80) . PHP_EOL;
43+
echo "ID: " . $server->id() . " | "
44+
. "Name: " . $server->name() . " | "
45+
. "Image ID: " . $server->image->id . PHP_EOL;
46+
echo str_repeat("-", 80) . PHP_EOL;
47+
}

tests/OpenCloud/Tests/Compute/Resource/ServerTest.php

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -333,4 +333,18 @@ public function test_Create_Fails_Without_Correct_Networks()
333333
)
334334
));
335335
}
336+
337+
public function test_Create_With_Bootable_Volume()
338+
{
339+
$new = new PublicServer($this->service);
340+
$new->volume = new Volume($this->service, '5286e0c0-4906-11e4-916c-0800200c9a66');
341+
342+
$json = $new->createJson();
343+
$obj = $json->server->block_device_mapping_v2[0];
344+
345+
$this->assertEquals('5286e0c0-4906-11e4-916c-0800200c9a66', $obj->uuid);
346+
$this->assertEquals('volume', $obj->source_type);
347+
$this->assertEquals('volume', $obj->destination_type);
348+
$this->assertEquals(0, $obj->boot_index);
349+
}
336350
}

0 commit comments

Comments
 (0)