如何在fabfile中确定fabric角色以发送特定文件到主机

2 投票
2 回答
1496 浏览
提问于 2025-04-17 13:23

我有一个环境,大概是这样的:

env.roledefs = {
    'cisco-collectors': ['hosta', 'hostb', 'hostc'],
    'brocade-collectors': ['hosta', 'hostd']
}

我有一些特定的文件需要发送给特定角色的主机:

files = {
    'cisco-collectors': ['/path/to/filea', '/path/to/fileb'],
    'brocade-collectors': ['/path/to/filec', '/path/to/filed']
}

我该如何写我的sendFiles()函数,这样当在命令行上指定角色,或者使用@roles()装饰器时,我就能获取到正确的文件列表呢?

这个问题展示了一种判断主机是否属于某个角色的方法,但我需要获取当前正在执行的角色,这样我才能知道该发送哪个文件列表。

理想情况下,它应该是这样的:

@roles('cisco-collectors', 'brocade-collectors')    
def sendFiles():
  for file in files[env.current_role]:
    put(file)

2 个回答

0

在我的测试中,我觉得在1.5版本里,你不能可靠地获取当前的角色。可以看看Pavel的回答,里面提到这个情况会有所改变。虽然这听起来有点麻烦,但我认为原因是Fabric把主机的列表合并在一起,所以角色信息并不会被保留。

不过,如果你不需要使用角色功能的话,有一个变通的方法。你可以创建一个任务来修改主机列表。不过要注意,这个方法适用于一个角色!

from fabric.api import task, local, env

@task
def role1():
    env.current_role = 'role1'
    env.hosts.extend(['example.com'])

@task
def role2():
    env.current_role = 'role2'
    env.hosts.extend(['test.example.com'])

@task
def test():
    print env.current_role
    print env.hosts

如果你现在运行 fab role1 test,你会看到:

[localhost] Executing task 'test'
role1
['localhost', 'example.com']
[example.com] Executing task 'test'
role1
['localhost', 'example.com']

这可能不是你想要的结果……但可能会帮助你找到可行的方法。

1

env.host_string.role 这个东西在最新的 fabric 源代码中(还没发布)包含了当前的角色信息。

这是相关的提交记录

撰写回答