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

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 <>
# 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

names = []

def chhost():
    global hv_host
    global uri
    global conn

    print "Host is now set to "+hv_host

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

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

    print uri + " is set as URI"
    conn =
    if conn == None:
        print 'Failed to open connection to the hypervisor'
        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"
        for i in range ( len (active_hosts) ):
            dom0 = conn.lookupByID(active_hosts[i])
            print "\t%d\t%s"%(active_hosts[i],
        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):

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

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

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

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

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

    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] =
    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" %(, info(domain)),

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

    print "Id    Name                           State"
    print "-" * 52
    for dom in conn.listAllDomains() :
        [state, maxmem, mem, ncpu, cputime] =
        print "%3s %-31s%s" %\
            (dom.ID() if dom.ID() > 0 else "-",
        # 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 =
            print 'ID = %d' % id
            print 'Name =  %s' %
            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"

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'] )

        val = int(raw_input ("Please Select ::"))

    print len(mm)
    if val >= 0 and val < len (mm) :

uri = "qemu:///system"
conn =
if conn == None:
    print 'Failed to open connection to the hypervisor'

while 1:

Most simple and fast lightweight container with Fedora systemd

If you need to have a quick bash shell in sandbox with not network as well, then the most simple command I could find so far is:

sudo virt-sandbox -c lxc:/// /bin/bash

For this you will need to have libvirt-sandbox installed which you can do with the following command:

sudo yum install libvirt-sandbox

virsh – show ip address of all running VMs

If you are using the libvirt and associated tools, then you must be aware about virt-manager. However this being a GUI tools, it is not possible to always use this. “virsh” is a good option for this.

To start with, if you need to know all the VMs all the running VMs, then you can use (to only view the names):

virsh list --name

Extending this to make it more useful is the case if you need to know the IP address for the running VMs. Here is a simple code that you can put in alias or function that can be used to get the IP address of the running VM’s.

virsh list --name | \
while read line 
      [[ ! -z $line ]] && virsh domifaddr $line

Bonus note:
If you want to start the VM, then you can use

virsh start