Python script to manage virtual machines with python API for libvirt.

2016-07-04 840 words 4 mins read

Most of times I use virt-manager to manage VMs but sometimes, I have to manage VMs on other hosts over ssh when connected over VPN or while I am working remotely. GUI like virt-manager thus becomes slow, and hence I like to use cli commands and nothing is better than virsh. But here is simple script that I use sometimes to manage the VMs with CLI based menu. Hope you find it useful.

#! /usr/bin/env python
# -*- coding: utf-8 -*-
# vim:fenc=utf-8
#
# Copyright © 2016 Amit Agarwal <http://blog.amit-agarwal.co.in>
# Python scripts to manage virtual machines.
# 
# Distributed under terms of the MIT license.

"""
python wrapper for libvirt
"""

import libvirt
import sys
import pprint
from xml.dom import minidom

import os

hv_host="localhost"
names = []



def chhost():
    global hv_host
    global uri
    global conn

    print "Host is now set to "+hv_host

    try:
        ui = raw_input ("Provide the uri in format user@host : ")
    except:
        ui=''

    if len(ui) > 2 :
        if uri.find("lxc") :
            print "Using LXC uri"
        else:
            uri = "qemu+ssh://"+ui+"/system"
    else:
        uri = "qemu:///system"

    print uri + " is set as URI"
    conn = libvirt.open(uri)
    if conn == None:
        print 'Failed to open connection to the hypervisor'
        sys.exit(1)
    else:
        print "Connection established with "+uri

def vms(state):

    global names
    global conn
    if state == 'running' :
        active_hosts = conn.listDomainsID()
        if (len (active_hosts) == 0 ) :
            print "No Running VMs"
            return
        for i in range ( len (active_hosts) ):
            dom0 = conn.lookupByID(active_hosts[i])
            print "\t%d\t%s"%(active_hosts[i], dom0.name())
        val = input ( "Enter the ID ")
        return int(val)
    else :
        names = conn.listDefinedDomains()
        for i in range ( len (names) ):
            print "\t%d\t%s" %(i, names[i])
        tostart = input("Please enter number to start the VM :: ")
        print "Starting VM "+names[tostart]
        return names[tostart]

def writer(stream, data, buffer):
    buffer.write(data)

def start():
    global names
    global conn
    tostart = vms('')
    dom0 = conn.lookupByName(tostart)
    dom0.create()

def stop():
    print "List currently running VMs"
    val = vms('running')
    dom0 = conn.lookupByID(val)
    dom0.shutdown()


def view():
    print "List currently running VMs"
    val = vms('running')
    dom0 = conn.lookupByID(val)
    os.system("virt-viewer " + dom0.name() + " &" );

def viewip():
    val = vms('running')
    print "ID Returned is "+str(val)
    dom0 = conn.lookupByID(val)
    pprint.pprint (dom0.info())
    # pprint.pprint (dom0.GetInterfacesAddresses())

    for lease in conn.networkLookupByName("default").DHCPLeases():
        print(lease)

    raw_xml = dom0.XMLDesc (0)
    xml = minidom.parseString (raw_xml)
    interfaceTypes = xml.getElementsByTagName ( 'interface')
    for interfaceType in interfaceTypes :
        print ( 'interface: type=' +interfaceType.getAttribute ( 'type'))
        interfaceNodes = interfaceType.childNodes
        for interfaceNode in interfaceNodes :
            if interfaceNode.nodeName [0:1] != '#' :
                print ( '  ' +interfaceNode.nodeName)
                for attr in interfaceNode.attributes.keys ():
                    print ( '    ' +interfaceNode .attributes[attr].name + ' = ' + interfaceNode.attributes[attr].value)

    print 'View'


def state_to_string (state):
    statearr = [ "", "Running" ]
    return statearr[state[0]]

def info(dom):
    states = {
        libvirt.VIR_DOMAIN_NOSTATE: 'no state',
        libvirt.VIR_DOMAIN_RUNNING: 'running',
        libvirt.VIR_DOMAIN_BLOCKED: 'blocked on resource',
        libvirt.VIR_DOMAIN_PAUSED: 'paused by user',
        libvirt.VIR_DOMAIN_SHUTDOWN: 'being shut down',
        libvirt.VIR_DOMAIN_SHUTOFF: 'shut off',
        libvirt.VIR_DOMAIN_CRASHED: 'crashed',
    }

    [state, maxmem, mem, ncpu, cputime] = dom.info()
    return '%s' % (states.get(state, state))

def viewdets():
    global conn
    global names
    columns = 3


    domains = map(conn.lookupByName, names)

    ids = conn.listDomainsID()
    running = map(conn.lookupByID, ids)



    print 'Defined domains:'
    for row in map(None, *[iter(domains)] * columns):
        for domain in row:
            if domain:
                print "%s, %s" %( dom.name(), info(domain)),
        print
    print

    print 'Running domains:'
    for row in map(None, *[iter(running)] * columns):
        for domain in row:
            if domain:
                print info(domain),
        print



    print "Id    Name                           State"
    print "-" * 52
    for dom in conn.listAllDomains() :
        [state, maxmem, mem, ncpu, cputime] = dom.info()
        print "%3s %-31s%s" %\
            (dom.ID() if dom.ID() > 0 else "-",
             dom.name(),
             info(dom))
        # if dom.ID() > 0:
        # cpu_stats = dom.getCPUStats(False)
        # for (i, cpu) in enumerate(cpu_stats):
        # print 'CPU #%d Time: %.2lf sec' % (i, cpu['cpu_time'] / 1000000000.0 )

    print "View all details"
    print names
    active_hosts = conn.listDomainsID()
    if  len ( active_hosts ) > 0 :
        for id in active_hosts:
            dom = conn.lookupByID(id)
            infos = dom.info()
            print 'ID = %d' % id
            print 'Name =  %s' % dom.name()
            print 'State = %d' % infos[0]
            print 'Max Memory = %d' % infos[1]
            print 'Number of virt CPUs = %d' % infos[3]
            print 'CPU Time (in ns) = %d' % infos[2]
            print ' '

def quit():
    print "Exit on user request"
    sys.exit(0)


def menu():
    mm = [ {
        'Description': 'Change the host',
        'function' : chhost,
    },
          {
              'Description' : 'Start a Container' ,
              'function' : start
          },
          {
              'Description' : 'View a container',
              'function' : view
          },
          {
              'Description' : 'Stop a container',
              'function' : stop
          },
          {
              'Description' : "Take Screenshot",
              'function' : screenshot,
          },
          {
              'Description' :'View IP of Container',
              'function' : viewip,
          },
          {
              'Description' : 'View all Details of Conatainer',
              'function' : viewdets,
          },
          {
              'Description' : 'Quit',
              'function' : quit,
          },

          ]
    print "Virsh wrapper by Amit Agarwal"
    i = 0
    for i in range ( len (mm) ):
        print "\t%d) %s" % (i, mm[i]['Description'] )

    try:
        val = int(raw_input ("Please Select ::"))
    except:
        val=-1

    print len(mm)
    if val >= 0 and val < len (mm) :
        mm[val]['function']()


uri = "qemu:///system"
conn = libvirt.open(uri)
if conn == None:
    print 'Failed to open connection to the hypervisor'
    sys.exit(1)

while 1:
    menu()

author

Authored By Amit Agarwal

Amit Agarwal, Linux and Photography are my hobbies.Creative Commons Attribution 4.0 International License.

We notice you're using an adblocker. If you like our webite please keep us running by whitelisting this site in your ad blocker. We’re serving quality, related ads only. Thank you!

I've whitelisted your website.

Not now
This website uses cookies to ensure you get the best experience on our website. Learn more Got it