core Package

core Package

provy’s core classes. The modules in this namespace are the ones that run provy.

errors Module

exception provy.core.errors.ConfigurationError[source]

Bases: exceptions.RuntimeError

Raised when there’s a configuration error in the provyfile.

roles Module

Module responsible for the base Role and its operations.

class provy.core.roles.DistroInfo[source]

Bases: object

Value object used to contain distribution information.

Refer to Role.get_distro_info() usage.

codename = None
description = None
distributor_id = None
lsb_version = None
release = None
class provy.core.roles.Role(prov, context)[source]

Bases: object

Base Role class. This is the class that is inherited by all provy’s roles.

This class provides many utility methods for interacting with the remote server.

Example:

from provy.core import Role

class MySampleRole(Role):
    def provision(self):
        self.register_template_loader('my.full.namespace')
        self.execute('ls /home/myuser', sudo=False, stdout=False)
change_path_mode(path, mode, recursive=False)[source]

Changes the mode of a given path.

Parameters:
  • path (str) – Path to have its mode changed.
  • mode (int) – Mode to change to.
  • recursive (bool) – Indicates if the mode of the objects in the path should be changed recursively. Defaults to False.

Example:

from provy.core import Role

class MySampleRole(Role):
    def provision(self):
        self.change_path_mode(directory='/home/user/logs', mode=644, recursive=True)
change_path_owner(path, owner)[source]

Changes the owner of a given path. Please be advised that this method is recursive, so if the path is a directory, all contents of it will belong to the specified owner.

Parameters:
  • path (str) – Path to have its owner changed.
  • owner (str) – User that should own this path.

Example:

from provy.core import Role

class MySampleRole(Role):
    def provision(self):
        self.change_path_owner(path='/etc/my-path', owner='someuser')
cleanup()[source]

Base cleanup method. This is meant to be overriden and does not do anything.

The cleanup method is the method that provy calls after all Roles have been provisioned and is meant to allow Roles to perform any cleaning of resources or finish any pending operations.

Please note that when overriding this method you should call super method.

Example:

from provy.core import Role

class MySampleRole(Role):
    def cleanup(self):
        pass
create_remote_temp_dir(dirname=None, owner=None, chmod=None, cleanup=True)[source]

Creates temporary directory on remote server. This directory will be stored in temporary directory on remote server.

Parameters:
  • dirname (str) – Name of the directory. If None random name will be choosen. Defaults to None.
  • owner (str) – Username of user who will own this directory. Defaults to None which in turns means current remote user.
  • chmod (str) – File modifiers specified for this directory. Defaults to None which in turns means leave default chmod specified by the remote OS.
  • cleanup (bool) – If True directory will be deleted during cleanup phase. Default: True.
Returns:

Created directory name.

Return type:

str

create_remote_temp_file(prefix='', suffix='', cleanup=True)[source]

Creates random unique file name in the remote server temp dir.

This file is not uploaded by server, but because it is generated by uuid.uuid4 you can be sure no other process will clash with it.

Parameters:
  • prefix (str) – Optional prefix to the file name.
  • suffix (str) – Optional suffix to the file name. Usefull to provide extensions.
  • cleanup (bool) – If True file will be deleted during cleanup phase. Default: True.
Returns:

Created file name.

Return type:

str

ensure_dir(directory, owner=None, sudo=False)[source]

Make sure the specified directory exists in the remote server.

Parameters:
  • directory (str) – Directory to be created if it does not exist.
  • owner (str) – If specified, the directory will be created under this user, otherwise the currently logged user is the owner.
  • sudo (bool) – If specified, the directory is created under the super-user. This is particularly useful in conjunction with the owner parameter, to create folders for the owner where only the super-user can write.

Example:

from provy.core import Role

class MySampleRole(Role):
    def provision(self):
        self.ensure_dir('/etc/my-path', owner='myuser', sudo=True)
ensure_line(line, file_path, owner=None, sudo=False)[source]

Ensures that the given line exists in the given file_path. Adds it if it doesn’t exist, and creates the file if it doesn’t exist.

Parameters:
  • line (str) – Line of text to verify in the given file.
  • file_path (str) – Complete path of the remote file.
  • owner (str) – The user that owns the file. Defaults to None (the context user is used in this case).
  • sudo (bool) – Indicates whether the file should be managed by the super-user. Defaults to False.

Example:

from provy.core import Role

class MySampleRole(Role):
    def provision(self):
        self.ensure_line('127.0.0.1     localhost', '/etc/hosts')
execute(command, stdout=True, sudo=False, user=None, cwd=None)[source]

This method is the bread and butter of provy and is a base for most other methods that interact with remote servers.

It allows you to perform any shell action in the remote server. It is an abstraction over fabric run and sudo methods.

Parameters:
  • command (str) – The command to be executed.
  • stdout (bool) – If you specify this argument as False, the standard output of the command execution will not be displayed in the console. Defaults to True.
  • sudo (bool) – Specifies whether this command needs to be run as the super-user. Doesn’t need to be provided if the “user” parameter (below) is provided. Defaults to False.
  • user (str) – If specified, will be the user with which the command will be executed. Defaults to None.
  • cwd (str) – Represents a directory on remote server.If specified we will cd into that directory before executing command. Current path will be unchanged after the call.
Returns:

The execution result

Return type:

str

Example:

from provy.core import Role

class MySampleRole(Role):
    def provision(self):
        self.execute('ls /', stdout=False, sudo=True)
        self.execute('ls /', stdout=False, user='vip')
execute_local(command, stdout=True, sudo=False, user=None)[source]

Allows you to perform any shell action in the local machine. It is an abstraction over the fabric.api.local method.

Parameters:
  • command (str) – The command to be executed.
  • stdout (bool) – If you specify this argument as False, the standard output of the command execution will not be displayed in the console. Defaults to True.
  • sudo (bool) – Specifies whether this command needs to be run as the super-user. Doesn’t need to be provided if the “user” parameter (below) is provided. Defaults to False.
  • user (str) – If specified, will be the user with which the command will be executed. Defaults to None.
Returns:

The execution result

Return type:

str

Example:

from provy.core import Role

class MySampleRole(Role):
    def provision(self):
        self.execute_local('ls /', stdout=False, sudo=True)
        self.execute_local('ls /', stdout=False, user='vip')
execute_python(command, stdout=True, sudo=False)[source]

Just an abstraction over execute. This method executes the python code that is passed with python -c.

Parameters:
  • command (str) – The command to be executed.
  • stdout (bool) – If you specify this argument as False, the standard output of the command execution will not be displayed in the console. Defaults to True.
  • sudo (bool) – Specifies whether this command needs to be run as the super-user. Doesn’t need to be provided if the “user” parameter (below) is provided. Defaults to False.
Returns:

The execution result

Return type:

str

Example:

from provy.core import Role

class MySampleRole(Role):
    def provision(self):
        self.python_execute('import os; print os.curdir', stdout=False, sudo=True)
execute_python_script(script, stdout=True, sudo=False)[source]

Executes python script on remote server. Difference with execute_python() is that this implementation uploads a file with script to remote server and then executes it, so we have no problems with shell expansion.

Parameters:
  • script (string or an opened file) – Script to be executed on remote server. Can be either a string or a (opened) file like object.
  • stdout (bool) – If you specify this argument as False, the standard output of the command execution will not be displayed in the console. Defaults to True.
  • sudo (bool) – Specifies whether this command needs to be run as the super-user. Doesn’t need to be provided if the “user” parameter (below) is provided. Defaults to False.
Returns:

stdout of script

get_distro_info()[source]

Returns a DistroInfo with valuable information regarding the distribution of the server.

In the backgrounds, what it does is to run

$ lsb_release -a

in the server, so you might want to check which results are usual for your distribution.

Warning

The distribution info is requested to the server only once per Role instance, which means you won’t get the new distro info if it changes remotely.

Example:

from provy.core import Role

class MySampleRole(Role):
    def provision(self):
        distro_info = self.role.get_distro_info()

        # Supposing the server is a Debian Squeeze, the following statements will probably be true:
        distro_info.distributor_id == 'Debian'
        distro_info.description == 'Debian GNU/Linux 6.0.5 (squeeze)'
        distro_info.release == '6.0.5'
        distro_info.codename == 'squeeze'

        # Supposing the server is a Ubuntu Precise Pangolin, the following statements will probably be true:
        distro_info.distributor_id == 'Ubuntu'
        distro_info.description == 'Ubuntu 12.04.1 LTS'
        distro_info.release == '12.04'
        distro_info.codename == 'precise'

        # Supposing the server is a CentOS, the following statements may be true:
        distro_info.lsb_version == ':core-4.0-ia32:core-4.0-noarch:graphics-4.0-ia32:graphics-4.0-noarch:printing-4.0-ia32:printing-4.0-noarch'
        distro_info.distributor_id == 'CentOS'
        distro_info.description == 'CentOS release 5.8 (Final)'
        distro_info.release == '5.8'
        distro_info.codename == 'Final'
get_logged_user()[source]

Returns the currently logged user in the remote server.

Returns:The logged user
Return type:str

Example:

from provy.core import Role

class MySampleRole(Role):
    def provision(self):
        self.context['my-user'] = self.get_logged_user()
get_object_mode(path)[source]

Returns the permission mode of a given object. Raises IOError if the path doesn’t exist.

Parameters:path (str) – Path of the given object.
Returns:The path permission mode
Return type:int
Raise:IOError if the path doesn’t exist

Example:

from provy.core import Role

class MySampleRole(Role):
    def provision(self):
        if self.get_object_mode('/home/user/logs') == 644:
            pass
has_line(line, file_path)[source]

Returns True if the given line of text is present in the given file. Returns False otherwise (even if the file does not exist).

Parameters:
  • line (str) – Line of text to verify in the given file.
  • file_path (str) – Complete path of the remote file.
Returns:

Whether the line exists or not.

Return type:

bool

Example:

from provy.core import Role

class MySampleRole(Role):
    def provision(self):
        if self.has_line('127.0.0.1 localhost', '/etc/hosts'):
            pass
is_process_running(process, sudo=False)[source]

Returns True if the given process is running (listed in the process listing), False otherwise.

Parameters:
  • process (str) – Regular expression string that specifies the process name.
  • sudo (bool) – Indicates if the process listing should be done by the super-user. Defaults to False.
Returns:

Whether the process is running or not.

Return type:

bool

Example:

from provy.core import Role

class MySampleRole(Role):
    def provision(self):
        if self.is_process_running('nginx', sudo=True):
            self.execute('pkill nginx', stdout=False, sudo=True)
local_exists(file_path)[source]

Returns True if the file exists locally.

Parameters:file_path (str) – The path to check.
Returns:Whether the file exists or not
Return type:bool

Example:

from provy.core import Role

class MySampleRole(Role):
    def provision(self):
        if self.local_exists('/tmp/my-file'):
            pass
local_temp_dir()[source]

Returns the path of a temporary directory in the local machine.

Returns:The temp dir path
Return type:str

Example:

from provy.core import Role

class MySampleRole(Role):
    def provision(self):
        self.context['source_dir'] = self.local_temp_dir()
log(msg)[source]

Logs a message to the console with the hour prepended.

Parameters:msg (str) – Message to log.

Example:

from provy.core import Role

class MySampleRole(Role):
    def provision(self):
        self.log('Hello World')
md5_local(path)[source]

Calculates an md5 hash for a given file in the local system. Returns None if file does not exist.

Parameters:path (str) – Path of the local file.
Returns:The hash generated, or None if path doesn’t exist.
Return type:str

Example:

from provy.core import Role

class MySampleRole(Role):
    def provision(self):
        hash = self.md5_local('/tmp/my-file')
md5_remote(path)[source]

Calculates an md5 hash for a given file in the remote system. Returns None if file does not exist.

Parameters:path (str) – Path of the remote file.
Returns:The hash generated, or None if path doesn’t exist.
Return type:str

Example:

from provy.core import Role

class MySampleRole(Role):
    def provision(self):
        hash = self.md5_remote('/tmp/my-file')
provision()[source]

Base provision method. This is meant to be overriden and does not do anything.

The provision method of each Role is what provy calls on to provision servers.

Example:

from provy.core import Role

class MySampleRole(Role):
    def provision(self):
        pass
provision_role(role)[source]

Provisions a role inside your role. This method is the way to call other roles if you don’t need to call any methods other than provision.

provision_role keeps the context and lifecycle for the current server when calling the role and makes sure it is disposed correctly.

Note

There’s no need to call this method, if you’re using the using() as a context manager.

Parameters:role (Role) – The role to be provisioned.

Example:

from provy.core import Role

class MySampleRole(Role):
    def provision(self):
        self.provision_role(SomeOtherRole)
put_file(from_file, to_file, sudo=False, stdout=True)[source]

Puts a file to the remote server.

Parameters:
  • from_file (str) – Source file in the local system.
  • to_file (str) – Target path in the remote server.
  • sudo (bool) – Indicates whether the file should be created by the super-user. Defaults to False.

Example:

from provy.core import Role

class MySampleRole(Role):
    def provision(self):
        self.put_file('/home/user/my-app', '/etc/init.d/my-app', sudo=True)
read_remote_file(path, sudo=True)[source]

Returns the contents of a remote file.

Parameters:
  • path (str) – File path on the remote server.
  • sudo (bool) – Indicates whether the file should be read by a super-user. Defaults to True.
Returns:

The contents of the file.

Return type:

str

Example:

from provy.core import Role

class MySampleRole(Role):
    def provision(self):
        last_update = self.read_remote_file('/tmp/last-update')
register_template_loader(package_name)[source]

Register the package_name module as a valid source for templates in Jinja2.

Jinja2 will look inside a folder called templates in the specified module.

It is paramount that this module can be imported by python. The path must be well-known or be a sub-path of the provyfile.py directory.

Parameters:package_name (str) –

Full name of the module that Jinja2 will try to import.

Example:

from provy.core import Role

class MySampleRole(Role):
    def provision(self):
        self.register_template_loader('my.full.namespace')
remote_exists(file_path)[source]

Returns True if the file exists in the remote server.

Parameters:file_path (str) – The path to check.
Returns:Whether the file exists or not
Return type:bool

Example:

from provy.core import Role

class MySampleRole(Role):
    def provision(self):
        if self.remote_exists('/tmp/my-file'):
            pass
remote_exists_dir(file_path)[source]

Returns True if the directory exists in the remote server.

Parameters:file_path (str) – The path to check.
Returns:Whether the directory exists or not
Return type:bool

Example:

from provy.core import Role

class MySampleRole(Role):
    def provision(self):
        if self.remote_exists_dir('/tmp'):
            pass
remote_list_directory(path)[source]

Lists contents of remote directory and returns them as a python list.

Parameters:path (str) – Path to list on the remote side.
Returns:Remote directory lisitng.
Return type:list

Creates a symlink in the remote server.

Parameters:
  • from_file (str) – Symlink source.
  • to_file (str) – Symlink target.
  • sudo (bool) – Indicates whether the symlink should be created by the super-user. Defaults to False.

Example:

from provy.core import Role

class MySampleRole(Role):
    def provision(self):
        self.remote_symlink('/home/user/my-app', '/etc/init.d/my-app', sudo=True)
remote_temp_dir()[source]

Returns the path of a temporary directory in the remote server.

Returns:The temp dir path
Return type:str

Example:

from provy.core import Role

class MySampleRole(Role):
    def provision(self):
        self.context['target_dir'] = self.remote_temp_dir()
remove_dir(path, sudo=False, recursive=False, stdout=True)[source]

Removes a directory in the remote server. Returns True in the event of the directory actually been removed. False otherwise.

Parameters:
  • path (str) – Path of the remote directory.
  • sudo (bool) – Indicates whether the directory should be removed by the super-user. Defaults to False.
  • recursive (bool) – Indicates whether the directory should be removed recursively or not. Defaults to False.
Returns:

Whether the directory had to be removed or not.

Return type:

bool

Example:

from provy.core import Role

class MySampleRole(Role):
    def provision(self):
        self.remove_dir('/tmp/my-dir', sudo=True, recursive=True)
remove_file(path, sudo=False)[source]

Removes a file in the remote server. Returns True in the event of the file actually been removed. False otherwise.

Parameters:
  • path (str) – Path of the remote file.
  • sudo (bool) – Indicates whether the file should be removed by the super-user. Defaults to False.
Returns:

Whether the file had to be removed or not.

Return type:

bool

Example:

from provy.core import Role

class MySampleRole(Role):
    def provision(self):
        self.remove_file('/tmp/my-file', sudo=True)
render(template_file, options={})[source]

Renders a template with the given options and returns the rendered text.

The template_file parameter should be just the name of the file and not the file path. Jinja2 will look for templates at the files directory in the provyfile path, as well as in the templates directory of any registered module (check the register_template_loader() method).

The options parameter will extend the server context, so all context variables (including per-server options) are available to the renderer.

Parameters:
  • template_file (str) – Template file path in the local system.
  • options (dict) – Options to be passed to the template, as a dictionary. Defaults to empty dict.
Returns:

The contents of the file.

Return type:

str

Example:

from provy.core import Role

class MySampleRole(Role):
    def provision(self):
        contents = self.render('my-template', { 'user': 'heynemann' })
roles_in_context
schedule_cleanup()[source]

Makes sure that this role will be cleaned up properly after the server has been provisioned. Call this method in your provision method if you need your role’s cleanup method to be called.

Note

If you are using the proper ways of calling roles (provision_role(), using()) in your role, you do not need to call this method.

Example:

from provy.core import Role

class MySampleRole(Role):
    def provision(self):
        self.schedule_cleanup()
update_file(from_file, to_file, owner=None, options={}, sudo=None)[source]

One of the most used methods in provy. This method renders a template, then if the contents differ from the remote server (or the file does not exist at the remote server), it sends the results there.

Again, combining the parameters sudo and owner you can have files that belong to an user that is not a super-user in places that only a super-user can reach.

Returns True if the file was updated, False otherwise.

Parameters:
  • from_file (str) – Template file in the local system.
  • to_file (str) – Target path in the remote server.
  • owner (str) – Owner for the file in the remote server.
  • options (dict) – Dictionary of options that can be used in the template.
  • sudo (bool) – Indicates whether the file should be created by the super-user. Defaults to None.
Returns:

Whether the file was updated or not.

Return type:

bool

Example:

from provy.core import Role

class MySampleRole(Role):
    def provision(self):
        self.update_file('/home/user/my-app', '/etc/init.d/my-app', owner='my-user',
                         {
                            'option_a': 1,
                            'option_b': 2
                         },
                         sudo=True)
using(role)[source]

This method should be used when you want to use a different Role inside your own Role methods.

It returns a ContextManager object, so this is meant to go inside a with block.

Parameters:role (Role) – Role to be used.

Example:

from provy.core import Role

class MySampleRole(Role):
    def provision(self):
        with self.using(AptitudeRole) as role:
            role.ensure_package_installed('nginx')
write_to_temp_file(text)[source]

Writes some text to a temporary file and returns the file path.

Parameters:text (str) – Text to be written to the temp file.
Returns:Temp file path.
Return type:str

Example:

from provy.core import Role

class MySampleRole(Role):
    def provision(self):
        path = self.write_to_temp_file('some random text')
        self.put_file(path, '/tmp/some-file')
class provy.core.roles.UpdateData(local_temp_path, from_md5, to_md5)[source]

Bases: object

Value object used in the update_file method.

class provy.core.roles.UsingRole(role, prov, context)[source]

Bases: object

This is the contextmanager that allows using Roles in other Roles, in a nested manner.

Don’t use this directly; Instead, use the base Role‘s using method.

runner Module

This is the internal module responsible for running provy over the provyfile that was provided.

It’s recommended not to tinker with this module, as it might prevent your provyfile from working.

provy.core.runner.aggregate_node_options(server, context)[source]
provy.core.runner.build_prompt_options(servers, extra_options)[source]
provy.core.runner.get_items(prov, item_name, item_key, test_func)[source]
provy.core.runner.get_servers_for(prov, server_name)[source]
provy.core.runner.print_header(msg)[source]
provy.core.runner.provision_server(server, provfile_path, password, prov)[source]
provy.core.runner.recurse_items(col, test_func, found_items)[source]
provy.core.runner.run(provfile_path, server_name, password, extra_options)[source]

utils Module

Core utilities.

Provides the AskFor class, which is used to prompt for a password.

class provy.core.utils.AskFor(key, question)[source]

Bases: object

Responsible for prompting for a password to the user.

You may pass an instance of it, instead of a plain value, in the servers dictionary, so that you require the user to enter a value.

get_value(server)[source]
provy.core.utils.import_module(module_name)[source]
provy.core.utils.provyfile_module_from(path)[source]
provy.core.utils.provyfile_path_from(args)[source]