1
0
Fork 0
mirror of https://github.com/retspen/webvirtcloud synced 2026-03-23 11:04:49 +00:00

Added V2 from scratch

This commit is contained in:
retspen 2018-09-23 13:17:48 +03:00
parent 5c2232f4e8
commit 6c2925a35d
478 changed files with 21437 additions and 134206 deletions

View file

@ -0,0 +1,2 @@
__author__ = "Anatoliy Guskov"
__license__ = "Apache 2.0"

499
backend/libvmgr/connect.py Normal file
View file

@ -0,0 +1,499 @@
import libvirt
import threading
import socket
from libvmgr import util
from libvmgr.rwlock import ReadWriteLock
from libvirt import libvirtError
CONN_SOCKET = 4
CONN_TLS = 3
CONN_SSH = 2
CONN_TCP = 1
TLS_PORT = 16514
SSH_PORT = 22
TCP_PORT = 16509
KEEPALIVE_COUNT = 30
KEEPALIVE_INTERVAL = 5
def host_is_up(conn_type, hostname):
"""
returns True if the given host is up and we are able to establish
a connection using the given credentials.
"""
try:
socket_host = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
socket_host.settimeout(2)
if conn_type == CONN_SSH:
if ':' in hostname:
LIBVIRT_HOST, PORT = (hostname).split(":")
PORT = int(PORT)
else:
PORT = SSH_PORT
LIBVIRT_HOST = hostname
socket_host.connect((LIBVIRT_HOST, PORT))
if conn_type == CONN_TCP:
socket_host.connect((hostname, TCP_PORT))
if conn_type == CONN_TLS:
socket_host.connect((hostname, TLS_PORT))
socket_host.close()
except socket.error:
raise libvirtError('Unable to connect to host server: Operation timed out')
class wvcEventLoop(threading.Thread):
def __init__(self, group=None, target=None, name=None, args=(), kwargs={}):
# register the default event implementation
# of libvirt, as we do not have an existing
# event loop.
libvirt.virEventRegisterDefaultImpl()
if name is None:
name = 'libvirt event loop'
super(wvcEventLoop, self).__init__(group, target, name, args, kwargs)
# we run this thread in deamon mode, so it does
# not block shutdown of the server
self.daemon = True
def run(self):
while True:
# if this method will fail it raises libvirtError
# we do not catch the exception here so it will show up
# in the logs. Not sure when this call will ever fail
libvirt.virEventRunDefaultImpl()
class wvcConnection(object):
"""
class representing a single connection stored in the Connection Manager
# to-do: may also need some locking to ensure to not connect simultaniously in 2 threads
"""
def __init__(self, host, login, passwd, conn):
"""
Sets all class attributes and tries to open the connection
"""
# connection lock is used to lock all changes to the connection state attributes
# (connection and last_error)
self.connection_state_lock = threading.Lock()
self.connection = None
self.last_error = None
# credentials
self.host = host
self.login = login
self.passwd = passwd
self.type = conn
# connect
self.connect()
def connect(self):
self.connection_state_lock.acquire()
try:
# recheck if we have a connection (it may have been
if not self.connected:
if self.type == CONN_TCP:
self.__connect_tcp()
elif self.type == CONN_SSH:
self.__connect_ssh()
elif self.type == CONN_TLS:
self.__connect_tls()
elif self.type == CONN_SOCKET:
self.__connect_socket()
else:
raise ValueError('"{type}" is not a valid connection type'.format(type=self.type))
if self.connected:
# do some preprocessing of the connection:
# * set keep alive interval
# * set connection close/fail handler
try:
self.connection.setKeepAlive(connection_manager.keepalive_interval,
connection_manager.keepalive_count)
try:
self.connection.registerCloseCallback(self.__connection_close_callback, None)
except Exception:
# Temporary fix for libvirt > libvirt-0.10.2-41
pass
except libvirtError as e:
# hypervisor driver does not seem to support persistent connections
self.last_error = str(e)
finally:
self.connection_state_lock.release()
@property
def connected(self):
try:
return self.connection is not None and self.connection.isAlive()
except libvirtError:
# isAlive failed for some reason
return False
def __libvirt_auth_credentials_callback(self, credentials, user_data):
for credential in credentials:
if credential[0] == libvirt.VIR_CRED_AUTHNAME:
credential[4] = self.login
if len(credential[4]) == 0:
credential[4] = credential[3]
elif credential[0] == libvirt.VIR_CRED_PASSPHRASE:
credential[4] = self.passwd
else:
return -1
return 0
def __connection_close_callback(self, connection, reason, opaque=None):
self.connection_state_lock.acquire()
try:
# on server shutdown libvirt module gets freed before the close callbacks are called
# so we just check here if it is still present
if libvirt is not None:
self.last_error = 'Connection closed'
# prevent other threads from using the connection (in the future)
self.connection = None
finally:
self.connection_state_lock.release()
def __connect_tcp(self):
flags = [libvirt.VIR_CRED_AUTHNAME, libvirt.VIR_CRED_PASSPHRASE]
auth = [flags, self.__libvirt_auth_credentials_callback, None]
uri = 'qemu+tcp://%s/system' % self.host
try:
self.connection = libvirt.openAuth(uri, auth, 0)
self.last_error = None
except libvirtError as e:
self.last_error = 'Connection Failed: ' + str(e)
self.connection = None
def __connect_ssh(self):
uri = 'qemu+ssh://%s@%s/system' % (self.login, self.host)
try:
self.connection = libvirt.open(uri)
self.last_error = None
except libvirtError as e:
self.last_error = 'Connection Failed: ' + str(e) + ' --- ' + repr(libvirt.virGetLastError())
self.connection = None
def __connect_tls(self):
flags = [libvirt.VIR_CRED_AUTHNAME, libvirt.VIR_CRED_PASSPHRASE]
auth = [flags, self.__libvirt_auth_credentials_callback, None]
uri = 'qemu+tls://%s@%s/system' % (self.login, self.host)
try:
self.connection = libvirt.openAuth(uri, auth, 0)
self.last_error = None
except libvirtError as e:
self.last_error = 'Connection Failed: ' + str(e)
self.connection = None
def __connect_socket(self):
uri = 'qemu:///system'
try:
self.connection = libvirt.open(uri)
self.last_error = None
except libvirtError as e:
self.last_error = 'Connection Failed: ' + str(e)
self.connection = None
def close(self):
"""
closes the connection (if it is active)
"""
self.connection_state_lock.acquire()
try:
if self.connected:
try:
# to-do: handle errors?
self.connection.close()
except libvirtError:
pass
self.connection = None
self.last_error = None
finally:
self.connection_state_lock.release()
def __del__(self):
if self.connection is not None:
# unregister callback (as it is no longer valid if this instance gets deleted)
try:
self.connection.unregisterCloseCallback()
except Exception:
pass
def __unicode__(self):
if self.type == CONN_TCP:
type_str = u'tcp'
elif self.type == CONN_SSH:
type_str = u'ssh'
elif self.type == CONN_TLS:
type_str = u'tls'
else:
type_str = u'invalid_type'
return u'qemu+{type}://{user}@{host}/system'.format(type=type_str, user=self.login, host=self.host)
def __repr__(self):
return '<wvcConnection {connection_str}>'.format(connection_str=str(self))
class wvcConnectionManager(object):
def __init__(self, keepalive_interval=5, keepalive_count=5):
self.keepalive_interval = keepalive_interval
self.keepalive_count = keepalive_count
# connection dict
# maps hostnames to a list of connection objects for this hostname
# atm it is possible to create more than one connection per hostname
# with different logins or auth methods
# connections are shared between all threads, see:
# http://wiki.libvirt.org/page/FAQ#Is_libvirt_thread_safe.3F
self._connections = dict()
self._connections_lock = ReadWriteLock()
# start event loop to handle keepalive requests and other events
self._event_loop = wvcEventLoop()
self._event_loop.start()
def _search_connection(self, host, login, passwd, conn):
"""
search the connection dict for a connection with the given credentials
if it does not exist return None
"""
self._connections_lock.acquireRead()
try:
if (host in self._connections):
connections = self._connections[host]
for connection in connections:
if (connection.login == login and connection.passwd == passwd and connection.type == conn):
return connection
finally:
self._connections_lock.release()
return None
def get_connection(self, host, login, passwd, conn):
"""
returns a connection object (as returned by the libvirt.open* methods) for the given host and credentials
raises libvirtError if (re)connecting fails
"""
# force all string values to unicode changed for Python3 to str
host = str(host)
login = str(login)
passwd = str(passwd) if passwd is not None else None
connection = self._search_connection(host, login, passwd, conn)
if (connection is None):
self._connections_lock.acquireWrite()
try:
# we have to search for the connection again after aquireing the write lock
# as the thread previously holding the write lock may have already added our connection
connection = self._search_connection(host, login, passwd, conn)
if (connection is None):
# create a new connection if a matching connection does not already exist
connection = wvcConnection(host, login, passwd, conn)
# add new connection to connection dict
if host in self._connections:
self._connections[host].append(connection)
else:
self._connections[host] = [connection]
finally:
self._connections_lock.release()
elif not connection.connected:
# try to (re-)connect if connection is closed
connection.connect()
if connection.connected:
# return libvirt connection object
return connection.connection
else:
# raise libvirt error
raise libvirtError(connection.last_error)
connection_manager = wvcConnectionManager(KEEPALIVE_INTERVAL, KEEPALIVE_COUNT)
class wvcConnect(object):
def __init__(self, host, login=None, passwd=None, conn_type=CONN_SOCKET, keepalive=True):
self.login = login
self.host = host
self.passwd = passwd
self.conn_type = conn_type
self.keepalive = keepalive
# is host up?
host_is_up(self.conn_type, self.host)
# get connection from connection manager
if self.keepalive:
self.conn = connection_manager.get_connection(host, login, passwd, conn_type)
else:
if self.conn_type == CONN_TCP:
def creds(credentials, user_data):
for credential in credentials:
if credential[0] == libvirt.VIR_CRED_AUTHNAME:
credential[4] = self.login
if len(credential[4]) == 0:
credential[4] = credential[3]
elif credential[0] == libvirt.VIR_CRED_PASSPHRASE:
credential[4] = self.passwd
else:
return -1
return 0
flags = [libvirt.VIR_CRED_AUTHNAME, libvirt.VIR_CRED_PASSPHRASE]
auth = [flags, creds, None]
uri = 'qemu+tcp://%s/system' % self.host
try:
self.conn = libvirt.openAuth(uri, auth, 0)
except libvirtError:
raise libvirtError('Connection Failed')
if self.conn_type == CONN_SSH:
uri = 'qemu+ssh://%s@%s/system' % (self.login, self.host)
try:
self.conn = libvirt.open(uri)
except libvirtError as err:
raise err
if self.conn_type == CONN_TLS:
def creds(credentials, user_data):
for credential in credentials:
if credential[0] == libvirt.VIR_CRED_AUTHNAME:
credential[4] = self.login
if len(credential[4]) == 0:
credential[4] = credential[3]
elif credential[0] == libvirt.VIR_CRED_PASSPHRASE:
credential[4] = self.passwd
else:
return -1
return 0
flags = [libvirt.VIR_CRED_AUTHNAME, libvirt.VIR_CRED_PASSPHRASE]
auth = [flags, creds, None]
uri = 'qemu+tls://%s@%s/system' % (self.login, self.host)
try:
self.conn = libvirt.openAuth(uri, auth, 0)
except libvirtError:
raise libvirtError('Connection Failed')
def get_cap_xml(self):
"""Return xml capabilities"""
return self.conn.getCapabilities()
def is_kvm_supported(self):
"""Return KVM capabilities."""
return util.is_kvm_available(self.get_cap_xml())
def get_storages(self):
storages = []
for pool in self.conn.listStoragePools():
storages.append(pool)
for pool in self.conn.listDefinedStoragePools():
storages.append(pool)
return storages
def get_networks(self):
virtnet = []
for net in self.conn.listNetworks():
virtnet.append(net)
for net in self.conn.listDefinedNetworks():
virtnet.append(net)
return virtnet
def get_ifaces(self):
interface = []
for inface in self.conn.listInterfaces():
interface.append(inface)
for inface in self.conn.listDefinedInterfaces():
interface.append(inface)
return interface
def get_iface(self, name):
return self.conn.interfaceLookupByName(name)
def get_secrets(self):
return self.conn.listSecrets()
def get_secret(self, uuid):
return self.conn.secretLookupByUUIDString(uuid)
def get_storage(self, name):
return self.conn.storagePoolLookupByName(name)
def get_volume_by_path(self, path):
return self.conn.storageVolLookupByPath(path)
def get_network(self, net):
return self.conn.networkLookupByName(net)
def get_instance(self, name):
return self.conn.lookupByName(name)
def get_instance_status(self, name):
dom = self.conn.lookupByName(name)
return dom.info()[0]
def get_instances(self):
instances = []
for inst_id in self.conn.listDomainsID():
dom = self.conn.lookupByID(int(inst_id))
instances.append(dom.name())
for name in self.conn.listDefinedDomains():
instances.append(name)
return instances
def get_snapshots(self):
instance = []
for snap_id in self.conn.listDomainsID():
dom = self.conn.lookupByID(int(snap_id))
if dom.snapshotNum(0) != 0:
instance.append(dom.name())
for name in self.conn.listDefinedDomains():
dom = self.conn.lookupByName(name)
if dom.snapshotNum(0) != 0:
instance.append(dom.name())
return instance
def get_net_device(self):
netdevice = []
for dev in self.conn.listAllDevices(0):
xml = dev.XMLDesc(0)
if util.get_xml_data(xml, 'capability', 'type') == 'net':
netdevice.append(util.get_xml_data(xml, 'capability/interface'))
return netdevice
def get_host_instances(self):
vname = {}
for name in self.get_instances():
dom = self.get_instance(name)
mem = util.get_xml_data(dom.XMLDesc(0), 'currentMemory')
mem = round(int(mem) / 1024)
cur_vcpu = util.get_xml_data(dom.XMLDesc(0), 'vcpu', 'current')
if cur_vcpu:
vcpu = cur_vcpu
else:
vcpu = util.get_xml_data(dom.XMLDesc(0), 'vcpu')
vname[dom.name()] = {'status': dom.info()[0], 'uuid': dom.UUIDString(), 'vcpu': vcpu, 'memory': mem}
return vname
def close(self):
"""Close connection"""
if not self.keepalive:
self.conn.close()

81
backend/libvmgr/host.py Normal file
View file

@ -0,0 +1,81 @@
import time
from libvmgr import util
from libvmgr.connect import wvcConnect
class wvcHost(wvcConnect):
def __init__(self, conn):
self.conn = conn
def get_node_info(self):
"""
Function return host server information: hostname, cpu, memory, ...
"""
info = list()
info.append(self.conn.getHostname())
info.append(self.conn.getInfo()[0])
info.append(self.conn.getInfo()[1] * (1024**2))
info.append(self.conn.getInfo()[2])
info.append(util.get_xml_data(self.conn.getSysinfo(0), 'processor/entry[6]'))
info.append(self.conn.getURI())
return info
def hypervisor_type(self):
"""
Return hypervisor type
"""
return util.get_xml_data(self.get_cap_xml(), 'guest/arch/domain', 'type')
def get_memory_usage(self):
"""
Function return memory usage on node.
"""
host_mem = self.conn.getInfo()[1] * (1024**2)
free_mem = self.conn.getMemoryStats(-1, 0)
if isinstance(free_mem, dict):
mem = list(free_mem.values())
free = (mem[1] + mem[2] + mem[3]) * 1024
percent = (100 - ((free * 100) / host_mem))
usage = (host_mem - free)
mem_usage = {'size': host_mem, 'usage': usage, 'percent': round(percent)}
else:
mem_usage = {'size': 0, 'usage': 0, 'percent': 0}
return mem_usage
def get_storage_usage(self, name):
"""
Function return storage usage on node by name.
"""
pool = self.get_storage(name)
pool.refresh()
if pool.isActive():
size = pool.info()[1]
free = pool.info()[3]
used = size - free
percent = (used * 100) / size
return {'size': size, 'used': used, 'percent': percent}
else:
return {'size': 0, 'used': 0, 'percent': 0}
def get_cpu_usage(self):
"""
Function return cpu usage on node.
"""
prev_idle = 0
prev_total = 0
diff_usage = 0
cpu = self.conn.getCPUStats(-1, 0)
if isinstance(cpu, dict):
for num in range(2):
idle = self.conn.getCPUStats(-1, 0)['idle']
total = sum(self.conn.getCPUStats(-1, 0).values())
diff_idle = idle - prev_idle
diff_total = total - prev_total
diff_usage = (1000 * (diff_total - diff_idle) / diff_total + 5) / 10
prev_total = total
prev_idle = idle
if num == 0:
time.sleep(1)
if diff_usage < 0:
diff_usage = 0
return {'usage': round(diff_usage)}

226
backend/libvmgr/rwlock.py Normal file
View file

@ -0,0 +1,226 @@
# -*- coding: iso-8859-15 -*-
"""locks.py - Read-Write lock thread lock implementation
See the class documentation for more info.
Copyright (C) 2007, Heiko Wundram.
Released under the BSD-license.
found at: http://code.activestate.com/recipes/502283-read-write-lock-class-rlock-like/
"""
# Imports
# -------
from threading import Condition, Lock, currentThread
from time import time
# Read write lock
# ---------------
class ReadWriteLock(object):
"""Read-Write lock class. A read-write lock differs from a standard
threading.RLock() by allowing multiple threads to simultaneously hold a
read lock, while allowing only a single thread to hold a write lock at the
same point of time.
When a read lock is requested while a write lock is held, the reader
is blocked; when a write lock is requested while another write lock is
held or there are read locks, the writer is blocked.
Writers are always preferred by this implementation: if there are blocked
threads waiting for a write lock, current readers may request more read
locks (which they eventually should free, as they starve the waiting
writers otherwise), but a new thread requesting a read lock will not
be granted one, and block. This might mean starvation for readers if
two writer threads interweave their calls to acquireWrite() without
leaving a window only for readers.
In case a current reader requests a write lock, this can and will be
satisfied without giving up the read locks first, but, only one thread
may perform this kind of lock upgrade, as a deadlock would otherwise
occur. After the write lock has been granted, the thread will hold a
full write lock, and not be downgraded after the upgrading call to
acquireWrite() has been match by a corresponding release().
"""
def __init__(self):
"""Initialize this read-write lock."""
# Condition variable, used to signal waiters of a change in object
# state.
self.__condition = Condition(Lock())
# Initialize with no writers.
self.__writer = None
self.__upgradewritercount = 0
self.__pendingwriters = []
# Initialize with no readers.
self.__readers = {}
def acquireRead(self, timeout=None):
"""Acquire a read lock for the current thread, waiting at most
timeout seconds or doing a non-blocking check in case timeout is <= 0.
In case timeout is None, the call to acquireRead blocks until the
lock request can be serviced.
In case the timeout expires before the lock could be serviced, a
RuntimeError is thrown."""
if timeout is not None:
endtime = time() + timeout
me = currentThread()
self.__condition.acquire()
try:
if self.__writer is me:
# If we are the writer, grant a new read lock, always.
self.__writercount += 1
return
while True:
if self.__writer is None:
# Only test anything if there is no current writer.
if self.__upgradewritercount or self.__pendingwriters:
if me in self.__readers:
# Only grant a read lock if we already have one
# in case writers are waiting for their turn.
# This means that writers can't easily get starved
# (but see below, readers can).
self.__readers[me] += 1
return
# No, we aren't a reader (yet), wait for our turn.
else:
# Grant a new read lock, always, in case there are
# no pending writers (and no writer).
self.__readers[me] = self.__readers.get(me, 0) + 1
return
if timeout is not None:
remaining = endtime - time()
if remaining <= 0:
# Timeout has expired, signal caller of this.
raise RuntimeError("Acquiring read lock timed out")
self.__condition.wait(remaining)
else:
self.__condition.wait()
finally:
self.__condition.release()
def acquireWrite(self, timeout=None):
"""Acquire a write lock for the current thread, waiting at most
timeout seconds or doing a non-blocking check in case timeout is <= 0.
In case the write lock cannot be serviced due to the deadlock
condition mentioned above, a ValueError is raised.
In case timeout is None, the call to acquireWrite blocks until the
lock request can be serviced.
In case the timeout expires before the lock could be serviced, a
RuntimeError is thrown."""
if timeout is not None:
endtime = time() + timeout
me, upgradewriter = currentThread(), False
self.__condition.acquire()
try:
if self.__writer is me:
# If we are the writer, grant a new write lock, always.
self.__writercount += 1
return
elif me in self.__readers:
# If we are a reader, no need to add us to pendingwriters,
# we get the upgradewriter slot.
if self.__upgradewritercount:
# If we are a reader and want to upgrade, and someone
# else also wants to upgrade, there is no way we can do
# this except if one of us releases all his read locks.
# Signal this to user.
raise ValueError(
"Inevitable dead lock, denying write lock"
)
upgradewriter = True
self.__upgradewritercount = self.__readers.pop(me)
else:
# We aren't a reader, so add us to the pending writers queue
# for synchronization with the readers.
self.__pendingwriters.append(me)
while True:
if not self.__readers and self.__writer is None:
# Only test anything if there are no readers and writers.
if self.__upgradewritercount:
if upgradewriter:
# There is a writer to upgrade, and it's us. Take
# the write lock.
self.__writer = me
self.__writercount = self.__upgradewritercount + 1
self.__upgradewritercount = 0
return
# There is a writer to upgrade, but it's not us.
# Always leave the upgrade writer the advance slot,
# because he presumes he'll get a write lock directly
# from a previously held read lock.
elif self.__pendingwriters[0] is me:
# If there are no readers and writers, it's always
# fine for us to take the writer slot, removing us
# from the pending writers queue.
# This might mean starvation for readers, though.
self.__writer = me
self.__writercount = 1
self.__pendingwriters = self.__pendingwriters[1:]
return
if timeout is not None:
remaining = endtime - time()
if remaining <= 0:
# Timeout has expired, signal caller of this.
if upgradewriter:
# Put us back on the reader queue. No need to
# signal anyone of this change, because no other
# writer could've taken our spot before we got
# here (because of remaining readers), as the test
# for proper conditions is at the start of the
# loop, not at the end.
self.__readers[me] = self.__upgradewritercount
self.__upgradewritercount = 0
else:
# We were a simple pending writer, just remove us
# from the FIFO list.
self.__pendingwriters.remove(me)
raise RuntimeError("Acquiring write lock timed out")
self.__condition.wait(remaining)
else:
self.__condition.wait()
finally:
self.__condition.release()
def release(self):
"""Release the currently held lock.
In case the current thread holds no lock, a ValueError is thrown."""
me = currentThread()
self.__condition.acquire()
try:
if self.__writer is me:
# We are the writer, take one nesting depth away.
self.__writercount -= 1
if not self.__writercount:
# No more write locks; take our writer position away and
# notify waiters of the new circumstances.
self.__writer = None
self.__condition.notifyAll()
elif me in self.__readers:
# We are a reader currently, take one nesting depth away.
self.__readers[me] -= 1
if not self.__readers[me]:
# No more read locks, take our reader position away.
del self.__readers[me]
if not self.__readers:
# No more readers, notify waiters of the new
# circumstances.
self.__condition.notifyAll()
else:
raise ValueError("Trying to release unheld lock")
finally:
self.__condition.release()

159
backend/libvmgr/util.py Normal file
View file

@ -0,0 +1,159 @@
import re
import socket
import random
import libvirt
import paramiko
from time import sleep
from xml.etree import ElementTree
from string import ascii_letters, digits
from passlib.hash import sha512_crypt
def is_kvm_available(xml):
tree = ElementTree.fromstring(xml)
for dom in tree.findall('guest/arch/domain'):
if 'kvm' in dom.get('type'):
return True
return False
def randomMAC():
"""Generate a random MAC address."""
# qemu MAC
oui = [0x52, 0x54, 0x00]
mac = oui + [random.randint(0x00, 0xff),
random.randint(0x00, 0xff),
random.randint(0x00, 0xff)]
return ':'.join(map(lambda x: "%02x" % x, mac))
def randomUUID():
"""Generate a random UUID."""
u = [random.randint(0, 255) for dummy in range(0, 16)]
return "-".join(["%02x" * 4, "%02x" * 2, "%02x" * 2, "%02x" * 2, "%02x" * 6]) % tuple(u)
def get_max_vcpus(conn, type=None):
"""@param conn: libvirt connection to poll for max possible vcpus
@type type: optional guest type (kvm, etc.)"""
if type is None:
type = conn.getType()
try:
m = conn.getMaxVcpus(type.lower())
except libvirt.libvirtError:
m = 32
return m
def xml_escape(str):
"""Replaces chars ' " < > & with xml safe counterparts"""
if str is None:
return None
str = str.replace("&", "&amp;")
str = str.replace("'", "&apos;")
str = str.replace("\"", "&quot;")
str = str.replace("<", "&lt;")
str = str.replace(">", "&gt;")
return str
def compareMAC(p, q):
"""Compare two MAC addresses"""
pa = p.split(":")
qa = q.split(":")
if len(pa) != len(qa):
if p > q:
return 1
else:
return -1
for i in range(len(pa)):
n = int(pa[i], 0x10) - int(qa[i], 0x10)
if n > 0:
return 1
elif n < 0:
return -1
return 0
def get_xml_data(xml, path=None, element=None):
res = ''
if not path and not element:
return ''
tree = ElementTree.fromstring(xml)
if path:
child = tree.find(path)
if child is not None:
if element:
res = child.get(element)
else:
res = child.text
else:
res = tree.get(element)
return res
def get_xml_findall(xml, string):
tree = ElementTree.fromstring(xml)
return tree.findall(string)
def pretty_mem(val):
val = int(val)
if val > (10 * 1024 * 1024):
return "%2.2f GB" % (val / (1024.0 * 1024.0))
else:
return "%2.0f MB" % (val / 1024.0)
def pretty_bytes(val):
val = int(val)
if val > (1024 * 1024 * 1024):
return "%2.2f GB" % (val / (1024.0 * 1024.0 * 1024.0))
else:
return "%2.2f MB" % (val / (1024.0 * 1024.0))
def gen_password(length=14):
password = ''.join(
[random.choice(ascii_letters + digits) for dummy in range(length)]
)
return password
def password_to_hash(password):
salt = gen_password(8)
password_hash = sha512_crypt.encrypt(password, salt=salt, rounds=5000)
return password_hash
def similar_name(pattern, names):
res = []
for name in names:
match = re.match(pattern, name)
if match:
res.append(name)
return res
def check_ssh_connection(hostname, password, username='root', timeout=90):
ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
for i in range(timeout):
try:
ssh.connect(hostname, username=username, password=password)
ssh.close()
return True
except (paramiko.BadHostKeyException,
paramiko.AuthenticationException,
paramiko.SSHException,
socket.error,
EOFError):
sleep(1)
return False