sorin
sorin

Reputation: 170350

How do I run a local command with fabric 2?

I want to use Fabric and run a command on local, without having to establish any additional connections.

How do I do this in fabric 2? ... documentation seems to miss to give any example.

Upvotes: 26

Views: 12956

Answers (6)

Bryan Roach
Bryan Roach

Reputation: 883

This is similar to the answer by @phoibos, but I wanted to show that @task is not needed.

import sys
from fabric import Connection
from invoke.context import Context

target_host=sys.argv[1]

if target_host == 'localhost':
    ctx = Context()
else:
    ctx = Connection(target_host)

ctx.run('hostname', echo=False, hide=None)

if isinstance(ctx, Connection):
    ctx.close()

Local:

> python demo.py localhost
MyComputerName

Remote:

> python demo.py demo.example.com
demo.example.com

Upvotes: 1

clearwater
clearwater

Reputation: 21

# -*- coding: utf-8 -*-
from fabric import task
from invoke import run as local
@task(default=True)
def testwxmsg(c):
    local("pytest --reuse-db --no-migrations tests/weixin/test_release_accrual.py")

Upvotes: 2

RickyA
RickyA

Reputation: 16029

I am adding @TheRealChx101's comment as an answer because I ran into troubles with Connection.local. Not all environment variables got into the pty, so some of my scripts did not work properly.

With the import from invoke run as local stanza (Invoke's local instead of Fabric's), everything worked fine.

Upvotes: 2

phoibos
phoibos

Reputation: 3979

The design decision to drop the local command in Fabric 2 makes this more difficult, but I was able to simulate it by using Context from Invoke instead of Connection:

from fabric import Connection
from invoke.context import Context

@task
def hostname(c):
    c.run('hostname')

@task
def test(c):
    conn = Connection('user@host')
    hostname(conn)
    local_ctx = Context(c.config)  # can be passed into @task;
                                   # Connection is a subclass of Context
    hostname(local_ctx)

Upvotes: 10

contmp
contmp

Reputation: 426

After several different attemps and spending lots of time I found this elegant solution for starting a server (pty=True) and run local commands.

fabfile.py

from fabric import task

@task
def env_test(c):
    c.run("env", replace_env=False)

@task
def go(c):
    c.run("manage.py runserver", replace_env=False, pty=True)

Please be aware again, these two commands are only meant for local development tasks!

Further Reading: Fabric2 Connections, Upgrading from 1.x

Upvotes: 4

DataBlox
DataBlox

Reputation: 81

run, sudo, and local are done the same:

from fabric import Connection                                                                                  

cn = Connection('[email protected]')    # presumes ssh keys were exchanged                                        

cn.run('ls -al')     # assuming ssh to linux server - as scott                  
cn.sudo('whoami')    # as root                                                  
cn.local('echo ---------- now from local')                                      
cn.local('dir /w')   # assuming client is windows                               

Upvotes: 4

Related Questions