【发布时间】:2022-10-25 19:01:54
【问题描述】:
我有一个 Ansible 剧本,可以在我的角色中调用许多“函数”,每个函数根据过去的命令行/剧本选项运行不同的任务,其中两个由不同的调用组成,以获取有关单个 MQ 通道或多个通道的信息。
如果需要单个通道详细信息,则调用子函数
功能1
- include: subFunction1 CHANNEL_NAME={{CHANNELNAME}}..... where CHANNELNAME is a past value
多个通道调用相同的子函数:
功能2
- 'command to get a List Of Channels'
register: CHANNEL_LIST
- include: subfunction1 CHANNEL_NAME={{item}}
with_items: "{{CHANNEL_LIST.stdout_lines}}"
然后子函数继续获取有关通道的信息,在每个通道上使用 MQ 命令并输出状态和信息,包括所有通道是否处于以下状态之一,已停止、运行或混合(非活动,开始,停止),这些细节从任务注册值 stdout_lines 添加到嵌套变量中:
CHSstatus:
- CHANNEL: "[CHANNEL_NAME]"
STATUS: "[STATUS]"
如果找不到通道状态,则通道未定义或通道已定义但没有状态(一个 MQ 功能,其中通道的状态可以是多个之一,但如果它实际上是 INACTIVE 则不返回任何信息),在定义了 Channel 但没有状态 (INACTIVE) 的情况下,会创建一个虚拟嵌套变量:
CHSstatus:
- CHANNEL: "{{CHANNEL_NAME}}"
STATUS: "Unknown STATUS"
这两个函数都可以工作到这一点,但是当尝试将此虚拟值用于 Function2 时
我收到此嵌套变量的以下错误:
错误!意外异常:不可散列类型:'dict'
我能看到的唯一区别是对于 Function1,过去的 CHANNEL_NAME 是 AnsibleUnicode 类型,但是对于 Function2,过去的每个“项目”值都是 AnsibleUnsafeText 类型
有人对如何解决这个问题有任何建议吗?
感谢大家
调查进一步表明,错误发生在任务的后期,而不是它报告的行。 似乎这个问题已被标记为没有帮助或不清楚,并且没有进行任何研究。情况并非如此,因为我已经在这几天了,但是我似乎确实取得了一些进展
为了更清楚一点,我得到的基本上是两种运行代码的方法,方法或 Function1 如上所述
函数1.yml
include: subFunction1.yml CHANNEL_NAME={{CHANNELNAME}}
函数2.yml
# MQ command to get a list of Defined channels
shell: # runmqsc command on QMGR for CHANNEL_NAME
register: CHANNEL_LIST
include: subfunction1.yml CHANNEL_NAME={{item}}
with_items: "{{CHANNEL_LIST.stdout_lines}}
包含文件相当长,但基本上执行以下操作
子功能1 .yml
# check if the CHANNEL_NAME exists
# reports if channel does not exist
# get the status of the channel if it does
# parses the result of the status to a variable
CHLstatus: "{{CHLstatus + [result_dict]}}"
with_items: "{{above.result.stdout_lines}}"
vars:
result_dict: #parsed out from the stdout_lines
# if there is no output from above status call then a dummy variable is created
CHSstatus:
- CHANNEL: "{{CHANNEL_NAME}}"
STATUS: "Unknown STATUS"
至此,我已经输出了结果,可以看到一切正常。 下一步是确定当有多个 Channel 时,有多少 Channel 处于 RUNNING、STOPPED 或 OTHER 状态,从而发生错误。 工作正常时,变量类型是
CHANNEL_NAME = AnsibleUnicode
CHSstatus = list
CHSstatus.STATUS = unicode
CHSstatus.CHANNEL = unicode
失败时我们得到
CHANNEL_NAME = AnsibleUnsafeText
CHSstatus = list
CHSstatus.STATUS = unicode
CHSstatus.CHANNEL = unicode
所以看起来 DUMMY CHSstatus 的创建确实是问题所在 我什至硬编码了 CHANNEL_NAME 的值,但仍然没有解决它
正确值
CHSstatus = [{'STATUS': u'RUNNING', 'CHANNEL': u'TO_LOCAL'}]"
破碎值
CHSstatus = [{u'STATUS': u'Unknown STATUS', u'CHANNEL': u'DUMMY NOT DEFINED'}]
损坏的位中有一个额外的“u”,但我不知道如何摆脱它
【问题讨论】:
-
这是很多话,很少代码;请阅读MCVE 并考虑“最小”部分。它可以帮助您在制作本地可重现的案例时进行自我调试,并帮助为您提供免费咨询的人不必在午餐时阅读战争与和平。祝你好运
-
我可以理解您所说的代码很少,但由于实际代码分为几个任务文件,总共 6 个,我试图只提供相关的 sn-ps。基本上,错误仅在这些文件中的一个中,这些文件为过去包含的文件的每个 MQ 通道调用,我遇到的问题是,当我将 CHANNEL_NAME 作为字符串传递时它工作正常,但是当我通过通道列表时使用对 MQ 命令的调用的输出,注册的 stdout_lines 中的值不是字符串
-
对同一个 subfunction1 有两个不同的调用包括: subfunction1 CHANNEL_NAME="CHANNEL_A" 和 include: subfunction1 CHANNEL_NAME="{{item}}" with_items: "{{ListOfChennels.stdout_lines}}" 有没有办法确保没有传递列表项并将其转换为字符串?我认为第一个作为字符串“CHANNEL_A”传递,而列表作为“CHANNEL_n”元素的“字典”传递。希望能更好地解释我将不得不重写我拥有的代码,因为这是我无法真正分享的生产代码