Welcome to fabtools’s documentation!¶

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.
See also
- 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.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.arch¶
Arch Linux packages¶
This module provides tools to manage Arch Linux packages and repositories.
See also
- 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.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.deb¶
Debian packages¶
This module provides tools to manage Debian/Ubuntu packages and repositories.
See also
- 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.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.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.files¶
Files and directories¶
See also
- fabtools.files.is_link(path, use_sudo=False)[source]¶
Check if a path exists, and is a symbolic link.
- 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.
- 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.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.
See also
- fabtools.git.clone(remote_url, path=None, use_sudo=False, user=None)[source]¶
Clone a remote Git repository into a new directory.
Parameters: - remote_url (str) – URL of the remote repository to clone.
- path (str) – Path of the working copy directory. Must not exist yet.
- 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.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: - 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.
- 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¶
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.
See also
- fabtools.mercurial.clone(remote_url, path=None, use_sudo=False, user=None)[source]¶
Clone a remote Mercurial repository into a new directory.
Parameters: - remote_url (str) – URL of the remote repository to clone.
- path (str) – Path of the working copy directory. Must not exist yet.
- 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.mercurial.update(path, branch='default', use_sudo=False, user=None, force=False)[source]¶
Merge changes to a working copy and/or switch branches.
Parameters: - path (str) – Path of the working copy directory. This directory must exist and be a Mercurial working copy.
- 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.mercurial.pull(path, use_sudo=False, user=None)[source]¶
Pull changes from the default remote repository.
Parameters: - path (str) – Path of the working copy directory. This directory must exist and be a Mercurial working copy with a default remote to pull from.
- 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.mysql¶
MySQL users and databases¶
This module provides tools for creating MySQL users and databases.
See also
Manage users¶
Manage databases¶
- 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.nginx¶
Nginx¶
This module provides tools for managing the Nginx web server.
See also
- 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’)
See also
fabtools.nodejs¶
Node.js¶
This module provides tools for installing Node.js and managing packages using npm.
See also
- 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.
See also
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().
- 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().
fabtools.opkg¶
opkg packages¶
This module provides tools to manage opkg packages and repositories.
See also
- 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.oracle_jdk¶
Oracle JDK¶
This module provides tools for installing Oracle JDK
See also
fabtools.pkg¶
SmartOS packages¶
This module provides tools to manage SmartOS packages.
See also
- 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.
See also
- 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.postgres¶
PostgreSQL users and databases¶
This module provides tools for creating PostgreSQL users and databases.
See also
Manage users¶
- 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.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.
See also
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.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.
See also
- 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.
See also
- 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.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
See also
- 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.shorewall¶
Shorewall firewall¶
See also
Firewall status¶
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.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.supervisor¶
Supervisor processes¶
This module provides high-level tools for managing long-running processes using supervisord.
See also
Manage supervisord¶
Manage processes¶
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.")
Hardware detection¶
Hostname¶
Kernel parameters¶
Locales¶
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.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.user¶
Users¶
See also
- 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()
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.tomcat¶
Tomcat¶
This module provides tools for installing Tomcat.
See also
- 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.vagrant¶
Vagrant helpers¶
- 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.require¶
fabtools.require.apache¶
Apache¶
This module provides high-level tools for installing and configuring the Apache HTTP Server.
See also
- 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.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.deb¶
Debian packages¶
This module provides high-level tools for managing Debian/Ubuntu packages and repositories.
See also
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¶
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.files¶
Files and directories¶
This module provides high-level tools for managing files and directories.
See also
- 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.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.require.mercurial¶
Mercurial¶
This module provides high-level tools for managing Mercurial repositories.
See also
- 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.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.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.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.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
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.oracle_jdk¶
fabtools.require.pkg¶
SmartOS packages¶
This module provides high-level tools to manage SmartOS packages.
See also
- 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.portage¶
Gentoo packages¶
This module provides high-level tools for managing Gentoo packages and repositories using the Portage package manager.
See also
- 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.postfix¶
fabtools.require.postgres¶
PostgreSQL users and databases¶
See also
- 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.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
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
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')
See also
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=[])
See also
fabtools.require.rpm¶
RPM packages¶
This module provides high-level tools for managing CentOS/RHEL/SL/Fedora packages and repositories.
See also
- 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.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.require.service.started(service)[source]¶
Require a service to be started.
from fabtools import require require.service.started('foo')
fabtools.require.shorewall¶
Shorewall firewall¶
See also
- 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.supervisor¶
Supervisor processes¶
This module provides high-level tools for managing long-running processes using supervisor.
See also
- 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.require.tomcat¶
fabtools.require.users¶
System users¶
See also
- 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.
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