Servers

Server is the main resource in the Compute API. It represents a virtual machine.

More information can be found in the official documentation.

In order to work with servers you have to create the service first.

List

To list a collection of servers, you run:

$compute = $openstack->computeV2();

$servers = $compute->listServers();

foreach ($servers as $server) {
}

Each iteration will return a :apiref:Server instance <OpenStack/Compute/v2/Models/Server.html>.

By default, PHP generators are used to represent collections of resources in the SDK. The benefit of using generators is that it generally improves performance, since objects are not saved in memory as the iteration cycle goes on; instead, each resource is directly output to the user-defined foreach loop. For all intents and purposes, you interact with generators like any other Traversable object, but to retain collections in memory, you will need to implement your own logic.

Detailed information

By default, only the id, links and name attributes are returned by the server. To return all information for a server, you must enable detailed information, like so:

$servers = $service->listServers(true);

Filtering collections

By default, every server will be returned by the remote API. To filter the returned collection, you can provide query parameters which are documented in the reference documentation.

use OpenStack\Common\DateTime;

$servers = $service->listServers(false, [
    'changesSince' => DateTime::factory('yesterday')->toIso8601(),
    'flavorId'     => 'performance1-1',
]);

Create

The only attributes that are required when creating a server are a name, flavor ID and image ID. The simplest example would therefore be this:

$compute = $openstack->computeV2();

$options = [
    // Required
    'name'     => '{serverName}',
    'imageId'  => '{imageId}',
    'flavorId' => '{flavorId}',

    // Required if multiple network is defined
    'networks'  => [
        ['uuid' => '{networkId}']
    ],

    // Optional
    'metadata' => ['foo' => 'bar'],
    'userData' => base64_encode('echo "Hello World. The time is now $(date -R)!" | tee /root/output.txt')
];

// Create the server
$server = $compute->createServer($options);

You can further configure your new server, however, by following the below sections, which instruct you how to add specific functionality. They are interoperable and can work together.

Security groups

You can associate your new server with pre-existing security groups by specifying their _name_. One server can be associated with multiple security groups:

$options['securityGroups'] = ['secGroup1', 'default', 'secGroup2'];

Networks

By default, the server instance is provisioned with all isolated networks for the tenant. You can, however, configure access by specifying which networks your VM is connected to. To do this, you can either:

  • specify the UUID of a Neutron network. This is required if you omit the port ID.

  • specify the UUID of a Neutron port. This is required if you omit the network ID. The port must exist and be in a DOWN state.

// Specifying the network
$options['networks'] = [
    ['uuid' => '{network1Id}'],
    ['uuid' => '{network2Id}'],
];

// Or, specifying the port:
$options['networks'] = [
    ['port' => '{port1Id}'],
    ['port' => '{port2Id}'],
];

External devices and boot from volume

This option allows for the booting of the server from a volume. If specified, the volume status must be available, and the volume attach_status in the OpenStack Block Storage DB must be detached.

For example, to boot a server from a Cinder volume:

$options['blockDeviceMapping'] = [
    [
        'deviceName'      => '/dev/sda1',
        'sourceType'      => 'volume',
        'destinationType' => 'volume',
        'uuid'            => '{volumeId}',
        'bootIndex'       => 0,
    ]
];

Personality files

Servers, as they’re created, can be injected with arbitrary file data. To do this, you must specify the path and file contents (text only) to inject into the server at launch. The maximum size of the file path data is 255 bytes. The maximum limit refers to the number of bytes in the decoded data and not the number of characters in the encoded data.

The contents must be base-64 encoded.

$options['personality'] = [
    'path'     => '/etc/banner.txt',
    'contents' => base64_encode('echo "Hi!";'),
];

Metadata

The API also supports the ability to label servers with arbitrary key/value pairs, known as metadata. To specify this when the server is launched, use this option:

$options['metadata'] = [
    'foo' => 'bar',
    'baz' => 'bar',
];

Read

$compute = $openstack->computeV2();

$server = $compute->getServer(['id' => '{serverId}']);
$server->retrieve();

Update

The first step when updating a server is modifying the attributes you want updated. By default, only a server’s name, IPv4 and IPv6 IPs, and its auto disk config attributes can be edited.

$compute = $openstack->computeV2();

$server = $compute->getServer(['id' => '{serverId}']);

$server->name = '{newName}';
$server->update();

Delete

To permanently delete a server:

$compute = $openstack->computeV2();

$server = $compute->getServer(['id' => '{serverId}']);

$server->delete();

Retrieve metadata

This operation will retrieve the existing metadata for a server:

$compute = $openstack->computeV2(['region' => '{region}']);

$server = $compute->getServer(['id' => '{serverId}']);

$metadata = $server->getMetadata();

Reset metadata

This operation will _replace_ all existing metadata with whatever is provided in the request. Any existing metadata not specified in the request will be deleted.

$compute = $openstack->computeV2(['region' => '{region}']);

$server = $compute->getServer(['id' => '{serverId}']);

$server->resetMetadata([
    '{key}' => '{value}',
]);

Merge metadata

This operation will _merge_ specified metadata with what already exists. Existing values will be overriden, new values will be added. Any existing keys that are not specified in the request will remain unaffected.

$compute = $openstack->computeV2(['region' => '{region}']);

$server = $compute->getServer(['id' => '{serverId}']);

$server->mergeMetadata([
    '{key}' => '{value}'
]);

Retrieve metadata item

This operation allows you to retrieve the value for a specific metadata item:

$compute = $openstack->computeV2(['region' => '{region}']);

$server = $compute->getServer(['id' => '{serverId}']);

$metadataItem = $server->getMetadataItem('{metadataItem}');

Delete metadata item

This operation allows you to remove a specific metadata item:

$compute = $openstack->computeV2(['region' => '{region}']);

$server = $compute->getServer(['id' => '{serverId}']);

$server->deleteMetadataItem('{key}');

Change root password

This operation will replace the root password for a server.

$compute = $openstack->computeV2(['region' => '{region}']);

$server = $compute->getServer(['id' => '{serverId}']);

$server->changePassword('{newPassword}');

Reset server state

This operation will reset the state of the server.

$compute = $openstack->computeV2(['region' => '{region}']);

$server = $compute->getServer([
    'id' => '{serverId}',
]);

$server->resetState();

Reboot server

This operation will reboot a server. You can specify HARD reboot by passing argument Enum::REBOOT_HARD to the function. Otherwise, the default is a SOFT reboot.

$compute = $openstack->computeV2(['region' => '{region}']);

$server = $compute->getServer(['id' => '{serverId}']);

$server->reboot(\OpenStack\Compute\v2\Enum::REBOOT_HARD);

Rebuild server

Rebuilding a server will re-initialize the booting procedure for the server and effectively reinstall the operating system. It will shutdown, re-image and then reboot your instance. Any data saved on your instance will be lost when the rebuild is performed.

$compute = $openstack->computeV2(['region' => '{region}']);

$server = $compute->getServer(['id' => '{serverId}']);

$server->rebuild([
    'imageId'   => '{imageId}',
    'name'      => '{newName}',
    'adminPass' => '{adminPass}',
]);

Resize server

You can resize the flavor of a server by performing this operation. As soon the operation completes, the server will transition to a VERIFY_RESIZE state and a VM status of RESIZED. You will either need to confirm or revert the resize in order to continue.

$compute = $openstack->computeV2(['region' => '{region}']);

$server = $compute->getServer([
    'id' => '{serverId}',
]);

$server->resize('{flavorId}');

Confirm server resize

Once a server has been resized, you can confirm the operation by calling this. The server must have the status of VERIFY_RESIZE and a VM status of RESIZED. Once this operation completes, the server should transition to an ACTIVE state and a migration status of confirmed.

$compute = $openstack->computeV2(['region' => '{region}']);

$server = $compute->getServer([
    'id' => '{serverId}',
]);

$server->waitUntil('VERIFY_RESIZE');
$server->confirmResize();

Revert server resize

Once a server has been resized, you can revert the operation by calling this. The server must have the status of VERIFY_RESIZE and a VM status of RESIZED. Once this operation completes, the server should transition to an ACTIVE state and a migration status of reverted.

$compute = $openstack->computeV2(['region' => '{region}']);

$server = $compute->getServer([
    'id' => '{serverId}',
]);

$server->waitUntil('VERIFY_RESIZE');
$server->revertResize();

Create server image

This operation will create a new server image. The only required option is the new image’s name. You may also specify additional metadata:

$compute = $openstack->computeV2(['region' => '{region}']);

$server = $compute->getServer(['id' => '{serverId}']);

$server->createImage([
    'name' => '{imageName}',
]);

List server IP addresses

To list all the addresses for a specified server or a specified server and network:

$ipAddresses = $server->listAddresses();

$public  = $ipAddresses['public'];
$private = $ipAddresses['private'];

You can also refine by network label:

$ipAddresses = $server->listAddresses([
    'networkLabel' => '{networkLabel}',
]);

Suspend

$service = $openstack->computeV2();
$server = $service->getServer(['id' => '{serverId}']);

$server->suspend();

Resume

$service = $openstack->computeV2();
$server = $service->getServer(['id' => '{serverId}']);

$server->resume();