Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/opencv/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ansible 从主机中从“--limit”选项中获取数据_Ansible - Fatal编程技术网

Ansible 从主机中从“--limit”选项中获取数据

Ansible 从主机中从“--limit”选项中获取数据,ansible,Ansible,我有以下剧本(playbook.yaml) -hosts:myfirsthost[0] 任务: -姓名:获取令牌 啜食: src:/var/mytoken 寄存器:令牌文件 -主持人:myotherhosts 变量: fileToken:{{hostvars[groups['myfirsthost'][0]['tokenFile']['content']| b64解码|替换('\n','')} 任务: -调试: msg:token{{fileToken} 当我为所有主机运行它时,它工作正常 但

我有以下剧本(
playbook.yaml

-hosts:myfirsthost[0]
任务:
-姓名:获取令牌
啜食:
src:/var/mytoken
寄存器:令牌文件
-主持人:myotherhosts
变量:
fileToken:{{hostvars[groups['myfirsthost'][0]['tokenFile']['content']| b64解码|替换('\n','')}
任务:
-调试:
msg:token{{fileToken}
当我为所有主机运行它时,它工作正常

但是当我对组
myotherhosts
中包含的单个主机运行它时(不在组
myfirsthosts

它不执行第一个任务,那么变量就无法初始化,这是意料之中的

您知道我如何强制所有主机执行“获取令牌”任务吗,即使它们不在
myfirsthost

谢谢你解决了这个问题 在
ansible playbook
命令中使用
--limit
时,不能在超出此限制的主机上播放任何任务。这包括收集事实(即自动或显式播放
设置
模块)和
设置事实
(即为主机手动创建/更新事实)。使用ansible默认设置(内存事实缓存),您将无法在playbook中查询这些主机上的任何
主机名
,因为该目录中没有它们的
目录\u主机名

拯救真相 解决方案是在
ansible.cfg
中启用非临时事实缓存。默认缓存进入内存,并在剧本末尾消失

启用缓存 首先,您可以使用
ansible.cfg
中的以下设置启用缓存并将其存储在磁盘上的json文件中:

[defaults]
fact_caching = jsonfile
fact_caching_connection = /path/to/cache/folder
有关此功能和所有可能的缓存后端的详细信息,请查看中相关参数的注释,并检查

填充缓存 一旦有了非临时缓存,就可以为所有相关主机收集事实并
set\u fact
。如果您只需要从主机查询事实,则可以通过一个特别命令轻松完成此操作:

ansible -i your/inventory my_hosts -m setup
在您的例子中,它有点复杂,因为您希望将任务的结果推送到缓存中。您需要创建第一个剧本,在以后需要使用的所有主机上运行。我将其称为
init\u facts\u和\u tokens.yml

---
-名称:收集主机事实并初始化令牌
主持人:我的主持人
#您可以将下面的行取消注释为显式,但默认情况下此选项处于启用状态
#收集事实:真实
任务:
-名称:Slurp令牌文件令牌
啜食:
src:/var/mytoken
寄存器:令牌文件
-名称:在事实缓存中注册令牌
设定事实:
令牌:{{token_file.content | b64decode | replace('\n','')}
您可以在所有主机上使用

ansible-playbook -i your/inventory init_facts_and_tokens.yml
使用缓存 现在缓存已填充,您可以播放另一个playbook(有无限制),并为超出播放/限制的主机调用
hostvars
。如果他们的事实已被正确缓存,您将获得在上次事实收集或
set\u fact

在这种情况下,您可能可以禁用所有剧本上的事实收集,以节省最终剧本上的一些执行时间。如果出于任何原因(例如更改网络接口、添加lvm卷……)需要在播放过程中刷新事实,您只需运行。对于未从主机查询的任何其他事实,对给定变量使用
set\u fact
将创建/刷新其值

---
-名称:使用缓存事实执行作业
主持人:我的主持人
收集事实:错误
变量:
#我们将使用组中第一台服务器的toker,
#即使超出限制
此_play_令牌:{{hostvars[groups['my_hosts'][0]].token}”
任务:
-名称:Show token
调试:
msg:“这个游戏的令牌是{{this_play_token}}”
#举例说明上述解释
-名称:此任务可以使用缓存
调试:
msg:“somehost.com的操作系统是:{hostvars['somehost.com'].ansible_OS_family}”
-名称:此任务将更改目标,可能会废弃收集的事实
调试:
msg:“警告我可能会更改系统事实!”
-名称:刷新事实缓存
设置:
-名称:恢复正常活动
调试:
msg:“我使用从缓存中收集的最新事实”
-名称:这将刷新当前主机的缓存令牌
设定事实:
令牌:“不太有效的令牌”
您现在可以启动第二个剧本,有限制或没有限制。即使在游戏之外,它仍然能够读取任何主机的事实(查询或用户设置)

# run on all hosts
ansible-playbook -i your/inventory final_playbook.yml

# run only on third host of my_hosts group
ansible-playbook -i your/inventory --limit my_host[2] final_playbook.yml

SingleHost是文件名还是主机名?SingleHost是主机名不是应该是
-i“host”
那么?正如@Marged所指出的,您需要为
-i
指定一个文件或列表。您可以使用类似于
ansile inventory--list-i'thesinglehost'
的方法来检查如何解释这一点,并与
ansible inventory--list-i thesinglehost
进行比较。如果您在问题中犯了错误,请继续并修复它。如果你在问题中没有明确说明,人们就不会知道你想要什么。
# run on all hosts
ansible-playbook -i your/inventory final_playbook.yml

# run only on third host of my_hosts group
ansible-playbook -i your/inventory --limit my_host[2] final_playbook.yml