2016-04-15 34 views
0

运行Fabric(1.11.1)(Paramiko(1.16.0),Python(2.7.11))的最新版本,即时获取最奇怪的错误,我做了一些概念验证试试看。Fabric结构设置问题()

from fabric.api import run, sudo, task 
from fabric.context_managers import settings 


@task 
def test(): 
    print('regular run') 
    run('whoami') 

    print('regular sudo') 
    sudo('whoami') 

    print('sudo with user arg') 
    sudo('whoami', user='www-data') 

    with settings(user='www-data'): 
     print('run inside settings') 
     run('whoami') 

输出:

$ fab -f test.py -H [email protected]:2222 test 
[[email protected]:2222] Executing task 'test' 
regular run 
[[email protected]:2222] run: whoami 
[[email protected]:2222] out: vagrant  # <--- good 
[[email protected]:2222] out: 

regular sudo 
[[email protected]:2222] sudo: whoami 
[[email protected]:2222] out: root   # <--- good 
[[email protected]:2222] out: 

sudo with user arg 
[[email protected]:2222] sudo: whoami 
[[email protected]:2222] out: www-data  # <--- good 
[[email protected]:2222] out: 

run inside settings 
[[email protected]:2222] run: whoami 
[[email protected]:2222] out: vagrant  # <--- WHAT THE HECK!? this used to work 
[[email protected]:2222] out: 


Done. 

做了什么变化?或者我只是做错了什么?

回答

0

另一结构问题,原来如果你做可爱的东西,如:-H [email protected]:2222内部不打破它,你会想到什么:env.user = 'vagrant'; env.host = '127.0.0.1'; env.port = '2222'但它只是保持它在host_string 所以...啊,这里是世界上最丑陋的黑客:

from fabric.api import run, sudo, task, env 
from fabric.context_managers import settings as _settings 


def settings(*args, **kwargs): 
    """ 
    Helper function because Fabric's setting() is broken 

    Checks to see if there is a '@' in the host_string and if there is, it 
    will then append it to the host_string since that will be how it changes 
    users. Otherwise if the host_string is not being used, it will use the 
    default "swap user" functionality 
    """ 
    if 'user' in kwargs and '@' in env.host_string: 
     kwargs['host_string'] = '{}@{}'.format(
      kwargs.pop('user'), 
      env.host_string.split('@')[1] 
     ) 
    return _settings(*args, **kwargs) 


@task 
def test(): 
    print('regular run') 
    run('whoami') 
    print('regular sudo') 
    sudo('whoami') 

    print('sudo with user arg') 
    sudo('whoami', user='www-data') 
    with settings(user='www-data'): 
     print('run inside settings') 
     run('whoami') 

这有助于保持代码相当“干净”的,而不是让所有的地方一堆with settings(host_string='[email protected]' + env.host_string.split('@')[1]):,才意识到他们如果您定义结构命令如:fab .. --user=vagrant --host=127.0.0.1 --port=2222,则会中断。该解决方案适用于以下:

fab -f test.py --user=vagrant --host=127.0.0.1 --port=2222 test

fab -f test.py -H [email protected]:2222 test


老办法

from fabric.api import run, sudo, task, env 
from fabric.context_managers import settings 


@task 
def test(): 
    print('regular run') 
    run('whoami') 
    print('regular sudo') 
    sudo('whoami') 

    print('sudo with user arg') 
    sudo('whoami', user='www-data') 
    with settings(host_string='[email protected]' + env.host_string.split('@')[1]): 
     print('run inside settings') 
     run('whoami') 

输出:

$ fab -f test.py -H [email protected]:2222 test 
[[email protected]:2222] Executing task 'test' 
regular run 
[[email protected]:2222] run: whoami 
[[email protected]:2222] out: vagrant  # <--- good 
[[email protected]:2222] out: 

regular sudo 
[[email protected]:2222] sudo: whoami 
[[email protected]:2222] out: root   # <--- good 
[[email protected]:2222] out: 

sudo with user arg 
[[email protected]:2222] sudo: whoami 
[[email protected]:2222] out: www-data  # <--- good 
[[email protected]:2222] out: 

run inside settings 
[[email protected]:2222] run: whoami 
[[email protected]:2222] out: www-data  # <--- good 
[[email protected]:2222] out: 


Done. 

如果有人知道一个很好的解决方法,请让我知道,我所有的耳朵!