Fabric设置问题()

时间:2016-04-15 16:10:57

标签: python fabric

运行最新版本的Fabric(1.11.1)(Paramiko(1.16.0),Python(2.7.11))并且我得到了最奇怪的错误,我做了一个小概念证明来试试。

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 vagrant@127.0.0.1:2222 test
[vagrant@127.0.0.1:2222] Executing task 'test'
regular run
[vagrant@127.0.0.1:2222] run: whoami
[vagrant@127.0.0.1:2222] out: vagrant        # <--- good
[vagrant@127.0.0.1:2222] out: 

regular sudo
[vagrant@127.0.0.1:2222] sudo: whoami
[vagrant@127.0.0.1:2222] out: root           # <--- good
[vagrant@127.0.0.1:2222] out: 

sudo with user arg
[vagrant@127.0.0.1:2222] sudo: whoami
[vagrant@127.0.0.1:2222] out: www-data       # <--- good
[vagrant@127.0.0.1:2222] out: 

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


Done.

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

1 个答案:

答案 0 :(得分:0)

另一个Fabric问题,如果你做了一些可爱的事情,例如:-H vagrant@127.0.0.1:2222在内部它并没有将它分解为你所期望的:env.user = 'vagrant'; env.host = '127.0.0.1'; env.port = '2222'但它只是保留在host_string {1}}。 <罢工>所以......呃,这是世界上最丑陋的黑客:

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')

这有助于公平地保持代码&#34;清洁&#34;并且没有一堆with settings(host_string='www-data@' + 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 vagrant@127.0.0.1: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='www-data@' + env.host_string.split('@')[1]):
        print('run inside settings')
        run('whoami')

输出:

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

regular sudo
[vagrant@127.0.0.1:2222] sudo: whoami
[vagrant@127.0.0.1:2222] out: root           # <--- good
[vagrant@127.0.0.1:2222] out: 

sudo with user arg
[vagrant@127.0.0.1:2222] sudo: whoami
[vagrant@127.0.0.1:2222] out: www-data       # <--- good
[vagrant@127.0.0.1:2222] out: 

run inside settings
[vagrant@127.0.0.1:2222] run: whoami
[vagrant@127.0.0.1:2222] out: www-data       # <--- good
[vagrant@127.0.0.1:2222] out: 


Done.

如果有人知道这方面有好的工作,请全心全意地告诉我!