Last Updated: September 29, 2021
·
5.559K
· gavinbunney

Fabulous Fabric Fabfile

Fabric fabfile.org, to quote themselves, is

Fabric is a Python (2.5 or higher) library and command-line tool for streamlining the use of SSH for application deployment or systems administration tasks.

So... it's your devops-deployment-script best friend.

There are a bunch of example operations you can do (RTFM), but I thought I'd share a simple script I've been using for pulling artifacts out of Artifactory and deploying them to a glassfish container.

In the script, it allows for deploying to either a dev or test environment, and a bunch of remote operations, such as deploy, undeploy, restart-domain etc.

Operations

Copying the fabfile.py below, and running fab -l you will see the list of operations:

~/dev/fabulous$ fab -l
Available commands:

    deploy_all
    deploy_frown_app
    deploy_smile_app
    dev
    glassfish_asadmin
    glassfish_login
    restart_domain
    test
    undeploy_all

Example

Ok so now you have an awesome list of operations... what can you do? Well, fab allows you to chain commands together, keeping the context of one to the next;

So to perform the deploy_all against the dev server, we just:

$ fab dev deploy_all

And voila! fab will log into dev and deploy all of our apps.

Script - fabfile.py

import os
from fabric.api import *

env.hosts = []
defaults = {
    'admin_port': 4848,
    'glassfish_home': '/opt/glassfish3.1',
    'artifactory_user' : 'artifactory',
    'artifactory_password' : 'password',
}

smile_app = {
    'remote_app_name' : 'smile-app',
    'remote_war' : '/tmp/smile-app.war',
    'artifactory_war' : 'http://artifactory/artifactory/snapshots/au/net/bunney/smile/1.0-SNAPSHOT/smile-webapp-1.0-SNAPSHOT.war',
    'deploy_war' : './deploy/smile-webapp-1.0-SNAPSHOT.war'
}

frown_app = {
    'remote_app_name' : 'frown-app',
    'remote_war' : '/tmp/frown-app.war',
    'artifactory_war' : 'http://artifactory/artifactory/snapshots/au/net/bunney/frown/1.0-SNAPSHOT/frown-webapp-1.0-SNAPSHOT.war',
    'deploy_war' : './deploy/frown-webapp-1.0-SNAPSHOT.war'
}

def dev():
    print 'Configured for dev'
    env.hosts = ["10.1.1.1"]
    env.user = "glassfish"
    env.password = "password"

def test():
    print 'Configured for test'
    env.hosts = ["10.1.1.2"]
    env.user = "glassfish"
    env.password = "password"

############################################################
# Glassfish Administration Helpers
############################################################

def glassfish_asadmin(cmd):
    run("%s/bin/asadmin --host %s --port %d %s" % (defaults['glassfish_home'], env.hosts[0], defaults['admin_port'], cmd))

def glassfish_login():
    run("%s/bin/asadmin login --host %s --port %d" % (defaults['glassfish_home'], env.hosts[0], defaults['admin_port']))

def restart_domain():
    print 'Restarting domain'
    glassfish_asadmin("restart-domain --force --kill")


############################################################
# Artifactory Functions
############################################################
def __get_artifactory_file(warFile='UNKNOWN'):
    filename = os.path.basename(warFile)
    print 'Retrieving war file from artifactory'
    local('rm -rf ./deploy/%s' % (filename))
    local('curl -O %s -u%s:%s' % (warFile, defaults['artifactory_user'], defaults['artifactory_password']))
    local('mv %s ./deploy/' % (filename))

############################################################
# Smile App Functions
############################################################

def __get_smile_app_from_artifactory():
    __get_artifactory_file(warFile=smile_app['artifactory_war'])

def __copy_smile_app_to_remote(warFile=smile_app['deploy_war'], destination=smile_app['remote_war']):
    print 'Copying smile app war file to remote host'
    put(warFile, destination)

def __glassfish_undeploy_smile_app(appName=smile_app['remote_app_name']):
    print 'Undeploying smile app war file on remote host'
    with settings(warn_only=True):
        glassfish_asadmin("undeploy %s" % (appName))

def __glassfish_deploy_smile_app(warFile=smile_app['remote_war']):
    print 'Deploying smile app war file on remote host'
    glassfish_asadmin("deploy --libraries %s --force %s" % (smile_app['remote_app_name'], warFile))

def deploy_smile_app():
    __get_smile_app_from_artifactory()
    __copy_smile_app_to_remote()
    __glassfish_undeploy_smile_app()
    restart_domain()
    __glassfish_deploy_smile_app()

############################################################
# Frown App Functions
############################################################

def __get_frown_app_from_artifactory():
    __get_artifactory_file(warFile=frown_app['artifactory_war'])

def __copy_frown_app_to_remote(warFile=frown_app['deploy_war'], destination=frown_app['remote_war']):
    print 'Copying frown app war file to remote host'
    put(warFile, destination)

def __glassfish_undeploy_frown_app(appName=frown_app['remote_app_name']):
    print 'Undeploying frown app war file on remote host'
    with settings(warn_only=True):
        glassfish_asadmin("undeploy %s" % (appName))

def __glassfish_deploy_frown_app(warFile=frown_app['remote_war']):
    print 'Deploying frown app war file on remote host'
    glassfish_asadmin("deploy --libraries %s --force %s" % (frown_app['remote_app_name'], warFile))

def deploy_frown_app():
    __get_frown_app_from_artifactory()
    __copy_frown_app_to_remote()
    __glassfish_undeploy_frown_app()
    restart_domain()
    __glassfish_deploy_frown_app()

############################################################
# All Deploy
############################################################

def deploy_all():
    __get_smile_app_from_artifactory()
    __get_frown_app_from_artifactory()

    __copy_smile_app_to_remote()
    __copy_frown_app_to_remote()

    __glassfish_undeploy_smile_app()
    __glassfish_undeploy_frown_app()

    restart_domain()

    __glassfish_deploy_smile_app()
    __glassfish_deploy_frown_app()

def undeploy_all():
    __glassfish_undeploy_smile_app()
    __glassfish_undeploy_frown_app()
    restart_domain()