Red Hat Enterprise Virtualization Management (RHEV-M) – Overview, APIs and Code Examples

Overview

Red Hat Enterprise Virtualization has two main components: RHEV-H and RHEV-M. In this post we will be focusing on RHEV-M which provides a REST API and various SDKs. By integrating with RHEV-M we can integrate a powerful set of virtualization APIs into any applications, processes or workflows. If you are new to RHEV or don’t have a lab environment setup, check out this post on building a RHEV lab environment.

RHEV-H

Red Hat Enterprise Virtualization Hypervisor (RHEV-H) is a compact, full-featured virtualization platform built on Red Hat Enterprise Linux (RHEL). It has a very small footprint (less than 100MB) and is built from only a subset of RHEL components plus the Kernel-Based Virtual Machine (KVM).

RHEV-M

Red Hat Enterprise Virtualization Management (RHEV-M) is a virtual management console built on Red Hat Enterprise Linux (RHEL). It interacts with individual RHEV-H nodes using the Virtual Desktop Server Manager (VDSM). A VDSM agent is running on each of the RHEV-H nodes. RHEV-M allows administrators to manage multiple data centers and their network, compute and storage resources. In addition RHEV-M provides a central repository for storing virtual machines, disks, images and virtual machine snapshots. RHEV-M provides a common feature set such as HA, Load Balancing, Host Fencing, Networking, Storage and more across all hosts and virtual machines.

RHEVM_Architecture

RHEV-M Architecture

RHEV-M is built on top of libvirt and allows for the management of many KVM (Kernel-Based Virtual Machine) hosts. Libvirt just allows for the management of a single KVM host. RHEV-M is downstream from the open-source project oVirt. Red Hat started the oVirt project and though the hypervisor backend is open (KVM, XEN, or VirtualBox) the project is currently focused on KVM. Originally oVirt was based on C# and .NET but has since ported to Java.

RHEV-M has several components: Engine, Interfaces, VDSM Agent and SPICE.

Engine

The RHEV-M engine runs on a standalone RHEL host. It inventories as well as exposes virtual resources and allows the administrator to organise those resources across many data centers. In addition it provides capabilities such as HA, authentication, load balancing, live migration, network management, storage management, virtual machine management, image management and monitoring across an entire virtual ecosystem based around the KVM hypervisor. The engine maintains a postgreSQL database for storing relational information about the environment.

Interfaces

RHEV-M offers a CLI and a web-based UI built around the Google Web-Framework (GWT). Since RHEV-M uses GWT it is also possible to create plugins and add UI extensions during runtime. RHEV-M offers a powerful REST API and SDKs for Java as well as Python. Later in this post we will give some Java code examples and take a closer look at the SDK.

VDSM

The Virtual Desktop Server Manager is an interface abstraction built around libvirt. Since libvirt was only designed to manage a single KVM hypervisor it was necessary to extend capabilities to allow management of 1000s of virtual machines across many KVM hypervisors. VDSM provides the necessary scalability around libvirt. VDSM has a few components. It has a daemon agent that runs on the KVM hypervisor (either RHEV-H or RHEL + KVM), a client component and a manager that is built into the RHEV-M engine.

SPICE

RHEV-M uses SPICE in order to display the console of a virtual machine through user interfaces. SPICE is responsible for handling console graphics and sending control commands.

Java Coding Examples

Below are several coding examples in Java using the SDK built on the RHEV-M REST API. These code examples will work with RHEV-M and oVirt. The Java SDK is available through maven or direct download from oVirt. To use via maven simply add following to your pom.xml:

<dependency>
   <groupId>org.ovirt.engine.sdk</groupId>
   <artifactId>ovirt-engine-sdk-java</artifactId>
   <version>3.4.4.0</version>
</dependency>

RHEV-M Connection

Below is a class that we can instantiate with various parameters. It returns a connection object that is used as the basis in other examples:

import org.ovirt.engine.sdk.Api;

public class RhevConnection {

    private String URL;
    private String domain;
    private String username;
    private String password;

    public RhevConnection(String hostname, Integer port, Boolean sslEnable, String username, String password, String domain) {
        if (sslEnable) {
            this.URL = "https://" + hostname + ":" + port + "/api";
        } else {
            this.URL = "http://" + hostname + ":" + port + "/api";
        }

        this.domain = domain;
        this.username = username;
        this.password = password;
    }

    public Api getConnection() throws Exception {

        Api api = null;
        try {
            api = new Api(URL, username + "@" + domain, password, true);
        } catch (Exception e) {
            throw new Exception(e.getMessage(), e);
        }

        return api;
    }
}

Data Centers

The top-level organisational entity in RHEV-M is the data center. It is meant to be a logical or physical segregation of virtual resources. Data Centers contain storage domains, networks, clusters and of course hypervisor hosts. Below is a Java example that uses a defined model to return details about data centers:

    public List<DataCenterModel> inventoryDataCenters() throws Exception {
        List<DataCenterModel> dcModelList = new ArrayList<DataCenterModel>();

        try {
            for (DataCenter dc : api.getDataCenters().list()) {
                DataCenterModel dcModel = new DataCenterModel();

                dcModel.setName(dc.getName());
                dcModel.setDescription(dc.getDescription());
                dcModel.setIsLocal(dc.getLocal());
                dcModel.setStatus(dc.getStatus().getState());

                dcModelList.add(dcModel);
            }
        } catch (Exception e) {
            throw new Exception(e.getMessage(), e);
        }

        return dcModelList;
    }

 Storage Domains

Storage domains provide storage management within RHEV-M. Virtual machine images and disks are stored in storage domains. A storage domain can be local to hypervisor host or shared across many hosts. A storage domain can be NFS, ISCSI, FC, Gluster, Ceph or ZFS. Below is a Java example that uses a defined model to return details of storage domains:

    public List<StorageDomainModel> inventoryStorageDomains() throws Exception {
        List<StorageDomainModel> storageDomainModelList = new ArrayList<StorageDomainModel>();

        try {
            List<StorageDomain> storageDomainList = api.getStorageDomains().list();

            for (StorageDomain storageDomain : storageDomainList) {
                StorageDomainModel storageDomainModel = new StorageDomainModel();
                storageDomainModel.setName(storageDomain.getName());
                storageDomainModel.setDescription(storageDomain.getDescription());
                storageDomainModel.setDomainType(storageDomain.getType());
                storageDomainModel.setStorageType(storageDomain.getStorage().getType());
                storageDomainModel.setPath(storageDomain.getStorage().getPath());
                storageDomainModel.setAvailable(storageDomain.getAvailable());
                storageDomainModel.setUsed(storageDomain.getUsed());

                storageDomainModelList.add(storageDomainModel);
            }
        } catch (Exception e) {
            throw new Exception(e.getMessage(), e);
        }

        return storageDomainModelList;
    }

Hosts

In RHEV-M a host is a RHEL system running KVM and the VDSM agent. As mentioned you can either use RHEV-H which comes with everything you need out-of-the-box or RHEL and add KVM / VDSM packages manually. Below is a Java example that uses a defined model to return details of hosts:

    public List<HostModel> inventoryHosts() throws Exception {
        List<HostModel> hostList = new ArrayList<HostModel>();

        try {
            List<Host> hosts = api.getHosts().list();
            for (Host host : hosts) {
                HostModel hostModel = new HostModel();
                hostModel.setName(host.getName());
                hostModel.setIp(host.getAddress());
                hostModel.setCpuType(host.getCpu().getName());
                hostModel.setCpuCores(host.getCpu().getTopology().getCores());
                hostModel.setMemory(host.getMemory());
                hostModel.setOsType(host.getOs().getType());
                hostModel.setOsVersion(host.getOs().getVersion().getFullVersion());

                hostList.add(hostModel);
            }
        } catch (Exception e) {
            throw new Exception(e.getMessage(), e);
        }

        return hostList;
    }

Virtual Machines

In RHEV-H virtual machines or as they are referred to in KVM domains provide the building blocks for the RHEV platform. Most actions and things of interest are typically performed on virtual machines. Below are several code examples of typical things administrators would perform on virtual machines.

Listing Virtual Machines

    public List<VirtualMachineModel> inventoryVirtualMachines() throws Exception {
        List<VirtualMachineModel> vmModelList = new ArrayList<VirtualMachineModel>();

        try {
            List<VM> vmList = api.getVMs().list();

            for (VM vm : vmList) {
                VirtualMachineModel vmModel = new VirtualMachineModel();
                vmModel.setName(vm.getName());
                vmModel.setCpuCores(vm.getCpu().getTopology().getCores());
                vmModel.setMemory(vm.getMemory());
                vmModel.setOsType(vm.getOs().getType());
                vmModel.setState(vm.getStatus().getState());

                String hostId = vm.getPlacementPolicy().getHost().getId();
                vmModel.setHostName(api.getHosts().getById(hostId).getName());

                vmModelList.add(vmModel);
            }
        } catch (Exception e) {
            throw new Exception(e.getMessage(), e);
        }

        return vmModelList;
    }

Create Virtual Machine Snapshot

    public void createSnapshot(String vmName, String description) throws Exception {
        try {
            Snapshot snapshot = new Snapshot();
            snapshot.setDescription("XYZ snapshot [" + description + "]");
            api.getVMs().get(vmName).getSnapshots().add(snapshot);
        } catch (Exception e) {
            throw new Exception(e.getMessage(), e);
        }
    }

Delete Virtual Machine Snapshot

    public void deleteSnapshot(String vmName, String snapshotId) throws Exception {
        try {
            api.getVMs().get(vmName).getSnapshots().getById(snapshotId).delete();
        } catch (Exception e) {
            throw new Exception(e.getMessage(), e);
        }
    }

Restore Virtual Machine Snapshot

    public void restoreSnapshot(String vmName, String snapshotId) throws Exception {
        try {
            Action action = new Action();
            action.setId(snapshotId);
            api.getVMs().get(vmName).getSnapshots().getById(snapshotId).restore(action);
        } catch (Exception e) {
            throw new Exception(e.getMessage(), e);
        }
    }

List Virtual Machine Snapshots

    public List<SnapshotModel> listSnapshots(String vmName) throws Exception {
        List<SnapshotModel> snapshotList = new ArrayList<SnapshotModel>();

        List<VMSnapshot> snapshots = api.getVMs().get(vmName).getSnapshots().list();
        for (VMSnapshot snapshot : snapshots) {
            SnapshotModel snapshotModel = new SnapshotModel();
            snapshotModel.setId(snapshot.getId());
            snapshotModel.setDescription(snapshot.getDescription());
            snapshotModel.setDate(snapshot.getDate().toString());

            snapshotList.add(snapshotModel);
        }

        return snapshotList;
    }

Start Virtual Machine

    public void startVirtualMachine(String vmName) throws Exception {
        try {
            Action action = new Action();
            action.setName(vmName);
            ;
            api.getVMs().get(vmName).start(action);
        } catch (Exception e) {
            throw new Exception(e.getMessage(), e);
        }
    }

Stop Virtual Machine

    public void stopVirtualMachine(String vmName) throws Exception {
        try {
            Action action = new Action();
            action.setName(vmName);
            ;
            api.getVMs().get(vmName).shutdown(action);
        } catch (Exception e) {
            throw new Exception(e.getMessage(), e);
        }
    }

 Conclusion

RHEV is a powerful virtualization platform and certainly has not only the management but also feature capabilities to be on par with other virtualization platforms from VMware and Microsoft. The big advantage of RHEV over Microsoft or VMware is that everything is of course open-source and built in a thriving community. The industry has long wanted an enterprise open-source virtualization platform and now it has one! Hopefully this post was useful and informative. I was very impressed at the easy-of-use of RHEV-M interfaces and APIs. If you have any questions or comments please feel free to ask.

Happy RHEVing!

(c) 2015 Keith Tenzer

2 thoughts on “Red Hat Enterprise Virtualization Management (RHEV-M) – Overview, APIs and Code Examples

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s