运行最新版本的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.
有什么变化吗?或者我只是做错了什么?
答案 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.
如果有人知道这方面有好的工作,请全心全意地告诉我!