Importing fabric into your own scripts

“Fabric is a simple pythonic remote deployment tool” states the Fabric website. But fabric can offer more (or could, if certain assumptions were fixed). Fabric offers simple function calls to run commands locally, over the network, upload and download files and so on. You can of course program all this yourself using various stdlib and 3rd party libraries, but the simplicity of the fabric API feels nice, like this example shows (using fabric 0.0.9 or earlier):

import fabric
 
fabric.local('echo hello')
 
fabric.set(fab_hosts=['host-a'])
fabric.put('myfile.txt', 'myfile.txt')
fabric.run('uname -a')

I had made a script that used fabric like this. It worked fine when I tested against a single host. But when I tried to connect to different hosts in my script, and doing different things on each host, I run into a problem. It turns out that fabric cached the connection to the first host, and later on all my operations were executed against the first host. Luckily I found a simple workaround for that. After each fabric.set() do this:

fabric.CONNECTIONS = []

It may be that fabric caches other fab_* parameters as well, but my use case worked so I haven’t looked further into this yet.

Unfortunately fabric 0.1.0 breaks this import pattern. The developers are aware of the issue, though, so it may be that later versions of fabric could be used like this as well. But for the time being you should mark the dependency at 0.0.9 or 0.0.8.

There are some additional warts when importing fabric into your script. While it is great that fabric notices when a command fails, it will actually exit rather than raise an exception. Probably not an ideal situation for most scripts, so it would be nice if this was configurable. Another feature I would really like added was timeouts for all of the commands. Running external commands that can be killed after a timeout is difficult in Python.

Similar Posts:

    None Found

2 Comments

  1. phaithful:

    Curious, do you see a comparison of Fabric with Pexpect? And if so, from your experience is one a better alternative to the other?

  2. Heikki Toivonen:

    Pexpect can do everything Fabric can do, but not vice versa. On the other hand, Fabric has a really nice and simple API. So I like to use Fabric for things that it can do, and fall back to pexpect for the other cases.