Get disk usage for all the containers with python script

With my increasing love for python, here is my attempt to get the disk usage of all the containers on some host. Well, since the requirements vary for everyone, so this script is far from complete.

import docker
import json

# We will connect to 192.168.122.1 for docker daemon. If that is not the case,
# then change the below.

client = docker.DockerClient(base_url="tcp://192.168.122.1:4243")

# Get list of all containers.
cls=client.containers.list()
stats={}

# And now we will iterate over that list to get stats for all the containers.
for val in cls:
    print (val.name)
    stats[val.name] = val.stats(stream=False)
    # Get the disk usage for root and /tmp from containers with docker.exec
    stats[val.name]['df-root'] = ( str(val.exec_run(r'df -kh --output="size,used,avail,pcent" /', stream=False).splitlines()[1]).replace("'","").split()[1:] )
    stats[val.name]['df-tmp'] = ( str((val.exec_run(r'df -kh --output="size,used,avail,pcent" /tmp ', stream=False).splitlines()[1:]+[''])[0]).replace("'","").split()[1:] )

# Now if you want, we have dict of all the data and we can process the
# way we like it, for example create a html table for disk usage only.
print ('<table>')
for st in stats:
    print ('<tr>')
    print ("<td>Root-%s</td>"%(st))
    for i in stats[st]['df-root']:
        print ('<td>%s</td>'%(i) )
    print ('</tr>')
    print ('<tr>')
    print ("<td>tmp-%s</td>"%(st))
    for i in stats[st]['df-tmp']:
        print ('<td>%s</td>'%(i) )
    print ('</tr>')

print ('</table>')

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 <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()