lago.plugins package

exception lago.plugins.NoSuchPluginError[source]

Bases: lago.plugins.PluginError

lago.plugins.PLUGIN_ENTRY_POINTS = {'vm': 'lago.plugins.vm', 'vm-service': 'lago.plugins.vm_service', 'vm-provider': 'lago.plugins.vm_provider', 'cli': 'lago.plugins.cli', 'out': 'lago.plugins.output'}

Map of plugin type string -> setuptools entry point

class lago.plugins.Plugin[source]

Bases: object

Base class for all the plugins

exception lago.plugins.PluginError[source]

Bases: exceptions.Exception

lago.plugins.load_plugins(namespace, instantiate=True)[source]

Loads all the plugins for the given namespace

Parameters:
  • namespace (str) – Namespace string, as in the setuptools entry_points
  • instantiate (bool) – If true, will instantiate the plugins too
Returns:

Returns the list of loaded plugins

Return type:

dict of str, object

Submodules

lago.plugins.cli module

About CLIPlugins

A CLIPlugin is a subcommand of the lagocli command, it’s ment to group actions together in a logical sense, for example grouping all the actions done to templates.

To create a new subcommand for testenvcli you just have to subclass the CLIPlugin abstract class and declare it in the setuptools as an entry_point, see this module’s setup.py/setup.cfg for an example:

class NoopCLIplugin(CLIPlugin):
    init_args = {
        'help': 'dummy help string',
    }

    def populate_parser(self, parser):
        parser.addArgument('--dummy-flag', action='store_true')

    def do_run(self, args):
        if args.dummy_flag:
            print "Dummy flag passed to noop subcommand!"
        else:
            print "Dummy flag not passed to noop subcommand!"

You can also use decorators instead, an equivalent is:

@cli_plugin_add_argument('--dummy-flag', action='store_true')
@cli_plugin(help='dummy help string')
def my_fancy_plugin_func(dummy_flag, **kwargs):
    if dummy_flag:
        print "Dummy flag passed to noop subcommand!"
    else:
        print "Dummy flag not passed to noop subcommand!"

Or:

@cli_plugin_add_argument('--dummy-flag', action='store_true')
def my_fancy_plugin_func(dummy_flag, **kwargs):
    "dummy help string"
    if dummy_flag:
        print "Dummy flag passed to noop subcommand!"
    else:
        print "Dummy flag not passed to noop subcommand!"

Then you will need to add an entry_points section in your setup.py like:

setup(
    ...
    entry_points={
        'lago.plugins.cli': [
            'noop=noop_module:my_fancy_plugin_func',
        ],
    }
    ...
)

Or in your setup.cfg like:

[entry_points]
lago.plugins.cli =
    noop=noop_module:my_fancy_plugin_func

Any of those will add a new subcommand to the lagocli command that can be run as:

$ lagocli noop
Dummy flag not passed to noop subcommand!

TODO: Allow per-plugin namespacing to get rid of the **kwargs parameter

class lago.plugins.cli.CLIPlugin[source]

Bases: lago.plugins.Plugin

_abc_cache = <_weakrefset.WeakSet object>
_abc_negative_cache = <_weakrefset.WeakSet object>
_abc_negative_cache_version = 35
_abc_registry = <_weakrefset.WeakSet object>
do_run(args)[source]

Execute any actions given the arguments

Parameters:args (Namespace) – with the arguments
Returns:None
init_args

Dictionary with the argument to initialize the cli parser (for example, the help argument)

populate_parser(parser)[source]

Add any required arguments to the parser

Parameters:parser (ArgumentParser) – parser to add the arguments to
Returns:None
class lago.plugins.cli.CLIPluginFuncWrapper(do_run=None, init_args=None)[source]

Bases: lago.plugins.cli.CLIPlugin

Special class to handle decorated cli plugins, take into account that the decorated functions have some limitations on what arguments can they define actually, if you need something complicated, used the abstract class CLIPlugin instead.

Keep in mind that right now the decorated function must use **kwargs as param, as it will be passed all the members of the parser, not just whatever it defined

__call__(*args, **kwargs)[source]

Keep the original function interface, so it can be used elsewhere

_abc_cache = <_weakrefset.WeakSet object>
_abc_negative_cache = <_weakrefset.WeakSet object>
_abc_negative_cache_version = 35
_abc_registry = <_weakrefset.WeakSet object>
add_argument(*argument_args, **argument_kwargs)[source]
do_run(args)[source]
init_args
populate_parser(parser)[source]
set_help(help=None)[source]
set_init_args(init_args)[source]
lago.plugins.cli.cli_plugin(func=None, **kwargs)[source]

Decorator that wraps the given function in a CLIPlugin

Parameters:
  • func (callable) – function/class to decorate
  • **kwargs – Any other arg to use when initializing the parser (like help, or prefix_chars)
Returns:

cli plugin that handles that method

Return type:

CLIPlugin

Notes

It can be used as a decorator or as a decorator generator, if used as a decorator generator don’t pass any parameters

Examples

>>> @cli_plugin
... def test(**kwargs):
...     print 'test'
...
>>> print test.__class__
<class 'cli.CLIPluginFuncWrapper'>
>>> @cli_plugin()
... def test(**kwargs):
...     print 'test'
>>> print test.__class__
<class 'cli.CLIPluginFuncWrapper'>
>>> @cli_plugin(help='dummy help')
... def test(**kwargs):
...     print 'test'
>>> print test.__class__
<class 'cli.CLIPluginFuncWrapper'>
>>> print test.init_args['help']
'dummy help'
lago.plugins.cli.cli_plugin_add_argument(*args, **kwargs)[source]

Decorator generator that adds an argument to the cli plugin based on the decorated function

Parameters:
  • *args – Any args to be passed to argparse.ArgumentParser.add_argument()
  • *kwargs – Any keyword args to be passed to argparse.ArgumentParser.add_argument()
Returns:

Decorator that builds or extends the cliplugin for the

decorated function, adding the given argument definition

Return type:

function

Examples

>>> @cli_plugin_add_argument('-m', '--mogambo', action='store_true')
... def test(**kwargs):
...     print 'test'
...
>>> print test.__class__
<class 'cli.CLIPluginFuncWrapper'>
>>> print test._parser_args
[(('-m', '--mogambo'), {'action': 'store_true'})]
>>> @cli_plugin_add_argument('-m', '--mogambo', action='store_true')
... @cli_plugin_add_argument('-b', '--bogabmo', action='store_false')
... @cli_plugin
... def test(**kwargs):
...     print 'test'
...
>>> print test.__class__
<class 'cli.CLIPluginFuncWrapper'>
>>> print test._parser_args 
[(('-b', '--bogabmo'), {'action': 'store_false'}),
 (('-m', '--mogambo'), {'action': 'store_true'})]
lago.plugins.cli.cli_plugin_add_help(help)[source]

Decorator generator that adds the cli help to the cli plugin based on the decorated function

Parameters:help (str) – help string for the cli plugin
Returns:
Decorator that builds or extends the cliplugin for the
decorated function, setting the given help
Return type:function

Examples

>>> @cli_plugin_add_help('my help string')
... def test(**kwargs):
...     print 'test'
...
>>> print test.__class__
<class 'cli.CLIPluginFuncWrapper'>
>>> print test.help
my help string
>>> @cli_plugin_add_help('my help string')
... @cli_plugin()
... def test(**kwargs):
...     print 'test'
>>> print test.__class__
<class 'cli.CLIPluginFuncWrapper'>
>>> print test.help
my help string

lago.plugins.output module

About OutFormatPlugins

An OutFormatPlugin is used to format the output of the commands that extract information from the perfixes, like status.

class lago.plugins.output.DefaultOutFormatPlugin[source]

Bases: lago.plugins.output.OutFormatPlugin

_abc_cache = <_weakrefset.WeakSet object>
_abc_negative_cache = <_weakrefset.WeakSet object>
_abc_negative_cache_version = 35
_abc_registry = <_weakrefset.WeakSet object>
format(info_obj, indent='')[source]
indent_unit = ' '
class lago.plugins.output.FlatOutFormatPlugin[source]

Bases: lago.plugins.output.OutFormatPlugin

_abc_cache = <_weakrefset.WeakSet object>
_abc_negative_cache = <_weakrefset.WeakSet object>
_abc_negative_cache_version = 35
_abc_registry = <_weakrefset.WeakSet object>
format(info_dict, delimiter='/')[source]

This formatter will take a data structure that represent a tree and will print all the paths from the root to the leaves

in our case it will print each value and the keys that needed to get to it, for example:

vm0:
net: lago memory: 1024

will be output as:

vm0/net/lago vm0/memory/1024

Args:
info_dict (dict): information to reformat delimiter (str): a delimiter for the path components
Returns:
str: String representing the formatted info
class lago.plugins.output.JSONOutFormatPlugin[source]

Bases: lago.plugins.output.OutFormatPlugin

_abc_cache = <_weakrefset.WeakSet object>
_abc_negative_cache = <_weakrefset.WeakSet object>
_abc_negative_cache_version = 35
_abc_registry = <_weakrefset.WeakSet object>
format(info_dict)[source]
class lago.plugins.output.OutFormatPlugin[source]

Bases: lago.plugins.Plugin

_abc_cache = <_weakrefset.WeakSet object>
_abc_negative_cache = <_weakrefset.WeakSet object>
_abc_negative_cache_version = 35
_abc_registry = <_weakrefset.WeakSet object>
format(info_dict)[source]

Execute any actions given the arguments

Parameters:info_dict (dict) – information to reformat
Returns:String representing the formatted info
Return type:str
class lago.plugins.output.YAMLOutFormatPlugin[source]

Bases: lago.plugins.output.OutFormatPlugin

_abc_cache = <_weakrefset.WeakSet object>
_abc_negative_cache = <_weakrefset.WeakSet object>
_abc_negative_cache_version = 35
_abc_registry = <_weakrefset.WeakSet object>
format(info_dict)[source]

lago.plugins.service module

Service Plugin

This plugins are used in order to manage services in the vms

class lago.plugins.service.ServicePlugin(vm, name)[source]

Bases: lago.plugins.Plugin

BIN_PATH

Path to the binary used to manage services in the vm, will be checked for existence when trying to decide if the serviece is supported on the VM (see func:is_supported).

Returns:Full path to the binary insithe the domain
Return type:str
_abc_cache = <_weakrefset.WeakSet object>
_abc_negative_cache = <_weakrefset.WeakSet object>
_abc_negative_cache_version = 35
_abc_registry = <_weakrefset.WeakSet object>
_request_start()[source]

Low level implementation of the service start request, used by the func:start method

Returns:True if the service succeeded to start, False otherwise
Return type:bool
_request_stop()[source]

Low level implementation of the service stop request, used by the func:stop method

Returns:True if the service succeeded to stop, False otherwise
Return type:bool
alive()[source]
exists()[source]
classmethod is_supported(vm)[source]
start()[source]
state()[source]

Check the current status of the service

Returns:Which state the service is at right now
Return type:ServiceState
stop()[source]
class lago.plugins.service.ServiceState[source]

Bases: enum.Enum

ACTIVE = 2
INACTIVE = 1
MISSING = 0

This state corresponds to a service that is not available in the domain

_member_map_ = OrderedDict([('MISSING', <ServiceState.MISSING: 0>), ('INACTIVE', <ServiceState.INACTIVE: 1>), ('ACTIVE', <ServiceState.ACTIVE: 2>)])
_member_names_ = ['MISSING', 'INACTIVE', 'ACTIVE']
_member_type_

alias of object

_value2member_map_ = {0: <ServiceState.MISSING: 0>, 1: <ServiceState.INACTIVE: 1>, 2: <ServiceState.ACTIVE: 2>}

lago.plugins.vm module

VM Plugins

There are two VM-related plugin extension points, there’s the VM Type Plugin, that allows you to modify at a higher level the inner workings of the VM class (domain concept in the initfile). The other plugin extension point, the [VM Provider Plugin], that allows you to create an alternative implementation of the provisioning details for the VM, for example, using a remote libvirt instance or similar.

exception lago.plugins.vm.ExtractPathError[source]

Bases: lago.plugins.vm.VMError

exception lago.plugins.vm.ExtractPathNoPathError[source]

Bases: lago.plugins.vm.VMError

exception lago.plugins.vm.VMError[source]

Bases: exceptions.Exception

class lago.plugins.vm.VMPlugin(env, spec)[source]

Bases: lago.plugins.Plugin

_abc_cache = <_weakrefset.WeakSet object>
_abc_negative_cache = <_weakrefset.WeakSet object>
_abc_negative_cache_version = 35
_abc_registry = <_weakrefset.WeakSet object>
_artifact_paths()[source]
_detect_service_provider()[source]
_get_service_provider()[source]

NOTE: Can be reduced to just one get call once we remove support for the service_class spec entry

Returns:class for the loaded provider for that vm_spec None: if no provider was specified in the vm_spec
Return type:class
_get_vm_provider()[source]
classmethod _normalize_spec(spec)[source]
_scp(*args, **kwds)[source]
_template_metadata()[source]
alive()[source]
all_ips()[source]
bootstrap(*args, **kwargs)[source]

Thin method that just uses the provider

collect_artifacts(host_path, ignore_nopath)[source]
copy_from(remote_path, local_path, recursive=True, propagate_fail=True)[source]
copy_to(local_path, remote_path, recursive=True)[source]
create_snapshot(name, *args, **kwargs)[source]

Thin method that just uses the provider

defined(*args, **kwargs)[source]

Thin method that just uses the provider

disks
distro()[source]
export_disks(standalone=True, dst_dir=None, compress=False, collect_only=False, with_threads=True, *args, **kwargs)[source]

Thin method that just uses the provider

extract_paths(paths, *args, **kwargs)[source]

Thin method that just uses the provider

extract_paths_dead(paths, *args, **kwargs)[source]

Thin method that just uses the provider

groups

Returns

list of str: The names of the groups to which this vm belongs
(as specified in the init file)
guest_agent()[source]
has_guest_agent()[source]
interactive_console(*args, **kwargs)[source]

Thin method that just uses the provider

interactive_ssh(*args, **kwargs)[source]
ip()[source]
ips_in_net(net_name)[source]
iscsi_name()[source]
metadata
mgmt_name
mgmt_net
name()[source]
nets()[source]
nics()[source]
reboot(*args, **kwargs)[source]

Thin method that just uses the provider

revert_snapshot(name, *args, **kwargs)[source]

Thin method that just uses the provider

root_password()[source]
save(path=None)[source]
service(*args, **kwargs)[source]
shutdown(*args, **kwargs)[source]

Thin method that just uses the provider

spec
ssh(command, data=None, show_output=True, propagate_fail=True, tries=None)[source]
ssh_reachable(*args, **kwargs)[source]

Check if the VM is reachable with ssh

Parameters:
  • tries (int) – Number of tries to try connecting to the host
  • propagate_fail (bool) – If set to true, this event will appear
  • the log and fail the outter stage. Otherwise, it will be (in) –
  • discarded.
Returns:

True if the VM is reachable.

Return type:

bool

ssh_script(path, show_output=True)[source]
start(*args, **kwargs)[source]

Thin method that just uses the provider

state(*args, **kwargs)[source]

Thin method that just uses the provider

stop(*args, **kwargs)[source]

Thin method that just uses the provider

vm_type
wait_for_ssh()[source]
class lago.plugins.vm.VMProviderPlugin(vm)[source]

Bases: lago.plugins.Plugin

If you want to use a custom provider for you VMs (say, ovirt for example), you have to inherit from this class, and then define the ‘default_vm_provider’ in your config to be your plugin, or explicitly specify it on each domain definition in the initfile with ‘vm-provider’ key

You will have to override at least all the abstractmethods in order to write a provider plugin, even if they are just runnig pass.

_extract_paths_scp(paths, ignore_nopath)[source]
bootstrap(*args, **kwargs)[source]

Does any actions needed to get the domain ready to be used, ran on prefix init.

Returns:None
create_snapshot(name, *args, **kwargs)[source]

Take any actions needed to create a snapshot

Parameters:name (str) – Name for the snapshot, will be used as key to retrieve it later
Returns:None
defined(*args, **kwargs)[source]

Return if the domain is defined (libvirt concept), currently used only by the libvirt provider, put here to allow backwards compatibility.

Returns:True if the domain is already defined (libvirt concept)
Return type:bool
export_disks(standalone, dst_dir, compress, *args, **kwargs)[source]

Export ‘disks’ as a standalone image or a layered image.

Parameters:
  • disks (list) – The names of the disks to export (None means all the disks)
  • standalone (bool) – If true create a copy of the layered image else create a new disk which is a combination of the current layer and the base disk.
  • dst_dir (str) – dir to place the exported images
  • compress (bool) – if true, compress the exported image.
extract_paths(paths, ignore_nopath)[source]

Extract the given paths from the domain

Parameters:
  • paths (list of str) – paths to extract
  • ignore_nopath (boolean) – if True will ignore none existing paths.
Returns:

None

Raises:
extract_paths_dead(paths, ignore_nopath)[source]

Extract the given paths from the domain, without the underlying OS awareness

interactive_console()[source]

Run an interactive console

Returns:resulf of the interactive execution
Return type:lago.utils.CommandStatus
reboot(*args, **kwargs)[source]

Reboot a domain

Returns:None
revert_snapshot(name, *args, **kwargs)[source]

Take any actions needed to revert/restore a snapshot

Parameters:name (str) – Name for the snapshot, same that was set on creation
Returns:None
shutdown(*args, **kwargs)[source]

Shutdown a domain

Returns:None
start(*args, **kwargs)[source]

Start a domain

Returns:None
state(*args, **kwargs)[source]

Return the current state of the domain

Returns:Small description of the current domain state
Return type:str
stop(*args, **kwargs)[source]

Stop a domain

Returns:None
lago.plugins.vm._resolve_service_class(class_name, service_providers)[source]

NOTE: This must be remved once the service_class spec entry is fully deprecated

Retrieves a service plugin class from the class name instead of the provider name

Parameters:
  • class_name (str) – Class name of the service plugin to retrieve
  • service_providers (dict) – provider_name->provider_class of the loaded service providers
Returns:

Class of the plugin that matches that name

Return type:

class

Raises:

lago.plugins.NoSuchPluginError – if there was no service plugin that matched the search

lago.plugins.vm.check_alive(func)[source]
lago.plugins.vm.check_defined(func)[source]