Reputation: 5391
I have a django app and I wrote a fabric script that installs my app on deployment server (Cent OS 5).
Now I want to run the same fabric script locally on the deployment server.
Is there a way to do it without supplying ssh user and password?
I mean just with "-H localhost"?
Thanks, Alex A.
Upvotes: 43
Views: 17218
Reputation: 1202
A modified version of Varun's answer that takes into account local not capturing stdout/stderr. Without specifying capture=True you would not be able to get results from local.
from fabric.operations import local, run
from fabric.api import task
from fabric.state import env
def local_run(*args):
return local(args[0], capture=True)
@task
def localhost():
env.run = local_run
env.hosts = ['localhost']
@task
def remote():
env.run = run
env.hosts = ['some.remote.host']
@task
def install():
env.run('deploymentcmd')
Upvotes: 0
Reputation: 310
First, make sure you can ssh into your localhost without a password:
$ ssh-copy-id localhost
And then just run it as you said, with the -H localhost
command line option
Upvotes: 3
Reputation: 924
You can run ssh server on your local machine to be able to ssh to localhost. And then just run scripts with "-H localhost". Works perfectly for me.
Upvotes: 2
Reputation: 2409
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 localhost
env.hosts = ["localhost"]
DEPLOYMENT_PATH = "/some/path/{}/"
def local_or_remote(*args, **kwargs):
func = local if env.host == "localhost" else run
return func(*args, **kwargs)
@task
def live():
"""
Select live environment
"""
env.hosts = ["host1", "host2"]
env.path = DEPLOYMENT_PATH.format("live")
@task
def beta():
"""
Select beta environment
"""
env.hosts = ["host1", "host2"]
env.path = DEPLOYMENT_PATH.format("beta")
@task
def 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.
Upvotes: 4
Reputation: 6836
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
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
Upvotes: 80
Reputation: 2460
I am using another trick for executing remote task locally:
from fabric.api import run, sudo, local
from contextlib import contextmanager
@contextmanager
def locally():
global run
global sudo
global local
_run, _sudo = run, sudo
run = sudo = local
yield
run, sudo = _run, _sudo
def local_task():
with locally():
run("ls -la")
Upvotes: 7