This chapter defines the modules and classes of the Ruby Software Development Kit and describes their usage.
Classes
The OvirtSDK4 module contains the following software development kit classes:
- Connection
-
The Connection class is the mechanism for connecting to the server and obtaining the reference to the root of the services tree. See Connecting to the server for details.
- Types
-
The Type classes implement the types supported by the API. For example, the Vm class is the implementation of the virtual machine type. The classes are data containers and do not contain any logic. You will be working with instances of types.
Instances of these classes are used as parameters and return values of service methods. The conversion to or from the underlying representation is handled transparently by the software development kit.
- Services
-
The Service classes implement the services supported by the API. For example, the VmsService class is the implementation of the service that manages the collection of virtual machines in the system.
Instances of these classes are automatically created by the SDK when a service is referenced. For example, a new instance of the
VmsService
class is created automatically by the SDK when you call thevms_service
method of theSystemService
class:vms_service = connection.system_service.vms_service
Do not create instances of these classes manually. The constructor parameters and methods may change in the future. |
- Error
-
The Error class is the base exception class that the software development kit raises when it reports an error.
Certain specific error classes extend the base error class:
-
AuthError - Authentication or authorization failure
-
ConnectionError - Server name cannot be resolved or server is unreachable
-
NotFoundError - Requested object does not exist
-
TimeoutError - Operation time-out
-
- Other Classes
-
Other classes (for example, HTTP client classes, readers, and writers) are used for HTTP communication and for XML parsing and rendering. Using these classes is not recommended, because they comprise internal implementation details that may change in the future. Their backwards-compatibility cannot be relied upon.
Types
Creating and Modifying Instances of Types
Creating or modifying an instance of a type does not have any effect on the server side, unless the changes are explicitly sent to the server calling a service method, as described below. Changes on the server side are not automatically reflected in instances that already exist in memory.
The constructors of these classes have multiple optional arguments, one for each attribute of the type. This simplifies the creation of objects, by using nested calls to multiple constructors.
In the following example, an instance of a virtual machine is created and its attributes (cluster, template, and memory) are set:
vm = OvirtSDK4::Vm.new(
name: 'myvm',
cluster: OvirtSDK4::Cluster.new(
name: 'mycluster'
),
template: OvirtSDK4::Template.new(
name: 'mytemplate'
),
memory: 1073741824
)
The hashes (for example, cluster: OvirtSDK4::Cluster.new
) passed to these constructors are processed recursively.
In the following example, plain hashes are used instead of explicitly calling the constructors for the Cluster and Template classes. The SDK internally converts the hashes to the required classes.
vm = OvirtSDK4::Vm.new(
name: 'myvm',
cluster: {
name: 'mycluster'
},
template: {
name: 'mytemplate'
},
memory: 1073741824
)
Using constructors in this way is recommended, but not mandatory.
In the following example, a virtual machine instance is created with no arguments in the call to the constructor. You can add the virtual machine instance’s attributes one by one, using setters, or by using a combination of setters and constructors.
vm = OvirtSDK4::Vm.new
vm.name = 'myvm'
vm.cluster = OvirtSDK4::Cluster.new(name: 'mycluster')
vm.template = OvirtSDK4::Template.new(name: 'mytemplate')
vm.memory = 1073741824
Attributes that are defined as lists of objects in the API specification are implemented as Ruby arrays. For example, the custom_properties
attributes of the Vm
type are defined as a list of objects of type CustomProperty
.
vm = OvirtSDK4::Vm.new(
name: 'myvm',
custom_properties: [
OvirtSDK4::CustomProperty.new(...),
OvirtSDK4::CustomProperty.new(...),
...
]
)
Attributes that are defined as enumerated values in the API are implemented as constants in a module with the same name as the enumerated type.
The following example shows how the status attribute of the Vm
type is defined using the VmStatus
enumerated value.
case vm.status
when OvirtSDK4::VmStatus::DOWN
...
when OvirtSDK4::VmStatus::IMAGE_LOCKED
...
end
In the API specification, the values of |
Retrieving Instance Attributes
You can retrieve instance attributes using the corresponding attribute readers.
The following example retrieves the name and memory of the virtual machine instance:
puts "vm.name: #{vm.name}"
puts "vm.memory: #{vm.memory}"
vm.custom_properties.each do |custom_property|
...
end
Retrieving Instance Attributes as Links
Some instance attributes are returned as links and require the follow_link
method to retrieve the data. In the following example, the response to a request for a virtual machine’s attributes is formatted as XML with a link:
<vm id="123" href="/ovirt-engine/api/vms/123">
<name>myvm</name>
<link rel="diskattachments" href="/ovirt-engine/api/vms/123/diskattachments/">
...
</vm>
The link, vm.disk_attachments
, does not contain the actual disk attachments. To retrieve the data, the Connection class provides a follow_link method that uses the value of the href
XML attribute to retrieve the actual data.
In the following example, follow_link
enables you to go to the disk attachments, and then to each disk, to retrieve the alias
:
vm = vm_service.get
follow_link
to Retrieve Disk Attachment and Disk Aliasattachments = connection.follow_link(vm.disk_attachments)
attachments.each do |attachment|
disk = connection.follow_link(attachment.disk)
puts "disk.alias: #{disk.alias}"
end
Services
Retrieving Services
The API provides a set of services, each associated with a server path. For example, the service that manages the collection of virtual machines in the system is located in /vms
, and the service that manages the virtual machine with identifier 123
is located in /vms/123
.
In the Ruby software development kit, the root of that tree of services is implemented by the system service
. It is retrieved by calling the system_service method of the connection:
system_service = connection.system_service
Once you have the reference to the system service
, you can use it to retrieve references to other services, using the *_service
methods (called service locators
).
For example, to retrieve a reference to the service that manages the collection of virtual machines in the system, you can use the vms_service service locator:
vms_service = system_service.vms_service
To retrieve a reference to the service that manages the virtual machine with identifier 123
, use the service locator of the vm_service service. The service locator uses the virtual machine identifier as a parameter:
vm_service = vms_service.vms_service('123')
The objects returned by the service locator calls are pure services, and do not contain data. For example, the |
Service Methods
After you have located the service you want, you can call its service methods. These methods send requests to the server and do the real work.
Services that manage collections of objects usually have the list
and add
methods.
Services that manage a single object usually have the get
, update
, and remove
methods.
Services may have additional action methods, which perform actions other than retrieving, creating, updating, or removing. These methods are most commonly found in services that manage a single object.
Get
The get
method retrieves the representation of a single object.
The following example locates and retrieves the representation of the virtual machine with identifier 123
:
# Find the service that manages the virtual machine:
vms_service = system_service.vms_service
vm_service = vms_service.vm_service('123')
# Retrieve the representation of the virtual machine:
vm = vm_service.get
The result will be an instance of the corresponding type. In this case, the result is an instance of the Ruby class Vm.
The get
method of some services supports additional parameters that control how to retrieve the representation of the object, or which representation to retrieve, if there is more than one.
For example, you may want to retrieve a virtual machine’s future state, after boot-up. The get
method of the service that manages a virtual machine supports a next_run Boolean parameter:
next_run
State# Retrieve the representation of the virtual machine; not the
# current one, but the one that will be used after the next
# boot:
vm = vm_service.get(next_run: true)
See the reference documentation of the software development kit for details.
If the object cannot be retrieved, the software development kit will raise an Error exception, containing details of the failure. This will occur if you try to retrieve a non-existent object.
The call to the |
In the following examples, the service locator
method will succeed, while the get
method will raise an exception:
# Find the service that manages a virtual machine that does
# not exist. This will succeed.
vm_service = vms_service.vm_service('non_existent_VM')
# Retrieve the virtual machine. This will raise an exception.
vm = vm_service.get
List
The list
method retrieves the representations of multiple objects in a collection.
# Find the service that manages the collection of virtual
# machines:
vms_service = system_service.vms_service
vms = vms_service.list
The result is a Ruby array containing the instances of the corresponding types. In the above example, the response is a list of instances of the Ruby class Vm.
The list
method of some services supports additional parameters.
For example, almost all of the top-level collections support a search
parameter to filter the results, and a max
parameter to limit the number of results returned by the server.
vms = vms_service.list(search: 'name=my*', max: 10)
Not all the list methods support the |
If the list of results is empty, the returned value will be an empty Ruby array. It will never be nil
.
If the list of results cannot be retrieved, the SDK will raise an Error exception containing the details of the failure.
Add
Add
methods add new elements to collections. They receive an instance of the relevant type describing the object to add, send the request to add it, and return an instance of the type describing the added object.
# Add the virtual machine:
vm = vms_service.add(
OvirtSDK4::Vm.new(
name: 'myvm',
cluster: {
name: 'mycluster'
},
template: {
name: 'mytemplate'
}
)
)
The Ruby object returned by the |
If you need to perform an action on the virtual machine you just added, you must locate the service that manages it and call the service locator:
# Add the virtual machine:
vm = vms_service.add(
...
)
# Find the service that manages the virtual machine:
vm_service = vms_service.vm_service(vm.id)
# Start the virtual machine:
vm_service.start
The creation of most objects is an asynchronous task. For example, if you create a new virtual machine, the add
method will return the virtual machine before the virtual machine is completely created and ready to be used. You should poll the status of the object until it is completely created. For a virtual machine that means checking until the status is DOWN
.
The recommended approach is to create a virtual machine, locate the service that manages the new virtual machine, and retrieve the status repeatedly until the virtual machine status is DOWN
, indicating that all the disks have been created.
# Add the virtual machine:
vm = vms_service.add(
...
)
# Find the service that manages the virtual machine:
vm_service = vms_service.vm_service(vm.id)
# Wait until the virtual machine is DOWN, indicating that all the
# disks have been created:
loop do
sleep(5)
vm = vm_service.get
break if vm.status == OvirtSDK4::VmStatus::DOWN
end
If the object cannot be created, the SDK will raise an Error exception containing the details of the failure. It will never return nil
.
Update
Update
methods update existing objects. They receive an instance of the relevant type describing the update to perform, send the request to update it, and return an instance of the type describing the updated object.
The Ruby object returned by this update method is an instance of the relevant type. It is not a service, just a container of data. In this particular example the returned object will be an instance of the Vm class. |
In the following example, the service locator
method locates the service managing the virtual machine and the update
method updates its name:
# Find the virtual machine and the service that
# manages it:
vm = vms_service.list(search: 'name=myvm').first
vm_service = vms_service.vm_service(vm.id)
# Update the name:
updated_vm = vms_service.update(
OvirtSDK4::Vm.new(
name: 'newvm'
)
)
When you update an object, update only the attributes you want to update:
vm = vm_service.get
vm.name = 'newvm'
Do not update the entire object:
# Retrieve the current representation:
vms_service.update(vm)
Updating all attributes of the virtual machine is a waste of resources and can introduce unexpected bugs on the server side.
Update
methods of some services support additional parameters that can be used to control how or what to update. For example, you may want to update the memory of a virtual machine, not in its current state, but the next time it is started. The update
method of the service that manages a virtual machine supports a next_run Boolean parameter:
vm = vm_service.update(
OvirtSDK4::Vm.new(
memory: 1073741824
),
next_run: true
)
If the update cannot be performed, the SDK will raise an Error exception containing the details of the failure. It will never return nil
.
Remove
Remove
methods remove existing objects. They normally do not support parameters because they are methods of services that manage single objects, and the service already knows what object to remove.
123
vm_service = vms_service.vm_service('123')
vms_service.remove
Some remove
methods support parameters that control how or what to remove. For example, it is possible to remove a virtual machine while preserving its disks, using the detach_only Boolean parameter:
vm_service.remove(detach_only: true)
The remove
method returns nil
if the object is removed successfully. It does not return the removed object.
If the object cannot be removed, the SDK will raise an Error exception containing the details of the failure.
Additional Actions
There are additional action methods, apart from the methods described above. The service that manages a virtual machine has methods to start and stop it.
vm_service.start
Some action methods include parameters that modify the operation. For example, the start
method supports a use_cloud_init parameter.
vm_service.start(use_cloud_init: true)
Most action methods return nil
when they succeed, and raise an Error when they fail. Some action methods, however, return values. For example, the service that manages storage domains has an is_attached action method that checks whether the storage domain is already attached to a data center. The is_attached action method returns a Boolean value:
sds_service = system_service.storage_domains_service
sd_service = sds_service.storage_domain_service('123')
if sd_service.is_attached
...
end
See the reference documentation of the software development kit to see the action methods supported by each service, their parameters, and return values.