Fabric

Introduction

Fabric is a Python library that allows you execute remove commands over SSH. It comes in handy when you find yourself connecting to SSH and running same commands redundantly. Fabric is also useful when you have multiple servers to administer.

Installation

Being a python package it is simple to install

pip install fabric

Supported operations

Official Documentation has more details, few important operations are:

  1. run : Fabric’s run procedure is used for executing a shell command on one or more remote hosts.The output results of run can be captured using a variable. If command succeeded or failed can be checked using .failed and .succeeded.

  2. sudo : It allows the execution of a given set of commands and arguments with sudo (i.e. superuser) privileges on the remote host.

  3. local : It allows the execution of a given set of commands locally.

  4. get : The get command exists to download (i.e. pull) file(s) from the remote system to the computer where the Fabric is being used.

  5. putWhen you need to upload files, put command can be used very similarly to get. Parameters:
    • local_path : set the local path.

    • remote_path : set the remote path.

    • use_sudo : upload the file to anywhere on the remote machine using a nifty trick: upload to a temporary location then move.

    • mode : set the file mode (flags).

    • mirror_local : set the file flags (i.e. make executable) automatically by reading the local file’s mode.

    • prompt : This command does exactly what its name suggests and asks the user (i.e. one that is running the script) to input a certain data to use during the successive execution.

  6. reboot: The reboot command is also self explanatory: it is used to reboot the remote system. By default, it waits two minutes (i.e. 120 seconds -> wait=120) before doing its job

Context Managers

Fabric’s context managers are used with the Python’s with statement. The reason for this is how sessions between execution of commands are not kept between shell-less connections.

  1. cd (fabric.context_managers.cd)
    • cd context manager allows keeping the directory state (i.e. where the following block of comments are to be executed). It is similar to running the cd command during an SSH session and running various different commands.

  2. lcd (fabric.context_managers.lcd)
    • The lcd context manager (local cd) works very similarly to one above (cd); however, it only affects the local system’s state.

  3. prefix (fabric.context_managers.prefix)
    • prefix statement does what its name suggests and wraps given run and sudo command with the specified one.

Executing fab file

fab update_install

Sample fab file

from fabric.api import *
from fabric.api import task,run
from fabric.context_managers import cd
import os


env.user = "user"

env.hosts = ['<IP_ADDRESS>']
env.password = '<SECRET>'
code_dir = '/home/user/matchapp'
env.project_directory = "~/matchapp/xchangeplay"
env.solr_url = 'https://archive.apache.org/dist/lucene/solr/4.10.3/solr-4.10.3.tgz'

# os.path.basename(env.solr_url) returns tail(end) part i.e solr-4.4.0.tgz
env.solr_tgz = os.path.basename(env.solr_url)

env.directory = "~/Install/envs"
env.activate = "source matchapp3/bin/activate"


def create_directory():
run("mkdir ~/matchapp")

def clone_project():
    #clone project from bitbucket
    run("git clone <REPO> %s" % code_dir)

def create_virtualenv():
    #command to create virtual env
    with cd( "~/Install/envs" ):
        run("virtualenv matchapp3")


def install_requirements_file():
    with cd(env.directory):
        with prefix(env.activate):
            run("pip install -r %s" %  os.path.join("~/matchapp","requirements.txt"))

def load_fixtures():
    with cd(env.project_directory):
        run(" sudo python manage.py loaddata {0}/fixtures/core_21_dec.json".format(env.project_directory))


def migrate():
    with cd(env.project_directory):
        run(" sudo python manage.py migrate")


def update_apt():
    sudo("apt-get update")

def install_jdk():
    sudo("apt-get -y install openjdk-7-jdk")


def setup_solr():
    update_apt()
    install_jdk()
    run("mkdir -p ~/Installs")
    with cd("~/Installs"):
        run("wget {0}".format(env.solr_url))
        #tar command is used to unzip file.
        run("tar xvfz {0}".format(env.solr_tgz))

        with cd("solr-4.10.3/example/solr/collection1/conf"):
            run("mv schema.xml schema1.xml")
            run("cp %s/search/solr/schema.xml  ."% env.project_directory)


def start_solr():
    with cd("~/Installs/solr-4.10.3"):
        run("bin/solr start")


def ingest_data_to_solr():
    with cd(env.directory):
        run(env.activate)
    with cd (env.project_directory):
        run("python manage.py shell < search/solr/ingest_from_db_to_solr.py")

def install_supervisor():
    with cd(env.directory):
        with prefix(env.activate):
            run("pip install supervisor")


def install_celery():
    with cd(env.directory):
        with prefix(env.activate):
            run("pip install celery")


def set_up_virtualenv():
    sudo("apt-get install python-pip")
    sudo("pip install virtualenv")
    run("mkdir ~/.Install")
    run("pip install virtualenvwrapper")