我有以下CSV:
ip, arg1, arg2
1.2.3.4, foo, bar
1.3.4.5, baz, bub
我正在尝试执行:
apt-get
等命令 Fabric有execute(do_work, hosts=host_list)
但我无法为此指定正确的上下文。到目前为止,我已经在一起攻击了一些东西:
from fabric.api import env, execute
arguments = {}
def _deploy():
print env.host_string, arguments[env.host_string]
def deploy():
global arguments
arguments['1.2.3.4'] = ('foo', 'bar')
arguments['2.3.4.5'] = ('baz', 'bub')
execute(_deploy, hosts=arguments.keys())
打印出来:
[1.2.3.4] Executing task '_deploy'
1.2.3.4 ('foo', 'bar')
[2.3.4.5] Executing task '_deploy'
2.3.4.5 ('baz', 'bub')
目前,这并没有破坏任何东西。有没有更好的方法,甚至更好的lib我这样做?
注意:我不是paramiko的粉丝,因为它太低了。
答案 0 :(得分:0)
这是织物中不时出现的边缘情况。我可以向您展示我过去使用的策略,但我会从更安全的策略变化开始。
env词典旨在存储可供其他任务使用的环境数据。任何应该在任务之间共享但不能作为参数传递的数据都可以在这里,所以我将更改你的代码以保持env中的参数:
from fabric.api import env, execute, task
def _deploy():
print env.host_string, env.arguments[env.host_string]
@task
def deploy():
env.arguments = {}
env.arguments['1.2.3.4'] = ('foo', 'bar')
env.arguments['2.3.4.5'] = ('baz', 'bub')
execute(_deploy, hosts=env.arguments.keys())
第二个策略是我过去用来执行这样的工作的策略,它涉及将所有参数作为主机字符串的一部分传递,并让任务负责将其解析为可用数据。它使您无法在全球范围内传递大型字典,并且您的用例可能会有效:
hosts.csv
1.2.3.4, foo, bar
1.3.4.5, baz, bub
1.4.5.6, complex-args, maybe with spaces
fabfile.py
from fabric.api import env, execute, run, settings, task
def _parse_args(argument_string):
# you should really use the csv module here to split properly (escapes, etc)
args = argument_string.split(', ')
if len(args) != 3:
raise ValueError("Only the host and 2 arguments are allowed")
return args
def _deploy():
host, arg1, arg2 = _parse_args(env.host_string)
with settings(host_string=host):
# run("apt-get '{}'".format(arg1))
# run("service '{}' restart".format(arg2)
print "[{}] apt-get '{}'".format(env.host_string, arg1)
print "[{}] service '{}' restart".format(env.host_string, arg2)
@task
def deploy():
with open('hosts.csv') as f:
hosts = [ line.strip() for line in f ]
execute(_deploy, hosts=hosts)
以下是您使用此策略看到的输出:
$ fab deploy
[1.2.3.4, foo, bar] Executing task '_deploy'
[1.2.3.4] apt-get 'foo'
[1.2.3.4] service 'bar' restart
[1.3.4.5, baz, bub] Executing task '_deploy'
[1.3.4.5] apt-get 'baz'
[1.3.4.5] service 'bub' restart
[1.4.5.6, complex-args, maybe with spaces] Executing task '_deploy'
[1.4.5.6] apt-get 'complex-args'
[1.4.5.6] service 'maybe with spaces' restart
Done.
答案 1 :(得分:0)
不优雅本身,但这是我解决的解决方案:
def special_echo(matrix):
key = 'ubuntu@' + env.host
name = matrix[key]
run('echo %s `hostname --ip-address`' % name)
A = {}
A['ubuntu@54.219.171.62'] = 'first'
A['ubuntu@52.53.149.140'] = 'second'
A['ubuntu@54.183.255.58'] = 'third'
execute(special_echo, A, hosts=A.keys())
结果:
[ubuntu@54.219.171.62] Executing task 'special_echo'
[ubuntu@54.219.171.62] run: echo first `hostname --ip-address`
[ubuntu@54.219.171.62] out: first 172.31.1.234
[ubuntu@54.219.171.62] out:
[ubuntu@54.183.255.58] Executing task 'special_echo'
[ubuntu@54.183.255.58] run: echo third `hostname --ip-address`
[ubuntu@54.183.255.58] out: third 172.31.15.36
[ubuntu@54.183.255.58] out:
[ubuntu@52.53.149.140] Executing task 'special_echo'
[ubuntu@52.53.149.140] run: echo second `hostname --ip-address`
[ubuntu@52.53.149.140] out: second 172.31.8.138
[ubuntu@52.53.149.140] out: