Skip to content

Instantly share code, notes, and snippets.

@outbounder
Created August 5, 2011 09:54
Show Gist options
  • Save outbounder/1127241 to your computer and use it in GitHub Desktop.
Save outbounder/1127241 to your computer and use it in GitHub Desktop.
Execute Fabric task
import fabric.main as fab
from fabric.api import *
def getFabCommand(name):
parts = name.split(".")
p = parts.pop(0)
if p not in fab.commands:
return None
else:
command = fab.commands[p]
while len(parts) > 0:
p = parts.pop(0)
command = command[p]
return command
def parseArguments(cmd):
args = []
kwargs = {}
hosts = []
roles = []
if ':' in cmd:
cmd, argstr = cmd.split(':', 1)
for pair in argstr.split(','):
k, _, v = pair.partition('=')
if v:
# Catch, interpret host/hosts/role/roles kwargs
if k in ['host', 'hosts', 'role', 'roles']:
if k == 'host':
hosts = [v.strip()]
elif k == 'hosts':
hosts = [x.strip() for x in v.split(';')]
elif k == 'role':
roles = [v.strip()]
elif k == 'roles':
roles = [x.strip() for x in v.split(';')]
# Otherwise, record as usual
else:
kwargs[k] = v
else:
args.append(k)
return (cmd, args, kwargs, hosts, roles)
def executeTask(task):
# get task arguments
task = parseArguments(task)
# Get callable by itself
command = getFabCommand(task[0])
if not command:
# Abort if any unknown commands were specified
abort("Command not found:\n%s" % fab.indent(name))
# Set current command name (used for some error messages)
env.command = task[0]
# If hosts found, execute the function on each host in turn
for host in env.hosts:
# Preserve user
prev_user = env.user
# Split host string and apply to env dict
username, hostname, port = fab.interpret_host_string(host)
# Log to stdout
if fab.state.output.running:
print("[%s] Executing task '%s'" % (host, env.command))
# Actually run command
command(*task[1], **task[2])
# Put old user back
env.user = prev_user
# If no hosts found, assume local-only and run once
if not env.hosts:
command(*task[1], **task[2])
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment