Ansible win_package模块执行报错:find()仅接受2个参数(传入3个)
我来帮你搞定这个问题——这个TypeError: find() takes exactly 2 arguments (3 given)错误在使用win_package模块时挺常见的,主要和版本兼容性或者参数格式有关,下面给你详细分析和解决步骤:
你的问题回顾
你在运行安装JDK的Ansible剧本时遇到了执行失败:
fatal: [smuc8562]: FAILED! => {"failed": true, "msg": "Unexpected failure during module execution.", "stdout": ""}
加上-vvv调试后看到核心错误是TypeError,对应的剧本片段是:
- name: Install JDK - {{ jdk_exe }} win_package: path: '{{ jdk_exe }}' arguments: /s ADDLOCAL="ToolsFeature,SourceFeature" product_id: "{{ jdk_product_id }}"
问题根源
这个错误本质是旧版本Ansible的win_package模块存在内部函数调用bug——模块里的find()函数被错误地传入了3个参数,但它只接受2个。另外,也有可能是product_id的格式不符合模块预期,导致字符串处理时触发了这个bug。
具体解决方案
1. 优先升级Ansible到稳定版本
这个bug在Ansible 2.8及以后的版本已经被官方修复了,升级到最新稳定版是最直接的解决办法:
# 用pip升级Ansible(如果是pip安装的) pip install --upgrade ansible
如果是用系统包管理器(比如Ubuntu的apt、CentOS的yum)安装的,记得切换到官方维护的软件源来更新到稳定版。
2. 检查并修正product_id参数
确保你的jdk_product_id变量是JDK安装包对应的正确产品GUID:
- Oracle JDK的产品ID通常带大括号,比如JDK 8u202的ID是
'{26A24AE4-039D-4CA4-87B4-2F32180201F0}' - OpenJDK的产品ID格式会有差异,需要对应确认
如果不知道正确的product_id,可以手动运行安装包生成日志来查看:
msiexec /i "你的JDK安装包路径.exe" /qn /l*v install.log
然后在install.log里搜索ProductCode字段,就能找到对应的ID。
3. 调整arguments的格式
有时候参数的引号转义也会触发模块的异常,试试把arguments改成更规范的写法:
# 去掉内部的引号,或者用单引号包裹整个参数 arguments: '/s ADDLOCAL=ToolsFeature,SourceFeature'
或者用YAML的折叠写法来避免转义问题:
arguments: >- /s ADDLOCAL="ToolsFeature,SourceFeature"
验证方法
升级或调整参数后,重新运行剧本并加上调试参数确认:
ansible-playbook -i 你的清单文件.yml 你的剧本文件.yml -vvv
如果还是有问题,可以尝试临时去掉product_id参数(单次安装时模块可以自动识别,但不推荐长期这么做,不利于后续的包管理)。
内容的提问来源于stack exchange,提问作者MTh

