Skip to content

Commit 780dfb0

Browse files
author
Ignasi Barrera
committed
Merge branch 'master' into compute
Conflicts: examples/skel.py kahuna/plugins/deployer.py kahuna/plugins/env.py kahuna/plugins/machine.py kahuna/plugins/shell.py kahuna/plugins/template.py kahuna/plugins/vdc.py kahuna/plugins/vm.py kahuna/plugins/volume.py
2 parents a937de2 + 73bf6d2 commit 780dfb0

14 files changed

+278
-255
lines changed

.gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -5,4 +5,5 @@
55
*.swp
66
*.tmp
77
catalina.base_IS_UNDEFINED
8+
target/
89

config/kahuna.conf

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
# Main configuration file for Kahuna
22

33
[connection]
4-
address = 10.60.1.222
4+
address = 10.60.21.181
55
user = admin
66
pass = xabiquo
77

examples/skel.py

+8-11
Original file line numberDiff line numberDiff line change
@@ -9,24 +9,21 @@
99
# The documentation string in the plugin class will be used to
1010
# print the help of the plugin.
1111

12+
from kahuna.abstract import AbsPlugin
1213

13-
class SkeletonPlugin:
14-
""" An example plugin that prints dummy messages """
14+
15+
class SkeletonPlugin(AbsPlugin):
16+
""" An example plugin that prints dummy messages. """
1517
def __init__(self):
1618
pass
1719

18-
def commands(self):
19-
""" Returns the provided commands, mapped to handler methods """
20-
commands = {}
21-
# Bind the 'print' plugin command to the 'print_handler' method
22-
commands['print'] = self.print_handler
23-
return commands
24-
20+
# Public methods will be considered plugin commands.
21+
# The name of the command will be the method name.
2522
# The documentation string in command methods will be used to
2623
# print the help of the command.
2724
# The arguments are the options given to the command itself
28-
def print_handler(self, args):
29-
""" Prints a dummy message """
25+
def dummy(self, args):
26+
""" Prints a dummy message. """
3027
print "This is the print_handler in the example plugin"
3128

3229

kahuna/abstract.py

+24
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
#!/usr/bin/env jython
2+
3+
4+
class AbsPlugin:
5+
""" Abstract plugin. """
6+
def _commands(self):
7+
""" Get the list of commands for the current plugin.
8+
By default all public methods in the plugin implementation
9+
will be used as plugin commands. This method can be overriden
10+
in subclasses to customize the available command list. """
11+
attrs = filter(lambda attr: not attr.startswith('_'), dir(self))
12+
commands = {}
13+
for attr in attrs:
14+
method = getattr(self, attr)
15+
commands[attr] = method
16+
return commands
17+
18+
def _load_context(self, context):
19+
""" Set the context of the execution.
20+
21+
It should be called only from the plugin manager once
22+
it has the context loaded.
23+
"""
24+
self._context = context

kahuna/cli.py

+4-4
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
#!/usr/bin/env jython
2-
3-
import sys
42
from pluginmanager import PluginManager
3+
import sys
54

65

76
class CLI:
@@ -24,8 +23,9 @@ def parse_input(self):
2423
else:
2524
# Call the command in the given plugin with the
2625
# remaining of the arguments
27-
return self.__pluginmanager.call(sys.argv[1], sys.argv[2],
28-
sys.argv[3:])
26+
return self.__pluginmanager.call(sys.argv[1],
27+
sys.argv[2], sys.argv[3:])
28+
2929

3030
if __name__ == "__main__":
3131
cli = CLI()

kahuna/pluginmanager.py

+23-2
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
11
#!/usr/bin/env jython
22

3+
from __future__ import with_statement # jython 2.5.2 issue
34
import logging
45
from plugins import __all__
6+
from kahuna.session import ContextLoader
7+
from contextlib import contextmanager
58

69
log = logging.getLogger('kahuna')
710

@@ -27,14 +30,21 @@ def load_plugin(self, plugin_name):
2730
return plugin
2831

2932
def call(self, plugin_name, command_name, args):
33+
""" Encapsulate the call into a context already loaded.
34+
"""
35+
with opencontext() as context:
36+
return self._call(context, plugin_name, command_name, args)
37+
38+
def _call(self, context, plugin_name, command_name, args):
3039
""" Calls the given command on the given plugin. """
3140
try:
3241
plugin = self.load_plugin(plugin_name)
42+
plugin._load_context(context)
3343
if not command_name:
3444
self.help(plugin)
3545
else:
3646
try:
37-
command = plugin.commands()[command_name]
47+
command = plugin._commands()[command_name]
3848
return command(args)
3949
except KeyError:
4050
# Command not found in plugin. Print only plugin help
@@ -45,7 +55,7 @@ def call(self, plugin_name, command_name, args):
4555

4656
def help(self, plugin):
4757
""" Prints the help for the given plugin. """
48-
commands = plugin.commands()
58+
commands = plugin._commands()
4959
tokens = plugin.__module__.split('.')
5060
plugin_name = tokens[len(tokens) - 1]
5161
print "%s" % plugin.__doc__
@@ -59,3 +69,14 @@ def help_all(self):
5969
plugin = self.load_plugin(name)
6070
self.help(plugin)
6171
print
72+
73+
74+
@contextmanager
75+
def opencontext():
76+
""" Loads the context each plugin needs to be initialized
77+
in order to be executed. """
78+
log.debug("Loading context for plugin execution")
79+
context = ContextLoader().load()
80+
yield context
81+
log.debug("Context closed after plugin execution")
82+
context.close()

kahuna/plugins/deployer.py

+64
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
#!/usr/bin/env jython
2+
3+
import time
4+
from optparse import OptionParser
5+
from org.jclouds.abiquo.domain.exception import AbiquoException
6+
from org.jclouds.rest import AuthorizationException
7+
from kahuna.abstract import AbsPlugin
8+
9+
10+
class DeployerPlugin(AbsPlugin):
11+
""" Massive deployer plugin. """
12+
def __init__(self):
13+
pass
14+
15+
def start(self, args):
16+
""" Deploys and undeploys the first virtual appliance N times. """
17+
# Parse user input to get the number of deployments and undeployments
18+
parser = OptionParser(usage="deployer start <options>")
19+
parser.add_option("-n", "--num", dest="num",
20+
help="The number of deployments to execute")
21+
(options, args) = parser.parse_args(args)
22+
if not options.num:
23+
parser.print_help()
24+
return
25+
26+
# Once user input has been read, find the VM
27+
max = int(options.num)
28+
try:
29+
cloud = self._context.getCloudService()
30+
monitor = self._context.getMonitoringService() \
31+
.getVirtualApplianceMonitor()
32+
33+
vdc = cloud.listVirtualDatacenters()[0]
34+
vapp = vdc.listVirtualAppliances()[0]
35+
num_vms = len(vapp.listVirtualMachines())
36+
37+
print "Starting %s deployment iterations for %s (%s vms)" % (max,
38+
vapp.getName(), num_vms)
39+
40+
for i in range(0, max):
41+
print "Iteration #%s" % (i + 1)
42+
print " Deploying %s (%s vms)" % (vapp.getName(), num_vms)
43+
vapp.deploy()
44+
monitor.awaitCompletionDeploy(vapp)
45+
46+
# Bypass current issues with state by waiting a bit
47+
# before undeploying
48+
time.sleep(5)
49+
50+
print " Undeploying %s (%s vms)" % (vapp.getName(), num_vms)
51+
vapp.undeploy()
52+
monitor.awaitCompletionUndeploy(vapp)
53+
54+
# Currently there is a minor issue when undeploying that puts
55+
# the vm in state UNKNOWN. Wait a bit so it gets in
56+
# NOT_ALLOCATED state before deploying again
57+
time.sleep(5)
58+
except (AbiquoException, AuthorizationException), ex:
59+
print "Error: %s" % ex.getMessage()
60+
61+
62+
def load():
63+
""" Loads the deployer plugin. """
64+
return DeployerPlugin()

kahuna/plugins/env.py

+16-29
Original file line numberDiff line numberDiff line change
@@ -11,50 +11,37 @@
1111
from environment.users.tenants import cleanup_default_tenants
1212
from environment.users.tenants import create_default_tenants
1313
from kahuna.config import ConfigLoader
14-
from kahuna.session import ContextLoader
1514
from org.jclouds.abiquo.domain.exception import AbiquoException
1615
from org.jclouds.rest import AuthorizationException
16+
from kahuna.abstract import AbsPlugin
1717

1818

19-
class EnvironmentPlugin:
20-
""" Environment generator plugin """
19+
class EnvironmentPlugin(AbsPlugin):
20+
""" Environment generator plugin. """
2121
def __init__(self):
2222
self.__config = ConfigLoader().load("env.conf", "config/env.conf")
2323

24-
def commands(self):
25-
""" Returns the available commands in this plugin """
26-
commands = {}
27-
commands['create'] = self.create
28-
commands['clean'] = self.cleanup
29-
return commands
30-
3124
def create(self, args):
32-
""" Creates the environment """
33-
context = ContextLoader().load()
25+
""" Creates the environment. """
3426
try:
35-
apply_default_configuration(self.__config, context)
36-
dc = create_infrastructure_compute(self.__config, context)
37-
create_infrastructure_storage(self.__config, context, dc)
38-
create_infrastructure_network(self.__config, context, dc)
39-
create_default_tenants(self.__config, context, dc)
40-
vdc = create_cloud_compute(self.__config, context, dc)
41-
create_cloud_storage(self.__config, context, vdc)
27+
apply_default_configuration(self.__config, self._context)
28+
dc = create_infrastructure_compute(self.__config, self._context)
29+
create_infrastructure_storage(self.__config, self._context, dc)
30+
create_infrastructure_network(self.__config, self._context, dc)
31+
create_default_tenants(self.__config, self._context, dc)
32+
vdc = create_cloud_compute(self.__config, self._context, dc)
33+
create_cloud_storage(self.__config, self._context, vdc)
4234
except (AbiquoException, AuthorizationException), ex:
4335
print "Error: %s" % ex.getMessage()
44-
finally:
45-
context.close()
4636

47-
def cleanup(self, args):
48-
""" Cleans up the environment """
49-
context = ContextLoader().load()
37+
def clean(self, args):
38+
""" Cleans up the environment. """
5039
try:
51-
cleanup_cloud_compute(self.__config, context)
52-
cleanup_default_tenants(self.__config, context)
53-
cleanup_infrastructure_compute(self.__config, context)
40+
cleanup_cloud_compute(self.__config, self._context)
41+
cleanup_default_tenants(self.__config, self._context)
42+
cleanup_infrastructure_compute(self.__config, self._context)
5443
except (AbiquoException, AuthorizationException), ex:
5544
print "Error: %s" % ex.getMessage()
56-
finally:
57-
context.close()
5845

5946

6047
def load():

0 commit comments

Comments
 (0)