fabric, local and virtualenvwrapper

Fabric is a great tool for running system commands on a remote machine. It also has functionality for running commands locally. If all you needed to do is run local commands, then there probably are better options.

Since I needed to do both, I thought one fabfile with local and remote commands would be simplest. Unfortunately the “local” command and virtualenvwrapper do not play well together. Here is the magic to get them to work together:

local('source /usr/local/bin/virtualenvwrapper.sh && mkvirtualenv my_env', shell='/bin/bash')

Also, it is important to note that with fabric, the “local” command is not just a local version of the “run” command. The context manager (prefix) does not work with “local”. Neither does the “cd” command (use lcd).

I suppose I should also mention that you should not run this fabfile from inside a virtualenv. mkvirtulenv changes the virtualenv which leads to errors like:

/home/me/.virtualenvs/meta/bin/python: No module named virtualenvwrapper

Copying Postgresql to Another Server on Webfaction

Here is how I copied a postgresql database from one Webfaction server to another. My original thought was to do this using Fabric. But on Webfaction, they do not recommend creating or dropping databases from the command line. Instead they recommend using the Webfaction Control Panel.

There are posts on Stackoverflow for copying a database without writing it to an intermediate file. I chose to not do that. The command for dumping the database was:

pg_dump -C -U username database_name > output_file

Next, I copied the file to the other server. After that, I created the new database on the new server using the Webfaction Control Panel. I named the new database the same name as the old. I am not sure if this is necessary. I did not run the Django command syncdb.

Then I ran:

psql -U username -d database_name -f file_name

Fabric

Getting it to work from Fabric was a little tricky because you need to get Fabric to talk to two different servers. The trick involved using the Fabric hosts decorator:

@hosts('webxxx.webfaction.com')
def copy_from():
    your code here

Then run that function using “execute”:

def copy_db():
    r = execute(copy_from)    # execute returns a dict
    return_value = r['webxxx.webfaction.com']
    your code here