Automation with Platter¶
Platter is built with automation in mind. There are a handful of tools you can use platter together with, to make automated deployments a reality.
Automated Building¶
To automate the building process we recommend Fabric. Fabric can be used to upload the source artifacts on a build server, then invoke the building process there and to fetch down the resulting build artifact. This allows you to trigger a build from any machine even if it does not have the correct architecture or operating system.
You will need fabric
installed locally and a fabfile.py that looks
something like this:
import os
import tempfile
from fabric.api import task, local, run, cd, get, put, hosts
@task
@hosts('my-build-server-hostname')
def build(rev='HEAD'):
# ask git to create an archive for the right version.
tmp = tempfile.mktemp(suffix='.tar.gz')
local('git archive "%s" | gzip > "%s"' % (rev, tmp))
# upload that archive to a temporary folder
buildtmp = '/tmp/build-%s' % os.urandom(20).encode('hex')
run('mkdir %s' % buildtmp)
put(tmp, '%s/src.tar.gz' % buildtmp)
# In that folder
with cd(buildtmp):
# extract the uploaded archive
run('tar xzf src.tar.gz')
# and invoke platter to build it
run('/path/to/venv/bin/platter build .')
# then download the archive and place it in `dist`
local('mkdir -p dist')
get('dist/*.tar.gz', 'dist')
# Clean up
run('rm -rf %s' % buildtmp)
This example requires a few things:
- in this case we use git as source control system. If you use something else you will need to adjust the code accordingly.
- platter is installed on the build server into
/path/to/venv
into a virtualenv. You can obviously adjust this.
To build the package you can then run this:
$ fab build
Or to build a specific version:
$ fab build:rev=1.0-rc1
The resulting build artifact will end up in the dist directory next to the fabfile.
Automated Installing¶
For automated installation the archive can be placed on a server, extracted and installed. The usually recommended way for this is to extract the package to a version specific folder and to then symlink the virtualenv to an alias.
This is easy to accomplish because the tarball generated by platter
contains metadata that can be used by tools. For instance it contains a
file named VERSION
with the version number.
Here an example fabfile.py which can upload a package to hosts:
import os
from fabric.api import task, put, run, cd
@task
def deploy(archive=None):
# If archive is not provided, we use the 'last' one
if archive is None:
archive = os.path.join('dist',
sorted(os.listdir('dist'))[-1])
# Upload the archive and make some temporary space in /tmp
put(archive, '/tmp/yourapp.tar.gz')
run('rm -rf /tmp/yourapp && mkdir -p /tmp/yourapp')
# Now enter the temporary folder
with cd('/tmp/yourapp'):
# Extract the archive, throwing away the toplevel folder
run('tar --strip-components=1 -xzf /tmp/yourapp.tar.gz')
# Ask for the version
version = str(run('cat VERSION'))
# Install into a version specific directory
run('./install.sh /srv/yourapp/versions/%s' % version)
# Create a symlink for the current version
run('ln -sf %s /srv/yourapp/versions/current' % version)
# Clean up the mess
run('rm -rf /tmp/yourapp /tmp/yourapp.tar.gz')
You can then deploy an archive trivially:
$ fab -H myserver deploy