Question

I really need this to work somehow:

from fabric.api import *
from fabric.contrib import *

def test():
  global env
  env.user = 'vagrant'
  env.hosts = ['127.0.0.1', ]
  env.port = 2222
  env.key_filename = "/Users/sscarduzio/.vagrant.d/insecure_private_key"
  run('ls /')

test case:

$ fab test
No hosts found. Please specify (single) host string for connection:

I can't figure out why it's ok to change the value of env.* outside a function and as soon as structure my code in functions (or classes) fabric ignores it.

Thanks!

Was it helpful?

Solution 3

So, the answer was right in the docs. I didn't see it because Google always finds the old version of the docs, I don't know why.

The main issue is indeed with the propagation of the env.hosts (other env.* values seem to propagate normally.The solution to call a method with an arbitrary list of hosts was of invoking it using execute(<someFunction>, hosts=<someHostList>).

For example:

from fabric.api import env, run, execute
def f1():
  someList = ['remoteHost1','remoteHost2']
  execute(f2, hosts=someList)

def f2():
  run('ls /')

To be run with the command: $ fab f1.

EDIT: updated version

OTHER TIPS

Don't use import *, and don't use globals. There's no need for either.

from fabric.api import env, run

def test():
  env.user = 'vagrant'
  env.hosts = ['127.0.0.1', ]
  env.port = 2222
  env.key_filename = "/Users/sscarduzio/.vagrant.d/insecure_private_key"
  run('ls /')

With my Amazon machines I use:

from fabric.api import env, sudo

def set_env():
  env.host_string = "myuser@myhost"
  env.key_filename = "myfile.pem"

  # run commands
  sudo("ls /")

you should try something like this:

def test():
  with settings(user='vagrant', host_string='localhost',...):
      run('ls /')

According to what I found, env needs item access instead of attributes.

Thus, do

from fabric.api import env, run

def test():
    env['user'] = 'vagrant'
    env['hosts'] = ['127.0.0.1', ]
    env['port'] = 2222
    env['key_filename'] = "/Users/sscarduzio/.vagrant.d/insecure_private_key"
    run('ls /')

I am not sure, however, if this information is right, and I haven't the ability to test it.

This isn't really a fabric problem at all and although you can solve the problem this way you're better not to. SSH really does have much better tools for managing this issue, and for scaling up to more complex setups.

Firstly setup an alternate SSH config file, or add this to your ~/.ssh/config

Host myvagrant
  HostName 127.0.0.1
  Port 2222
  User vagrant
  IdentityFile /Users/sscarduzio/.vagrant.d/insecure_private_key

At that point you should be able to ssh into myvagrant

$ ssh myvagrant

Or:

$ ssh -F .ssh_config myvagrant

Now your fabric code should read:

from fabric.api import *
env.use_ssh_config = True
#env.ssh_config_path = '.ssh_config'
@task
def f2():
    run('ls /')
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top