You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Ansible uri模块检查Jenkins重启后页面状态时遭遇ImportError: cannot import name 'prepare_multipart'问题的排查求助

Ansible uri模块出现ImportError: cannot import name 'prepare_multipart'的排查与解决

我在使用Ansible的uri模块检查Jenkins重启后的页面状态时,遇到了这个导入错误,模块代码和错误输出如下:

模块代码

- name: result-test
  uri:
    url: "http://{{ jenkins_cm_hostname }}:{{ jenkins_http_port }}{{ jenkins_url_prefix }}"
    method: GET
    return_content: "yes"
    timeout: 5
    body_format: raw
    follow_redirects: "no"
    status_code: 200,403
  register: result

错误输出

{
  "module_stdout": "/etc/bashrc: line 94: TMOUT: readonly variable\r\nTraceback (most recent call last):\r\n File \"/home/ec2-user/.ansible/tmp/ansible-tmp-1628318438.5060062-180720-115929401717244/AnsiballZ_uri.py\", line 100, in <module>\r\n _ansiballz_main()\r\n File \"/home/ec2-user/.ansible/tmp/ansible-tmp-1628318438.5060062-180720-115929401717244/AnsiballZ_uri.py\", line 92, in _ansiballz_main\r\n invoke_module(zipped_mod, temp_path, ANSIBALLZ_PARAMS)\r\n File \"/home/ec2-user/.ansible/tmp/ansible-tmp-1628318438.5060062-180720-115929401717244/AnsiballZ_uri.py\", line 41, in invoke_module\r\n run_name='__main__', alter_sys=True)\r\n File \"/usr/lib64/python2.7/runpy.py\", line 176, in run_module\r\n fname, loader, pkg_name)\r\n File \"/usr/lib64/python2.7/runpy.py\", line 82, in _run_module_code\r\n mod_name, mod_fname, mod_loader, pkg_name)\r\n File \"/usr/lib64/python2.7/runpy.py\", line 72, in _run_code\r\n exec code in run_globals\r\n File \"/tmp/ansible_ansible.legacy.uri_payload_bBh_2I/ansible_ansible.legacy.uri_payload.zip/ansible/modules/uri.py\", line 423, in <module>\r\nImportError: cannot import name prepare_multipart\r\n",
  "msg": "MODULE FAILURE\nSee stdout/stderr for the exact error",
  "rc": 1
}

我的环境情况:Ansible控制器仅通过pip安装,目标节点未安装Ansible,所有节点由Terraform部署。之前看到有博客说这个问题是多版本Ansible共存导致,但我的情况不符合,求排查方向。


排查与解决思路

别着急,这个问题虽然看起来是模块导入错误,但核心大概率和目标节点的Python环境(尤其是requests库版本)与Ansible uri模块不兼容有关——毕竟Ansible的uri模块依赖requests库,而且会把模块代码推到目标节点执行,哪怕目标节点没装Ansible,也会用到目标节点本地的Python环境和依赖库。

下面给你一步步的排查和解决步骤:

1. 检查目标节点的Python版本和requests库版本

先登录到出问题的目标节点,执行以下命令确认环境:

# 查看默认Python版本
python --version
# 查看已安装的requests版本
pip show requests

从错误日志能看到目标节点用的是Python2.7,而prepare_multipart是requests库特定版本才有的方法,旧版本或过新版本都可能出现导入失败的情况(Python2.7本身已经停止维护,对应的requests兼容版本非常有限)。

2. 安装目标节点兼容的requests版本

如果目标节点的requests版本不符合要求,可以卸载现有版本,安装Python2.7支持的最后几个兼容版本之一,比如2.27.1:

# 卸载现有requests
pip uninstall -y requests
# 安装指定兼容版本
pip install requests==2.27.1

安装完成后重新运行Ansible playbook,看看问题是否解决。

3. 指定playbook使用Python3解释器

如果目标节点同时安装了Python3,可以在playbook中明确指定使用Python3执行模块,避开Python2.7的兼容性问题:

- name: result-test
  uri:
    url: "http://{{ jenkins_cm_hostname }}:{{ jenkins_http_port }}{{ jenkins_url_prefix }}"
    method: GET
    return_content: "yes"
    timeout: 5
    body_format: raw
    follow_redirects: "no"
    status_code: 200,403
  register: result
  vars:
    ansible_python_interpreter: /usr/bin/python3

Python3的requests库兼容性更好,大概率能解决这个导入错误。

4. 排除bash配置的干扰

错误日志里还提到了/etc/bashrc: line 94: TMOUT: readonly variable,虽然看起来和导入错误无关,但有可能是bash配置导致环境变量异常,影响了Python的库路径。可以临时注释掉目标节点/etc/bashrc中设置TMOUT的行,重新连接节点后再测试,排除这个干扰因素。

5. 确认控制器的requests版本(可选)

虽然核心问题在目标节点,但也可以检查控制器上的requests版本是否和目标节点差异过大——如果差异太大,可能会导致模块打包时引入不兼容代码。在控制器上执行pip show requests查看版本,必要时调整为和目标节点一致的兼容版本。


总结

这个问题和控制器是否多版本安装Ansible关系不大,核心是目标节点的Python2.7环境与requests库版本不兼容。按照上面的步骤一步步排查,应该能解决问题。

内容的提问来源于stack exchange,提问作者JPNagarajan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.29 15:22:32