Add vm listing
This commit is contained in:
parent
3fc7c633d4
commit
e00189e21f
@ -3,3 +3,5 @@ Jinja2>=2.8
|
||||
netaddr>=0.7.18
|
||||
libvirt-python>=1.3.1
|
||||
ovh==0.4.7
|
||||
termcolor==1.1.0
|
||||
terminaltables==3.1.0
|
||||
|
173
vm.py
173
vm.py
@ -1,11 +1,14 @@
|
||||
#!/usr/bin/env python
|
||||
"""vm - simple libvirt wrapper
|
||||
usage: vm [--version] [--help] <command> [<args>...]
|
||||
usage: vm [--version] [--help] [options] <command> [<args>...]
|
||||
|
||||
Available commands are:
|
||||
create Create new VM from cloud image
|
||||
ip:list List available OVH IPs
|
||||
ip:sync Create missing vMACs for OVH IPs
|
||||
|
||||
Available options are:
|
||||
-l, --libvirt=URI Use provided URI to connect to libvirt host
|
||||
"""
|
||||
|
||||
from __future__ import print_function
|
||||
@ -29,6 +32,7 @@ import libvirt
|
||||
import ovhtool
|
||||
import ovh
|
||||
import ovh.exceptions
|
||||
from collections import namedtuple
|
||||
|
||||
BASE = os.path.dirname(os.path.abspath(__file__))
|
||||
|
||||
@ -73,7 +77,8 @@ class Instance(object):
|
||||
ovh_ips = None
|
||||
|
||||
def __init__(self, name, cpus, memory, storage, template,
|
||||
ip=None, mac=None, dns=None, password=None):
|
||||
ip=None, mac=None, dns=None, password=None,
|
||||
libvirt_conn=None):
|
||||
# General
|
||||
self.name = name
|
||||
self.cpus = cpus
|
||||
@ -98,6 +103,8 @@ class Instance(object):
|
||||
if not self.password:
|
||||
self.password = gen_password()
|
||||
|
||||
self._libvirt_conn = libvirt_conn
|
||||
|
||||
def create(self):
|
||||
self.prepare_datasource()
|
||||
self.prepare_storage()
|
||||
@ -133,10 +140,16 @@ class Instance(object):
|
||||
self.template_path, self.storage_path)
|
||||
|
||||
def prepare_instance(self):
|
||||
conn = libvirt.open(None)
|
||||
conn = self.libvirt_conn
|
||||
dom = conn.defineXML(self.libvirt_definition)
|
||||
dom.create()
|
||||
|
||||
@property
|
||||
def libvirt_conn(self):
|
||||
if not self._libvirt_conn:
|
||||
self._libvirt_conn = libvirt.open(None)
|
||||
return self._libvirt_conn
|
||||
|
||||
def generate_ip(self):
|
||||
'''Generates IP address when none was provided by user'''
|
||||
if not self.ovh_ips:
|
||||
@ -271,16 +284,170 @@ ey?
|
||||
return 0
|
||||
|
||||
|
||||
from xml.dom import minidom
|
||||
|
||||
DomainInfo = namedtuple('DomainInfo', [
|
||||
'state', 'max_memory', 'memory', 'vcpus', 'cpu_time'
|
||||
])
|
||||
|
||||
BlockInfo = namedtuple('BlockInfo', [
|
||||
'capacity', 'allocation', 'physical'
|
||||
])
|
||||
|
||||
class LibvirtInterface(object):
|
||||
def __init__(self, elm):
|
||||
self.elm = elm
|
||||
|
||||
@property
|
||||
def type(self):
|
||||
return self.elm.getAttribute('type')
|
||||
|
||||
@property
|
||||
def mac(self):
|
||||
return self.elm.getElementsByTagName('mac')[0].getAttribute('address')
|
||||
|
||||
@property
|
||||
def alias(self):
|
||||
return self.elm.getElementsByTagName('alias')[0].getAttribute('name')
|
||||
|
||||
@property
|
||||
def source(self):
|
||||
return self.elm.getElementsByTagName('source')[0].getAttribute('bridge')
|
||||
|
||||
|
||||
class LibvirtDisk(object):
|
||||
def __init__(self, elm, dom):
|
||||
self.elm = elm
|
||||
self.domain = dom
|
||||
|
||||
@property
|
||||
def type(self):
|
||||
return self.elm.getAttribute('type')
|
||||
|
||||
@property
|
||||
def source(self):
|
||||
src = self.elm.getElementsByTagName('source')
|
||||
|
||||
if src:
|
||||
return src[0].getAttribute('dev')
|
||||
|
||||
@property
|
||||
def info(self):
|
||||
if self.source:
|
||||
return BlockInfo(*self.domain.blockInfo(self.source))
|
||||
|
||||
@property
|
||||
def present(self):
|
||||
return bool(self.source)
|
||||
|
||||
|
||||
class LibvirtDomain(object):
|
||||
_xml = None
|
||||
|
||||
def __init__(self, dom, conn=None):
|
||||
self.domain = dom
|
||||
self.conn = conn
|
||||
|
||||
@property
|
||||
def xml(self):
|
||||
if not self._xml:
|
||||
self._xml = minidom.parseString(self.domain.XMLDesc(0))
|
||||
|
||||
return self._xml
|
||||
|
||||
@property
|
||||
def info(self):
|
||||
return DomainInfo(*self.domain.info())
|
||||
|
||||
@property
|
||||
def name(self):
|
||||
return self.domain.name()
|
||||
|
||||
@property
|
||||
def interfaces(self):
|
||||
for interface in self.xml.getElementsByTagName('interface'):
|
||||
yield LibvirtInterface(interface)
|
||||
|
||||
@property
|
||||
def disks(self):
|
||||
for disk in self.xml.getElementsByTagName('disk'):
|
||||
yield LibvirtDisk(disk, self.domain)
|
||||
|
||||
def cmd_list(args):
|
||||
'''usage: vm list
|
||||
|
||||
List existing virtual machines with a summary
|
||||
'''
|
||||
import terminaltables
|
||||
from termcolor import colored
|
||||
|
||||
global libvirt_conn
|
||||
|
||||
def domains_list():
|
||||
state_colors = {
|
||||
1: 'green',
|
||||
3: 'yellow',
|
||||
5: 'red',
|
||||
}
|
||||
|
||||
yield ['Name', 'RAM', 'vCPUs', 'IP', 'Storage']
|
||||
|
||||
mem_sum = 0
|
||||
|
||||
for dom in libvirt_conn.listAllDomains():
|
||||
state, max_mem, mem, vcpus, cputime = dom.info()
|
||||
|
||||
d = LibvirtDomain(dom)
|
||||
|
||||
formatted_mem = '%dM' % (mem/1024)
|
||||
|
||||
if mem != max_mem:
|
||||
formatted_mem += colored(' (%dM)' % (max_mem/1024), 'grey')
|
||||
|
||||
mem_sum += mem
|
||||
|
||||
disk_info = []
|
||||
for disk in d.disks:
|
||||
if disk.type == 'block' and disk.present:
|
||||
disk_info.append(
|
||||
('%dG ' + colored('(%s)', 'grey')) % (
|
||||
disk.info.physical/(1024*1024*1024), disk.source
|
||||
)
|
||||
)
|
||||
yield [
|
||||
colored(d.name, state_colors.get(state, None)),
|
||||
formatted_mem,
|
||||
vcpus,
|
||||
'',
|
||||
', '.join(disk_info)
|
||||
]
|
||||
|
||||
yield []
|
||||
yield ['', '%dM' % (mem_sum/1024), '', '', '']
|
||||
|
||||
table = terminaltables.SingleTable(list(domains_list()))
|
||||
table.justify_columns={
|
||||
0: 'right', 1: 'right', 2: 'right'
|
||||
}
|
||||
|
||||
print(table.table)
|
||||
|
||||
|
||||
commands = {
|
||||
'create': cmd_create,
|
||||
'list': cmd_list,
|
||||
'ip:list': cmd_iplist,
|
||||
'ip:sync': cmd_ipsync,
|
||||
'help': cmd_help,
|
||||
}
|
||||
|
||||
libvirt_conn = None
|
||||
|
||||
def main(gargv):
|
||||
global libvirt_conn
|
||||
args = docopt(__doc__, version='vm '+__version__,
|
||||
options_first=True, argv=gargv)
|
||||
libvirt_conn = libvirt.open(args['--libvirt'])
|
||||
cmd = args['<command>'].lower()
|
||||
argv = [cmd] + args['<args>']
|
||||
if cmd not in commands:
|
||||
|
Loading…
x
Reference in New Issue
Block a user