Chapter 3. Ruby Examples
3.1. Connecting to the Red Hat Virtualization Manager
The Connection
class is the entry point of the software development kit. It provides access to the services of the Red Hat Virtualization Manager’s REST API.
The parameters of the Connection
class are:
-
url
- Base URL of the Red Hat Virtualization Manager API -
username
-
password
-
ca_file
- PEM file containing the trusted CA certificates. Theca.pem
file is required when connecting to a server protected by TLS. If you do not specify theca_file
, the system-wide CA certificate store is used.
Connecting to the Red Hat Virtualization Manager
connection = OvirtSDK4::Connection.new( url: 'https://engine.example.com/ovirt-engine/api', username: 'admin@internal', password: '...', ca_file: 'ca.pem', )
The connection holds critical resources, including a pool of HTTP connections to the server and an authentication token. You must free these resources when they are no longer in use:
connection.close
The connection, and all the services obtained from it, cannot be used after the connection has been closed.
If the connection fails, the software development kit will raise an Error exception, containing details of the failure.
For more information, see http://www.rubydoc.info/gems/ovirt-engine-sdk/OvirtSDK4/Connection:initialize.
3.2. Listing Data Centers
This Ruby example lists the data centers.
# Get the reference to the root of the services tree: system_service = connection.system_service # Get the reference to the service that manages the # collection of data centers: dcs_service = system_service.data_centers_service # Retrieve the list of data centers and for each one # print its name: dcs = dcs_service.list dcs.each do |dc| puts dc.name end
In an environment with only the Default data center, the example outputs:
Default
For more information, see http://www.rubydoc.info/gems/ovirt-engine-sdk/OvirtSDK4/DataCentersService:list.
3.3. Listing Clusters
This Ruby example lists the clusters.
# Get the reference to the root of the services tree: system_service = connection.system_service # Get the reference to the service that manages the # collection of clusters: cls_service = system_service.clusters_service # Retrieve the list of clusters and for each one # print its name: cls = cls_service.list cls.each do |cl| puts cl.name end
In an environment with only the Default cluster, the example outputs:
Default
For more information, see http://www.rubydoc.info/gems/ovirt-engine-sdk/OvirtSDK4/ClustersService:list.
3.4. Listing Logical Networks
This Ruby example lists the logical networks.
# Get the reference to the root of the services tree: system_service = connection.system_service # Get the reference to the service that manages the # collection of networks: nws_service = system_service.networks_service # Retrieve the list of clusters and for each one # print its name: nws = nws_service.list nws.each do |nw| puts nw.name end
In an environment with only the default management network, the example outputs:
ovirtmgmt
For more information, see http://www.rubydoc.info/gems/ovirt-engine-sdk/OvirtSDK4/NetworksService:list.
3.5. Listing Hosts
This Ruby example lists the hosts.
# Get the reference to the root of the services tree: system_service = connection.system_service # Get the reference to the service that manages the # collection of hosts: host_service = system_service.hosts_service # Retrieve the list of hosts and for each one # print its name: host = host_service.list host.each do |host| puts host.name end
In an environment with only one attached host (Atlantic
) the example outputs:
Atlantic
For more information, see http://www.rubydoc.info/gems/ovirt-engine-sdk/OvirtSDK4/HostsService:list.
3.6. Listing ISO Files in the ISO Storage Domain
This Ruby example lists the ISO files in the ISO storage domain, myiso
.
# Get the reference to the root of the services tree:
system_service = connection.system_service
# Find the service that manages the collection of storage domains:
sds_service = system_service.storage_domains_service
# Find the ISO storage domain:
sd = sds_service.list(search: 'name=myiso').first
# Find the service that manages the ISO storage domain:
sd_service = sds_service.storage_domain_service(sd.id)
# Find the service that manages the collection of files available in the storage domain:
files_service = sd_service.files_service
# List the names of the files. Note that the name of the .iso file is contained
# in the id
attribute.
files = files_service.list
files.each do |file|
puts file.id
end
For more information, see http://www.rubydoc.info/gems/ovirt-engine-sdk/OvirtSDK4%2FFilesService:list.
If you do not know the name of the ISO storage domain, this Ruby example retrieves all the ISO storage domains.
# Find the ISO storage domain: iso_sds = sds_service.list.select { |sd| sd.type == OvirtSDK4::StorageDomainType::ISO }
For more information, see http://www.rubydoc.info/gems/ovirt-engine-sdk/OvirtSDK4/StorageDomainsService:list.
3.7. Creating an NFS Storage Domain
This Ruby example adds an NFS storage domain.
# Get the reference to the root of the services tree: system_service = connection.system_service # Get the reference to the storage domains service: sds_service = connection.system_service.storage_domains_service # Create a new NFS data storage domain: sd = sds_service.add( OvirtSDK4::StorageDomain.new( name: 'mydata', description: 'My data', type: OvirtSDK4::StorageDomainType::DATA, host: { name: 'myhost' }, storage: { type: OvirtSDK4::StorageType::NFS, address: 'server0.example.com', path: '/nfs/ovirt/40/mydata' } ) ) # Wait until the storage domain is unattached: sd_service = sds_service.storage_domain_service(sd.id) loop do sleep(5) sd = sd_service.get break if sd.status == OvirtSDK4::StorageDomainStatus::UNATTACHED end
For more information, see http://www.rubydoc.info/gems/ovirt-engine-sdk/OvirtSDK4/StorageDomainsService:add.
3.8. Attaching a Storage Domain to a Data Center
This Ruby example attaches an existing NFS storage domain, mydata
, to an existing data center, mydc
. This example is used to attach both data and ISO storage domains.
# Get the reference to the root of the services tree: system_service = connection.system_service # Locate the service that manages the storage domains and use it to # search for the storage domain: sds_service = system_service.storage_domains_service sd = sds_service.list(search: 'name=mydata')[0] # Locate the service that manages the data centers and use it to # search for the data center: dcs_service = system_service.data_centers_service dc = dcs_service.list(search: 'name=mydc')[0] # Locate the service that manages the data center where you want to # attach the storage domain: dc_service = dcs_service.data_center_service(dc.id) # Locate the service that manages the storage domains that are attached # to the data centers: attached_sds_service = dc_service.storage_domains_service # Use the "add" method of service that manages the attached storage # domains to attach it: attached_sds_service.add( OvirtSDK4::StorageDomain.new( id: sd.id ) ) # Wait until the storage domain is active: attached_sd_service = attached_sds_service.storage_domain_service(sd.id) loop do sleep(5) sd = attached_sd_service.get break if sd.status == OvirtSDK4::StorageDomainStatus::ACTIVE end
For more information, see http://www.rubydoc.info/gems/ovirt-engine-sdk/OvirtSDK4/StorageDomainsService:add.
3.9. Creating a Virtual Machine
This Ruby example creates a virtual machine. This example uses a hash with symbols and nested hashes as their values. Another method, more verbose, is to use the constructors of the corresponding objects directly. See Creating a Virtual Machine Instance with Attributes for more information.
# Get the reference to the "vms" service: vms_service = connection.system_service.vms_service # Use the "add" method to create a new virtual machine: vms_service.add( OvirtSDK4::Vm.new( name: 'myvm', cluster: { name: 'mycluster' }, template: { name: 'Blank' } ) )
After creating a virtual machine, it is recommended to poll the virtual machine’s status, to ensure that all the disks have been created.
For more information, see http://www.rubydoc.info/gems/ovirt-engine-sdk/OvirtSDK4/VmsService:add.
3.10. Creating a vNIC Profile
This Ruby example creates a vNIC profile.
# Find the root of the tree of services: system_service = connection.system_service # Find the network where you want to add the profile. There may be multiple # networks with the same name (in different data centers, for example). # Therefore, you must look up a specific network by name, in a specific data center. dcs_service = system_service.data_centers_service dc = dcs_service.list(search: 'name=mydc').first networks = connection.follow_link(dc.networks) network = networks.detect { |n| n.name == 'mynetwork' } # Create the vNIC profile, with pass-through and port mirroring disabled: profiles_service = system_service.vnic_profiles_service profiles_service.add( OvirtSDK4::VnicProfile.new( name: 'myprofile', pass_through: { mode: OvirtSDK4::VnicPassThroughMode::DISABLED, }, port_mirroring: false, network: { id: network.id } ) )
For more information, see http://www.rubydoc.info/gems/ovirt-engine-sdk/OvirtSDK4/VnicProfilesService:add.
3.11. Creating a vNIC
To ensure that a newly created virtual machine has network access you must create and attach a vNIC.
This Ruby example creates a vNIC and attaches it to an existing virtual machine, myvm
.
# Find the root of the tree of services: system_service = connection.system_service # Find the virtual machine: vms_service = system_service.vms_service vm = vms_service.list(search: 'name=myvm').first # In order to specify the network that the new NIC will be connected to, you must # specify the identifier of the vNIC profile. However, there may be multiple # profiles with the same name (for different data centers, for example), so first # you must find the networks that are available in the cluster that the # virtual machine belongs to. cluster = connection.follow_link(vm.cluster) networks = connection.follow_link(cluster.networks) network_ids = networks.map(&:id) # Now that you know what networks are available in the cluster, you can select a # vNIC profile that corresponds to one of those networks, and has the # name that you want to use. The system automatically creates a vNIC # profile for each network, with the same name as the network. profiles_service = system_service.vnic_profiles_service profiles = profiles_service.list profile = profiles.detect { |p| network_ids.include?(p.network.id) && p.name == 'myprofile' } # Locate the service that manages the network interface cards collection of the # virtual machine: nics_service = vms_service.vm_service(vm.id).nics_service # Add the new network interface card: nics_service.add( OvirtSDK4::Nic.new( name: 'mynic', description: 'My network interface card', vnic_profile: { id: profile.id } ) )
For more information, see http://www.rubydoc.info/gems/ovirt-engine-sdk/OvirtSDK4/VmsService:add.
3.12. Creating a Virtual Disk
To ensure that a newly created virtual machine has access to persistent storage you must create and attach a disk.
This Ruby example creates and attaches a virtual storage disk to a virtual machine.
# Locate the virtual machines service and use it to find the virtual
# machine:
vms_service = connection.system_service.vms_service
vm = vms_service.list(search: 'name=myvm')[0]
# Locate the service that manages the disk attachments of the virtual
# machine:
disk_attachments_service = vms_service.vm_service(vm.id).disk_attachments_service
# Use the "add" method of the disk attachments service to add the disk.
# Note that the size of the disk, the provisioned_size
attribute, is
# specified in bytes, so to create a disk of 10 GiB the value should
# be 10 * 2^30.
disk_attachment = disk_attachments_service.add(
OvirtSDK4::DiskAttachment.new(
disk: {
name: 'mydisk',
description: 'My disk',
format: OvirtSDK4::DiskFormat::COW,
provisioned_size: 10 * 2**30,
storage_domains: [{
name: 'mydata'
}]
},
interface: OvirtSDK4::DiskInterface::VIRTIO,
bootable: false,
active: true
)
)
# Wait until the disk status is OK:
disks_service = connection.system_service.disks_service
disk_service = disks_service.disk_service(disk_attachment.disk.id)
loop do
sleep(5)
disk = disk_service.get
break if disk.status == OvirtSDK4::DiskStatus::OK
end
For more information, see http://www.rubydoc.info/gems/ovirt-engine-sdk/OvirtSDK4/DiskAttachmentsService:add.
3.13. Attaching an ISO Image to a Virtual Machine
This Ruby example attaches a CD-ROM to a virtual machine and changes it to an ISO image in order to install the guest operating system.
# Get the reference to the "vms" service: vms_service = connection.system_service.vms_service # Find the virtual machine: vm = vms_service.list(search: 'name=myvm')[0] # Locate the service that manages the virtual machine: vm_service = vms_service.vm_service(vm.id) # Locate the service that manages the CDROM devices of the VM: cdroms_service = vm_service.cdroms_service # List the first CDROM device: cdrom = cdroms_service.list[0] # Locate the service that manages the CDROM device you just found: cdrom_service = cdroms_service.cdrom_service(cdrom.id) # Change the CD of the VM to 'my_iso_file.iso'. By default this # operation permanently changes the disk that is visible to the # virtual machine after the next boot, but it does not have any effect # on the currently running virtual machine. If you want to change the # disk that is visible to the current running virtual machine, change # thecurrent
parameter's value totrue
. cdrom_service.update( OvirtSDK4::Cdrom.new( file: { id: 'CentOS-7-x86_64-DVD-1511.iso' } ), current: false )
For more information, see http://www.rubydoc.info/gems/ovirt-engine-sdk/OvirtSDK4%2FVmService:cdroms_service.
3.14. Detaching a Virtual Disk
This Ruby example detaches a disk from a virtual machine.
# Find the virtual machine: vm = vms_service.list(search: 'name=myvm').first # Detach the first disk from the virtual machine: vm_service = vms_service.vm_service(vm.id) attachments_service = vm_service.disk_attachments_service attachment = attachments_service.list.first # Remove the attachment. The default behavior is that the disk is detached # from the virtual machine, but not deleted from the system. If you wish to # delete the disk, change thedetach_only
parameter tofalse
. attachment.remove(detach_only: true)
For more information, see http://www.rubydoc.info/gems/ovirt-engine-sdk/OvirtSDK4/VmService:disk_attachments_service.
3.15. Starting a Virtual Machine
This Ruby example starts a virtual machine.
# Get the reference to the "vms" service: vms_service = connection.system_service.vms_service # Find the virtual machine: vm = vms_service.list(search: 'name=myvm')[0] # Locate the service that manages the virtual machine, as that is where # the action methods are defined: vm_service = vms_service.vm_service(vm.id) # Call the "start" method of the service to start it: vm_service.start # Wait until the virtual machine status is UP: loop do sleep(5) vm = vm_service.get break if vm.status == OvirtSDK4::VmStatus::UP end
For more information, see http://www.rubydoc.info/gems/ovirt-engine-sdk/OvirtSDK4/VmService:start.
3.16. Starting a Virtual Machine with Specific Boot Devices and Boot Order
This Ruby example starts a virtual machine specifying the boot devices and boot order.
# Find the root of the tree of services: system_service = connection.system_service # Find the virtual machine: vms_service = system_service.vms_service vm = vms_service.list(search: 'name=myvm').first # Find the service that manages the virtual machine: vm_service = vms_service.vm_service(vm.id) # Start the virtual machine explicitly indicating the boot devices and order: vm_service.start( vm: { os: { boot: { devices: [ OvirtSDK4::BootDevice::NETWORK, OvirtSDK4::BootDevice::CDROM ] } } } ) # Wait until the virtual machine is up: loop do sleep(5) vm = vm_service.get break if vm.status == OvirtSDK4::VmStatus::UP end
For more information, see http://www.rubydoc.info/gems/ovirt-engine-sdk/OvirtSDK4/BootDevice.
3.17. Starting a Virtual Machine with Cloud-Init
This Ruby example starts a virtual machine using the Cloud-Init tool to set the root
password and network configuration.
# Find the virtual machine:
vms_service = connection.system_service.vms_service
vm = vms_service.list(search: 'name=myvm')[0]
# Find the service that manages the virtual machine:
vm_service = vms_service.vm_service(vm.id)
# Create a cloud-init script to execute in the
# deployed virtual machine. The script must be correctly
# formatted and indented because it uses YAML.
my_script = "
write_files:
- content: |
Hello, world!
path: /tmp/greeting.txt
permissions: '0644'
"
# Start the virtual machine, enabling cloud-init and providing the
# password for the root
user and the network configuration:
vm_service.start(
use_cloud_init: true,
vm: {
initialization: {
user_name: 'root',
root_password: 'redhat123',
host_name: 'myvm.example.com',
nic_configurations: [
{
name: 'eth0',
on_boot: true,
boot_protocol: OvirtSDK4::BootProtocol::STATIC,
ip: {
version: OvirtSDK4::IpVersion::V4,
address: '192.168.0.100',
netmask: '255.255.255.0',
gateway: '192.168.0.1'
}
}
],
dns_servers: '192.168.0.1 192.168.0.2 192.168.0.3',
dns_search: 'example.com',
custom_script: my_script
}
}
)
For more information, see http://www.rubydoc.info/gems/ovirt-engine-sdk/OvirtSDK4/VmService:start.
3.18. Checking System Events
This Ruby example retrieves logged system events.
# In order to ensure that no events are lost, it is recommended to write # the index of the last processed event, in persistent storage. # Here, it is stored in a file calledindex.txt
. In a production environment, # it will likely be stored in a database. INDEX_TXT = 'index.txt'.freeze def write_index(index) File.open(INDEX_TXT, 'w') { |f| f.write(index.to_s) } end def read_index return File.read(INDEX_TXT).to_i if File.exist?(INDEX_TXT) nil end # This is the function that is called to process the events. It prints # the identifier and description of each event. def process_event(event) puts("#{event.id} - #{event.description}") end # Find the root of the tree of services: system_service = connection.system_service # Find the service that manages the collection of events: events_service = system_service.events_service # If no index is stored yet, retrieve the last event and start with it. # Events are ordered by index, in ascending order.max=1
retrieves only one event, # the last event. unless read_index events = events_service.list(max: 1) unless events.empty? first = events.first process_event(first) write_index(first.id.to_i) end end # This loop retrieves the events, always starting from the last index. It waits # before repeating. Thefrom
parameter specifies that you want to retrieve # events that are newer than the last index that was processed. Note: themax
# parameter is not used, so that all pending events will be retrieved. loop do sleep(5) events = events_service.list(from: read_index) events.each do |event| process_event(event) write_index(event.id.to_i) end end
For more information, see http://www.rubydoc.info/gems/ovirt-engine-sdk/OvirtSDK4%2FEventsService:list.