From eecdccfee93adbcfefc618836e2b4bce4bfa74e5 Mon Sep 17 00:00:00 2001 From: vic Date: Mon, 21 Jan 2013 01:10:22 +0400 Subject: [PATCH] The next intermediate state --- bin/devops | 4 -- setup.py | 5 +- src/devops.py | 64 ----------------- src/devops/driver/libvirt/libvirt_driver.py | 12 ++-- .../driver/libvirt/libvirt_xml_builder.py | 7 +- src/devops/manager.py | 8 +-- src/devops/models.py | 12 ++-- src/devops/settings.py | 1 - src/devops/shell.py | 72 +++++++++++++++++++ src/devops/tests/test_manager.py | 5 +- src/dos.py | 6 ++ 11 files changed, 104 insertions(+), 92 deletions(-) delete mode 100755 bin/devops delete mode 100644 src/devops.py create mode 100644 src/devops/shell.py create mode 100644 src/dos.py diff --git a/bin/devops b/bin/devops deleted file mode 100755 index 496f93a3..00000000 --- a/bin/devops +++ /dev/null @@ -1,4 +0,0 @@ -#!/bin/sh - -exec python -m devops "$@" - diff --git a/setup.py b/setup.py index da52e4e1..375f6b22 100644 --- a/setup.py +++ b/setup.py @@ -6,7 +6,8 @@ setup( description='Library for creating and manipulating virtual environments', author='Mirantis, Inc.', author_email='product@mirantis.com', - packages=['devops', 'devops.driver'], - scripts=['bin/devops'], + packages=['devops', 'devops.driver', 'devops.helpers', 'devops.tests', 'devops.driver.libvirt'], + package_dir={'': 'src'}, + scripts=['src/dos.py'], install_requires=['xmlbuilder', "ipaddr", "paramiko", "django"] ) diff --git a/src/devops.py b/src/devops.py deleted file mode 100644 index bfcea411..00000000 --- a/src/devops.py +++ /dev/null @@ -1,64 +0,0 @@ -#!/usr/bin/env python -import os, sys - - -def saved(args): - c = getController() - for saved_env in c.saved_environments: - print(saved_env) - - -def resume(args): - parser = argparse.ArgumentParser(prog='devops resume') - parser.add_argument('environment') - arguments = parser.parse_args(args) - env = load(arguments.environment) - import code - - code.InteractiveConsole(locals={'environment': env}).interact() - -import sys -import argparse - -parser = argparse.ArgumentParser(prog='devops') -parser.add_argument('command', choices=['saved', 'resume']) -parser.add_argument('command_args', nargs=argparse.REMAINDER) -arguments = parser.parse_args() - -if arguments.command == 'saved': - saved(arguments.command_args) -elif arguments.command == 'resume': - resume(arguments.command_args) -else: - help() - sys.exit(1) - - -from src.devops.controller import Controller - -class ControllerSingleton(Controller): - _instance = None - - def __new__(cls, *args, **kwargs): - if not cls._instance: - cls._instance = super(ControllerSingleton, cls).__new__( - cls, *args, **kwargs) - return cls._instance - - -def getController(): - return ControllerSingleton(Libvirt()) - - -def build(environment): - getController().build_environment(environment) - - -def destroy(environment): - getController().destroy_environment(environment) - - - - -if __name__ == "__main__": - pass \ No newline at end of file diff --git a/src/devops/driver/libvirt/libvirt_driver.py b/src/devops/driver/libvirt/libvirt_driver.py index 01b41046..c4bd1a60 100644 --- a/src/devops/driver/libvirt/libvirt_driver.py +++ b/src/devops/driver/libvirt/libvirt_driver.py @@ -105,9 +105,9 @@ class LibvirtDriver(object): """ :rtype : None """ - network.uuid = self.conn.networkDefineXML( - self.xml_builder.build_network_xml(network) - ).UUIDString() + ret = self.conn.networkDefineXML(self.xml_builder.build_network_xml(network)) + ret.setAutostart(True) + network.uuid = ret.UUIDString() @retry() def network_destroy(self, network): @@ -148,12 +148,8 @@ class LibvirtDriver(object): 'guest/arch[@name="{0:>s}"]/domain[@type="{1:>s}"]/emulator'.format( node.architecture, node.hypervisor)).text node_xml = self.xml_builder.build_node_xml(node, emulator) - for network in node.networks: - print network - if not self.network_active(network): - self.network_create(network) print node_xml - self.uuid = self.conn.createXML(node_xml, 0).UUIDString() + self.uuid = self.conn.defineXML(node_xml).UUIDString() @retry() def node_destroy(self, node): diff --git a/src/devops/driver/libvirt/libvirt_xml_builder.py b/src/devops/driver/libvirt/libvirt_xml_builder.py index d8fa638c..f95b9095 100644 --- a/src/devops/driver/libvirt/libvirt_xml_builder.py +++ b/src/devops/driver/libvirt/libvirt_xml_builder.py @@ -39,10 +39,10 @@ class LibvirtXMLBuilder(object): network_xml.range(start=str(network.ip_pool_start), end=str(network.ip_pool_end)) for interface in network.interfaces: for address in interface.addresses: - if IPAddress(address) in ip_network: + if IPAddress(address.ip_address) in ip_network: network_xml.host( mac=str(interface.mac_address), - ip=str(address), + ip=str(address.ip_address), name=interface.node.name ) if network.has_pxe_server: @@ -87,9 +87,10 @@ class LibvirtXMLBuilder(object): if interface.type != 'network': raise NotImplementedError() with device_xml.interface(type=interface.type): + device_xml.mac(address = interface.mac_address) device_xml.source(network=self.driver.network_name(interface.network)) if not (interface.type is None): - device_xml.model(type=interface.type) + device_xml.model(type=interface.model) def build_node_xml(self, node, emulator): """ diff --git a/src/devops/manager.py b/src/devops/manager.py index 550b0365..ee566c3f 100644 --- a/src/devops/manager.py +++ b/src/devops/manager.py @@ -22,13 +22,13 @@ class Manager(object): return self.create_network_pool(networks=[ipaddr.IPNetwork('10.0.0.0/16')], prefix=24) def create_network( - self, name, environment=None, ip_network=None, pool=None, has_dhcp_server=False, has_pxe_server=False, + self, name, environment, ip_network=None, pool=None, has_dhcp_server=True, has_pxe_server=False, forward='route'): allocated_network = ip_network or environment.allocate_network(pool or self._get_default_pool()) return Network.objects.create(environment=environment, name=name, ip_network=ip_network or allocated_network, has_pxe_server=has_pxe_server, has_dhcp_server=has_dhcp_server, forward=forward) - def create_node(self, name, environment=None, role=None, vcpu=2, + def create_node(self, name, environment, role=None, vcpu=2, memory=1024, has_vnc=True, metadata=None, hypervisor='kvm', os_type='hvm', architecture='x86_64', boot=None): if not boot: boot = ['network', 'cdrom', 'hd'] @@ -52,9 +52,9 @@ class Manager(object): def _generate_mac(self): return generate_mac() - def create_interface(self, network, node, type='network', target_dev=None, mac_address=None): + def create_interface(self, network, node, type='network', target_dev=None, mac_address=None, model='virtio'): interface = Interface.objects.create(network=network, node=node, type=type, target_dev=target_dev, - mac_address=mac_address or self._generate_mac()) + mac_address=mac_address or self._generate_mac(), model=model) interface.add_address(str(network.next_ip())) return interface diff --git a/src/devops/models.py b/src/devops/models.py index f497299a..6fadc647 100644 --- a/src/devops/models.py +++ b/src/devops/models.py @@ -1,6 +1,5 @@ from ipaddr import IPNetwork from devops.driver.libvirt.libvirt_driver import LibvirtDriver - from django.db import models def choices(*args, **kwargs): @@ -101,7 +100,9 @@ class ExternalModel(models.Model): name = models.CharField(max_length=255, unique=False, null=False) uuid = models.CharField(max_length=255) - environment = models.ForeignKey(Environment, null=True) + #todo is it necessary to share networks and volumes between environments? + #environment = models.ManyToMany(Environment, null=True) + environment = models.ForeignKey(Environment, null=False) class Meta: unique_together = ('name', 'environment') @@ -192,9 +193,9 @@ class Node(ExternalModel): def disk_devices(self): return DiskDevice.objects.filter(node=self) - @property - def networks(self): - return Network.objects.filter(interface__node=self) +# @property +# def networks(self): +# return Network.objects.filter(interface__node=self) def interface_by_name(self, name): self.interfaces.filter(name=name) @@ -255,6 +256,7 @@ class Interface(models.Model): node = models.ForeignKey(Node) type = models.CharField(max_length=255, null=False) target_dev = models.CharField(max_length=255, unique=True, null=True) + model = choices('virtio') @property def addresses(self): diff --git a/src/devops/settings.py b/src/devops/settings.py index a29b4285..7229f5fc 100644 --- a/src/devops/settings.py +++ b/src/devops/settings.py @@ -6,7 +6,6 @@ HOME_DIR = os.environ.get('DEVOPS_HOME') or os.environ.get('APPDATA') or os.envi INSTALLED_APPS = ['devops'] - DATABASES = { 'default': { 'ENGINE': 'django.db.backends.sqlite3', diff --git a/src/devops/shell.py b/src/devops/shell.py new file mode 100644 index 00000000..3f800af0 --- /dev/null +++ b/src/devops/shell.py @@ -0,0 +1,72 @@ +#class ControllerSingleton(Controller): +# _instance = None +# +# def __new__(cls, *args, **kwargs): +# if not cls._instance: +# cls._instance = super(ControllerSingleton, cls).__new__( +# cls, *args, **kwargs) +# return cls._instance + +import argparse +import os +from devops.manager import Manager + +class Shell(object): + + def __init__(self): + super(Shell, self).__init__() + self.params = self.get_params() + self.manager = Manager() + + + def execute(self): + self.commands.get(self.params.command)() + + def do_list(self): + pass + + def do_show(self): + pass + + def do_erase(self): + pass + + def do_suspend(self): + pass + + def do_resume(self): + pass + + def do_revert(self): + pass + + def do_snapshot(self): + pass + + commands = { + 'list' : 'do_list', + 'show': 'do_show', + 'erase': 'do_erase', + 'suspend': 'do_suspend', + 'resume': 'do_resume', + 'revert': 'do_revert', + 'snapshot': 'do_snapshot' + } + + def get_params(self): + parser = argparse.ArgumentParser(description="Integration test suite") + parser.add_argument('command', + choices=self.commands.keys(), + help="command to execute") + parser.add_argument( + '--name', metavar='', + default=os.environ.get('ENV_NAME'), + help='Environment name') + parser.add_argument( + '--snapshot-name', metavar='', + default=os.environ.get('SNAPSHOT_NAME'), + help='Snapshot name') + return parser.parse_args() + + + diff --git a/src/devops/tests/test_manager.py b/src/devops/tests/test_manager.py index f03eaca3..f5f94118 100644 --- a/src/devops/tests/test_manager.py +++ b/src/devops/tests/test_manager.py @@ -4,7 +4,7 @@ from devops.helpers.network import IpNetworksPool from devops.manager import Manager -class TestIpNetworksPool(TestCase): +class TestManager(TestCase): manager = Manager() @@ -54,6 +54,7 @@ class TestIpNetworksPool(TestCase): def test_node_creation(self): try: + print 1 environment = self.manager.create_environment('test_env2') internal = self.manager.create_network( environment=environment, name='internal', pool=None) @@ -67,7 +68,9 @@ class TestIpNetworksPool(TestCase): # self.manager.create_interface(node=node, network=private) environment.define() except: + print 2 environment.erase() + raise diff --git a/src/dos.py b/src/dos.py new file mode 100644 index 00000000..cab76b30 --- /dev/null +++ b/src/dos.py @@ -0,0 +1,6 @@ +import os + +if __name__ == "__main__": + os.environ.setdefault("DJANGO_SETTINGS_MODULE", "devops.settings") + from devops.shell import Shell + Shell().execute()