Streamlining your admin duties with Fabric

June 25, 2010 by Zoran

We’ve all been there at one point or another. You need to do some complex but repetitive task for the x-th time (where x tends to be a very high number indeed). And since I am a firm believer that everything I need to do more than about 2 times I have to do it with a click, or key-press, or some other similar simple feat of manual dexterity I will discuss some one of the solutions to this problem.

Traditionally this whole situation was tackled with shell scripts. But for all you Python fans there is an alternative and it’s called Fabric. So now you can leverage all your Python guru-ism and familiar-ism in making your world a one click place. Presenting all of the Fabric power is beyond the scope of this post so I will just do a quick tour and you can find everything you wanted to know on the Fabric web page.

So let’s say that you want to streamline a very important part of your regular work… backup. Let’ see how something like this would look like using Fabric. First we need some Python code:

from fabric.api import *

def do_backup():
  local('cp important_folder_1 tmp_folder/', capture=False)
  local('cp important_folder_2 tmp_folder/', capture=False)
  local('tar -czf backup_folder/backup.tgz tmp_folder/', capture=False)
  local('rm -rf tmp_folder/*', capture=False)

We save this code as fabfile.py and run it by typing fab do_backup on the command line while positioned in the folder containing fabfile.py. The capture=False parameter just tells Fabric not to capture the output of the command so it will print it on the screen instead. This is just a glorified shell script wrapped in Python but Fabric gives us something more besides the ability to use Python constructs while starting shell commands in an easy way. Consider the following snippet (it should be put in the same file as the code we already used):

env.hosts = ['my-remote-server.com']

def put_backup_on_server():
  put('backup_folder/backup.tgz', 'remote_backup_folder/backup.tgz')
  run('ls remote_backup_folder/')

def do_remote_backup():
  do_backup()
  put_backup_on_server()

Now if we do fab do_remote_backup Fabric will do our backup as earlier, put the backup file on the my-remote-server.com remote server using SSH connection and print a list of the remote_backup_folder folder contents. So the put command puts any local file on the remote server and the run command executes any shell command on the remote server using SSH connection.

But there’s more… If you call in the next 5 minutes… Sorry, wrong show. If we put several hosts in the env.hosts array Fabric will do all the remote commands on every host in the list. So we can put our backup on more that one server at once. Now that’s very handy if you are the paranoid type ;)

Like I said earlier this is not meant to be the entire tutorial but just something to tickle your curiosity. If you want to know more (if you are wondering should you want to know more  read my earlier post on the essence of being a programmer) stop by the Fabric documentation page and have fun.