API documentation

Lifecycle

class armonic.lifecycle.Lifecycle[source]

The Lifecycle of a service or application is represented by transitions between State classes. The transitions list is specified in the class attribute Lifecycle.transition.

Main operations on a Lifecycle are:

States applied are recorded in a stack to be able to unapply them. The State stack does not contain the same State twice.

abstract = False

If the Lifecycle is abstract it won’t be loaded in the LifecycleManager and in the XML registery.

doc()[source]

Return docstring of this lifecycle.

init(state, requires=[])[source]

If it is not already initialized, push state in stack.

initial_state = None

The initial state for this Lifecycle

os_type = <OsType(Ubuntu - 14.04)>

To specify the current OS type. By default, OS type is automatically discovered but it is possible to override this attribute to manually specify one.

provide_call(state, provide_name, requires=, []path_idx=0)[source]

Go to provide state and call provide.

Parameters:
  • state (state_name | State) – the target state
  • provide_name (str) – name of the provide
  • requires (tuple of variable values and deployment info) –

    variable values to fill the requires

    ([
        ("//xpath/to/variable", {0: value}),
        ("//xpath/to/variable", {0: value})
     ], {'source' : xpath, 'id': uuid})
    
Return type:

provide result

provide_call_args(state_name, provide_name)[source]

From a provide_name, returns its needed arguments.

provide_call_path(state)[source]

Get paths to call a provide in state.

Parameters:state (state_name | State) – the target state
provide_call_requires(state, path_idx=0)[source]

Get requires to call provide in state.

Parameters:
  • state (state_name | State) – the target state
  • path_idx (int) – the path to use when there is multiple paths to go to the target State
provide_list(reachable=False)[source]

Get all available provides

Parameters:reachable (bool) – list only reachable provides from the current state
Return type:[(State, [Provide])]
state_by_name(name)[source]

Get state from its name

Parameters:name (str) – the name of a state
Return type:State
state_current()[source]

Get current state.

Return type:State
state_goto(state, requires=, []path_idx=0)[source]

Go to state.

Parameters:
  • state (state_name | State) – the target state
  • requires (tuple of variable values and deployment info) –

    variable values to fill the requires

    ([
        ("//xpath/to/variable", {0: value}),
        ("//xpath/to/variable", {0: value})
     ], {'source' : xpath, 'id': uuid})
    
  • path_idx (int) – the path to use when there is multiple paths to go to the target State
Return type:

None

state_goto_path(state, func=None, path_idx=0)[source]

Get one path to go to State.

Parameters:
  • state (state_name | State) – the target state
  • func (function) – function to apply on all States of the path
  • path_idx (int) – the path to use when there is multiple paths to go to the target State
Return type:

[(State, method), (State, method), ...]

state_goto_path_list(state)[source]

Get the list of paths to go to State.

Parameters:state (state_name | State) – the target state
Return type:[[(State, method), (State, method), ...], ...]
state_goto_requires(state, path_idx=0)[source]

Get Requires to go to State.

Parameters:
  • state (state_name | State) – the target state
  • path_idx (int) – the path to use when there is multiple paths to go to the target State
Return type:

[Provide]

state_list(reachable=False)[source]

To get all available states.

Parameters:reachable (bool) – list only reachable states from the current state
Return type:[State]
to_dot(cross=False, enter_doc=False, leave_doc=False, reachable=False)[source]

Return a dot string of lifecycle.

class armonic.lifecycle.LifecycleManager(os_type=None, autoload=True, public_ip='localhost')[source]

The LifecyleManager is used to manage Lifecyle objects. It permits to interact with lifecycles by provinding xpaths.

The full path to a variable is:

/hostname/lifecycle_name/state_name/provide_name/require_name/variable_name

The xpath to get all states of the Mysql Lifecyle would be:

//Mysql/*

To get the add_database provide in the Mysql Lifecyle:

//Mysql//add_database

All methods of LifecyleManager returns python objects.

Parameters:
  • os_type – to specify which kind of os has to be used. If it is not specified, the os type is automatically discovered.
  • public_ip – the public ip of the agent. This is used by clients to know how to contact services deployed by this agent.
from_xpath(xpath, ret='lifecycle')[source]

From a xpath try to get the object of type ret

Parameters:
  • xpath (str) – xpath to a ressource
  • ret (str) – object type to return (lifecycle, state, provide, require, variable)
Return type:

Lifecycle | State | Provide | Require | Variable

info()[source]

Get info of armonic agent

Return type:dict
lifecycle(lifecycle_xpath)[source]

List loaded lifecycle objects

Parameters:lifecycle_xpath (str) – xpath that matches lifecycles
Returns:list of Lifecycle
Return type:[Lifecycle]
load(lf_name)[source]

Load a Lifecycle in the manager and register it in the XML register.

Parameters:lf_name (str) – the Lifecycle name to load
Raises LifecycleNotExist:
 if the Lifecycle isn’t found
Returns:the loaded Lifecycle
Return type:Lifecycle
provide(provide_xpath)[source]

Return provides that match provide_xpath and that can be reached (OS_TYPE).

Parameters:provide_xpath (str) – xpath to provide
Returns:list of provides that match provide_xpath
Return type:[Provide]
provide_call(provide_xpath_uri, requires=, []path_idx=0)[source]

Call a provide of a lifecycle and go to provider state if needed

Parameters:
  • xpath (str) – xpath of the provide to call
  • requires (tuple of variable values and deployment info) –

    variable values to fill the requires

    ([
        ("//xpath/to/variable", {0: value}),
        ("//xpath/to/variable", {0: value})
     ], {'source' : xpath, 'id': uuid})
    
Returns:

provide_xpath_uri call result

provide_call_path(provide_xpath)[source]

Paths for provides that matches provide_xpath.

Parameters:provide_xpath (str) – xpath to provide
Returns:list of paths to call provides that match provide_xpath
Return type:[(Provide, [path, ...])]
provide_call_requires(provide_xpath_uri, path_idx=0)[source]

Requires for the provide.

Parameters:
  • provide_xpath_uri (str) – unique xpath to provide
  • path_idx (int) – path to use when there is multiple paths to go to the provide
Returns:

list of provides to call it order to call provide_xpath_uri

Return type:

[Provide]

provide_call_validate(provide_xpath_uri, requires=, []path_idx=0)[source]

Validate requires to call the provide

Parameters:
  • xpath (str) – unique xpath of the provide to call
  • requires (tuple of variable values and deployment info) –

    variable values to fill the requires

    ([
        ("//xpath/to/variable", {0: value}),
        ("//xpath/to/variable", {0: value})
     ], {'source' : xpath, 'id': uuid})
    
Returns:

list of validated provides to call in order to call provide_xpath_uri

Return type:

{‘errors’: bool, ‘xpath’: xpath, ‘requires’: [Provide]}

register()[source]

Register the manager in the XMLRegistery.

state(state_xpath)[source]

Return a list of states that matches state_xpath.

Parameters:state_xpath (str) – xpath that can match multiple states
Returns:list of State
Return type:[State]
state_current(lifecycle_xpath)[source]

Get the current state name of matched lifecycles.

Parameters:lifecyle_xpath – xpath that can match multiple Lifecycle
Return type:[State]
state_goto(state_xpath_uri, requires=, []path_idx=0)[source]

From the current state go to state.

Parameters:
  • xpath (str) – unique xpath of a state
  • requires (tuple of variable values and deployment info) –

    variable values to fill the requires

    ([
        ("//xpath/to/variable", {0: value}),
        ("//xpath/to/variable", {0: value})
     ], {'source' : xpath, 'id': uuid})
    
Return type:

None

state_goto_path(state_xpath)[source]

From the current state, returns all paths to goto states that match state_xpath.

Parameters:state_xpath (str) – xpath that can match multiple states
Returns:list of paths for every state matched by state_xpath
Return type:[(State, [path])]
state_goto_requires(state_xpath_uri, path_idx=0)[source]

Return the list a special provide required to go from the current state to the state that match state_xpath_uri.

Parameters:
  • state_xpath_uri (str) – unique state xpath
  • path_idx (int) – path to use when there is multiple paths to go to the provide
Return type:

[Provide]

to_dot(lf_name, reachable=False)[source]

Return the dot string of a lifecyle object

Parameters:lf_name (str) – name of the lifecycle object
Return type:dot file string
to_primitive(lf_name, reachable=False)[source]

Return a serialized Lifecycle object

Parameters:lf_name (str) – name of the Lifecycle object
Returns:serialized Lifecycle object
Return type:dict
to_xml(xpath=None)[source]

Return the xml representation of the LifecyleManager.

uri(xpath='//', relative=False, resource=None)[source]

Return the list of xpath_uris that match this xpath.

Parameters:
  • xpath (str) – an xpath string
  • relative (bool) – If true, returns relative xpath
  • resource (str) – Returns only xpath that describe this resource type
Returns:

list of xpaths

Return type:

[xpath_uri]

class armonic.lifecycle.MetaState[source]

Set by state.__new__ to add implementation of this metastate.

Be careful, provides of states that implement a MetaState are _removed_. You then have to manually redefine them in the metastate if they are required.

Provide

class armonic.provide.Flags(**flags)[source]

Decorator to define flags on a state method.

class armonic.provide.Provide(name=None, requires=, []flags={}, **extra)[source]

Basically, this describes the method of a armonic.lifecycle.State.

It contains the list of armonic.require.Require needed to call the method.

Parameters:
  • name – name of the method
  • requires – list of requires
  • flags – flags to be propagated
  • tags (list) – a list of tags where tags are strings
  • label – a human readable short description
  • help – a long help message
fill(requires=[])[source]

Fill the provide with variables values.

Parameters:variables_values

list of tuple (variable_xpath, variable_values):

("//xpath/to/variable", {0: value}),
("//xpath/to/variable", {0: value})
require_by_name(require_name)[source]
Parameters:require_name (str) – require name
Return type:armonic.require.Require
to_primitive()[source]

Serialize the provide to a python dict.

validate()[source]

Validate the provide.

Raises ValidationError:
 when validation fails
class armonic.provide.ProvideHistory(initial_history=[])[source]

Record provide calls.

Require

A Require permits to a module developper to specify what type of value it must provide to go to a state. They are specified in armonic.lifecycle.State.

Two subclasses of Require can be used if value can be provided by a lifecycle provider, namely RequireLocal and RequireExternal. These requires permit to specify the name of a provide and what variables it needs and returns. Moreover, it is sometime intersting to be able to call several time this provide and then, to use several values returned by this provide (see armonic.varnish for instance).

To provide values to a require, Require.fill() method has to be used. Note that this method is automatically called when a state is reached. Require.fill() take a dict (or a list) of primitive types to fill values of a require.

class armonic.require.Require(name, variables, nargs='1', **extra)[source]

Basically, a require is a set of armonic.variable.Variable. They are defined in a state and are used to specify, verify and store values needed to enter in this state.

To submit variable values of a require, fill() method must be used. Then, method validate() can be used to validate that values respect constraints defined by the require.

Parameters:
  • name – name of the require
  • variables – list of variables
  • nargs – variables occurences (1 or more, ‘*’, ‘?’)
factory_variable()[source]

Return an Itercontainer of variables based on variables_skel

Return type:IterContainer of Variable
fill(variables_values)[source]

Fill the require with a list of variables values

Parameters:variables_values – list of tuple (variable_xpath, variable_values) variable_xpath is a full xpath variable_values is dict of index=value
generate_args(dct={})[source]

Return a tuple. First element of tuple a dict of argName:value where value is the default value. Second is a list of argName without default value.

Parameters:dct – To specify a argName and its value.
validate(values=[])[source]

Validate Require values. If values is specified, they are used to validate the require variables. Otherwise, you must already have fill it because filled values will be used.

Return type:boolean
validate_one_set(iterContainer, values={})[source]

Validate Require values on one variables set. If values is specified, they are used to validate the require variables. Otherwise, you must already have fill it because filled values will be used.

Return type:boolean
variable_by_name(variable_name, index=0)[source]

From a variable name return the corresponding instance

Parameters:
  • variable_name (str) – variable name
  • index (int) – variable set index
Return type:

Variable

variables(index=0, all=False)[source]

Return variables of given index.

TODO: Check if index respect nargs. :param index: index of a variable set. :param all: if true returns all variables :rtype: iterContainer or ([iterContainer] if all == True)

exception armonic.require.RequireDefinitionError[source]

This is raised when the definition of a require is not correct.

class armonic.require.RequireExternal(name, xpath, provide_args=, []provide_ret=, []nargs='1', **extra)[source]

To specify a configuration variable which can be provided by a provide of a external module. A ‘host’ variable is automatically added to the args list. It MUST be provided.

class armonic.require.RequireLocal(name, xpath, provide_args=, []provide_ret=, []nargs='1', **extra)[source]

To specify a configuration variable which can be provided by a provide_name of a local Lifecycle object.

nargs parameters permits to specify how many time you can call a provide. It can be ‘1’, ‘?’, ‘*’ times. Then, variables is a list which will contains many values for each variables.

Parameters:
  • name – name of the require
  • xpath – the path of the provide to call
  • provide_args – default values for the provide
  • provide_ret – provide return value
  • nargs – provide occurences (1 or more, ‘*’) or is optional (‘?’)
generate_args(dct={})[source]

Return a tuple. First element of tuple a dict of argName:value where value is the default value. Second is a list of argName without default value.

Parameters:dct – To specify a argName and its value.
exception armonic.require.RequireNotFilled(require_name, variable_name)[source]

Raise if the value of variable is None.

Variables

class armonic.variable.ArmonicFirstInstance(name, default=None, required=True, from_xpath=None, **extra)[source]

This variable must be used to specify if an instance is the first one or not. This will be used by the lifecycle to realize some special initial stuff.

This special variable type allows smartlib to specify first instance and other. This is useful for replicated instances such as Galera.

class armonic.variable.ArmonicHost(name, default=None, required=True, from_xpath=None, modifier='%s', **extra)[source]

Internal variable that contains the host of an RequireExternal

class armonic.variable.ArmonicHosts(name, default=None, required=True, from_xpath=None, **extra)[source]

Internal variable to store the list of hosts when deploying multiple instances.

class armonic.variable.ArmonicThisHost(name, default=None, required=True, from_xpath=None, modifier='%s', **extra)[source]

This variable describe the host where the current provide is executed.

class armonic.variable.Host(name, default=None, required=True, from_xpath=None, modifier='%s', **extra)[source]

Variable for hosts.

Validate that the value is an IP or a hostname

class armonic.variable.Hostname(name, default=None, required=True, from_xpath=None, modifier='%s', **extra)[source]

Variable for hostnames.

Validate that the value is a hostname

class armonic.variable.Port(name, default=None, required=True, from_xpath=None, **extra)[source]

Variable for port numbers.

Validate that the value is between 0 and 65535

class armonic.variable.VBool(name, default=None, required=True, from_xpath=None, **extra)[source]

Variable of type boolean.

class armonic.variable.VFloat(name, default=None, required=True, from_xpath=None, **extra)[source]

Variable of type float.

class armonic.variable.VInt(name, default=None, required=True, from_xpath=None, **extra)[source]

Variable of type int.

max_val = None

Maximum value

min_val = None

Minimum value

class armonic.variable.VList(name, inner, default=None, required=True, from_xpath=None, **extra)[source]

VList provide a list container for Variable instances.

Running the validation on VList will recursively run the validation for all contained instances.

Parameters:
  • name (str) – variable name
  • inner (all instances of Variable) – the type of variable used in the list
  • default (list) – default value
  • required (bool) – required variable
  • **extra

    extra variable fields

class armonic.variable.VString(name, default=None, required=True, from_xpath=None, modifier='%s', **extra)[source]

Variable of type string

pattern = None

Validate the value again a regexp

pattern_error = None

Error message if the value doesn’t match the regexp

class armonic.variable.VUrl(name, default=None, required=True, from_xpath=None, modifier='%s', **extra)[source]

Open an url, download the remote object to a local file and return the local path of this object.

This should be renamed.

get_file()[source]
Return type:A local file name which contain uri object datas.
class armonic.variable.Variable(name, default=None, required=True, from_xpath=None, **extra)[source]

Describes a value used in a state provide.

Only name is required.

The type of a variable is validated (with _validate_type()) when the value is set. The value of a variable can be validated by hand with the _validate() method.

Parameters:
  • name (str) – variable name
  • default – default value
  • required (bool) – required variable
  • from_xpath (str) – use the xpath value for this variable
  • **extra

    extra variable fields

validate(value=None)[source]

Run the variable validation

Validate value or self.value if value is not set. If values is specified, they are used to validate the require variables. Otherwise, you must already have fill it because filled values will be used.

Set self.error when ValidationError is raised.

Raises:ValidationError
validation(value)[source]

Override for custom validation

Utils

Process

class armonic.process.ProcessThread(type, status, module, command, cwd=None, callback=None, shell=None, env=None)[source]

Base class for running tasks

catch_output()[source]

get command context

launch()[source]

Thread is started and joined. This is a blocking method.

Return type:True if process execution success
run()[source]

run command

stop()[source]

stop current process if exists

armonic.process.run(executable, args=, []cwd=None, env=None)[source]

Launch a executable and wait it. Return True if command succeed (ie. if executable return 0).

Parameters:
  • executable – Absolute path of executable
  • args – List of arguments
  • cwd – The working directory
  • env – A optionnal dict containing environnement variable name and its value

Augeas

Clients

Smart

Smart module offers a high level way to call a provide. Function smart_call() generates steps to help the user to

  • define LifecycleManager,
  • specialize xpath provide,
  • specify variable value,
  • ...

To use this module, you have to create a armonic.client.smart.Provide, and call armonic.client.smart.smart_call(). In the following, the classical code to use this library.

First, we define by inheritance global behavior of provides. In this example, we want to ‘manage’ all provides:

from armonic.client.smart import Provide, smart_call

class MyProvide(Provide):
    def on_manage(self, data):
        return True

Then, we can build a provide from this classe and call smart_call on it which returns a generator. We use this generator to walk on provides:

my_provide = MyProvide("//a/xpath)
generator = smart_call(my_provide)
data = None
while True:
    provide, step, args = generator.send(data)
    data = None

    if step == "manage":
        print "Provide %s is managed!" % provide.generic_xpath
    elif step == "specialize":
        # Do others stuffs on specialize step
        # ...
    elif step == ....

Some tips about how it works...

About provide_ret validation: Since provide_ret variables’s values are known at runtime, we need to do special thing to pass agent validation before deployement. Smart ignore validation errors returned by agents if error occurs on variables that belongs to provide_ret.

class armonic.client.smart.Provide(generic_xpath, requirer=None, child_num=None, require=None)[source]

This class describe a provide and its requires and remotes requires contains provide. Thus, this object can describe a tree. To build the tree, the function smart_call() must be used.

To adapt the behavior of this class, redefine methods on_step and do_step, where step is manage, lfm, specialize, etc. If method do_step returns True, this step is ‘yielded’. Method on_step takes as input the sent data.

Parameters:
  • child_number – if this Provide is a dependencies, this is the number of this child.
  • requirer – the provide that need this require
  • require – the remote require of the requirer that leads to this provide.
build_child(generic_xpath, child_num, require)[source]

Build and return a new provide by using the same class.

do_lfm()[source]

The step lfm is applied if it returns True.

Currently, do_lfm is already called, even if the provide is local. We may only call it when the provide is external

do_specialize()[source]

Specialization can not be avoided. If the provide matches only 1 xpath, yield doesn’t occurs if this method returns False.

Thus, by returning True, specialization always yields.

has_requirer()[source]

To know if it is the root provide.

matches()[source]

Return the list of provides that matched the generic_xpath

on_call(call)[source]
on_multiplicity(requires, data)[source]

Can be overload to adapt behavior of multiplicity step. This method must return either a number or a list.

This is different than others steps because we can not bind the multiplicity value to the provide object since each require have its own multiplicity.

Moreover, on_multiplicity is always called even if do_multiplicity returns False.

on_specialize(xpath)[source]

Actions after the provide has been specialized.

require = None

Contains the Require that requires this provide.

requirer = None

Contains the Provide that requires this current provide.

reset_lfm()[source]

Reset all data set at the lfm step

update_scope_provide_ret(provide_ret)[source]

When the provide call returns value, we habve to update the scope of the require in order to be able to use these value to fill depending provides.

validate(values, static=False)[source]

Validate all variables using values from data. Moreover, variable value is set with values coming from data.

The static validation is used to validate variables before deployment is running. In this case, we don’t handle error on provide_ret’s variables since we don’t know value returned by porvide calls.

Parameters:static – If True, run a static validation.
Return type:bool
variables()[source]
Return type:[Variable]
variables_scope()[source]

Return the variable scope of this provide.

Return type:[Variable]
variables_serialized()[source]

Get variables in the format for provide_call

armonic.client.smart.smart_call(root_provide, values={})[source]

Generator which ‘yields’ a 3-uple (provide, step, optionnal_args).

Socket

class armonic.client.sock.ClientSocket(host='127.0.0.1', port=8000, handlers=[])[source]

A simple socket client for armonic agent.

Logs emit by agent are forwarded to this client. To use them, add a logging handler with add_logging_handler() or they can be specified as arguments at init time.

Parameters:handlers ([logging.Handler]) – To set handlers to forward agent logs
add_logging_handler(handler)[source]

Set a handler. You can use handler defined by the standard logging module, for instance logging.StreamHandler

call(method, *args, **kwargs)[source]

Make a call to the agent. See armonic.lifecycle.LifecycleManager to know which methods can be called.

to_xml(xpath=None)[source]

Return the xml representation of agent.