running fabric script locally
Yes, you can run fab locally by using method local instead of run. What I do typically is have methods for setting up the environment, and call these methods first before calling the actual task. Let me illustrate this with an example for your specific question
fabfile.py
from fabric.operations import local as lrun, run from fabric.api import task from fabric.state import env @task def localhost(): env.run = lrun env.hosts = ['localhost'] @task def remote(): env.run = run env.hosts = ['some.remote.host'] @task def install(): env.run('deploymentcmd')
And based on the environment, you can do the following
Install on localhost:
fab localhost install
Install on remote machine:
fab remote install
I am using another trick for executing remote task locally:
from fabric.api import run, sudo, localfrom contextlib import contextmanager@contextmanagerdef locally(): global run global sudo global local _run, _sudo = run, sudo run = sudo = local yield run, sudo = _run, _sudodef local_task(): with locally(): run("ls -la")
Slightly less elegant than Varun's answer, but maybe more practical by defaulting to run on the local machine unless another environment selector is given.
from fabric.api import *# default to running on localhostenv.hosts = ["localhost"]DEPLOYMENT_PATH = "/some/path/{}/"def local_or_remote(*args, **kwargs): func = local if env.host == "localhost" else run return func(*args, **kwargs)@taskdef live(): """ Select live environment """ env.hosts = ["host1", "host2"] env.path = DEPLOYMENT_PATH.format("live")@taskdef beta(): """ Select beta environment """ env.hosts = ["host1", "host2"] env.path = DEPLOYMENT_PATH.format("beta")@taskdef host_info(): local_or_remote("uname -a")
Then run locally as:
fab host_info
or remotely with:
fab live host_info
PS. Here is the Github issue on this topic.