Как правильно установить `env.hosts` в функции в моей Python Fabric` fabfile.py`? - PullRequest
8 голосов
/ 31 января 2012

Когда я запускаю это fabfile.py ...

from fabric.api import env, run, local, cd

def setenv(foo):
  env.hosts = ['myhost']

def mycmd(foo):
  setenv(foo)
  print(env.hosts)
  run('ls')

с помощью этой команды fab mycmd:bar. Я получаю этот вывод ...

['myhost']
No hosts found. Please specify (single) host string for connection:

Что, что ?! Я не понимаю? Я установил env.hosts, и кажется, что он действителен "внутри" функции mycmd, но по какой-то причине команда run не знает о указанном hosts.

Цвет меня смутил. Любая помощь будет оценена!

Ответы [ 4 ]

7 голосов
/ 18 сентября 2012

@ Крис, причина такого поведения в том, что список хостов составлен за до , вызывается функция задачи.Таким образом, даже если вы изменяете env.hosts внутри функции, уже слишком поздно, чтобы она имела какой-либо эффект.

В то время как команда fab setenv:foo mycmd:bar привела бы к тому, что вы ожидали:

$ fab setenv:foo mycmd:bar
[myhost] Executing task 'mycmd'
['myhost']
[myhost] run: ls

Это то же самое, что и принятый ответ, но из-за способа определения setenv необходим аргумент.

Другой пример:

from fabric.api import env, run, local, cd

env.hosts = ['other_host']

def setenv(foo):
    env.hosts = ['myhost']

def mycmd(foo):
    setenv(foo)
    print('env.hosts inside mycmd: %s' % env.hosts)
    run('ls')

Вывод этого:

$ fab mycmd:bar
[other_host] Executing task 'mycmd'
env.hosts inside mycmd: ['myhost']
[other_host] run: ls

Fatal error: Name lookup failed for other_host

Underlying exception:
    (8, 'nodename nor servname provided, or not known')
Aborting.

Как видите, список хостов уже установлен на ['other_host', ], когда фабрика начинает выполнять mycmd.

5 голосов
/ 31 января 2012

То, как вы это делаете, обычно не так, как я бы использовал Fabric.

from fabric.api import *

def hostname():

    env.hosts = ['myhosts']

def mycmd():
    print env.hosts
    run('ls -l')

Чтобы выполнить это, я бы тогда сделал

fab hostname mycmd

thisпозволяет вам указать, на каком хосте / хостах вы хотите выполнить команду.

надеюсь, это поможет.

3 голосов
/ 31 января 2012

Вы пытались использовать декоратор hosts ?

from fabric.api import env, run, hosts

@hosts('myhost')
def mycmd(foo):
    print(env.hosts)
    run('ls')
0 голосов
/ 04 мая 2015

Я понял, как заставить это работать:

from fabric.api import env, run, local, cd

def setenv(foo):
  env.hosts = ['myhost']
  return env

def mycmd(foo):
  env = setenv(foo)
  print(env.hosts)
  run('ls')
...