Fix flake8 errors and add tox flake8 tests
Change-Id: I970c75fb6859a9c186636f111ac1e97b253e591c
This commit is contained in:
parent
d261da013a
commit
1def596d99
|
@ -3,5 +3,7 @@ dist
|
|||
MANIFEST
|
||||
.idea
|
||||
*.pyc
|
||||
*~
|
||||
TAGS
|
||||
local_settings.py
|
||||
.tox
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
|
||||
class DevopsDriver(object):
|
||||
|
||||
def __init__(self, **driver_parameters):
|
||||
|
|
|
@ -12,23 +12,20 @@
|
|||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
|
||||
from contextlib import contextmanager
|
||||
import os
|
||||
import shutil
|
||||
import subprocess
|
||||
import time
|
||||
|
||||
from contextlib import contextmanager
|
||||
from devops.helpers.retry import retry
|
||||
from devops import error
|
||||
from devops.helpers.retry import retry
|
||||
from devops import logger as LOGGER
|
||||
|
||||
|
||||
class DevopsDriver(object):
|
||||
def __getattr__(self, name):
|
||||
"""
|
||||
Default method for all unimplemented functions
|
||||
"""
|
||||
"""Default method for all unimplemented functions."""
|
||||
def default_method(*args, **kwargs):
|
||||
LOGGER.debug('Call of unimplemented method detected. '
|
||||
'Method is {0}{1}{2}'.format(name, args, kwargs))
|
||||
|
@ -88,7 +85,8 @@ class DevopsDriver(object):
|
|||
|
||||
@retry(20, 30)
|
||||
def set_node_boot(self, device):
|
||||
"""
|
||||
"""Set boot device
|
||||
|
||||
Valid are:
|
||||
pxe,
|
||||
disk,
|
||||
|
@ -177,7 +175,7 @@ class DevopsDriver(object):
|
|||
return True
|
||||
|
||||
def _add_self_temp_ip(self):
|
||||
#Check all IPs
|
||||
# Check all IPs
|
||||
cmd = ['sudo', 'ip', 'addr', 'sh']
|
||||
output = subprocess.check_output(cmd)
|
||||
if output.find(self.ip_install_server) > -1:
|
||||
|
@ -227,7 +225,7 @@ class DevopsDriver(object):
|
|||
subprocess.call(cmd)
|
||||
pid_file.close()
|
||||
LOGGER.debug('dnsmasq killed')
|
||||
except subprocess.CalledProcessError, e:
|
||||
except subprocess.CalledProcessError as e:
|
||||
LOGGER.warning("Can't stop dnsmasq: {0}".format(e.output))
|
||||
return True
|
||||
|
||||
|
|
|
@ -18,11 +18,11 @@ import libvirt
|
|||
from time import sleep
|
||||
import xml.etree.ElementTree as ET
|
||||
|
||||
from devops import logger
|
||||
from devops.driver.libvirt.libvirt_xml_builder import LibvirtXMLBuilder
|
||||
from devops.helpers import scancodes
|
||||
from devops.helpers.helpers import _get_file_size
|
||||
from devops.helpers.retry import retry
|
||||
from devops.helpers import scancodes
|
||||
from devops import logger
|
||||
|
||||
from django.conf import settings
|
||||
|
||||
|
@ -49,7 +49,8 @@ class DevopsDriver(object):
|
|||
|
||||
@retry()
|
||||
def get_capabilities(self):
|
||||
"""
|
||||
"""Get host capabilities
|
||||
|
||||
:rtype : ET
|
||||
"""
|
||||
if self.capabilities is None:
|
||||
|
@ -58,7 +59,8 @@ class DevopsDriver(object):
|
|||
|
||||
@retry()
|
||||
def network_bridge_name(self, network):
|
||||
"""
|
||||
"""Get bridge name from UUID
|
||||
|
||||
:type network: Network
|
||||
:rtype : String
|
||||
"""
|
||||
|
@ -66,7 +68,8 @@ class DevopsDriver(object):
|
|||
|
||||
@retry()
|
||||
def network_name(self, network):
|
||||
"""
|
||||
"""Get network name from UUID
|
||||
|
||||
:type network: Network
|
||||
:rtype : String
|
||||
"""
|
||||
|
@ -74,7 +77,8 @@ class DevopsDriver(object):
|
|||
|
||||
@retry()
|
||||
def network_active(self, network):
|
||||
"""
|
||||
"""Check if network is active
|
||||
|
||||
:type network: Network
|
||||
:rtype : Boolean
|
||||
"""
|
||||
|
@ -82,7 +86,8 @@ class DevopsDriver(object):
|
|||
|
||||
@retry()
|
||||
def node_active(self, node):
|
||||
"""
|
||||
"""Check if node is active
|
||||
|
||||
:type node: Node
|
||||
:rtype : Boolean
|
||||
"""
|
||||
|
@ -90,14 +95,15 @@ class DevopsDriver(object):
|
|||
|
||||
@retry()
|
||||
def network_exists(self, network):
|
||||
"""
|
||||
"""Check if network exists
|
||||
|
||||
:type network: Network
|
||||
:rtype : Boolean
|
||||
"""
|
||||
try:
|
||||
self.conn.networkLookupByUUIDString(network.uuid)
|
||||
return True
|
||||
except libvirt.libvirtError, e:
|
||||
except libvirt.libvirtError as e:
|
||||
if e.get_error_code() == libvirt.VIR_ERR_NO_NETWORK:
|
||||
return False
|
||||
else:
|
||||
|
@ -105,14 +111,15 @@ class DevopsDriver(object):
|
|||
|
||||
@retry()
|
||||
def node_exists(self, node):
|
||||
"""
|
||||
"""Check if node exists
|
||||
|
||||
:type node: Node
|
||||
:rtype : Boolean
|
||||
"""
|
||||
try:
|
||||
self.conn.lookupByUUIDString(node.uuid)
|
||||
return True
|
||||
except libvirt.libvirtError, e:
|
||||
except libvirt.libvirtError as e:
|
||||
if e.get_error_code() == libvirt.VIR_ERR_NO_DOMAIN:
|
||||
return False
|
||||
else:
|
||||
|
@ -120,15 +127,17 @@ class DevopsDriver(object):
|
|||
|
||||
@retry()
|
||||
def node_snapshot_exists(self, node, name):
|
||||
"""
|
||||
"""Check if snapshot exists
|
||||
|
||||
:type node: Node
|
||||
:type name: String
|
||||
:rtype : Boolean
|
||||
"""
|
||||
ret = self.conn.lookupByUUIDString(node.uuid)
|
||||
try:
|
||||
ret.snapshotLookupByName(name, 0)
|
||||
return True
|
||||
except libvirt.libvirtError, e:
|
||||
except libvirt.libvirtError as e:
|
||||
if e.get_error_code() == libvirt.VIR_ERR_NO_DOMAIN_SNAPSHOT:
|
||||
return False
|
||||
else:
|
||||
|
@ -136,14 +145,15 @@ class DevopsDriver(object):
|
|||
|
||||
@retry()
|
||||
def volume_exists(self, volume):
|
||||
"""
|
||||
"""Check if volume exists
|
||||
|
||||
:type volume: Volume
|
||||
:rtype : Boolean
|
||||
"""
|
||||
try:
|
||||
self.conn.storageVolLookupByKey(volume.uuid)
|
||||
return True
|
||||
except libvirt.libvirtError, e:
|
||||
except libvirt.libvirtError as e:
|
||||
if e.get_error_code() == libvirt.VIR_ERR_NO_STORAGE_VOL:
|
||||
return False
|
||||
else:
|
||||
|
@ -151,8 +161,10 @@ class DevopsDriver(object):
|
|||
|
||||
@retry()
|
||||
def network_define(self, network):
|
||||
"""
|
||||
:rtype : None
|
||||
"""Define network
|
||||
|
||||
:type network: Network
|
||||
:rtype : None
|
||||
"""
|
||||
ret = self.conn.networkDefineXML(
|
||||
self.xml_builder.build_network_xml(network))
|
||||
|
@ -161,28 +173,35 @@ class DevopsDriver(object):
|
|||
|
||||
@retry()
|
||||
def network_destroy(self, network):
|
||||
"""
|
||||
:rtype : None
|
||||
"""Destroy network
|
||||
|
||||
:type network: Network
|
||||
:rtype : None
|
||||
"""
|
||||
self.conn.networkLookupByUUIDString(network.uuid).destroy()
|
||||
|
||||
@retry()
|
||||
def network_undefine(self, network):
|
||||
"""
|
||||
:rtype : None
|
||||
"""Undefine network
|
||||
|
||||
:type network: Network
|
||||
:rtype : None
|
||||
"""
|
||||
self.conn.networkLookupByUUIDString(network.uuid).undefine()
|
||||
|
||||
@retry()
|
||||
def network_create(self, network):
|
||||
"""
|
||||
:rtype : None
|
||||
"""Create network
|
||||
|
||||
:type network: Network
|
||||
:rtype : None
|
||||
"""
|
||||
self.conn.networkLookupByUUIDString(network.uuid).create()
|
||||
|
||||
@retry()
|
||||
def node_define(self, node):
|
||||
"""
|
||||
"""Define node
|
||||
|
||||
:type node: Node
|
||||
:rtype : None
|
||||
"""
|
||||
|
@ -197,7 +216,8 @@ class DevopsDriver(object):
|
|||
|
||||
@retry()
|
||||
def node_destroy(self, node):
|
||||
"""
|
||||
"""Destroy node
|
||||
|
||||
:type node: Node
|
||||
:rtype : None
|
||||
"""
|
||||
|
@ -205,9 +225,14 @@ class DevopsDriver(object):
|
|||
|
||||
@retry()
|
||||
def node_undefine(self, node, undefine_snapshots=False):
|
||||
"""
|
||||
"""Undefine domain.
|
||||
|
||||
If undefine_snapshot is set, discard all snapshots.
|
||||
|
||||
:type node: Node
|
||||
:type undefine_snapshots: Boolean
|
||||
:rtype : None
|
||||
|
||||
"""
|
||||
domain = self.conn.lookupByUUIDString(node.uuid)
|
||||
if undefine_snapshots:
|
||||
|
@ -218,8 +243,9 @@ class DevopsDriver(object):
|
|||
|
||||
@retry()
|
||||
def node_undefine_by_name(self, node_name):
|
||||
"""
|
||||
:type node: Node
|
||||
"""Undefine domain discarding all snapshots
|
||||
|
||||
:type node_name: String
|
||||
:rtype : None
|
||||
"""
|
||||
domain = self.conn.lookupByName(node_name)
|
||||
|
@ -227,7 +253,8 @@ class DevopsDriver(object):
|
|||
|
||||
@retry()
|
||||
def node_get_vnc_port(self, node):
|
||||
"""
|
||||
"""Get VNC port
|
||||
|
||||
:type node: Node
|
||||
:rtype : String
|
||||
"""
|
||||
|
@ -239,7 +266,8 @@ class DevopsDriver(object):
|
|||
|
||||
@retry()
|
||||
def node_get_interface_target_dev(self, node, mac):
|
||||
"""
|
||||
"""Get target device
|
||||
|
||||
:type node: Node
|
||||
:type mac: String
|
||||
:rtype : String
|
||||
|
@ -252,7 +280,8 @@ class DevopsDriver(object):
|
|||
|
||||
@retry()
|
||||
def node_create(self, node):
|
||||
"""
|
||||
"""Create node
|
||||
|
||||
:type node: Node
|
||||
:rtype : None
|
||||
"""
|
||||
|
@ -266,7 +295,8 @@ class DevopsDriver(object):
|
|||
|
||||
@retry()
|
||||
def node_reset(self, node):
|
||||
"""
|
||||
"""Reset node
|
||||
|
||||
:type node: Node
|
||||
:rtype : None
|
||||
"""
|
||||
|
@ -274,7 +304,8 @@ class DevopsDriver(object):
|
|||
|
||||
@retry()
|
||||
def node_reboot(self, node):
|
||||
"""
|
||||
"""Reboot node
|
||||
|
||||
:type node: Node
|
||||
:rtype : None
|
||||
"""
|
||||
|
@ -282,7 +313,8 @@ class DevopsDriver(object):
|
|||
|
||||
@retry()
|
||||
def node_suspend(self, node):
|
||||
"""
|
||||
"""Suspend node
|
||||
|
||||
:type node: Node
|
||||
:rtype : None
|
||||
"""
|
||||
|
@ -290,7 +322,8 @@ class DevopsDriver(object):
|
|||
|
||||
@retry()
|
||||
def node_resume(self, node):
|
||||
"""
|
||||
"""Resume node
|
||||
|
||||
:type node: Node
|
||||
:rtype : None
|
||||
"""
|
||||
|
@ -298,7 +331,8 @@ class DevopsDriver(object):
|
|||
|
||||
@retry()
|
||||
def node_shutdown(self, node):
|
||||
"""
|
||||
"""Shutdown node
|
||||
|
||||
:type node: Node
|
||||
:rtype : None
|
||||
"""
|
||||
|
@ -306,7 +340,8 @@ class DevopsDriver(object):
|
|||
|
||||
@retry()
|
||||
def node_get_snapshots(self, node):
|
||||
"""
|
||||
"""Get list of snapshots
|
||||
|
||||
:rtype : List
|
||||
:type node: Node
|
||||
"""
|
||||
|
@ -314,7 +349,8 @@ class DevopsDriver(object):
|
|||
|
||||
@retry()
|
||||
def node_create_snapshot(self, node, name=None, description=None):
|
||||
"""
|
||||
"""Create snapshot
|
||||
|
||||
:type description: String
|
||||
:type name: String
|
||||
:type node: Node
|
||||
|
@ -328,7 +364,9 @@ class DevopsDriver(object):
|
|||
logger.info(domain.state(0))
|
||||
|
||||
def _get_snapshot(self, domain, name):
|
||||
"""
|
||||
"""Get snapshot
|
||||
|
||||
:type domain: Node
|
||||
:type name: String
|
||||
:rtype : libvirt.virDomainSnapshot
|
||||
"""
|
||||
|
@ -339,7 +377,8 @@ class DevopsDriver(object):
|
|||
|
||||
@retry()
|
||||
def node_revert_snapshot(self, node, name=None):
|
||||
"""
|
||||
"""Revert snapshot for node
|
||||
|
||||
:type node: Node
|
||||
:type name: String
|
||||
:rtype : None
|
||||
|
@ -350,6 +389,11 @@ class DevopsDriver(object):
|
|||
|
||||
@retry()
|
||||
def node_delete_all_snapshots(self, node):
|
||||
"""Delete all snapshots for node
|
||||
|
||||
:type node: Node
|
||||
"""
|
||||
|
||||
domain = self.conn.lookupByUUIDString(node.uuid)
|
||||
for name in domain.snapshotListNames(
|
||||
libvirt.VIR_DOMAIN_SNAPSHOT_LIST_ROOTS):
|
||||
|
@ -358,7 +402,8 @@ class DevopsDriver(object):
|
|||
|
||||
@retry()
|
||||
def node_delete_snapshot(self, node, name=None):
|
||||
"""
|
||||
"""Delete snapshot
|
||||
|
||||
:type node: Node
|
||||
:type name: String
|
||||
"""
|
||||
|
@ -368,8 +413,10 @@ class DevopsDriver(object):
|
|||
|
||||
@retry()
|
||||
def node_send_keys(self, node, keys):
|
||||
"""
|
||||
"""Send keys to node
|
||||
|
||||
:type node: Node
|
||||
:type keys: String
|
||||
:rtype : None
|
||||
"""
|
||||
|
||||
|
@ -385,7 +432,8 @@ class DevopsDriver(object):
|
|||
|
||||
@retry()
|
||||
def volume_define(self, volume, pool=None):
|
||||
"""
|
||||
"""Define volume
|
||||
|
||||
:type volume: Volume
|
||||
:type pool: String
|
||||
:rtype : None
|
||||
|
@ -416,7 +464,8 @@ class DevopsDriver(object):
|
|||
|
||||
@retry()
|
||||
def volume_delete(self, volume):
|
||||
"""
|
||||
"""Delete volume
|
||||
|
||||
:type volume: Volume
|
||||
:rtype : None
|
||||
"""
|
||||
|
@ -424,7 +473,8 @@ class DevopsDriver(object):
|
|||
|
||||
@retry()
|
||||
def volume_capacity(self, volume):
|
||||
"""
|
||||
"""Get volume capacity
|
||||
|
||||
:type volume: Volume
|
||||
:rtype : Long
|
||||
"""
|
||||
|
@ -432,7 +482,8 @@ class DevopsDriver(object):
|
|||
|
||||
@retry()
|
||||
def volume_format(self, volume):
|
||||
"""
|
||||
"""Get volume format
|
||||
|
||||
:type volume: Volume
|
||||
:rtype : String
|
||||
"""
|
||||
|
@ -442,7 +493,8 @@ class DevopsDriver(object):
|
|||
|
||||
@retry()
|
||||
def get_allocated_networks(self):
|
||||
"""
|
||||
"""Get list of allocated networks
|
||||
|
||||
:rtype : List
|
||||
"""
|
||||
if self.allocated_networks is None:
|
||||
|
@ -458,5 +510,3 @@ class DevopsDriver(object):
|
|||
"{0:>s}/{1:>s}".format(address, prefix_or_netmask)))
|
||||
self.allocated_networks = allocated_networks
|
||||
return self.allocated_networks
|
||||
|
||||
# vim: ts=4 sw=4 expandtab
|
||||
|
|
|
@ -14,7 +14,8 @@
|
|||
|
||||
import json
|
||||
|
||||
from ipaddr import IPNetwork, IPAddress
|
||||
from ipaddr import IPAddress
|
||||
from ipaddr import IPNetwork
|
||||
from xmlbuilder import XMLBuilder
|
||||
|
||||
|
||||
|
@ -33,7 +34,8 @@ class LibvirtXMLBuilder(object):
|
|||
return name
|
||||
|
||||
def build_network_xml(self, network):
|
||||
"""
|
||||
"""Generate network XML
|
||||
|
||||
:type network: Network
|
||||
:rtype : String
|
||||
"""
|
||||
|
@ -70,7 +72,8 @@ class LibvirtXMLBuilder(object):
|
|||
return str(network_xml)
|
||||
|
||||
def build_volume_xml(self, volume):
|
||||
"""
|
||||
"""Generate volume XML
|
||||
|
||||
:type volume: Volume
|
||||
:rtype : String
|
||||
"""
|
||||
|
@ -89,7 +92,8 @@ class LibvirtXMLBuilder(object):
|
|||
return str(volume_xml)
|
||||
|
||||
def build_snapshot_xml(self, name=None, description=None):
|
||||
"""
|
||||
"""Generate snapshot XML
|
||||
|
||||
:rtype : String
|
||||
:type name: String
|
||||
:type description: String
|
||||
|
@ -102,13 +106,25 @@ class LibvirtXMLBuilder(object):
|
|||
return str(xml_builder)
|
||||
|
||||
def _build_disk_device(self, device_xml, disk_device):
|
||||
"""Build xml for disk
|
||||
|
||||
:param device_xml: XMLBuilder
|
||||
:param disk_device: DiskDevice
|
||||
"""
|
||||
|
||||
with device_xml.disk(type=disk_device.type, device=disk_device.device):
|
||||
#https://bugs.launchpad.net/ubuntu/+source/qemu-kvm/+bug/741887
|
||||
# https://bugs.launchpad.net/ubuntu/+source/qemu-kvm/+bug/741887
|
||||
device_xml.driver(type=disk_device.volume.format, cache="unsafe")
|
||||
device_xml.source(file=self.driver.volume_path(disk_device.volume))
|
||||
device_xml.target(dev=disk_device.target_dev, bus=disk_device.bus)
|
||||
|
||||
def _build_interface_device(self, device_xml, interface):
|
||||
"""Build xml for interface
|
||||
|
||||
:param device_xml: XMLBuilder
|
||||
:param interface: Network
|
||||
"""
|
||||
|
||||
if interface.type != 'network':
|
||||
raise NotImplementedError(
|
||||
message='Interface types different from network are not '
|
||||
|
@ -122,9 +138,11 @@ class LibvirtXMLBuilder(object):
|
|||
device_xml.model(type=interface.model)
|
||||
|
||||
def build_node_xml(self, node, emulator):
|
||||
"""
|
||||
:rtype : String
|
||||
"""Generate node XML
|
||||
|
||||
:type node: Node
|
||||
:type emulator: String
|
||||
:rtype : String
|
||||
"""
|
||||
node_xml = XMLBuilder("domain", type=node.hypervisor)
|
||||
node_xml.name(
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
|
||||
class DevopsError(Exception):
|
||||
def __init__(self, message):
|
||||
self.message = message
|
||||
|
|
|
@ -12,26 +12,28 @@
|
|||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
import BaseHTTPServer
|
||||
import httplib
|
||||
import logging
|
||||
import os
|
||||
import paramiko
|
||||
import posixpath
|
||||
import random
|
||||
from SimpleHTTPServer import SimpleHTTPRequestHandler
|
||||
import socket
|
||||
import stat
|
||||
from threading import Thread
|
||||
import time
|
||||
import urllib
|
||||
import xmlrpclib
|
||||
import BaseHTTPServer
|
||||
|
||||
from threading import Thread
|
||||
from SimpleHTTPServer import SimpleHTTPRequestHandler
|
||||
import paramiko
|
||||
|
||||
from devops import logger
|
||||
from devops.error import AuthenticationError
|
||||
from devops.error import DevopsCalledProcessError
|
||||
from devops.error import DevopsError
|
||||
from devops.error import TimeoutError
|
||||
from devops.helpers.retry import retry
|
||||
from devops.error import DevopsError, DevopsCalledProcessError, TimeoutError, \
|
||||
AuthenticationError
|
||||
from devops import logger
|
||||
|
||||
|
||||
def get_free_port():
|
||||
|
@ -44,8 +46,7 @@ def get_free_port():
|
|||
|
||||
|
||||
def icmp_ping(host, timeout=1):
|
||||
"""
|
||||
icmp_ping(host, timeout=1)
|
||||
"""Run ICMP ping
|
||||
|
||||
returns True if host is pingable
|
||||
False - otherwise.
|
||||
|
@ -62,8 +63,7 @@ def _tcp_ping(host, port):
|
|||
|
||||
|
||||
def tcp_ping(host, port):
|
||||
"""
|
||||
tcp_ping(host, port)
|
||||
"""Run TCP ping
|
||||
|
||||
returns True if TCP connection to specified host and port
|
||||
can be established
|
||||
|
@ -77,9 +77,8 @@ def tcp_ping(host, port):
|
|||
|
||||
|
||||
def wait(predicate, interval=5, timeout=None):
|
||||
"""
|
||||
wait(predicate, interval=5, timeout=None) - wait until predicate will
|
||||
become True.
|
||||
"""Wait until predicate will become True.
|
||||
|
||||
returns number of seconds that is left or 0 if timeout is None.
|
||||
|
||||
Options:
|
||||
|
@ -124,7 +123,7 @@ def http(host='localhost', port=80, method='GET', url='/', waited_code=200):
|
|||
if res.status == waited_code:
|
||||
return True
|
||||
return False
|
||||
except:
|
||||
except Exception:
|
||||
return False
|
||||
|
||||
|
||||
|
@ -392,7 +391,7 @@ def xmlrpctoken(uri, login, password):
|
|||
server = xmlrpclib.Server(uri)
|
||||
try:
|
||||
return server.login(login, password)
|
||||
except:
|
||||
except Exception:
|
||||
raise AuthenticationError("Error occured while login process")
|
||||
|
||||
|
||||
|
@ -400,7 +399,7 @@ def xmlrpcmethod(uri, method):
|
|||
server = xmlrpclib.Server(uri)
|
||||
try:
|
||||
return getattr(server, method)
|
||||
except:
|
||||
except Exception:
|
||||
raise AttributeError("Error occured while getting server method")
|
||||
|
||||
|
||||
|
@ -410,7 +409,8 @@ def generate_mac():
|
|||
|
||||
|
||||
def _get_file_size(path):
|
||||
"""
|
||||
"""Get size of file-like object
|
||||
|
||||
:type file: String
|
||||
:rtype : int
|
||||
"""
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
|
||||
class IpNetworksPool(object):
|
||||
def __init__(self, networks, prefix):
|
||||
self.networks = networks
|
||||
|
|
|
@ -13,7 +13,6 @@
|
|||
# under the License.
|
||||
|
||||
import functools
|
||||
|
||||
from time import sleep
|
||||
|
||||
|
||||
|
@ -23,10 +22,10 @@ def retry(count=10, delay=1):
|
|||
def wrapper(*args, **kwargs):
|
||||
i = 0
|
||||
while True:
|
||||
#noinspection PyBroadException
|
||||
# noinspection PyBroadException
|
||||
try:
|
||||
return func(*args, **kwargs)
|
||||
except:
|
||||
except Exception:
|
||||
i += 1
|
||||
if i >= count:
|
||||
raise
|
||||
|
|
|
@ -12,18 +12,25 @@
|
|||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
import ipaddr
|
||||
import json
|
||||
|
||||
from os import environ
|
||||
|
||||
environ.setdefault("DJANGO_SETTINGS_MODULE", "devops.settings")
|
||||
from django.db import IntegrityError, transaction
|
||||
|
||||
from django.db import IntegrityError
|
||||
from django.db import transaction
|
||||
import ipaddr
|
||||
|
||||
from devops.helpers.helpers import generate_mac
|
||||
from devops.helpers.network import IpNetworksPool
|
||||
from devops.models import Address, Interface, Node, Network, Environment, \
|
||||
Volume, DiskDevice, ExternalModel
|
||||
from devops.models import Address
|
||||
from devops.models import DiskDevice
|
||||
from devops.models import Environment
|
||||
from devops.models import ExternalModel
|
||||
from devops.models import Interface
|
||||
from devops.models import Network
|
||||
from devops.models import Node
|
||||
from devops.models import Volume
|
||||
|
||||
|
||||
class Manager(object):
|
||||
|
@ -32,7 +39,8 @@ class Manager(object):
|
|||
self.default_pool = None
|
||||
|
||||
def environment_create(self, name):
|
||||
"""
|
||||
"""Create environment
|
||||
|
||||
:rtype : Environment
|
||||
"""
|
||||
return Environment.objects.create(name=name)
|
||||
|
@ -41,13 +49,15 @@ class Manager(object):
|
|||
return Environment.objects.all()
|
||||
|
||||
def environment_get(self, name):
|
||||
"""
|
||||
"""Get environment by name
|
||||
|
||||
:rtype : Environment
|
||||
"""
|
||||
return Environment.objects.get(name=name)
|
||||
|
||||
def create_network_pool(self, networks, prefix):
|
||||
"""
|
||||
"""Create network pool
|
||||
|
||||
:rtype : IpNetworksPool
|
||||
"""
|
||||
pool = IpNetworksPool(networks=networks, prefix=prefix)
|
||||
|
@ -55,7 +65,8 @@ class Manager(object):
|
|||
return pool
|
||||
|
||||
def _get_default_pool(self):
|
||||
"""
|
||||
"""Get default pool. If it does not exists, create 10.0.0.0/16 pool.
|
||||
|
||||
:rtype : IpNetworksPool
|
||||
"""
|
||||
self.default_pool = self.default_pool or self.create_network_pool(
|
||||
|
@ -89,7 +100,8 @@ class Manager(object):
|
|||
has_dhcp_server=True, has_pxe_server=False,
|
||||
forward='nat'
|
||||
):
|
||||
"""
|
||||
"""Create network
|
||||
|
||||
:rtype : Network
|
||||
"""
|
||||
if ip_network:
|
||||
|
@ -112,7 +124,8 @@ class Manager(object):
|
|||
def node_create(self, name, environment=None, role=None, vcpu=1,
|
||||
memory=1024, has_vnc=True, metadata=None, hypervisor='kvm',
|
||||
os_type='hvm', architecture='x86_64', boot=None):
|
||||
"""
|
||||
"""Create node
|
||||
|
||||
:rtype : Node
|
||||
"""
|
||||
if not boot:
|
||||
|
@ -126,7 +139,8 @@ class Manager(object):
|
|||
return node
|
||||
|
||||
def volume_get_predefined(self, uuid):
|
||||
"""
|
||||
"""Get predefined volume
|
||||
|
||||
:rtype : Volume
|
||||
"""
|
||||
try:
|
||||
|
@ -139,7 +153,8 @@ class Manager(object):
|
|||
|
||||
def volume_create_child(self, name, backing_store, format=None,
|
||||
environment=None):
|
||||
"""
|
||||
"""Create new volume based on backing_store
|
||||
|
||||
:rtype : Volume
|
||||
"""
|
||||
return Volume.objects.create(
|
||||
|
@ -148,7 +163,8 @@ class Manager(object):
|
|||
format=format or backing_store.format, backing_store=backing_store)
|
||||
|
||||
def volume_create(self, name, capacity, format='qcow2', environment=None):
|
||||
"""
|
||||
"""Create volume
|
||||
|
||||
:rtype : Volume
|
||||
"""
|
||||
return Volume.objects.create(
|
||||
|
@ -156,7 +172,8 @@ class Manager(object):
|
|||
capacity=capacity, format=format)
|
||||
|
||||
def _generate_mac(self):
|
||||
"""
|
||||
"""Generate MAC-address
|
||||
|
||||
:rtype : String
|
||||
"""
|
||||
return generate_mac()
|
||||
|
@ -164,16 +181,17 @@ class Manager(object):
|
|||
def interface_create(self, network, node, type='network',
|
||||
mac_address=None, model='virtio',
|
||||
interface_map={}):
|
||||
"""
|
||||
"""Create interface
|
||||
|
||||
:rtype : Interface
|
||||
"""
|
||||
interfaces = []
|
||||
|
||||
def _create(mac_addr=None):
|
||||
interface = Interface.objects.create(
|
||||
network=network, node=node, type=type,
|
||||
mac_address=mac_addr or self._generate_mac(),
|
||||
model=model)
|
||||
network=network, node=node, type=type,
|
||||
mac_address=mac_addr or self._generate_mac(),
|
||||
model=model)
|
||||
interface.add_address(str(network.next_ip()))
|
||||
return interface
|
||||
|
||||
|
@ -186,7 +204,8 @@ class Manager(object):
|
|||
return _create(mac_address)
|
||||
|
||||
def network_create_address(self, ip_address, interface):
|
||||
"""
|
||||
"""Create address
|
||||
|
||||
:rtype : Address
|
||||
"""
|
||||
return Address.objects.create(ip_address=ip_address,
|
||||
|
@ -194,7 +213,8 @@ class Manager(object):
|
|||
|
||||
def node_attach_volume(self, node, volume, device='disk', type='file',
|
||||
bus='virtio', target_dev=None):
|
||||
"""
|
||||
"""Attach volume to node
|
||||
|
||||
:rtype : DiskDevice
|
||||
"""
|
||||
return DiskDevice.objects.create(
|
||||
|
|
|
@ -14,13 +14,14 @@
|
|||
|
||||
import json
|
||||
|
||||
from ipaddr import IPNetwork
|
||||
|
||||
from django.conf import settings
|
||||
from django.db import models
|
||||
from django.utils.importlib import import_module
|
||||
from ipaddr import IPNetwork
|
||||
|
||||
from devops.helpers.helpers import SSHClient, _wait, _tcp_ping
|
||||
from devops.helpers.helpers import _tcp_ping
|
||||
from devops.helpers.helpers import _wait
|
||||
from devops.helpers.helpers import SSHClient
|
||||
from devops import logger
|
||||
|
||||
|
||||
|
@ -46,7 +47,8 @@ class DriverModel(models.Model):
|
|||
|
||||
@classmethod
|
||||
def get_driver(cls):
|
||||
"""
|
||||
"""Get driver
|
||||
|
||||
:rtype : DevopsDriver
|
||||
"""
|
||||
driver = import_module(settings.DRIVER)
|
||||
|
@ -56,7 +58,8 @@ class DriverModel(models.Model):
|
|||
|
||||
@property
|
||||
def driver(self):
|
||||
"""
|
||||
"""Driver object
|
||||
|
||||
:rtype : DevopsDriver
|
||||
"""
|
||||
return self.get_driver()
|
||||
|
@ -156,8 +159,9 @@ class Environment(DriverModel):
|
|||
# Disabled untill a safer implmentation arrives
|
||||
|
||||
# Undefine domains without devops nodes
|
||||
#domains_to_undefine = domains - set(nodes.keys())
|
||||
#for d in domains_to_undefine:
|
||||
#
|
||||
# domains_to_undefine = domains - set(nodes.keys())
|
||||
# for d in domains_to_undefine:
|
||||
# driver.node_undefine_by_name(d)
|
||||
|
||||
# Remove devops nodes without domains
|
||||
|
@ -291,7 +295,8 @@ class Node(ExternalModel):
|
|||
return Address.objects.get(interface=interface).ip_address
|
||||
|
||||
def remote(self, network_name, login, password=None, private_keys=None):
|
||||
"""
|
||||
"""Create SSH-connection to the network
|
||||
|
||||
:rtype : SSHClient
|
||||
"""
|
||||
return SSHClient(
|
||||
|
|
|
@ -13,7 +13,6 @@
|
|||
# under the License.
|
||||
|
||||
import argparse
|
||||
|
||||
from os import environ
|
||||
|
||||
from devops.manager import Manager
|
||||
|
@ -31,7 +30,7 @@ class Shell(object):
|
|||
def do_list(self):
|
||||
env_list = self.manager.environment_list().values('name')
|
||||
for env in env_list:
|
||||
print env['name']
|
||||
print(env['name'])
|
||||
|
||||
return env_list
|
||||
|
||||
|
@ -42,9 +41,9 @@ class Shell(object):
|
|||
def do_show(self):
|
||||
environment = self.manager.environment_get(self.params.name)
|
||||
|
||||
print '%5s %25s' % ("VNC", "NODE-NAME")
|
||||
print ('%5s %25s' % ("VNC", "NODE-NAME"))
|
||||
for item in map(lambda x: self.node_dict(x), environment.nodes):
|
||||
print '%5s %25s' % (item['vnc'], item['name'])
|
||||
print ('%5s %25s' % (item['vnc'], item['name']))
|
||||
|
||||
def do_erase(self):
|
||||
self.manager.environment_get(self.params.name).erase()
|
||||
|
|
|
@ -15,17 +15,21 @@
|
|||
import json
|
||||
import random
|
||||
from unittest import TestCase
|
||||
|
||||
from mock import Mock
|
||||
|
||||
from devops.driver.libvirt.libvirt_xml_builder import LibvirtXMLBuilder
|
||||
|
||||
|
||||
class BaseTestXMLBuilder(TestCase):
|
||||
def setUp(self):
|
||||
self.xml_builder = LibvirtXMLBuilder(Mock())
|
||||
self.xml_builder.driver.volume_path = \
|
||||
Mock(return_value="volume_path_mock")
|
||||
self.xml_builder.driver.network_name = \
|
||||
Mock(return_value="network_name_mock")
|
||||
self.xml_builder.driver.volume_path = Mock(
|
||||
return_value="volume_path_mock"
|
||||
)
|
||||
self.xml_builder.driver.network_name = Mock(
|
||||
return_value="network_name_mock"
|
||||
)
|
||||
self.net = Mock()
|
||||
self.vol = Mock()
|
||||
self.node = Mock()
|
||||
|
@ -99,8 +103,10 @@ class TestVolumeXml(BaseTestXMLBuilder):
|
|||
</target>'''.format(self.vol.format), xml)
|
||||
|
||||
def test_backing_store(self):
|
||||
self.vol.backing_store = \
|
||||
Mock(uuid="volume_uuid", format="raw")
|
||||
self.vol.backing_store = Mock(
|
||||
uuid="volume_uuid",
|
||||
format="raw"
|
||||
)
|
||||
xml = self.xml_builder.build_volume_xml(self.vol)
|
||||
self.assertIn(
|
||||
'''
|
||||
|
|
|
@ -13,7 +13,9 @@
|
|||
# under the License.
|
||||
|
||||
from django.test import TestCase
|
||||
from ipaddr import IPNetwork, IPv4Network
|
||||
from ipaddr import IPNetwork
|
||||
from ipaddr import IPv4Network
|
||||
|
||||
from devops.helpers.network import IpNetworksPool
|
||||
from devops.manager import Manager
|
||||
|
||||
|
@ -64,7 +66,7 @@ class TestManager(TestCase):
|
|||
|
||||
def test_environment_values(self):
|
||||
environment = self.manager.environment_create('test_env')
|
||||
print environment.volumes
|
||||
print(environment.volumes)
|
||||
|
||||
def test_network_pool(self):
|
||||
environment = self.manager.environment_create('test_env2')
|
||||
|
|
|
@ -13,8 +13,10 @@
|
|||
# under the License.
|
||||
|
||||
import random
|
||||
from django.utils import unittest
|
||||
import threading
|
||||
|
||||
from django.utils import unittest
|
||||
|
||||
from devops.manager import Manager
|
||||
from devops.models import double_tuple
|
||||
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
# under the License.
|
||||
|
||||
import unittest
|
||||
|
||||
from devops.helpers import scancodes
|
||||
|
||||
|
||||
|
|
|
@ -14,10 +14,12 @@
|
|||
|
||||
import os
|
||||
import unittest
|
||||
|
||||
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "devops.settings")
|
||||
from devops import manager
|
||||
|
||||
from devops.driver.libvirt import libvirt_driver
|
||||
from devops.helpers.helpers import _get_file_size
|
||||
from devops import manager
|
||||
|
||||
|
||||
class UseCases(unittest.TestCase):
|
||||
|
|
|
@ -70,13 +70,13 @@ release = '2.3.1'
|
|||
|
||||
# The language for content autogenerated by Sphinx. Refer to documentation
|
||||
# for a list of supported languages.
|
||||
#language = None
|
||||
# language = None
|
||||
|
||||
# There are two options for replacing |today|: either, you set today to some
|
||||
# non-false value, then it is used:
|
||||
#today = ''
|
||||
# today = ''
|
||||
# Else, today_fmt is used as the format for a strftime call.
|
||||
#today_fmt = '%B %d, %Y'
|
||||
# today_fmt = '%B %d, %Y'
|
||||
|
||||
# List of patterns, relative to source directory, that match files and
|
||||
# directories to ignore when looking for source files.
|
||||
|
@ -84,24 +84,24 @@ exclude_patterns = []
|
|||
|
||||
# The reST default role (used for this markup: `text`) to use for
|
||||
# all documents.
|
||||
#default_role = None
|
||||
# default_role = None
|
||||
|
||||
# If true, '()' will be appended to :func: etc. cross-reference text.
|
||||
#add_function_parentheses = True
|
||||
# add_function_parentheses = True
|
||||
|
||||
# If true, the current module name will be prepended to all description
|
||||
# unit titles (such as .. function::).
|
||||
#add_module_names = True
|
||||
# add_module_names = True
|
||||
|
||||
# If true, sectionauthor and moduleauthor directives will be shown in the
|
||||
# output. They are ignored by default.
|
||||
#show_authors = False
|
||||
# show_authors = False
|
||||
|
||||
# The name of the Pygments (syntax highlighting) style to use.
|
||||
pygments_style = 'sphinx'
|
||||
|
||||
# A list of ignored prefixes for module index sorting.
|
||||
#modindex_common_prefix = []
|
||||
# modindex_common_prefix = []
|
||||
|
||||
|
||||
# -- Options for HTML output --------------------------------------------------
|
||||
|
@ -113,26 +113,26 @@ html_theme = 'default'
|
|||
# Theme options are theme-specific and customize the look and feel of a theme
|
||||
# further. For a list of options available for each theme, see the
|
||||
# documentation.
|
||||
#html_theme_options = {}
|
||||
# html_theme_options = {}
|
||||
|
||||
# Add any paths that contain custom themes here, relative to this directory.
|
||||
#html_theme_path = []
|
||||
# html_theme_path = []
|
||||
|
||||
# The name for this set of Sphinx documents. If None, it defaults to
|
||||
# "<project> v<release> documentation".
|
||||
#html_title = None
|
||||
# html_title = None
|
||||
|
||||
# A shorter title for the navigation bar. Default is the same as html_title.
|
||||
#html_short_title = None
|
||||
# html_short_title = None
|
||||
|
||||
# The name of an image file (relative to this directory) to place at the top
|
||||
# of the sidebar.
|
||||
#html_logo = None
|
||||
# html_logo = None
|
||||
|
||||
# The name of an image file (within the static path) to use as favicon of the
|
||||
# docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32
|
||||
# pixels large.
|
||||
#html_favicon = None
|
||||
# html_favicon = None
|
||||
|
||||
# Add any paths that contain custom static files (such as style sheets) here,
|
||||
# relative to this directory. They are copied after the builtin static files,
|
||||
|
@ -141,44 +141,44 @@ html_static_path = ['_static']
|
|||
|
||||
# If not '', a 'Last updated on:' timestamp is inserted at every page bottom,
|
||||
# using the given strftime format.
|
||||
#html_last_updated_fmt = '%b %d, %Y'
|
||||
# html_last_updated_fmt = '%b %d, %Y'
|
||||
|
||||
# If true, SmartyPants will be used to convert quotes and dashes to
|
||||
# typographically correct entities.
|
||||
#html_use_smartypants = True
|
||||
# html_use_smartypants = True
|
||||
|
||||
# Custom sidebar templates, maps document names to template names.
|
||||
#html_sidebars = {}
|
||||
# html_sidebars = {}
|
||||
|
||||
# Additional templates that should be rendered to pages, maps page names to
|
||||
# template names.
|
||||
#html_additional_pages = {}
|
||||
# html_additional_pages = {}
|
||||
|
||||
# If false, no module index is generated.
|
||||
#html_domain_indices = True
|
||||
# html_domain_indices = True
|
||||
|
||||
# If false, no index is generated.
|
||||
#html_use_index = True
|
||||
# html_use_index = True
|
||||
|
||||
# If true, the index is split into individual pages for each letter.
|
||||
#html_split_index = False
|
||||
# html_split_index = False
|
||||
|
||||
# If true, links to the reST sources are added to the pages.
|
||||
#html_show_sourcelink = True
|
||||
# html_show_sourcelink = True
|
||||
|
||||
# If true, "Created using Sphinx" is shown in the HTML footer. Default is True.
|
||||
#html_show_sphinx = True
|
||||
# html_show_sphinx = True
|
||||
|
||||
# If true, "(C) Copyright ..." is shown in the HTML footer. Default is True.
|
||||
#html_show_copyright = True
|
||||
# html_show_copyright = True
|
||||
|
||||
# If true, an OpenSearch description file will be output, and all pages will
|
||||
# contain a <link> tag referring to it. The value of this option must be the
|
||||
# base URL from which the finished HTML is served.
|
||||
#html_use_opensearch = ''
|
||||
# html_use_opensearch = ''
|
||||
|
||||
# This is the file name suffix for HTML files (e.g. ".xhtml").
|
||||
#html_file_suffix = None
|
||||
# html_file_suffix = None
|
||||
|
||||
# Output file base name for HTML help builder.
|
||||
htmlhelp_basename = 'devopsdoc'
|
||||
|
@ -207,23 +207,23 @@ latex_documents = [
|
|||
|
||||
# The name of an image file (relative to this directory) to place at the top of
|
||||
# the title page.
|
||||
#latex_logo = None
|
||||
# latex_logo = None
|
||||
|
||||
# For "manual" documents, if this is true, then toplevel headings are parts,
|
||||
# not chapters.
|
||||
#latex_use_parts = False
|
||||
# latex_use_parts = False
|
||||
|
||||
# If true, show page references after internal links.
|
||||
#latex_show_pagerefs = False
|
||||
# latex_show_pagerefs = False
|
||||
|
||||
# If true, show URL addresses after external links.
|
||||
#latex_show_urls = False
|
||||
# latex_show_urls = False
|
||||
|
||||
# Documents to append as an appendix to all manuals.
|
||||
#latex_appendices = []
|
||||
# latex_appendices = []
|
||||
|
||||
# If false, no module index is generated.
|
||||
#latex_domain_indices = True
|
||||
# latex_domain_indices = True
|
||||
|
||||
|
||||
# -- Options for manual page output -------------------------------------------
|
||||
|
@ -236,7 +236,7 @@ man_pages = [
|
|||
]
|
||||
|
||||
# If true, show URL addresses after external links.
|
||||
#man_show_urls = False
|
||||
# man_show_urls = False
|
||||
|
||||
|
||||
# -- Options for Texinfo output -----------------------------------------------
|
||||
|
@ -251,10 +251,10 @@ texinfo_documents = [
|
|||
]
|
||||
|
||||
# Documents to append as an appendix to all manuals.
|
||||
#texinfo_appendices = []
|
||||
# texinfo_appendices = []
|
||||
|
||||
# If false, no module index is generated.
|
||||
#texinfo_domain_indices = True
|
||||
# texinfo_domain_indices = True
|
||||
|
||||
# How to display URL addresses: 'footnote', 'no', or 'inline'.
|
||||
#texinfo_show_urls = 'footnote'
|
||||
# texinfo_show_urls = 'footnote'
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
# under the License.
|
||||
|
||||
import ipaddr
|
||||
|
||||
from devops.helpers.helpers import SSHClient
|
||||
|
||||
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
# under the License.
|
||||
|
||||
import ipaddr
|
||||
|
||||
from devops.helpers.helpers import SSHClient
|
||||
|
||||
|
||||
|
|
4
setup.py
4
setup.py
|
@ -13,8 +13,10 @@
|
|||
# under the License.
|
||||
|
||||
import os
|
||||
from setuptools import setup
|
||||
|
||||
from setuptools import find_packages
|
||||
from setuptools import setup
|
||||
|
||||
|
||||
setup(
|
||||
name='devops',
|
||||
|
|
|
@ -0,0 +1,20 @@
|
|||
# Tox (http://tox.testrun.org/) is a tool for running tests
|
||||
# in multiple virtualenvs. This configuration file will run the
|
||||
# test suite on all supported python versions. To use it, "pip install tox"
|
||||
# and then run "tox" from this directory.
|
||||
|
||||
[tox]
|
||||
minversion = 1.6
|
||||
envlist = flake8
|
||||
skipsdist = True
|
||||
|
||||
[flake8]
|
||||
ignore = H234,H302,H802
|
||||
exclude = .venv,.git,.tox,dist,doc,*lib/python*,*egg,build,tools,__init__.py,docs
|
||||
show-pep8 = True
|
||||
show-source = True
|
||||
count = True
|
||||
|
||||
[testenv:flake8]
|
||||
deps = hacking==0.9
|
||||
commands = flake8
|
Loading…
Reference in New Issue