使用Ansible uri模块无法上传非文本文件至JFrog Artifactory
解决Ansible上传二进制文件到JFrog Artifactory失败的问题
问题根源
- 文本类文件(ASCII格式)可正常上传,但zip、tar.gz等二进制文件上传失败
- 两种尝试的报错原因:
- 使用
body: "{{ lookup('file', item) }}"时,lookup('file')默认以文本模式读取二进制文件,触发Unicode编码错误 - 使用
src属性时错误设置remote_src: true(该参数用于指定文件在远程主机而非控制节点),导致字符串与字节拼接报错
- 使用
正确实现方案
方案一:兼容文本与二进制的通用上传写法
通过wantlist=True让lookup以二进制模式读取文件,配合body_format: raw确保请求正确传输:
- name: 上传所有文件到Artifactory uri: url: "{{ jfrog_artifact_url }}{{ item | trim | basename }}" method: PUT user: "{{ JFrogUser }}" password: "{{ JFrogUserPassword | replace('~', '=') }}" body: "{{ lookup('file', item, wantlist=True) | first }}" status_code: 201 timeout: 900 return_content: yes body_format: "raw" loop: - "/tmp/file1.txt" - "/tmp/{{ build_number | trim }}.zip" - "/tmp/{{ build_number | trim }}.tar.gz"
说明:
wantlist=True使lookup返回二进制数据列表,| first提取实际文件内容,body_format: raw确保以原始字节形式发送请求
方案二:针对二进制文件的简洁写法
去掉remote_src: true(文件在控制节点本地),添加body_format: raw保证二进制传输格式:
- name: 上传二进制文件到Artifactory uri: url: "{{ jfrog_artifact_url }}{{ item | basename }}" method: PUT user: "{{ JFrogUser }}" password: "{{ JFrogUserPassword | replace('~', '=') }}" src: "{{ item }}" status_code: 201 timeout: 900 return_content: yes body_format: "raw" loop: - "/tmp/{{ build_number | trim }}.zip" - "/tmp/{{ build_number | trim }}.tar.gz"
说明:
src默认读取控制节点本地文件,body_format: raw避免二进制文件被错误编码
前置验证步骤
执行Playbook前可先确认文件路径与权限:
ls -l /tmp/{{ build_number | trim }}.zip /tmp/{{ build_number | trim }}.tar.gz
内容的提问来源于stack exchange,提问作者Ashar
相关产品推荐
相关产品推荐

