Add vm listing
This commit is contained in:
parent
3fc7c633d4
commit
e00189e21f
@ -3,3 +3,5 @@ Jinja2>=2.8
|
|||||||
netaddr>=0.7.18
|
netaddr>=0.7.18
|
||||||
libvirt-python>=1.3.1
|
libvirt-python>=1.3.1
|
||||||
ovh==0.4.7
|
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
|
#!/usr/bin/env python
|
||||||
"""vm - simple libvirt wrapper
|
"""vm - simple libvirt wrapper
|
||||||
usage: vm [--version] [--help] <command> [<args>...]
|
usage: vm [--version] [--help] [options] <command> [<args>...]
|
||||||
|
|
||||||
Available commands are:
|
Available commands are:
|
||||||
create Create new VM from cloud image
|
create Create new VM from cloud image
|
||||||
ip:list List available OVH IPs
|
ip:list List available OVH IPs
|
||||||
ip:sync Create missing vMACs for 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
|
from __future__ import print_function
|
||||||
@ -29,6 +32,7 @@ import libvirt
|
|||||||
import ovhtool
|
import ovhtool
|
||||||
import ovh
|
import ovh
|
||||||
import ovh.exceptions
|
import ovh.exceptions
|
||||||
|
from collections import namedtuple
|
||||||
|
|
||||||
BASE = os.path.dirname(os.path.abspath(__file__))
|
BASE = os.path.dirname(os.path.abspath(__file__))
|
||||||
|
|
||||||
@ -73,7 +77,8 @@ class Instance(object):
|
|||||||
ovh_ips = None
|
ovh_ips = None
|
||||||
|
|
||||||
def __init__(self, name, cpus, memory, storage, template,
|
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
|
# General
|
||||||
self.name = name
|
self.name = name
|
||||||
self.cpus = cpus
|
self.cpus = cpus
|
||||||
@ -98,6 +103,8 @@ class Instance(object):
|
|||||||
if not self.password:
|
if not self.password:
|
||||||
self.password = gen_password()
|
self.password = gen_password()
|
||||||
|
|
||||||
|
self._libvirt_conn = libvirt_conn
|
||||||
|
|
||||||
def create(self):
|
def create(self):
|
||||||
self.prepare_datasource()
|
self.prepare_datasource()
|
||||||
self.prepare_storage()
|
self.prepare_storage()
|
||||||
@ -133,10 +140,16 @@ class Instance(object):
|
|||||||
self.template_path, self.storage_path)
|
self.template_path, self.storage_path)
|
||||||
|
|
||||||
def prepare_instance(self):
|
def prepare_instance(self):
|
||||||
conn = libvirt.open(None)
|
conn = self.libvirt_conn
|
||||||
dom = conn.defineXML(self.libvirt_definition)
|
dom = conn.defineXML(self.libvirt_definition)
|
||||||
dom.create()
|
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):
|
def generate_ip(self):
|
||||||
'''Generates IP address when none was provided by user'''
|
'''Generates IP address when none was provided by user'''
|
||||||
if not self.ovh_ips:
|
if not self.ovh_ips:
|
||||||
@ -271,16 +284,170 @@ ey?
|
|||||||
return 0
|
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 = {
|
commands = {
|
||||||
'create': cmd_create,
|
'create': cmd_create,
|
||||||
|
'list': cmd_list,
|
||||||
'ip:list': cmd_iplist,
|
'ip:list': cmd_iplist,
|
||||||
'ip:sync': cmd_ipsync,
|
'ip:sync': cmd_ipsync,
|
||||||
'help': cmd_help,
|
'help': cmd_help,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
libvirt_conn = None
|
||||||
|
|
||||||
def main(gargv):
|
def main(gargv):
|
||||||
|
global libvirt_conn
|
||||||
args = docopt(__doc__, version='vm '+__version__,
|
args = docopt(__doc__, version='vm '+__version__,
|
||||||
options_first=True, argv=gargv)
|
options_first=True, argv=gargv)
|
||||||
|
libvirt_conn = libvirt.open(args['--libvirt'])
|
||||||
cmd = args['<command>'].lower()
|
cmd = args['<command>'].lower()
|
||||||
argv = [cmd] + args['<args>']
|
argv = [cmd] + args['<args>']
|
||||||
if cmd not in commands:
|
if cmd not in commands:
|
||||||
|
Loading…
x
Reference in New Issue
Block a user