Welcome to fabtools’s documentation!

https://api.travis-ci.org/ronnix/fabtools.png

About

fabtools includes useful functions to help you write your Fabric files.

fabtools makes it easier to manage system users, packages, databases, etc.

fabtools includes a number of low-level actions, as well as a higher level interface called fabtools.require.

Using fabtools.require allows you to use a more declarative style, similar to Chef or Puppet.

Installing

To install the latest release from PyPI

$ pip install fabtools

To install the latest development version from GitHub

$ pip install git+git://github.com/ronnix/fabtools.git

Example

Here is an example fabfile.py using fabtools

from fabric.api import *
from fabtools import require
import fabtools

@task
def setup():

    # Require some Debian/Ubuntu packages
    require.deb.packages([
        'imagemagick',
        'libxml2-dev',
    ])

    # Require a Python package
    with fabtools.python.virtualenv('/home/myuser/env'):
        require.python.package('pyramid')

    # Require an email server
    require.postfix.server('example.com')

    # Require a PostgreSQL server
    require.postgres.server()
    require.postgres.user('myuser', 's3cr3tp4ssw0rd')
    require.postgres.database('myappsdb', 'myuser')

    # Require a supervisor process for our app
    require.supervisor.process('myapp',
        command='/home/myuser/env/bin/gunicorn_paster /home/myuser/env/myapp/production.ini',
        directory='/home/myuser/env/myapp',
        user='myuser'
        )

    # Require an nginx server proxying to our app
    require.nginx.proxied_site('example.com',
        docroot='/home/myuser/env/myapp/myapp/public',
        proxy_url='http://127.0.0.1:8888'
        )

    # Setup a daily cron task
    fabtools.cron.add_daily('maintenance', 'myuser', 'my_script.py')

Supported targets

fabtools currently supports the following target operating systems:

  • Debian 6.0 (squeeze)
  • Ubuntu 10.04 (lucid)
  • Ubuntu 12.04 (precise)
  • RHEL 5/6
  • CentOS 5/6
  • Scientific Linux 5/6
  • SmartOS (Joyent)
  • Arch Linux

Contributions to help support other Unix/Linux distributions are welcome!

API Documentation

fabtools

fabtools.apache

Apache

This module provides tools for configuring the Apache HTTP Server.

fabtools.apache.is_module_enabled(module)[source]

Check if an Apache module is enabled.

fabtools.apache.enable_module(module)[source]

Enable an Apache module.

This creates a symbolic link from /etc/apache2/mods-available/ into /etc/apache2/mods-enabled/.

This does not cause Apache to reload its configuration.

import fabtools

fabtools.apache.enable_module('rewrite')
fabtools.service.reload('apache2')
fabtools.apache.disable_module(module)[source]

Disable an Apache module.

This deletes the symbolink link in /etc/apache2/mods-enabled/.

This does not cause Apache to reload its configuration.

import fabtools

fabtools.apache.disable_module('rewrite')
fabtools.service.reload('apache2')
fabtools.apache.is_site_enabled(config)[source]

Check if an Apache site is enabled.

fabtools.apache.enable_site(config)[source]

Enable an Apache site.

This creates a symbolic link from /etc/apache2/sites-available/ into /etc/apache2/sites-enabled/.

This does not cause Apache to reload its configuration.

import fabtools

fabtools.apache.enable_site('default')
fabtools.service.reload('apache2')
fabtools.apache.disable_site(config)[source]

Disable an Apache site.

This deletes the symbolink link in /etc/apache2/sites-enabled/.

This does not cause Apache to reload its configuration.

import fabtools

fabtools.apache.disable_site('default')
fabtools.service.reload('apache2')

fabtools.arch

Arch Linux packages

This module provides tools to manage Arch Linux packages and repositories.

fabtools.arch.update_index(quiet=True)[source]

Update pacman package definitions.

fabtools.arch.upgrade()[source]

Upgrade all packages.

fabtools.arch.is_installed(pkg_name)[source]

Check if an Arch Linux package is installed.

fabtools.arch.install(packages, update=False, options=None)[source]

Install one or more Arch Linux packages.

If update is True, the package definitions will be updated first, using update_index().

Extra options may be passed to pacman if necessary.

Example:

import fabtools

# Update index, then install a single package
fabtools.arch.install('mongodb', update=True)

# Install multiple packages
fabtools.arch.install([
    'mongodb',
    'python-pymongo',
])
fabtools.arch.uninstall(packages, options=None)[source]

Remove one or more Arch Linux packages.

Extra options may be passed to pacman if necessary.

fabtools.cron

Cron tasks

This module provides tools to manage periodic tasks using cron.

fabtools.cron.add_task(name, timespec, user, command, environment=None)[source]

Add a cron task.

The command will be run as user periodically.

You can use any valid crontab(5) timespec, including the @hourly, @daily, @weekly, @monthly and @yearly shortcuts.

You can also provide an optional dictionary of environment variables that should be set when running the periodic command.

Examples:

from fabtools.cron import add_task

# Run every month
add_task('cleanup', '@monthly', 'alice', '/home/alice/bin/cleanup.sh')

# Run every tuesday and friday at 5:30am
add_task('reindex', '30 5 * * 2,4', 'bob', '/home/bob/bin/reindex.sh')
fabtools.cron.add_daily(name, user, command, environment=None)[source]

Shortcut to add a daily cron task.

Example:

import fabtools

# Run every day
fabtools.cron.add_daily('backup', 'root', '/usr/local/bin/backup.sh')

fabtools.deb

Debian packages

This module provides tools to manage Debian/Ubuntu packages and repositories.

fabtools.deb.update_index(quiet=True)[source]

Update APT package definitions.

fabtools.deb.upgrade(safe=True)[source]

Upgrade all packages.

fabtools.deb.is_installed(pkg_name)[source]

Check if a package is installed.

fabtools.deb.install(packages, update=False, options=None, version=None)[source]

Install one or more packages.

If update is True, the package definitions will be updated first, using update_index().

Extra options may be passed to apt-get if necessary.

Example:

import fabtools

# Update index, then install a single package
fabtools.deb.install('build-essential', update=True)

# Install multiple packages
fabtools.deb.install([
    'python-dev',
    'libxml2-dev',
])

# Install a specific version
fabtools.deb.install('emacs', version='23.3+1-1ubuntu9')
fabtools.deb.uninstall(packages, purge=False, options=None)[source]

Remove one or more packages.

If purge is True, the package configuration files will be removed from the system.

Extra options may be passed to apt-get if necessary.

fabtools.deb.preseed_package(pkg_name, preseed)[source]

Enable unattended package installation by preseeding debconf parameters.

Example:

import fabtools

# Unattended install of Postfix mail server
fabtools.deb.preseed_package('postfix', {
    'postfix/main_mailer_type': ('select', 'Internet Site'),
    'postfix/mailname': ('string', 'example.com'),
    'postfix/destinations': ('string', 'example.com, localhost.localdomain, localhost'),
})
fabtools.deb.install('postfix')
fabtools.deb.get_selections()[source]

Get the state of dkpg selections.

Returns a dict with state => [packages].

fabtools.deb.apt_key_exists(keyid)[source]

Check if the given key id exists in apt keyring.

fabtools.deb.add_apt_key(filename=None, url=None, keyid=None, keyserver='subkeys.pgp.net', update=False)[source]

Trust packages signed with this public key.

Example:

import fabtools

# Varnish signing key from URL and verify fingerprint)
fabtools.deb.add_apt_key(keyid='C4DEFFEB', url='http://repo.varnish-cache.org/debian/GPG-key.txt')

# Nginx signing key from default key server (subkeys.pgp.net)
fabtools.deb.add_apt_key(keyid='7BD9BF62')

# From custom key server
fabtools.deb.add_apt_key(keyid='7BD9BF62', keyserver='keyserver.ubuntu.com')

# From a file
fabtools.deb.add_apt_key(keyid='7BD9BF62', filename='nginx.asc'
fabtools.deb.last_update_time()[source]

Get the time of last APT index update

This is the last modification time of /var/lib/apt/periodic/fabtools-update-success-stamp.

Returns -1 if there was no update before.

Example:

import fabtools

print(fabtools.deb.last_update_time())
# 1377603808.02

fabtools.disk

Disk Tools
fabtools.disk.partitions(device='')[source]

Get a partition list for all disk or for selected device only

Example:

from fabtools.disk import partitions

spart = {'Linux': 0x83, 'Swap': 0x82}
parts = partitions()
# parts =  {'/dev/sda1': 131, '/dev/sda2': 130, '/dev/sda3': 131}
r = parts['/dev/sda1'] == spart['Linux']
r = r and parts['/dev/sda2'] == spart['Swap']
if r:
    print("You can format these partitions")
fabtools.disk.getdevice_by_uuid(uuid)[source]

Get a HDD device by uuid

Example:

from fabtools.disk import getdevice_by_uuid 

device = getdevice_by_uuid("356fafdc-21d5-408e-a3e9-2b3f32cb2a8c")
if device:
    mount(device,'/mountpoint')
fabtools.disk.mount(device, mountpoint)[source]

Mount a partition

Example:

from fabtools.disk import mount

mount('/dev/sdb1', '/mnt/usb_drive')
fabtools.disk.swapon(device)[source]

Active swap partition

Example:

from fabtools.disk import swapon

swapon('/dev/sda1')
fabtools.disk.ismounted(device)[source]

Check if partition is mounted

Example:

from fabtools.disk import ismounted

if ismounted('/dev/sda1'):
   print ("disk sda1 is mounted")
fabtools.disk.mkfs(device, ftype)[source]

Format filesystem

Example:

from fabtools.disk import mkfs

mkfs('/dev/sda2', 'ext4')
fabtools.disk.mkswap(device)[source]

Format swap partition

Example:

from fabtools.disk import mkswap

mkswap('/dev/sda2')

fabtools.files

Files and directories
fabtools.files.is_file(path, use_sudo=False)[source]

Check if a path exists, and is a file.

fabtools.files.is_dir(path, use_sudo=False)[source]

Check if a path exists, and is a directory.

Check if a path exists, and is a symbolic link.

fabtools.files.owner(path, use_sudo=False)[source]

Get the owner name of a file or directory.

fabtools.files.group(path, use_sudo=False)[source]

Get the group name of a file or directory.

fabtools.files.mode(path, use_sudo=False)[source]

Get the mode (permissions) of a file or directory.

Returns a string such as '0755', representing permissions as an octal number.

fabtools.files.umask(use_sudo=False)[source]

Get the user’s umask.

Returns a string such as '0002', representing the user’s umask as an octal number.

If use_sudo is True, this function returns root’s umask.

fabtools.files.upload_template(filename, destination, context=None, use_jinja=False, template_dir=None, use_sudo=False, backup=True, mirror_local_mode=False, mode=None, mkdir=False, chown=False, user=None)[source]

Upload a template file.

This is a wrapper around fabric.contrib.files.upload_template() that adds some extra parameters.

If mkdir is True, then the remote directory will be created, as the current user or as user if specified.

If chown is True, then it will ensure that the current user (or user if specified) is the owner of the remote file.

fabtools.files.md5sum(filename, use_sudo=False)[source]

Compute the MD5 sum of a file.

class fabtools.files.watch(filenames, callback=None, use_sudo=False)[source]

Context manager to watch for changes to the contents of some files.

The filenames argument can be either a string (single filename) or a list (multiple filenames).

You can read the changed attribute at the end of the block to check if the contents of any of the watched files has changed.

You can also provide a callback that will be called at the end of the block if the contents of any of the watched files has changed.

Example using an explicit check:

from fabric.contrib.files import comment, uncomment

from fabtools.files import watch
from fabtools.services import restart

# Edit configuration file
with watch('/etc/daemon.conf') as config:
    uncomment('/etc/daemon.conf', 'someoption')
    comment('/etc/daemon.conf', 'otheroption')

# Restart daemon if needed
if config.changed:
    restart('daemon')

Same example using a callback:

from functools import partial

from fabric.contrib.files import comment, uncomment

from fabtools.files import watch
from fabtools.services import restart

with watch('/etc/daemon.conf', callback=partial(restart, 'daemon')):
    uncomment('/etc/daemon.conf', 'someoption')
    comment('/etc/daemon.conf', 'otheroption')
fabtools.files.uncommented_lines(filename, use_sudo=False)[source]

Get the lines of a remote file, ignoring empty or commented ones

fabtools.files.getmtime(path, use_sudo=False)[source]

Return the time of last modification of path. The return value is a number giving the number of seconds since the epoch

Same as os.path.getmtime()

fabtools.files.copy(source, destination, recursive=False, use_sudo=False)[source]

Copy a file or directory

fabtools.files.move(source, destination, use_sudo=False)[source]

Move a file or directory

Create a symbolic link to a file or directory

fabtools.files.remove(path, recursive=False, use_sudo=False)[source]

Remove a file or directory

fabtools.git

Git

This module provides low-level tools for managing Git repositories. You should normally not use them directly but rather use the high-level wrapper fabtools.require.git.working_copy() instead.

fabtools.git.clone(remote_url, path=None, use_sudo=False, user=None)[source]

Clone a remote Git repository into a new directory.

Parameters:
fabtools.git.add_remote(path, name, remote_url, use_sudo=False, user=None, fetch=True)[source]

Add a remote Git repository into a directory.

Parameters:
  • path (str) – Path of the working copy directory. This directory must exist and be a Git working copy with a default remote to fetch from.
  • use_sudo (bool) – If True execute git with fabric.operations.sudo(), else with fabric.operations.run().
  • user (str) – If use_sudo is True, run fabric.operations.sudo() with the given user. If use_sudo is False this parameter has no effect.
  • name (str) – name for the remote repository
  • remote_url (str) – URL of the remote repository
  • fetch (bool) – If True execute git remote add -f
fabtools.git.fetch(path, use_sudo=False, user=None, remote=None)[source]

Fetch changes from the default remote repository.

This will fetch new changesets, but will not update the contents of the working tree unless yo do a merge or rebase.

Parameters:
fabtools.git.pull(path, use_sudo=False, user=None, force=False)[source]

Fetch changes from the default remote repository and merge them.

Parameters:
  • path (str) – Path of the working copy directory. This directory must exist and be a Git working copy with a default remote to pull from.
  • use_sudo (bool) – If True execute git with fabric.operations.sudo(), else with fabric.operations.run().
  • user (str) – If use_sudo is True, run fabric.operations.sudo() with the given user. If use_sudo is False this parameter has no effect.
  • force (bool) – If True, append the --force option to the command.
fabtools.git.checkout(path, branch='master', use_sudo=False, user=None, force=False)[source]

Checkout a branch to the working directory.

Parameters:
  • path (str) – Path of the working copy directory. This directory must exist and be a Git working copy.
  • branch (str) – Name of the branch to checkout.
  • use_sudo (bool) – If True execute git with fabric.operations.sudo(), else with fabric.operations.run().
  • user (str) – If use_sudo is True, run fabric.operations.sudo() with the given user. If use_sudo is False this parameter has no effect.
  • force (bool) – If True, append the --force option to the command.

fabtools.gvm

GVM

This module provides tools for installing GVM : the Groovy enVironment Manager

fabtools.gvm.install(java_version=None)[source]

Install dependencies (curl and unzip) and Install GVM

import fabtools

# Install GVM
fabtools.gvm.install()
fabtools.gvm.install_candidate(candidate, version=None, java_version=None)[source]

Install a candidate

import fabtools

# Install a GVM candidate (For example Groovy)
fabtools.gvm.install_candidate('groovy')

fabtools.group

Groups
fabtools.group.exists(name)[source]

Check if a group exists.

fabtools.group.create(name, gid=None)[source]

Create a new group.

Example:

import fabtools

if not fabtools.group.exists('admin'):
    fabtools.group.create('admin')

fabtools.mercurial

Mercurial

This module provides low-level tools for managing Mercurial repositories. You should normally not use them directly but rather use the high-level wrapper fabtools.require.mercurial.working_copy() instead.

fabtools.mercurial.clone(remote_url, path=None, use_sudo=False, user=None)[source]

Clone a remote Mercurial repository into a new directory.

Parameters:
fabtools.mercurial.update(path, branch='default', use_sudo=False, user=None, force=False)[source]

Merge changes to a working copy and/or switch branches.

Parameters:
fabtools.mercurial.pull(path, use_sudo=False, user=None)[source]

Pull changes from the default remote repository.

Parameters:

fabtools.mysql

MySQL users and databases

This module provides tools for creating MySQL users and databases.

Queries
fabtools.mysql.query(query, use_sudo=True, **kwargs)[source]

Run a MySQL query.

Manage users
fabtools.mysql.user_exists(name, host='localhost', **kwargs)[source]

Check if a MySQL user exists.

fabtools.mysql.create_user(name, password, host='localhost', **kwargs)[source]

Create a MySQL user.

Example:

import fabtools

# Create DB user if it does not exist
if not fabtools.mysql.user_exists('dbuser'):
    fabtools.mysql.create_user('dbuser', password='somerandomstring')
Manage databases
fabtools.mysql.database_exists(name, **kwargs)[source]

Check if a MySQL database exists.

fabtools.mysql.create_database(name, owner=None, owner_host='localhost', charset='utf8', collate='utf8_general_ci', **kwargs)[source]

Create a MySQL database.

Example:

import fabtools

# Create DB if it does not exist
if not fabtools.mysql.database_exists('myapp'):
    fabtools.mysql.create_database('myapp', owner='dbuser')

fabtools.network

Network
fabtools.network.interfaces()[source]

Get the list of network interfaces. Will return all datalinks on SmartOS.

fabtools.network.address(interface)[source]

Get the IPv4 address assigned to an interface.

Example:

import fabtools

# Print all configured IP addresses
for interface in fabtools.network.interfaces():
    print(fabtools.network.address(interface))
fabtools.network.nameservers()[source]

Get the list of nameserver addresses.

Example:

import fabtools

# Check that all name servers are reachable
for ip in fabtools.network.nameservers():
    run('ping -c1 %s' % ip)

fabtools.nginx

Nginx

This module provides tools for managing the Nginx web server.

fabtools.nginx.enable(config)[source]

Create link from /etc/nginx/sites-available/ in /etc/nginx/sites-enabled/

(does not reload nginx config)

::

from fabtools import require

require.nginx.enable(‘default’)

fabtools.nginx.disable(config)[source]

Delete link in /etc/nginx/sites-enabled/

(does not reload nginx config)

::

from fabtools import require

require.nginx.disable(‘default’)

fabtools.nodejs

Node.js

This module provides tools for installing Node.js and managing packages using npm.

fabtools.nodejs.install_from_source(version='0.10.13', checkinstall=False)[source]

Install Node JS from source.

If checkinstall is True, a distribution package will be built.

import fabtools

# Install Node.js
fabtools.nodejs.install_nodejs()

Note

This function may not work for old versions of Node.js.

fabtools.nodejs.version(node='node')[source]

Get the version of Node.js currently installed.

Returns None if it is not installed.

fabtools.nodejs.install_package(package, version=None, local=False, npm='npm')[source]

Install a Node.js package.

If local is True, the package will be installed locally.

import fabtools

# Install package globally
fabtools.nodejs.install_package('express')

# Install package locally
fabtools.nodejs.install_package('underscore', local=False)
fabtools.nodejs.install_dependencies(npm='npm')[source]

Install Node.js package dependencies.

This function calls npm install, which will locally install all packages specified as dependencies in the package.json file found in the current directory.

from fabric.api import cd
from fabtools import nodejs

with cd('/path/to/nodejsapp/'):
    nodejs.install_dependencies()
fabtools.nodejs.package_version(package, local=False, npm='npm')[source]

Get the installed version of a Node.js package.

Returns None``is the package is not installed. If *local* is ``True, returns the version of the locally installed package.

fabtools.nodejs.update_package(package, local=False, npm='npm')[source]

Update a Node.js package.

If local is True, the package will be updated locally.

fabtools.nodejs.uninstall_package(package, version=None, local=False, npm='npm')[source]

Uninstall a Node.js package.

If local is True, the package will be uninstalled locally.

import fabtools

# Uninstall package globally
fabtools.nodejs.uninstall_package('express')

# Uninstall package locally
fabtools.nodejs.uninstall_package('underscore', local=False)

fabtools.openvz

OpenVZ containers

This module provides high-level tools for managing OpenVZ templates and containers.

Warning

The remote host needs a patched kernel with OpenVZ support.

Manage templates
fabtools.openvz.download_template(name=None, url=None)

Download an OpenVZ template.

Example:

from fabtools.openvz import download_template

# Use custom OS template
download_template(url='http://example.com/templates/mybox.tar.gz')

If no url is provided, the OS template will be downloaded from the download.openvz.org repository:

from fabtools.openvz import download_template

# Use OS template from http://download.openvz.org/template/precreated/
download_template('debian-6.0-x86_64')
Manage containers
fabtools.openvz.exists(ctid_or_name)

Check if the container exists.

fabtools.openvz.create(ctid, ostemplate=None, config=None, private=None, root=None, ipadd=None, hostname=None, **kwargs)

Create an OpenVZ container.

fabtools.openvz.set(ctid_or_name, save=True, **kwargs)

Set container parameters.

fabtools.openvz.status(ctid_or_name)

Get the status of the container.

fabtools.openvz.start(ctid_or_name, wait=False, force=False, **kwargs)

Start the container.

If wait is True, wait until the container is up and running.

Warning

wait=True is broken with vzctl 3.0.24 on Debian 6.0 (squeeze)

fabtools.openvz.stop(ctid_or_name, fast=False, **kwargs)

Stop the container.

fabtools.openvz.restart(ctid_or_name, wait=True, force=False, fast=False, **kwargs)

Restart the container.

fabtools.openvz.destroy(ctid_or_name)

Destroy the container.

Run commands inside a container
fabtools.openvz.exec2(ctid_or_name, command)

Run a command inside the container.

import fabtools

res = fabtools.openvz.exec2('foo', 'hostname')

Warning

the command will be run as root.

fabtools.openvz.guest(*args, **kwds)

Context manager to run commands inside a guest container.

Supported basic operations are: run, sudo and put.

Warning

commands executed with run() will be run as root inside the container. Use sudo(command, user='foo') to run them as an unpriviledged user.

Example:

from fabtools.openvz import guest

with guest('foo'):
    run('hostname')
    sudo('whoami', user='alice')
    put('files/hello.txt')
Container class
class fabtools.openvz.container.Container(ctid)[source]

Object-oriented interface to OpenVZ containers.

create(**kwargs)[source]

Create the container.

Extra args are passed to fabtools.openvz.create().

destroy()[source]

Destroy the container.

set(**kwargs)[source]

Set container parameters.

Extra args are passed to fabtools.openvz.set().

start(**kwargs)[source]

Start the container.

Extra args are passed to fabtools.openvz.start().

stop(**kwargs)[source]

Stop the container.

Extra args are passed to fabtools.openvz.stop().

restart(**kwargs)[source]

Restart the container.

Extra args are passed to fabtools.openvz.restart().

status()[source]

Get the container’s status.

running()[source]

Check if the container is running.

exists()[source]

Check if the container exists.

exec2(command)[source]

Run a command inside the container.

from fabtools.require.openvz import container

with container('foo') as ct:
    res = ct.exec2('hostname')

Warning

the command will be run as root.

fabtools.opkg

opkg packages

This module provides tools to manage opkg packages and repositories.

fabtools.opkg.update_index(quiet=True)[source]

Update opkg package definitions.

fabtools.opkg.upgrade()[source]

Upgrade all packages.

fabtools.opkg.is_installed(pkg_name)[source]

Check if a package is installed.

fabtools.opkg.install(packages, update=False, options=None)[source]

Install one or more packages.

If update is True, the package definitions will be updated first, using update_index().

Extra options may be passed to opkg if necessary.

Example:

import fabtools

# Update index, then install a single package
fabtools.opkg.install('build-essential', update=True)

# Install multiple packages
fabtools.opkg.install([
    'mc',
    'htop',
])
fabtools.opkg.uninstall(packages, options=None)[source]

Remove one or more packages.

Extra options may be passed to opkg if necessary.

fabtools.oracle_jdk

Oracle JDK

This module provides tools for installing Oracle JDK

fabtools.oracle_jdk.install_from_oracle_site(version='7u25-b15')[source]

Download tarball from Oracle site and install JDK.

import fabtools

# Install Oracle JDK
fabtools.oracle_jdk.install_from_oracle_site()
fabtools.oracle_jdk.version()[source]

Get the version of currently installed JDK.

Returns None if it is not installed.

fabtools.pkg

SmartOS packages

This module provides tools to manage SmartOS packages.

fabtools.pkg.update_index(force=False)[source]

Update pkgin package definitions.

fabtools.pkg.upgrade(full=False)[source]

Upgrade all packages.

fabtools.pkg.is_installed(pkg_name)[source]

Check if a package is installed.

fabtools.pkg.install(packages, update=False, yes=None, options=None)[source]

Install one or more packages.

If update is True, the package definitions will be updated first, using update_index().

Extra yes may be passed to pkgin to validate license if necessary.

Extra options may be passed to pkgin if necessary.

Example:

import fabtools

# Update index, then verbosely install a single package
fabtools.pkg.install('redis', update=True, options='-V',)

# Install multiple packages
fabtools.pkg.install([
    'unzip',
    'top'
])
fabtools.pkg.uninstall(packages, orphan=False, options=None)[source]

Remove one or more packages.

If orphan is True, orphan dependencies will be removed from the system.

Extra options may be passed to pkgin if necessary.

fabtools.pkg.smartos_build()[source]

Get the build of SmartOS. Useful to determine provider for example.

Example:

from fabtools.pkg import smartos_build

if smartos_build().startswith('joyent'):
    print('SmartOS Joyent')
fabtools.pkg.smartos_image()[source]

Get the SmartOS image. Useful to determine the image/dataset for example. Returns None if it can’t be determined.

Example:

from fabtools.pkg import smartos_image

if smartos_image().startswith('percona'):
    sudo("mysql -uroot -psecretpassword -e 'show databases;'")

fabtools.portage

Gentoo packages

This module provides tools for managing Gentoo packages and repositories using the Portage package manager.

fabtools.portage.update_index(quiet=True)[source]

Update Portage package definitions.

fabtools.portage.is_installed(pkg_name)[source]

Check if a Portage package is installed.

fabtools.portage.install(packages, update=False, options=None)[source]

Install one or more Portage packages.

If update is True, the package definitions will be updated first, using update_index().

Extra options may be passed to emerge if necessary.

Example:

import fabtools

# Update index, then install a single package
fabtools.portage.install('mongodb', update=True)

# Install multiple packages
fabtools.arch.install([
    'dev-db/mongodb',
    'pymongo',
])
fabtools.portage.uninstall(packages, options=None)[source]

Remove one or more Portage packages.

Extra options may be passed to emerge if necessary.

fabtools.postgres

PostgreSQL users and databases

This module provides tools for creating PostgreSQL users and databases.

Manage users
fabtools.postgres.user_exists(name)[source]

Check if a PostgreSQL user exists.

fabtools.postgres.create_user(name, password, superuser=False, createdb=False, createrole=False, inherit=True, login=True, connection_limit=None, encrypted_password=False)[source]

Create a PostgreSQL user.

Example:

import fabtools

# Create DB user if it does not exist
if not fabtools.postgres.user_exists('dbuser'):
    fabtools.postgres.create_user('dbuser', password='somerandomstring')

# Create DB user with custom options
fabtools.postgres.create_user('dbuser2', password='s3cr3t',
    createdb=True, createrole=True, connection_limit=20)
Manage databases
fabtools.postgres.database_exists(name)[source]

Check if a PostgreSQL database exists.

fabtools.postgres.create_database(name, owner, template='template0', encoding='UTF8', locale='en_US.UTF-8')[source]

Create a PostgreSQL database.

Example:

import fabtools

# Create DB if it does not exist
if not fabtools.postgres.database_exists('myapp'):
    fabtools.postgres.create_database('myapp', owner='dbuser')

fabtools.python

Python environments and packages

This module provides tools for using Python virtual environments and installing Python packages using the pip installer.

Virtual environments
fabtools.python.virtualenv(*args, **kwds)[source]

Context manager to activate an existing Python virtual environment.

from fabric.api import run
from fabtools.python import virtualenv

with virtualenv('/path/to/virtualenv'):
    run('python -V')
Installing pip
fabtools.python.is_pip_installed(version=None, pip_cmd='pip')[source]

Check if pip is installed.

fabtools.python.install_pip(python_cmd='python', use_sudo=True)[source]

Install the latest version of pip, using the given Python interpreter.

import fabtools

if not fabtools.python.is_pip_installed():
    fabtools.python.install_pip()

Note

pip is automatically installed inside a virtualenv, so there is no need to install it yourself in this case.

Installing packages
fabtools.python.is_installed(package, pip_cmd='pip')[source]

Check if a Python package is installed (using pip).

Package names are case insensitive.

Example:

from fabtools.python import virtualenv
import fabtools

with virtualenv('/path/to/venv'):
    fabtools.python.install('Flask')
    assert fabtools.python.is_installed('flask')
fabtools.python.install(packages, upgrade=False, download_cache=None, allow_external=None, allow_unverified=None, quiet=False, pip_cmd='pip', use_sudo=False, user=None, exists_action=None)[source]

Install Python package(s) using pip.

Package names are case insensitive.

Starting with version 1.5, pip no longer scrapes insecure external urls by default and no longer installs externally hosted files by default. Use allow_external=['foo', 'bar'] or allow_unverified=['bar', 'baz'] to change these behaviours for specific packages.

Examples:

import fabtools

# Install a single package
fabtools.python.install('package', use_sudo=True)

# Install a list of packages
fabtools.python.install(['pkg1', 'pkg2'], use_sudo=True)
fabtools.python.install_requirements(filename, upgrade=False, download_cache=None, allow_external=None, allow_unverified=None, quiet=False, pip_cmd='pip', use_sudo=False, user=None, exists_action=None)[source]

Install Python packages from a pip requirements file.

import fabtools

fabtools.python.install_requirements('project/requirements.txt')

fabtools.python_setuptools

Python packages

This module provides tools for installing Python packages using the easy_install command provided by setuptools.

fabtools.python_setuptools.package_version(name, python_cmd='python')[source]

Get the installed version of a package

Returns None if it can’t be found.

fabtools.python_setuptools.is_setuptools_installed(python_cmd='python')[source]

Check if setuptools is installed.

fabtools.python_setuptools.install_setuptools(python_cmd='python', use_sudo=True)[source]

Install the latest version of setuptools.

import fabtools

fabtools.python_setuptools.install_setuptools()
fabtools.python_setuptools.install(packages, upgrade=False, use_sudo=False, python_cmd='python')[source]

Install Python packages with easy_install.

Examples:

import fabtools

# Install a single package
fabtools.python_setuptools.install('package', use_sudo=True)

# Install a list of packages
fabtools.python_setuptools.install(['pkg1', 'pkg2'], use_sudo=True)

Note

most of the time, you’ll want to use fabtools.python.install() instead, which uses pip to install packages.

fabtools.rpm

RPM packages

This module provides tools to manage CentOS/RHEL/SL/Fedora packages and repositories.

fabtools.rpm.update(kernel=False)[source]

Upgrade all packages, skip obsoletes if obsoletes=0 in yum.conf.

Exclude kernel upgrades by default.

fabtools.rpm.upgrade(kernel=False)[source]

Upgrade all packages, including obsoletes.

Exclude kernel upgrades by default.

fabtools.rpm.groupupdate(group, options=None)[source]

Update an existing software group, skip obsoletes if obsoletes=1 in yum.conf.

Extra options may be passed to yum if necessary.

fabtools.rpm.is_installed(pkg_name)[source]

Check if an RPM package is installed.

fabtools.rpm.install(packages, repos=None, yes=None, options=None)[source]

Install one or more RPM packages.

Extra repos may be passed to yum to enable extra repositories at install time.

Extra yes may be passed to yum to validate license if necessary.

Extra options may be passed to yum if necessary (e.g. ['--nogpgcheck', '--exclude=package']).

import fabtools

# Install a single package, in an alternative install root
fabtools.rpm.install('emacs', options='--installroot=/my/new/location')

# Install multiple packages silently
fabtools.rpm.install([
    'unzip',
    'nano'
], '--quiet')
fabtools.rpm.groupinstall(group, options=None)[source]

Install a group of packages.

You can use yum grouplist to get the list of groups.

Extra options may be passed to yum if necessary like (e.g. ['--nogpgcheck', '--exclude=package']).

import fabtools

# Install development packages
fabtools.rpm.groupinstall('Development tools')
fabtools.rpm.uninstall(packages, options=None)[source]

Remove one or more packages.

Extra options may be passed to yum if necessary.

fabtools.rpm.groupuninstall(group, options=None)[source]

Remove an existing software group.

Extra options may be passed to yum if necessary.

fabtools.rpm.repolist(status='', media=None)[source]

Get the list of yum repositories.

Returns enabled repositories by default. Extra status may be passed to list disabled repositories if necessary.

Media and debug repositories are kept disabled, except if you pass media.

import fabtools

# Install a package that may be included in disabled repositories
fabtools.rpm.install('vim', fabtools.rpm.repolist('disabled'))

fabtools.service

System services

This module provides low-level tools for managing system services, using the service command. It supports both upstart services and traditional SysV-style /etc/init.d/ scripts.

See also

fabtools.systemd

fabtools.service.is_running(service)[source]

Check if a service is running.

import fabtools

if fabtools.service.is_running('foo'):
    print "Service foo is running!"
fabtools.service.start(service)[source]

Start a service.

import fabtools

# Start service if it is not running
if not fabtools.service.is_running('foo'):
    fabtools.service.start('foo')
fabtools.service.stop(service)[source]

Stop a service.

import fabtools

# Stop service if it is running
if fabtools.service.is_running('foo'):
    fabtools.service.stop('foo')
fabtools.service.restart(service)[source]

Restart a service.

import fabtools

# Start service, or restart it if it is already running
if fabtools.service.is_running('foo'):
    fabtools.service.restart('foo')
else:
    fabtools.service.start('foo')
fabtools.service.reload(service)[source]

Reload a service.

import fabtools

# Reload service
fabtools.service.reload('foo')

Warning

The service needs to support the reload operation.

fabtools.service.force_reload(service)[source]

Force reload a service.

import fabtools

# Force reload service
fabtools.service.force_reload('foo')

Warning

The service needs to support the force-reload operation.

fabtools.shorewall

Shorewall firewall
Firewall status
fabtools.shorewall.status()[source]

Get the firewall status.

fabtools.shorewall.is_started()[source]

Check if the firewall is started.

fabtools.shorewall.is_stopped()[source]

Check if the firewall is stopped.

Firewall rules
fabtools.shorewall.rule(port, action='ACCEPT', source='net', dest='$FW', proto='tcp')[source]

Helper to build a firewall rule.

Examples:

from fabtools.shorewall import rule

# Rule to accept connections from example.com on port 1234
r1 = rule(port=1234, source=hosts(['example.com']))

# Rule to reject outgoing SMTP connections
r2 = rule(port=25, action='REJECT', source='$FW', dest='net')
fabtools.shorewall.hosts(hostnames, zone='net')[source]

Builds a host list suitable for use in a firewall rule.

fabtools.shorewall.Ping(**kwargs)[source]

Helper to build a firewall rule for ICMP pings.

Extra args will be passed to rule().

fabtools.shorewall.SSH(port=22, **kwargs)[source]

Helper to build a firewall rule for SSH connections

Extra args will be passed to rule().

fabtools.shorewall.HTTP(port=80, **kwargs)[source]

Helper to build a firewall rule for HTTP connections

Extra args will be passed to rule().

fabtools.shorewall.HTTPS(port=443, **kwargs)[source]

Helper to build a firewall rule for HTTPS connections

Extra args will be passed to rule().

fabtools.shorewall.SMTP(port=25, **kwargs)[source]

Helper to build a firewall rule for SMTP connections

Extra args will be passed to rule().

fabtools.ssh

OpenSSH tasks

This module provides tools to manage OpenSSH server and client.

fabtools.ssh.harden(allow_root_login=False, allow_password_auth=False, sshd_config='/etc/ssh/sshd_config')[source]

Apply best practices for ssh security.

See fabtools.ssh.disable_password_auth() and fabtools.ssh.disable_root_login() for a detailed description.

import fabtools

# This will apply all hardening techniques.
fabtools.ssh.harden()

# Only apply some of the techniques.
fabtools.ssh.harden(allow_password_auth=True)

# Override the sshd_config file location.
fabtools.ssh.harden(sshd_config='/etc/sshd_config')
fabtools.ssh.disable_password_auth(sshd_config='/etc/ssh/sshd_config')[source]

Do not allow users to use passwords to login via ssh.

fabtools.ssh.enable_password_auth(sshd_config='/etc/ssh/sshd_config')[source]

Allow users to use passwords to login via ssh.

fabtools.ssh.disable_root_login(sshd_config='/etc/ssh/sshd_config')[source]

Do not allow root to login via ssh.

fabtools.ssh.enable_root_login(sshd_config='/etc/ssh/sshd_config')[source]

Allow root to login via ssh.

fabtools.supervisor

Supervisor processes

This module provides high-level tools for managing long-running processes using supervisord.

Manage supervisord
fabtools.supervisor.reload_config()[source]

Reload supervisor configuration.

fabtools.supervisor.update_config()[source]

Reread and update supervisor job configurations.

Less heavy-handed than a full reload, as it doesn’t restart the backend supervisor process and all managed processes.

Manage processes
fabtools.supervisor.process_status(name)[source]

Get the status of a supervisor process.

fabtools.supervisor.start_process(name)[source]

Start a supervisor process

fabtools.supervisor.stop_process(name)[source]

Stop a supervisor process

fabtools.supervisor.restart_process(name)[source]

Restart a supervisor process

fabtools.system

System settings
OS detection
fabtools.system.distrib_id()[source]

Get the OS distribution ID.

Returns a string such as "Debian", "Ubuntu", "RHEL", "CentOS", "SLES", "Fedora", "Arch", "Gentoo", "SunOS"...

Example:

from fabtools.system import distrib_id

if distrib_id() != 'Debian':
    abort(u"Distribution is not supported")
fabtools.system.distrib_family()[source]

Get the distribution family.

Returns one of debian, redhat, arch, gentoo, sun, other.

fabtools.system.distrib_release()[source]

Get the release number of the distribution.

Example:

from fabtools.system import distrib_id, distrib_release

if distrib_id() == 'CentOS' and distrib_release() == '6.1':
    print(u"CentOS 6.2 has been released. Please upgrade.")
fabtools.system.distrib_codename()[source]

Get the codename of the Linux distribution.

Example:

from fabtools.deb import distrib_codename

if distrib_codename() == 'precise':
    print(u"Ubuntu 12.04 LTS detected")
fabtools.system.distrib_desc()[source]

Get the description of the Linux distribution.

For example: Debian GNU/Linux 6.0.7 (squeeze).

Hardware detection
fabtools.system.get_arch()[source]

Get the CPU architecture.

Example:

from fabtools.system import get_arch

if get_arch() == 'x86_64':
    print(u"Running on a 64-bit Intel/AMD system")
fabtools.system.cpus()[source]

Get the number of CPU cores.

Example:

from fabtools.system import cpus

nb_workers = 2 * cpus() + 1
Hostname
fabtools.system.get_hostname()[source]

Get the fully qualified hostname.

fabtools.system.set_hostname(hostname, persist=True)[source]

Set the hostname.

Kernel parameters
fabtools.system.get_sysctl(key)[source]

Get a kernel parameter.

Example:

from fabtools.system import get_sysctl

print "Max number of open files:", get_sysctl('fs.file-max')
fabtools.system.set_sysctl(key, value)[source]

Set a kernel parameter.

Example:

import fabtools

# Protect from SYN flooding attack
fabtools.system.set_sysctl('net.ipv4.tcp_syncookies', 1)
Locales
fabtools.system.supported_locales()[source]

Gets the list of supported locales.

Each locale is returned as a (locale, charset) tuple.

Time
fabtools.system.time()[source]

Return the current time in seconds since the Epoch.

Same as time.time()

fabtools.systemd

Systemd services

This module provides low-level tools for managing systemd services.

See also

fabtools.service

fabtools.systemd.enable(service)[source]

Enable a service.

fabtools.enable('httpd')

Note

This function is idempotent.

fabtools.systemd.disable(service)[source]

Disable a service.

fabtools.systemd.disable('httpd')

Note

This function is idempotent.

fabtools.systemd.is_running(service)[source]

Check if a service is running.

if fabtools.systemd.is_running('httpd'):
    print("Service httpd is running!")
fabtools.systemd.start(service)[source]

Start a service.

if not fabtools.systemd.is_running('httpd'):
    fabtools.systemd.start('httpd')

Note

This function is idempotent.

fabtools.systemd.stop(service)[source]

Stop a service.

if fabtools.systemd.is_running('foo'):
    fabtools.systemd.stop('foo')

Note

This function is idempotent.

fabtools.systemd.restart(service)[source]

Restart a service.

if fabtools.systemd.is_running('httpd'):
    fabtools.systemd.restart('httpd')
else:
    fabtools.systemd.start('httpd')
fabtools.systemd.reload(service)[source]

Reload a service.

fabtools.systemd.reload('foo')

Warning

The service needs to support the reload operation.

fabtools.systemd.start_and_enable(service)[source]

Start and enable a service (convenience function).

Note

This function is idempotent.

fabtools.systemd.stop_and_disable(service)[source]

Stop and disable a service (convenience function).

Note

This function is idempotent.

fabtools.user

Users
fabtools.user.exists(name)[source]

Check if a user exists.

fabtools.user.create(name, comment=None, home=None, create_home=None, skeleton_dir=None, group=None, create_group=True, extra_groups=None, password=None, system=False, shell=None, uid=None, ssh_public_keys=None, non_unique=False)[source]

Create a new user and its home directory.

If create_home is None (the default), a home directory will be created for normal users, but not for system users. You can override the default behaviour by setting create_home to True or False.

If system is True, the user will be a system account. Its UID will be chosen in a specific range, and it will not have a home directory, unless you explicitely set create_home to True.

If shell is None, the user’s login shell will be the system’s default login shell (usually /bin/sh).

ssh_public_keys can be a (local) filename or a list of (local) filenames of public keys that should be added to the user’s SSH authorized keys (see fabtools.user.add_ssh_public_keys()).

Example:

import fabtools

if not fabtools.user.exists('alice'):
    fabtools.user.create('alice')

with cd('/home/alice'):
    # ...
fabtools.user.modify(name, comment=None, home=None, move_current_home=False, group=None, extra_groups=None, login_name=None, password=None, shell=None, uid=None, ssh_public_keys=None, non_unique=False)[source]

Modify an existing user.

ssh_public_keys can be a (local) filename or a list of (local) filenames of public keys that should be added to the user’s SSH authorized keys (see fabtools.user.add_ssh_public_keys()).

Example:

import fabtools

if fabtools.user.exists('alice'):
    fabtools.user.modify('alice', shell='/bin/sh')
fabtools.user.home_directory(name)[source]

Get the absolute path to the user’s home directory

Example:

import fabtools

home = fabtools.user.home_directory('alice')
fabtools.user.local_home_directory(name='')[source]

Get the absolute path to the local user’s home directory

Example:

import fabtools

local_home = fabtools.user.local_home_directory()
fabtools.user.authorized_keys(name)[source]

Get the list of authorized SSH public keys for the user

fabtools.user.add_ssh_public_key(name, filename)[source]

Add a public key to the user’s authorized SSH keys.

filename must be the local filename of a public key that should be added to the user’s SSH authorized keys.

Example:

import fabtools

fabtools.user.add_ssh_public_key('alice', '~/.ssh/id_rsa.pub')
fabtools.user.add_ssh_public_keys(name, filenames)[source]

Add multiple public keys to the user’s authorized SSH keys.

filenames must be a list of local filenames of public keys that should be added to the user’s SSH authorized keys.

Example:

import fabtools

fabtools.user.add_ssh_public_keys('alice', [
    '~/.ssh/id1_rsa.pub',
    '~/.ssh/id2_rsa.pub',
])
fabtools.user.add_host_keys(name, hostname)[source]

Add all public keys of a host to the user’s SSH known hosts file

fabtools.utils

Utilities
fabtools.utils.run_as_root(command, *args, **kwargs)[source]

Run a remote command as the root user.

When connecting as root to the remote system, this will use Fabric’s run function. In other cases, it will use sudo.

fabtools.tomcat

Tomcat

This module provides tools for installing Tomcat.

fabtools.tomcat.install_from_source(path='/usr/share/tomcat', version='7.0.47', mirror='http://archive.apache.org', overwrite=False)[source]

Install Tomcat from source.

import fabtools

# Install Tomcat
fabtools.tomcat.install_from_source(version='6.0.36')
fabtools.tomcat.start_tomcat()[source]

Start the Tomcat service.

fabtools.tomcat.stop_tomcat()[source]

Stop the Tomcat service.

fabtools.tomcat.version(path)[source]

Get the version of currently installed tomcat.

Returns None if it is not installed.

fabtools.tomcat.deploy_application(war_file, webapp_path=None)[source]

Deploy an application into the webapp path for a Tomcat installation.

fabtools.vagrant

Vagrant helpers
fabtools.vagrant.version()[source]

Get the Vagrant version.

fabtools.vagrant.ssh_config(name='')[source]

Get the SSH parameters for connecting to a vagrant VM.

fabtools.vagrant.vagrant[source]

Run the following tasks on a vagrant box.

First, you need to import this task in your fabfile.py:

from fabric.api import *
from fabtools.vagrant import vagrant

@task
def some_task():
    run('echo hello')

Then you can easily run tasks on your current Vagrant box:

$ fab vagrant some_task
fabtools.vagrant.vagrant_settings(name='', *args, **kwargs)[source]

Context manager that sets a vagrant VM as the remote host.

Use this context manager inside a task to run commands on your current Vagrant box:

from fabtools.vagrant import vagrant_settings

with vagrant_settings():
    run('hostname')
fabtools.vagrant.status(name='default')[source]

Get the status of a vagrant machine

fabtools.vagrant.machines()[source]

Get the list of vagrant machines

fabtools.vagrant.base_boxes()[source]

Get the list of vagrant base boxes

fabtools.require

fabtools.require.apache

Apache

This module provides high-level tools for installing and configuring the Apache HTTP Server.

See also

fabtools.apache

fabtools.require.apache.server()[source]

Require the Apache HTTP server to be installed and running.

from fabtools import require

require.apache.server()
fabtools.require.apache.module_enabled(module)[source]

Require an Apache module to be enabled.

This will cause Apache to reload its configuration.

from fabtools import require

require.apache.module_enabled('rewrite')
fabtools.require.apache.module_disabled(module)[source]

Require an Apache module to be disabled.

This will cause Apache to reload its configuration.

from fabtools import require

require.apache.module_disabled('rewrite')
fabtools.require.apache.site_enabled(config)[source]

Require an Apache site to be enabled.

This will cause Apache to reload its configuration.

from fabtools import require

require.apache.site_enabled('mysite')
fabtools.require.apache.site_disabled(config)[source]

Require an Apache site to be disabled.

This will cause Apache to reload its configuration.

from fabtools import require

require.apache.site_disabled('default')
fabtools.require.apache.site(config_name, template_contents=None, template_source=None, enabled=True, check_config=True, **kwargs)[source]

Require an Apache site.

You must provide a template for the site configuration, either as a string (template_contents) or as the path to a local template file (template_source).

from fabtools import require

CONFIG_TPL = '''
<VirtualHost *:%(port)s>
    ServerName %(hostname})s

    DocumentRoot %(document_root)s

    <Directory %(document_root)s>
        Options Indexes FollowSymLinks MultiViews

        AllowOverride All

        Order allow,deny
        allow from all
    </Directory>
</VirtualHost>
'''

require.apache.site(
    'example.com',
    template_contents=CONFIG_TPL,
    port=80,
    hostname='www.example.com',
    document_root='/var/www/mysite',
)

fabtools.require.arch

Arch Linux packages

This module provides high-level tools for managing Arch Linux packages and repositories.

See also

fabtools.arch

fabtools.require.arch.package(pkg_name, update=False)[source]

Require an Arch Linux package to be installed.

Example:

from fabtools import require

require.arch.package('foo')
fabtools.require.arch.packages(pkg_list, update=False)[source]

Require several Arch Linux packages to be installed.

Example:

from fabtools import require

require.arch.packages([
    'foo',
    'bar',
    'baz',
])
fabtools.require.arch.nopackage(pkg_name)[source]

Require an Arch Linux package to be uninstalled.

Example:

from fabtools import require

require.arch.nopackage('apache2')
fabtools.require.arch.nopackages(pkg_list)[source]

Require several Arch Linux packages to be uninstalled.

Example:

from fabtools import require

require.arch.nopackages([
    'perl',
    'php5',
    'ruby',
])

fabtools.require.curl

Curl

This module provides high-level tools for using curl.

fabtools.require.curl.command()[source]

Require the curl command-line tool.

Example:

from fabric.api import run
from fabtools import require

require.curl.command()
run('curl --help')

fabtools.require.deb

Debian packages

This module provides high-level tools for managing Debian/Ubuntu packages and repositories.

See also

fabtools.deb

Keys
fabtools.require.deb.key(keyid, filename=None, url=None, keyserver='subkeys.pgp.net', update=False)[source]

Require a PGP key for APT.

from fabtools import require

# Varnish signing key from URL
require.deb.key('C4DEFFEB', url='http://repo.varnish-cache.org/debian/GPG-key.txt')

# Nginx signing key from default key server (subkeys.pgp.net)
require.deb.key('7BD9BF62')

# From custom key server
require.deb.key('7BD9BF62', keyserver='keyserver.ubuntu.com')

# From file
require.deb.key('7BD9BF62', filename='nginx.asc')
Sources
fabtools.require.deb.source(name, uri, distribution, *components)[source]

Require a package source.

from fabtools import require

# Official MongoDB packages
require.deb.source('mongodb', 'http://downloads-distro.mongodb.org/repo/ubuntu-upstart', 'dist', '10gen')
fabtools.require.deb.ppa(name, auto_accept=True, keyserver=None)[source]

Require a PPA package source.

Example:

from fabtools import require

# Node.js packages by Chris Lea
require.deb.ppa('ppa:chris-lea/node.js', keyserver='my.keyserver.com')
Index
fabtools.require.deb.uptodate_index(quiet=True, max_age=86400)[source]

Require an up-to-date package index.

This will update the package index (using apt-get update) if the last update occured more than max_age ago.

max_age can be specified either as an integer (a value in seconds), or as a dictionary whose keys are units (seconds, minutes, hours, days, weeks, months) and values are integers. The default value is 1 hour.

Examples:

from fabtools import require

# Update index if last time was more than 1 day ago
require.deb.uptodate_index(max_age={'day': 1})

# Update index if last time was more than 1 hour and 30 minutes ago
require.deb.uptodate_index(max_age={'hour': 1, 'minutes': 30})
Packages
fabtools.require.deb.package(pkg_name, update=False, version=None)[source]

Require a deb package to be installed.

Example:

from fabtools import require

# Require a package
require.deb.package('foo')

# Require a specific version
require.deb.package('firefox', version='11.0+build1-0ubuntu4')
fabtools.require.deb.packages(pkg_list, update=False)[source]

Require several deb packages to be installed.

Example:

from fabtools import require

require.deb.packages([
    'foo',
    'bar',
    'baz',
])
fabtools.require.deb.nopackage(pkg_name)[source]

Require a deb package to be uninstalled.

Example:

from fabtools import require

require.deb.nopackage('apache2')
fabtools.require.deb.nopackages(pkg_list)[source]

Require several deb packages to be uninstalled.

Example:

from fabtools import require

require.deb.nopackages([
    'perl',
    'php5',
    'ruby',
])

fabtools.require.files

Files and directories

This module provides high-level tools for managing files and directories.

See also

fabtools.files

fabtools.require.files.directory(path, use_sudo=False, owner='', group='', mode='')[source]

Require a directory to exist.

from fabtools import require

require.directory('/tmp/mydir', owner='alice', use_sudo=True)

Note

This function can be accessed directly from the fabtools.require module for convenience.

fabtools.require.files.directories(path_list, use_sudo=False, owner='', group='', mode='')[source]

Require a list of directories to exist.

from fabtools import require
dirs=[
    '/tmp/mydir',
    '/tmp/mydear',
    '/tmp/my/dir'
]
require.directories(dirs, owner='alice', mode='750')

Note

This function can be accessed directly from the fabtools.require module for convenience.

fabtools.require.files.file(path=None, contents=None, source=None, url=None, md5=None, use_sudo=False, owner=None, group='', mode=None, verify_remote=True, temp_dir='/tmp')[source]

Require a file to exist and have specific contents and properties.

You can provide either:

  • contents: the required contents of the file:

    from fabtools import require
    
    require.file('/tmp/hello.txt', contents='Hello, world')
    
  • source: the local path of a file to upload:

    from fabtools import require
    
    require.file('/tmp/hello.txt', source='files/hello.txt')
    
  • url: the URL of a file to download (path is then optional):

    from fabric.api import cd
    from fabtools import require
    
    with cd('tmp'):
        require.file(url='http://example.com/files/hello.txt')
    

If verify_remote is True (the default), then an MD5 comparison will be used to check whether the remote file is the same as the source. If this is False, the file will be assumed to be the same if it is present. This is useful for very large files, where generating an MD5 sum may take a while.

When providing either the contents or the source parameter, Fabric’s put function will be used to upload the file to the remote host. When use_sudo is True, the file will first be uploaded to a temporary directory, then moved to its final location. The default temporary directory is /tmp, but can be overridden with the temp_dir parameter. If temp_dir is an empty string, then the user’s home directory will be used.

If use_sudo is True, then the remote file will be owned by root, and its mode will reflect root’s default umask. The optional owner, group and mode parameters can be used to override these properties.

Note

This function can be accessed directly from the fabtools.require module for convenience.

fabtools.require.files.template_file(path=None, template_contents=None, template_source=None, context=None, **kwargs)[source]

Require a file whose contents is defined by a template.

fabtools.require.files.temporary_directory(template=None)[source]

Require a temporary directory.

The directory is created using the mktemp command. It will be created in /tmp, unless the TMPDIR environment variable is set to another location.

from fabtools.require.files import temporary_directory

tmp_dir = temporary_directory()

You can choose a specific location and name template for the temporary directory:

from fabtools.require.files import temporary_directory

tmp_dir = temporary_directory('/var/tmp/temp.XXXXXX')

You can also call this function as a context manager. In this case, the directory and its contents will be automatically deleted when exiting the block:

from pipes import quote
from posixpath import join

from fabtools.require.files import temporary_directory

with temporary_directory() as tmp_dir:
    path = join(tmp_dir, 'foo')
    run('touch %s' % quote(path))

fabtools.require.git

Git

This module provides high-level tools for managing Git repositories.

See also

fabtools.git

fabtools.require.git.command()[source]

Require the git command-line tool.

Example:

from fabric.api import run
from fabtools import require

require.git.command()
run('git --help')
fabtools.require.git.working_copy(remote_url, path=None, branch='master', update=True, use_sudo=False, user=None)[source]

Require a working copy of the repository from the remote_url.

The path is optional, and defaults to the last segment of the remote repository URL, without its .git suffix.

If the path does not exist, this will clone the remote repository and check out the specified branch.

If the path exists and update is True, it will fetch changes from the remote repository, check out the specified branch, then merge the remote changes into the working copy.

If the path exists and update is False, it will only check out the specified branch, without fetching remote changesets.

Parameters:
  • remote_url (str) – URL of the remote repository (e.g. https://github.com/ronnix/fabtools.git). The given URL will be the origin remote of the working copy.
  • path (str) – Absolute or relative path of the working copy on the filesystem. If this directory doesn’t exist yet, a new working copy is created through git clone. If the directory does exist and update == True, a git fetch is issued. If path is None the git clone is issued in the current working directory and the directory name of the working copy is created by git.
  • branch (str) – Branch or tag to check out. If the given value is a tag name, update must be False or consecutive calls will fail.
  • update (bool) – Whether or not to fetch and merge remote changesets.
  • use_sudo (bool) – If True execute git with fabric.operations.sudo(), else with fabric.operations.run().
  • user (str) – If use_sudo is True, run fabric.operations.sudo() with the given user. If use_sudo is False this parameter has no effect.

fabtools.require.groups

System groups

See also

fabtools.group

fabtools.require.groups.group(name, gid=None)[source]

Require a group.

from fabtools import require

require.group('mygroup')

Note

This function can be accessed directly from the fabtools.require module for convenience.

fabtools.require.mercurial

Mercurial

This module provides high-level tools for managing Mercurial repositories.

fabtools.require.mercurial.command()[source]

Require the hg command-line tool.

Example:

from fabric.api import run
from fabtools import require

require.mercurial.command()
run('hg --help')
fabtools.require.mercurial.working_copy(remote_url, path=None, branch='default', update=True, use_sudo=False, user=None)[source]

Require a working copy of the repository from the remote_url.

The path is optional, and defaults to the last segment of the remote repository URL.

If the path does not exist, this will clone the remote repository and check out the specified branch.

If the path exists and update is True, it will pull changes from the remote repository, check out the specified branch, then update the working copy.

If the path exists and update is False, it will only check out the specified branch, without pulling remote changesets.

Parameters:
  • remote_url (str) – URL of the remote repository
  • path (str) – Absolute or relative path of the working copy on the filesystem. If this directory doesn’t exist yet, a new working copy is created through hg clone. If the directory does exist and update == True, a hg pull && hg up is issued. If path is None the hg clone is issued in the current working directory and the directory name of the working copy is created by hg.
  • branch (str) – Branch or tag to check out. If the given value is a tag name, update must be False or consecutive calls will fail.
  • update (bool) – Whether or not to pull and update remote changesets.
  • use_sudo (bool) – If True execute hg with fabric.operations.sudo(), else with fabric.operations.run().
  • user (str) – If use_sudo is True, run fabric.operations.sudo() with the given user. If use_sudo is False this parameter has no effect.

fabtools.require.mysql

MySQL

This module provides high-level tools for installing a MySQL server and creating MySQL users and databases.

See also

fabtools.mysql

fabtools.require.mysql.server(version=None, password=None)[source]

Require a MySQL server to be installed and running.

Example:

from fabtools import require

require.mysql.server(password='s3cr3t')
fabtools.require.mysql.user(name, password, **kwargs)[source]

Require a MySQL user.

Extra arguments will be passed to fabtools.mysql.create_user().

Example:

from fabric.api import settings
from fabtools import require

with settings(mysql_user='root', mysql_password='s3cr3t'):
    require.mysql.user('dbuser', 'somerandomstring')
fabtools.require.mysql.database(name, **kwargs)[source]

Require a MySQL database.

Extra arguments will be passed to fabtools.mysql.create_database().

Example:

from fabric.api import settings
from fabtools import require

with settings(mysql_user='root', mysql_password='s3cr3t'):
    require.mysql.database('myapp', owner='dbuser')

fabtools.require.nginx

Nginx

This module provides high-level tools for installing the nginx web server and managing the configuration of web sites.

See also

fabtools.nginx

fabtools.require.nginx.server(package_name='nginx')[source]

Require the nginx web server to be installed and running.

You can override the system package name, if you need to install a specific variant such as nginx-extras or nginx-light.

from fabtools import require

require.nginx.server()
fabtools.require.nginx.enabled(config)[source]

Require an nginx site to be enabled.

This will cause nginx to reload its configuration.

from fabtools import require

require.nginx.enabled('mysite')
fabtools.require.nginx.disabled(config)[source]

Require an nginx site to be disabled.

This will cause nginx to reload its configuration.

from fabtools import require

require.nginx.site_disabled('default')
fabtools.require.nginx.site(server_name, template_contents=None, template_source=None, enabled=True, check_config=True, **kwargs)[source]

Require an nginx site.

You must provide a template for the site configuration, either as a string (template_contents) or as the path to a local template file (template_source).

from fabtools import require

CONFIG_TPL = '''
server {
    listen      %(port)d;
    server_name %(server_name)s %(server_alias)s;
    root        %(docroot)s;
    access_log  /var/log/nginx/%(server_name)s.log;
}'''

require.nginx.site('example.com',
    template_contents=CONFIG_TPL,
    port=80,
    server_alias='www.example.com',
    docroot='/var/www/mysite',
)
fabtools.require.nginx.proxied_site(server_name, enabled=True, **kwargs)[source]

Require an nginx site for a proxied app.

This uses a predefined configuration template suitable for proxying requests to a backend application server.

Required keyword arguments are:

  • port: the port nginx should listen on
  • proxy_url: URL of backend application server
  • docroot: path to static files
from fabtools import require

require.nginx.proxied_site('example.com',
    port=80,
    proxy_url='http://127.0.0.1:8080/',
    docroot='/path/to/myapp/static',
)

fabtools.require.nodejs

Node.js

This module provides tools for installing Node.js and managing packages using npm.

See also

fabtools.nodejs

fabtools.require.nodejs.installed_from_source(version='0.10.13')[source]

Require Node.js to be installed from source.

from fabtools import require

require.nodejs.installed_from_source()
fabtools.require.nodejs.package(pkg_name, version=None, local=False)[source]

Require a Node.js package.

If the package is not installed, and no version is specified, the latest available version will be installed.

If a version is specified, and a different version of the package is already installed, it will be updated to the specified version.

If local is True, the package will be installed locally.

from fabtools import require

# Install package system-wide
require.nodejs.package('foo')

# Install package locally
require.nodejs.package('bar', local=True)

fabtools.require.openvz

OpenVZ containers

This module provides high-level tools for managing OpenVZ templates and containers.

Warning

The remote host needs a patched kernel with OpenVZ support.

See also

fabtools.openvz

fabtools.require.openvz.template(name=None, url=None)[source]

Require an OpenVZ OS template.

If the OS template is not installed yet, it will be downloaded from url using download_template():

from fabtools import require

# Use custom OS template
require.openvz.template(url='http://example.com/templates/mybox.tar.gz')

If no url is provided, download_template() will attempt to download the OS template from the download.openvz.org repository:

from fabtools import require

# Use OS template from http://download.openvz.org/template/precreated/
require.openvz.template('debian-6.0-x86_64')
fabtools.require.openvz.container(name, ostemplate, **kwargs)[source]

Require an OpenVZ container.

If it does not exist, the container will be created using the specified OS template (see fabtools.require.openvz.template()).

Extra args will be passed to fabtools.openvz.create():

from fabtools import require

require.openvz.container('foo', 'debian', ipadd='1.2.3.4')

This function returns a fabtools.openvz.Container object, that can be used to perform further operations:

from fabtools.require.openvz import container

ct = container('foo', 'debian')
ct.set('ipadd', '1.2.3.4')
ct.start()
ct.exec2('hostname')

This function can also be used as a context manager:

from fabtools.require.openvz import container

with container('foo', 'debian') as ct:
    ct.set('ipadd', '1.2.3.4')
    ct.start()
    ct.exec2('hostname')

fabtools.require.opkg

opkg packages

This module provides high-level tools for managing opkg packages and repositories.

See also

fabtools.opkg

Packages
fabtools.require.opkg.package(pkg_name, update=False)[source]

Require a opkg package to be installed.

Example:

from fabtools import require

# Require a package
require.opkg.package('foo')
fabtools.require.opkg.packages(pkg_list, update=False)[source]

Require several opkg packages to be installed.

Example:

from fabtools import require

require.opkg.packages([
    'foo',
    'bar',
    'baz',
])
fabtools.require.opkg.nopackage(pkg_name)[source]

Require a opkg package to be uninstalled.

Example:

from fabtools import require

require.opkg.nopackage('apache2')
fabtools.require.opkg.nopackages(pkg_list)[source]

Require several opkg packages to be uninstalled.

Example:

from fabtools import require

require.opkg.nopackages([
    'perl',
    'php5',
    'ruby',
])

fabtools.require.oracle_jdk

Oracle JDK

This module provides tools for installing Oracle JDK

fabtools.require.oracle_jdk.installed(version='7u25-b15')[source]

Require Oracle JDK to be installed.

from fabtools import require

require.oracle_jdk.installed()

fabtools.require.pkg

SmartOS packages

This module provides high-level tools to manage SmartOS packages.

See also

fabtools.pkg

fabtools.require.pkg.package(pkg_name, update=False, yes=None)[source]

Require a SmartOS package to be installed.

from fabtools import require

require.pkg.package('foo')
fabtools.require.pkg.packages(pkg_list, update=False)[source]

Require several SmartOS packages to be installed.

from fabtools import require

require.pkg.packages([
    'top',
    'unzip',
    'zip',
])
fabtools.require.pkg.nopackage(pkg_name, orphan=True)[source]

Require a SmartOS package to be uninstalled.

from fabtools import require

require.pkg.nopackage('top')
fabtools.require.pkg.nopackages(pkg_list, orphan=True)[source]

Require several SmartOS packages to be uninstalled.

from fabtools import require

require.pkg.nopackages([
    'top',
    'zip',
    'unzip',
])

fabtools.require.portage

Gentoo packages

This module provides high-level tools for managing Gentoo packages and repositories using the Portage package manager.

See also

fabtools.portage

fabtools.require.portage.package(pkg_name, update=False)[source]

Require a Portage package to be installed.

Example:

from fabtools import require

require.portage.package('foo')
fabtools.require.portage.packages(pkg_list, update=False)[source]

Require several Portage packages to be installed.

Example:

from fabtools import require

require.portage.packages([
    'foo',
    'bar',
    'baz',
])
fabtools.require.portage.nopackage(pkg_name)[source]

Require a Portage package to be uninstalled.

Example:

from fabtools import require

require.portage.nopackage('apache2')
fabtools.require.portage.nopackages(pkg_list)[source]

Require several Portage packages to be uninstalled.

Example:

from fabtools import require

require.portage.nopackages([
    'perl',
    'php5',
    'ruby',
])

fabtools.require.postfix

Postfix

This module provides high-level tools for managing the Postfix email server.

fabtools.require.postfix.server(mailname)[source]

Require a Postfix email server.

This makes sure that Postfix is installed and started.

from fabtools import require

# Handle incoming email for our domain
require.postfix.server('example.com')

fabtools.require.postgres

PostgreSQL users and databases
fabtools.require.postgres.server(version=None)[source]

Require a PostgreSQL server to be installed and running.

from fabtools import require

require.postgres.server()
fabtools.require.postgres.user(name, password, superuser=False, createdb=False, createrole=False, inherit=True, login=True, connection_limit=None, encrypted_password=False)[source]

Require the existence of a PostgreSQL user.

The password and options provided will only be applied when creating a new user (existing users will not be modified).

from fabtools import require

require.postgres.user('dbuser', password='somerandomstring')

require.postgres.user('dbuser2', password='s3cr3t',
    createdb=True, create_role=True, connection_limit=20)
fabtools.require.postgres.database(name, owner, template='template0', encoding='UTF8', locale='en_US.UTF-8')[source]

Require a PostgreSQL database.

from fabtools import require

require.postgres.database('myapp', owner='dbuser')

fabtools.require.python

Python environments and packages

This module provides high-level tools for using Python virtual environments and installing Python packages using the pip installer.

See also

fabtools.python

Virtual environments
fabtools.require.python.virtualenv(directory, system_site_packages=False, venv_python=None, use_sudo=False, user=None, clear=False, prompt=None, virtualenv_cmd='virtualenv', pip_cmd='pip', python_cmd='python')[source]

Require a Python virtual environment.

from fabtools import require

require.python.virtualenv('/path/to/venv')
Installing packages
fabtools.require.python.package(pkg_name, url=None, pip_cmd='pip', python_cmd='python', allow_external=False, allow_unverified=False, **kwargs)[source]

Require a Python package.

If the package is not installed, it will be installed using the pip installer.

Package names are case insensitive.

Starting with version 1.5, pip no longer scrapes insecure external urls by default and no longer installs externally hosted files by default. Use allow_external=True or allow_unverified=True to change these behaviours.

from fabtools.python import virtualenv
from fabtools import require

# Install package system-wide (not recommended)
require.python.package('foo', use_sudo=True)

# Install package in an existing virtual environment
with virtualenv('/path/to/venv'):
    require.python.package('bar')
fabtools.require.python.packages(pkg_list, pip_cmd='pip', python_cmd='python', allow_external=None, allow_unverified=None, **kwargs)[source]

Require several Python packages.

Package names are case insensitive.

Starting with version 1.5, pip no longer scrapes insecure external urls by default and no longer installs externally hosted files by default. Use allow_external=['foo', 'bar'] or allow_unverified=['bar', 'baz'] to change these behaviours for specific packages.

fabtools.require.python.requirements(filename, pip_cmd='pip', python_cmd='python', allow_external=None, allow_unverified=None, **kwargs)[source]

Require Python packages from a pip requirements file.

Starting with version 1.5, pip no longer scrapes insecure external urls by default and no longer installs externally hosted files by default. Use allow_external=['foo', 'bar'] or allow_unverified=['bar', 'baz'] to change these behaviours for specific packages.

from fabtools.python import virtualenv
from fabtools import require

# Install requirements in an existing virtual environment
with virtualenv('/path/to/venv'):
    require.python.requirements('requirements.txt')
fabtools.require.python.pip(version='1.5', pip_cmd='pip', python_cmd='python')[source]

Require pip to be installed.

If pip is not installed, or if a version older than version is installed, the latest version will be installed.

fabtools.require.python.setuptools(version='0.7', python_cmd='python')[source]

Require setuptools to be installed.

If setuptools is not installed, or if a version older than version is installed, the latest version will be installed.

fabtools.require.redis

Redis

This module provides high-level tools for managing Redis instances.

fabtools.require.redis.installed_from_source(version='2.6.16')[source]

Require Redis to be installed from source.

The compiled binaries will be installed in /opt/redis-{version}/.

fabtools.require.redis.instance(name, version='2.6.16', bind='127.0.0.1', port=6379, **kwargs)[source]

Require a Redis instance to be running.

The required Redis version will be automatically installed using fabtools.require.redis.installed_from_source() if needed.

You can specify the IP address and port on which to listen to using the bind and port parameters.

Warning

Redis is designed to be accessed by trusted clients inside trusted environments. It is usually not a good idea to expose the Redis instance directly to the internet. Therefore, with the default settings, the Redis instance will only listen to local clients.

If you want to make your Redis instance accessible to other servers over an untrusted network, you should probably add some firewall rules to restrict access. For example:

from fabtools import require
from fabtools.shorewall import Ping, SSH, hosts, rule

# The computers that will need to talk to the Redis server
REDIS_CLIENTS = [
    'web1.example.com',
    'web2.example.com',
]

# The Redis server port
REDIS_PORT = 6379

# Setup a basic firewall
require.shorewall.firewall(
    rules=[
        Ping(),
        SSH(),
        rule(port=REDIS_PORT, source=hosts(REDIS_CLIENTS)),
    ]
)

# Make the Redis instance listen on all interfaces
require.redis.instance('mydb', bind='0.0.0.0', port=REDIS_PORT)

See also

Redis Security

You can also use any valid Redis configuration directives as extra keyword arguments. For directives that can be repeated on multiple lines (such as save), you can supply a list of values.

The instance will be managed using supervisord, as a process named redis_{name}, running as the redis user.

from fabtools import require
from fabtools.supervisor import process_status

require.redis.instance('mydb')

print process_status('redis_mydb')

The default settings enable persistence using periodic RDB snapshots saved in the /var/db/redis directory.

You may want to use AOF persistence instead:

require.redis.instance('mydb', appendonly='yes', save=[])

In certain situations, you may want to disable persistence completely:

require.redis.instance('cache', port=6380, save=[])

fabtools.require.rpm

RPM packages

This module provides high-level tools for managing CentOS/RHEL/SL/Fedora packages and repositories.

See also

fabtools.rpm

fabtools.require.rpm.package(pkg_name, repos=None, yes=None, options=None)[source]

Require an RPM package to be installed.

Example:

from fabtools import require

require.rpm.package('emacs')
fabtools.require.rpm.packages(pkg_list, repos=None, yes=None, options=None)[source]

Require several RPM packages to be installed.

Example:

from fabtools import require

require.rpm.packages([
    'nano',
    'unzip',
    'vim',
])
fabtools.require.rpm.nopackage(pkg_name, options=None)[source]

Require an RPM package to be uninstalled.

Example:

from fabtools import require

require.rpm.nopackage('emacs')
fabtools.require.rpm.nopackages(pkg_list, options=None)[source]

Require several RPM packages to be uninstalled.

Example:

from fabtools import require

require.rpm.nopackages([
    'unzip',
    'vim',
    'emacs',
])
fabtools.require.rpm.repository(name)[source]

Require a repository. Aimed for 3rd party repositories.

Name currently only supports EPEL and RPMforge.

Example:

from fabtools import require

# RPMforge packages for CentOS 6
require.rpm.repository('rpmforge')

fabtools.require.service

System services

This module provides high-level tools for managing system services. The underlying operations use the service command, allowing to support both upstart services and traditional SysV-style /etc/init.d/ scripts.

See also

fabtools.service

fabtools.require.service.started(service)[source]

Require a service to be started.

from fabtools import require

require.service.started('foo')
fabtools.require.service.stopped(service)[source]

Require a service to be stopped.

from fabtools import require

require.service.stopped('foo')
fabtools.require.service.restarted(service)[source]

Require a service to be restarted.

from fabtools import require

require.service.restarted('foo')

fabtools.require.shorewall

Shorewall firewall
fabtools.require.shorewall.firewall(zones=None, interfaces=None, policy=None, rules=None, routestopped=None, masq=None)[source]

Ensure that a firewall is configured.

Example:

from fabtools.shorewall import *
from fabtools import require

# We need a firewall with some custom rules
require.shorewall.firewall(
    rules=[
        Ping(),
        SSH(),
        HTTP(),
        HTTPS(),
        SMTP(),
        rule(port=1234, source=hosts(['example.com'])),
    ]
)
fabtools.require.shorewall.started()[source]

Ensure that the firewall is started.

fabtools.require.shorewall.stopped()[source]

Ensure that the firewall is stopped.

fabtools.require.supervisor

Supervisor processes

This module provides high-level tools for managing long-running processes using supervisor.

fabtools.require.supervisor.process(name, **kwargs)[source]

Require a supervisor process to be running.

Keyword arguments will be used to build the program configuration file. Some useful arguments are:

  • command: complete command including arguments (required)
  • directory: absolute path to the working directory
  • user: run the process as this user
  • stdout_logfile: absolute path to the log file

You should refer to the supervisor documentation for the complete list of allowed arguments.

Note

the default values for the following arguments differs from the supervisor defaults:

  • autorestart: defaults to true
  • redirect_stderr: defaults to true

Example:

from fabtools import require

require.supervisor.process('myapp',
    command='/path/to/venv/bin/myapp --config production.ini --someflag',
    directory='/path/to/working/dir',
    user='alice',
    stdout_logfile='/path/to/logs/myapp.log',
    )

fabtools.require.system

System settings

See also

fabtools.system

fabtools.require.system.hostname(name)[source]

Require the hostname to have a specific value.

fabtools.require.system.sysctl(key, value, persist=True)[source]

Require a kernel parameter to have a specific value.

Locales
fabtools.require.system.default_locale(name)[source]

Require the locale to be the default.

fabtools.require.system.locale(name)[source]

Require the locale to be available.

fabtools.require.system.locales(names)[source]

Require the list of locales to be available.

fabtools.require.tomcat

Tomcat

This module provides tools for installing Tomcat

See also

fabtools.tomcat

fabtools.require.tomcat.installed(version='7.0.47')[source]

Require Tomcat to be installed.

from fabtools import require

require.tomcat.installed()

fabtools.require.users

System users

See also

fabtools.user

fabtools.require.users.user(name, comment=None, home=None, create_home=None, skeleton_dir=None, group=None, create_group=True, extra_groups=None, password=None, system=False, shell=None, uid=None, ssh_public_keys=None, non_unique=False)[source]

Require a user and its home directory.

See fabtools.user.create() for a detailed description of arguments.

from fabtools import require

# This will also create a home directory for alice
require.user('alice')

# Sometimes we don't need a home directory
require.user('mydaemon', create_home=False)

# Require a user without shell access
require.user('nologin', shell='/bin/false')

Note

This function can be accessed directly from the fabtools.require module for convenience.

fabtools.require.users.sudoer(username, hosts='ALL', operators='ALL', passwd=False, commands='ALL')[source]

Require sudo permissions for a given user.

Note

This function can be accessed directly from the fabtools.require module for convenience.

History

Changelog

Version 0.19.0 (2014-07-05)

  • Python improvements:
    • use new official download URLs for setuptools and pip (Arnaud Vazard)
    • fix virtualenv when the local flag is passed (Troy J. Farrell)
  • Node.js improvements:
    • fix package_version when no package is installed (Alexandre Patry)
    • add a checkinstall flasg to build and install a distribution package when installing from source (Fabien Meghazi)
  • Arch Linux improvements:
    • add support for the ManjaroLinux variant (Gaëtan Lamothe)
    • fixsupport for setuptools (Robin Lambertz)
    • fix support for supervisor (Robin Lambertz)
    • recognize all known distribution IDs and normalize them to Arch
  • Debian/Ubuntu improvements:
    • add support for the Elementary OS variant (Arnaud Vazard)

Version 0.18.0 (2014-05-02)

This release requires Fabric >= 1.7.0 and drops support for Python 2.5.

  • Add drop_user and drop_database in postgres module

  • Add LinuxMint to the Debian family list (Frank Rousseau)

  • Add support for git remotes (Bryan Folliot)

  • Add support for Tomcat (Jan Kowalski)

  • Add support for Gentoo / portage (Travis Shirk)

  • Add support for Mercurial (Travis Shirk)

  • Add support for GVM (Groovy environment manager) (Bryan Folliot)

  • Documentation fixes and updates

  • MySQL improvements:
    • do not require a password when a specific user is specified
    • expose mysql.query in the public API
  • Python improvements:
    • Switch to pip 1.5 (warning: you will need to use the allow_external and/or allow_unverified options to install packages not hosted on PyPI)
    • Update GitHub download URL for pip installer (Guillaume Andreu Sabater)
    • Retry when trying to download pip/setuptools installers
    • Add support for pip’s --exists-action option
  • Improved OS support in distrib_family() and new UnsupportedFamily exception

  • Make sure to install curl before using it (ponty)

  • Vagrant improvements:
    • Add function to get the Vagrant version
    • Add function to get the status of a Vagrant machine
    • Add function to get the list of Vagrant machines
    • Add function to get the list of Vagrant base boxes
  • Files improvements:
    • Add temp_dir parameter to require.file (default is tmp)
    • Add require.files.temporary_directory
    • Add files.umask to get the user’s umask
    • Fix require.file ownership and permissions when using sudo
    • Add helpers to copy, move, symlink or remove files
  • Fix require.deb.uptodate_index

  • Use rpm instead of yum to check if an RPM package is installed

  • Update JDK install to match changes to the Oracle web site

  • Fix cron.add_task (thanks to Dan Fairs and Ikuya Yamada)

Version 0.17.0 (2013-12-06)

  • Vagrant improvements:
    • Fix support for Vagrant >= 1.3.0
    • Fix duplicate function in vagrant module documentation (Dean Malmgren)
  • Package management improvements:
    • Ubuntu PPA fixes (Anthony Scalisi)
    • Add support for opkg package manager (ponty)
    • Add conditional APT index updates, based on the time of the last update (ponty)
  • Update files.upload_template to match Fabric parameters (thanks to Adam Patterson)

  • PostgreSQL improvements:
    • Fix: use run instead of sudo in _run_as_pg (iiie)
    • Improve SmartOS and locale support (Andreas Kaiser)
  • Support tags in addition to branches in require.git.working_copy (Andreas Kaiser)

  • Services management improvements:
    • Improve upstart support in service.is_running (John MacKenzie)
    • Add support for systemd in service.is_running (Adrien Raffin)
  • Improve support for Arch Linux in nodejs, service and supervisor modules (Steeve Chailloux)

  • Allow custom nginx package names (Laurent Meunier)

  • Add module management for Apache (Eugene Leonovich)

  • Fix test environment for Python 2.5

  • Use the new Read the Docs theme if available when building the docs locally

  • Fix bug with user/group creation with int UID/GID

Version 0.16.0 (2013-10-26)

  • Redis improvements
    • Make bind and port arguments explicit
    • Improve documentation
    • Upgrade default version to 2.6.16
  • Python improvements
    • Improve support for using specific Python interpreters (warning: API changes)
    • Expose low-level virtualenv operations
    • Improve pip installation
    • Switch from distribute to setuptools 0.7+ after project merge (warning: API changes)
    • Do not install curl and python-dev packages when setuptools is already installed (ponty)
    • Make package names case-insensitive in python.is_installed (ponty)
    • Fix pip version parsing when using pythonbrew switch
  • Fix require.system.locales when a prefix is set

  • Fix require.system.locale() on fresh Ubuntu systems

  • Add optional environment variables in crontab

  • Fix crontab permissions

  • Allow special characters in MySQL password (Régis Behmo)

  • Fix bug with some services not starting correctly (Chris Marinos)

  • Add getdevice_by_uuid to the disk module (Bruno Adele)

  • Fix implicit directory name in git.working_copy (iiie)

  • Make require.sysctl robust to procps start failure

Version 0.15.0 (2013-07-25)

  • Fix missing import in user.local_home_directory() (Sebastien Beal)

  • Improved Arch Linux support:
    • Fix locale support in Arch Linux (Bruno Adele)
    • Add support for yaourt package manager in Arch Linux (Bruno Adele)
  • Improvements to the redis module:
    • Fix Redis startup after reboot (Victor Perron)
    • Upgrade default Redis version to 2.6.14
  • Improvements to the git module:
    • Add optional force parameter to git pull and checkout (Sebastien Beal)
  • Improvements to the python module:
    • Add parameter to use a specific Python interpreter (Bruno Adele)
    • Stop using PyPI mirrors now that it has a CDN (Dominique Lederer)
  • Debian/Ubuntu improvements:
    • Add optional version parameter to deb.install() (Anthony Scalisi)
    • Improved support for installing APT public keys (Santiago Mola)
  • SmartOS improvements (Andreas Kaiser):
    • Fix md5sum on recent SmartOS
    • Fix bug in pkg.is_installed with certain package names
    • Add support for SmartOS in remote system identification
    • Add support for SmartOS in require.git.command()
  • RedHat improvements:
    • Fix broken rpm.install() (Sho Shimauchi)
  • Oracle JDK improvements:
    • Upgrade default version to 7u25-b15 (Sebastien Beal)
    • Fix Oracle JDK version parsing when OpenJDK is installed
    • Fix Oracle JDK installation on Debian squeeze (Stéphane Klein)
  • Better tests documentation (thanks to Stéphane Klein)

  • Add require.directories() (Edouard de Labareyre)

  • Add support for Apache web server (Stéphane Klein)

  • Upgrade default Node.js version to 0.10.13

Version 0.14.0 (2013-05-22)

Note: Fabtools now requires Fabric >= 1.6.0

  • Upgrade default pip version to 1.3.1

  • Improved vagrant support:
    • Add support for Vagrant 1.1 providers in functional tests
    • Also set env.user and env.hosts in vagrant context manager
  • Add fabtools.system.cpus to get the host’s CPU count

  • Less verbose output

  • Move OS detection functions to fabtools.system

  • Better support for Red Hat based systems

  • Improvements to the user module:
    • Fix home dir default behaviour in require.user
    • Add support for SSH authorized keys (Kamil Chmielewski)
    • Add support for SSH known hosts public keys
    • Add non_unique argument to user functions (Zhang Erning)
    • Get absolute path to the local user’s home dir (Sebastien Beal)
  • Use SHOW DATABASES to test existence of MySQL (Zhang Erning)

  • Improvements to the git module
    • Expose lower level fetch operation (Andreas Kaiser)
    • Fix missing import in require module (Muraoka Yusuke)
    • Require git command line tool
  • Use ifconfig as root in network module

  • Update OpenVZ guest context manager for Fabric 1.6.0

  • Improvements to the python module:
    • Improved detection of distribute
    • Add support for virtualenv --prompt option (Artem Nezvigin)
    • Allow relative path in virtualenv context manager
  • Improvements to the oracle_jdk module:
    • Upgrade default Oracle JDK version to 7u21-b11 (Kamil Chmielewski)
    • Add support for Oracle JDK version 6 (Sebastien Beal)
  • Fix broken fabtools.deb.upgrade

  • Add support for Arch Linux packages (Bruno Adele)

  • Add support for Linux disk partitions (Bruno Adele)

  • Add OpenSSH server hardening (Adam Patterson)

  • Add systemd module (Jakub Stasiak)

  • Improvements to the redis module:
    • Fix broken Redis configuration (Victor Perron)
    • Upgrade default Redis version to 2.6.13
  • Abort on nginx configuration errors

  • Upgrade default Node.js version to 0.10.7

Version 0.13.0 (2013-03-15)

  • Add support for managing remote git repositories (Andreas Kaiser)
  • Add intersphinx to docs (Andreas Kaiser)
  • Add HTTP proxy support to speed up functional tests
  • Upgrade default Node.js version to 0.10.0
  • Upgrade default Redis version to 2.6.11
  • Upgrade default Oracle JDK version to 7u17-b02
  • Fix vagrant support (thanks to Dominique Lederer and anentropic)

Version 0.12.0 (2013-03-04)

  • Do not create home directory for system users
  • Fix pkg.is_installed on SmartOS (thanks to Anthony Scalisi)
  • Fix system.get_arch (thanks to Kamil Chmielewski)
  • Add support for installing Oracle JDK (thanks to Kamil Chmielewski)
  • Add support for creating Postgres schemas (thanks to Michael Bommarito)
  • Fix mysql.user_exists (thanks to Serge Travin)

Version 0.11.0 (2013-02-15)

  • Fix requiring an existing user (thanks to Jonathan Peel)
  • Upgrade default Redis version to 2.6.10
  • Upgrade default Node.js version to 0.8.19
  • Better support for remote hosts where sudo is not installed

Version 0.10.0 (2013-02-12)

  • Enable/disable nginx sites (thanks to Sébastien Béal)
  • Add support for SmartOS (thanks to Anthony Scalisi)
  • Add support for RHEL/CentOS/SL (thanks to Anthony Scalisi)

Version 0.9.4 (2013-01-10)

  • Add files missing in 0.9.3 (thanks to Stéfane Fermigier)

Version 0.9.3 (2013-01-08)

  • Fix bugs in user creation (thanks pahaz and Stéphane Klein)
  • Add support for group creation

Version 0.9.2 (2013-01-05)

  • Add syntax highlighting in README (thanks to Artur Dryomov)

Version 0.9.1 (2013-01-04)

  • Fix documentation formatting issues

Version 0.9.0 (2013-01-04)

  • Improve user creation and modification
  • Add support for BSD / OS X to files.owner, files.group, files.mode and files.md5sum (thanks to Troy J. Farrell)
  • Improve PostgreSQL user creation (thanks to Troy J. Farrell and Axel Haustant)
  • Add reload and force_reload operations to the service module (thanks to Axel Haustant)
  • Fix missing import in require.redis (thanks to svevang and Sébastien Béal)
  • Add clear option to Python virtualenv (thanks to pahaz)
  • Upgrade default Redis version to 2.6.7
  • Upgrade default Node.js version to 0.8.16
  • Decrease verbosity of some operations
  • Speed up functional tests

Version 0.8.1 (2012-10-26)

  • Really fix pip version parsing issue
  • Upgrade default pip version to 1.2.1

Version 0.8.0 (2012-10-26)

  • Improve user module (thanks to Gaël Pasgrimaud)
  • Fix locale support on Debian (thanks to Olivier Kautz)
  • Fix version number in documentation (thanks to Guillaume Ayoub)
  • Fix potential issue with pip version parsing

Version 0.7.0 (2012-10-13)

  • Fix changed directory owner requirement (thanks to Troy J. Farrell)
  • Add functions to get a file’s owner, group and mode

Version 0.6.0 (2012-10-13)

  • Add support for Node.js (thanks to Frank Rousseau)
  • Fix dependency on Fabric >= 1.4.0 (thanks to Laurent Bachelier)

Version 0.5.1 (2012-09-21)

  • Documentation and packaging fixes

Version 0.5 (2012-09-21)

  • The watch context manager now allows you to either provide a callback or do an explicit check afterwards (warning: this change is not backwards compatible, please update your fabfiles)

  • Add support for some network-related operations:
    • get the IPV4 address assigned to an interface
    • get the list of name server IP addresses
  • The services module now supports both upstart and traditional SysV-style /etc/init.d scripts (thanks to Selwin Ong)

  • The virtualenv context manager can now also be used with local() (thanks to khorn)

  • The supervisor module now uses update instead of reload to avoid unnecessary restarts (thanks to Dan Fairs)

  • Add support for OpenVZ containers (requires a kernel with OpenVZ patches)

  • pip can now use a download cache

  • Upgrade Redis version to 2.4.17

  • Misc bug fixes and improvements

  • Support for Ubuntu 12.04 LTS and Debian 6.0

  • Documentation improvements

Version 0.4 (2012-05-30)

  • Added support for requiring an arbitrary APT source
  • Added support for adding APT signing keys
  • Added support for requiring a user with a home directory
  • Added vagrant helpers
  • Fixed Python virtualenv context manager

Version 0.3.2 (2012-03-19)

  • Fixed README formatting

Version 0.3.1 (2012-03-19)

  • Fixed bug in functional tests runner

Version 0.3 (2012-03-19)

  • Added support for Shorewall (Shoreline Firewall)
  • Fixed Python 2.5 compatibility
  • Refactored tests

Version 0.2.1 (2012-03-09)

  • Packaging fixes

Version 0.2 (2012-03-09)

  • Added support for hostname and sysctl (kernel parameters)
  • Added support for Redis
  • Simplified API for supervisor processes

Version 0.1.1 (2012-02-19)

  • Packaging fixes

Version 0.1 (2012-02-19)

  • Initial release

Development

Tests

Running tests

Using tox

The preferred way to run tests is to use tox. It will take care of everything and run the tests on all supported Python versions, each in its own virtual environment:

$ pip install tox
$ tox

You can ask tox to run tests only against specific Python versions like this:

$ tox -e py25
$ tox -e py26,py27

Note

If tox ever gives you trouble, you can ask it to recreate its virtualenvs by using the -r (or --recreate) option. Alternatively, you can start over completely by removing the .tox directory.

Using unittest

Alternatively, if you’re using Python 2.7, you can launch the tests using the built-in unittest runner:

$ python -m unittest discover

If you’re using Python 2.5 or 2.6, you’ll need to install unittest2 first, then use the provided unit2 command:

$ pip install unittest2
$ unit2 discover

Unit tests

The goal of the unit tests is to test the internal logic of fabtools functions, without actually running shell commands on a target system.

Running unit tests requires the mock library.

Functional tests

The goal of the functional tests is to test that fabtools functions have the expected effect when run against a real target system.

Functional tests are ordinary fabfiles, contained in the fabtools/tests/fabfiles/ folder.

Requirements

Running functional tests requires Vagrant to launch virtual machines, against which all the tests will be run.

If Vagrant is not installed, the functional tests will be skipped automatically.

Selecting base boxes

If Vagrant is installed, the default is to run the tests on all available base boxes. You can specify which base boxes should be used by setting the FABTOOLS_TEST_BOXES environment variable:

$ FABTOOLS_TEST_BOXES='ubuntu_10_04 ubuntu_12_04' tox -e py27

You can also use this to manually disable functional tests, and run only the unit tests:

$ FABTOOLS_TEST_BOXES='' tox
Selecting which tests to run

If you only want to execute specific fabfiles during a test run, you can select them using the FABTOOLS_TEST_INCLUDE environment variable:

$ FABTOOLS_TEST_INCLUDE='oracle.py redis.py' tox -e py27

If you want to exclude some fabfiles from a test run using the FABTOOLS_TEST_EXCLUDE environment variable:

$ FABTOOLS_TEST_EXCLUDE='nginx.py git.py' tox -e py27
Debugging functional tests

When you’re working on a test fabfile, sometimes you’ll want to manually inspect the state of the Vagrant VM. To do that, you can prevent it from being destroyed at the end of the test run by using the FABTOOLS_TEST_NODESTROY environment variable:

$ FABTOOLS_TEST_NODESTROY=1 tox -e py27
$ cd fabtools/tests
$ vagrant ssh

Indices and tables