Create a new virtual machine in oVirt with Python using the API

Recently, I started to work or play, it’s a matter of definition, a little more with oVirt. oVirt is less known than VMWare but it’s the upstream project for Red Hat’s Enterprise Virtualization (RHEV) and based on libvirt. In an earlier post, I explained how to create VM’s on VMWare vSphere environments using Python and the VMWare API. In this post, I’ll explain how to acomplish the same using the oVirt API. It turned out to be easier than I expected.

Less people know about oVirt in comparison with VMWare ESX and that’s a pitty. oVirt is built on libvirt so in theory it can support all kinds of hypervisors. Of all of them, KVM is the most popular choice for oVirt. When you’re reading this, I probably do not need to convince you anymore of the qualities of oVirt so let’s get started.

Preparation

The API of oVirt can be called from the machine running the engine, from another host in the cluster or just any host that has an IP-connection to the engine. Before we can use the API, we need to install the required packages from the oVirt repositories. While oVirt itself is still recommended to run on CentOS 6 (or RHEL 6), the API can perfectly be exploited from CentOS 7 (or RHEL 7).

Create the repositories by install ovirt-release:

[jensd@cen ~]$ sudo yum -y install http://resources.ovirt.org/pub/yum-repo/ovirt-release35.rpm
...
Complete !

Install the package with the required Python dependencies:

[jensd@cen ~]$ sudo yum -y install ovirt-engine-sdk-python
...
Complete !

As with my post about how to use the VMWare API with Python: Create a new virtual machine in Vsphere with Python, Pysphere and the VMWare API I will create a small Python script that can be included from other scripts in order to keep things clean. This also allows you to keep everything portable and have the flexibility to add functions later on.

You can copy the following contents or download the file here: http://jensd.be/download/api_ovirt_include.py

#! /usr/bin/python
#this script requires ovirt-engine-sdk-python

from ovirtsdk.api import API
from ovirtsdk.xml import params
from time import sleep

def connectToHost(host,host_user,host_pw):
    apiurl="https://"+host+"/api"
    #insecure -> skips SSL check
    api = API(url=apiurl,username=host_user,password=host_pw,insecure=True)
    return api

def createGuest(api,guest_cluster,guest_name,guest_description,guest_mem,guest_cpu,guest_disk_gb,guest_domain,guest_network):
    cpu_params = params.CPU(topology=params.CpuTopology(cores=guest_cpu))
    try:
        api.vms.add(params.VM(name=guest_name,memory=guest_mem*1024*1024,cluster=api.clusters.get(guest_cluster),template=api.templates.get('Blank'),cpu=cpu_params,type_="server",description=guest_description))
   
        api.vms.get(guest_name).nics.add(params.NIC(name='nic1', network=params.Network(name=guest_network), interface='virtio'))
        
        api.vms.get(guest_name).disks.add(params.Disk(storage_domains=params.StorageDomains(storage_domain=[api.storagedomains.get(guest_domain)]),size=guest_disk_gb*1024*1024*1024,status=None,interface='virtio',format='cow',sparse=True,bootable=True))
        while api.vms.get(guest_name).status.state != 'down':
            sleep(1)
   
    except Exception as e:
        print 'Failed to create VM with disk and NIC\n%s' % str(e)

    disk_name=guest_name+"_Disk1"
    print "Waiting for "+disk_name+" to reach ok status"
    while api.vms.get(guest_name).disks.get(name=disk_name).status.state != 'ok':
        sleep(1)

    return "Succesfully created guest: "+guest_name
    
def getMac(api,guest_name):
    return api.vms.get(guest_name).nics.get("nic1").mac.address

def powerOnGuest(api,guest_name):
    try:
        if api.vms.get(guest_name).status.state != 'up':
            print 'Starting VM'
            api.vms.get(guest_name).start()
            print 'Waiting for VM to reach Up status'
            while api.vms.get(guest_name).status.state != 'up':
                sleep(1)
        else:
            print 'VM already up'
    except Exception as e:
        print 'Failed to Start VM:\n%s' % str(e)

As you can see, the file is remarkably smaller than the one I created for VMWare while it basically supplies the same functionality.

Test the connection to oVirt

To test the connection to our oVirt host, create file called ovirt_list-vm.py and copy the following into it. Don’t forget to adjust to contents to match with your installation:

#! /usr/bin/python
from ovirtsdk.api import API
from ovirtsdk.xml import params
from time import sleep

def main():
    URL='https://192.168.0.10:443/api'
    USERNAME='admin@internal'
    PASSWORD='secretpass'

    api = API(url=URL, username=USERNAME, password=PASSWORD,insecure=True)
    vm_list=api.vms.list()
    for vm in vm_list:
        print vm.name
    api.disconnect()

if __name__ == '__main__':
        main()

Edit line 7, 8 and 9 to include the correct IP or hostname of your oVirt host, the username to authenticate, either a local or user@domain and the password for the connection.

Run the script and see if you get a list of virtual machines running on your oVirt host:

[jensd@cen ~]$ chmod +x ovirt_list-vm.py
[jensd@cen ~]$ ./ovirt_list-vm.py
testvm1
testvm2
testvm3

Create a new VM from within Python

The next step is to create a script that will actually add a VM to this host. To do so, copy and edit the contents of the following example to ovirt_create-vm.py:

#!/usr/bin/python
import api_ovirt_include

def main():
    #connection properties
    #change these to match your installation
    host="192.168.0.10"
    host_user="admin@internal"
    host_pw="secretpass"

    #properties of the new VM:
    guest_name="newvm"          #name of the VM
    guest_description="testvm"  #name of the VM
    guest_mem=1024              #memory in MB
    guest_cpu=1                 #number of virtual CPU
    guest_space=2               #space in GB
    storage_domain="ssd"        #name of the storage domain
    guest_cluster="Default"     #cluster name
    guest_network="ovirtmgmt"   #network-name

    #connect to the host
    host_con=api_ovirt_include.connectToHost(host,host_user,host_pw)

    #create the new VM
    res=api_ovirt_include.createGuest(host_con,guest_cluster,guest_name,guest_description,guest_mem,guest_cpu,guest_space,storage_domain,guest_network)
    print "Result:",res

    #start the new VM
    api_ovirt_include.powerOnGuest(host_con,guest_name)

    #disconnect from host
    host_con.disconnect()

if __name__ == '__main__':
        main()

Edit line 7, 8 and 9 to include the correct IP or hostname of your oVirt host, the username to authenticate, either a local or user@domain and the password for the connection.

Now, make the script executable and execute it. If all goes well, you should see something similar to this:

[jensd@cen ~]$ chmod +x ovirt_create-vm.py
[jensd@cen ~]$ ./ovirt_create-vm.py
Waiting for newvm_Disk1 to reach ok status
Result: Succesfully created guest: newvm
Starting VM
Waiting for VM to reach Up status

We can use our earlier created ovirt_list-vm.py to see if everything went as we expected:

[jensd@cen ~]$ ./ovirt_list-vm.py
newvm
testvm1
testvm2
testvm3

That’s all it takes to create new virtual machines from within a Python script. Offcourse this is only a basic example. The great power of it is to integrate it in a larger script that can do several actions and dynamically set the parameters of the VM.

More information about the scripts can be found on GitHub: https://github.com/jensdepuydt/python-hypervisor-api

3 thoughts on “Create a new virtual machine in oVirt with Python using the API

  1. How to install the ovirt-engine-sdk-python package in python?

    Using the above script I am not able to create api = API().

    How to overcome this?

Leave a Reply

Your email address will not be published. Required fields are marked *