我可以使用 ansible 将简单的文本文件上传到 Jrog 工件。但是,当我尝试上传不同类型的文件时,相同的代码会失败。
以下是文件类型。
[root@mylocalhost tmp]# file file1.txt
file1.txt: ASCII text, with CRLF line terminators
[root@mylocalhost tmp]# file toolkit_2
toolkit_2: ASCII text, with very long lines
[root@mylocalhost tmp]# file /tmp/zip/25.zip
/tmp/zip/25.zip: Zip archive data, at least v2.0 to extract
[root@mylocalhost tmp]# file /tmp/zip/25.tar.gz
/tmp/zip/25.tar.gz: gzip compressed data, from Unix, last modified: Fri Feb 9 03:16:32 2024
Ansible 剧本:
- name: List file on Runner Host
raw: "chmod 777 /tmp/{{ build_number | trim }}.zip && chmod 777 /tmp/{{ build_number | trim }}.tar.gz && chmod 777 /tmp/toolkit_2 && chmod 777 /tmp/file1.txt && ls -ltr /tmp/{{ build_number | trim }}.zip && ls -ltr /tmp/{{ build_number | trim }}.tar.gz && ls -ltr /tmp/toolkit_2 && ls -ltr /tmp/file1.txt"
register: runnerfiles
delegate_to: localhost
- debug:
msg: "{{ runnerfiles }}"
- name: Upload All to Artifactory
uri:
url: "{{ jfrog_artifact_url }}{{ item | trim | basename }}"
method: PUT
user: "{{ JFrogUser }}"
password: "{{ JFrogUserPassword | replace('~', '=') }}"
body: "{{ lookup('file', item ) }}"
status_code: 201 # Adjust based on the expected status code
timeout: 900
return_content: yes
body_format: "raw"
loop:
- "/tmp/file1.txt"
- "/tmp/{{ build_number | trim }}.zip"
- "/tmp/{{ build_number | trim }}.tar.gz"
输出:
TASK [wifideploy : List file on Runner Host] ***********************************
changed: [remhost -> localhost]
TASK [wifideploy : debug] ******************************************************
ok: [localhost] => {
"msg": {
"changed": true,
"failed": false,
"rc": 0,
"stderr": "",
"stderr_lines": [],
"stdout": "-rwxrwxrwx 1 root root 21230 Feb 9 11:48 /tmp/25.zip\\n-rwxrwxrwx 1 root root 18958 Feb 9 11:48 /tmp/25.tar.gz\\n-rwxrwxrwx 1 root root 55872 Feb 9 11:48 /tmp/toolkit_2\\n-rwxrwxrwx 1 root root 11 Feb 9 11:48 /tmp/file1.txt\\n",
"stdout_lines": [
"-rwxrwxrwx 1 root root 21230 Feb 9 11:48 /tmp/25.zip",
"-rwxrwxrwx 1 root root 18958 Feb 9 11:48 /tmp/25.tar.gz",
"-rwxrwxrwx 1 root root 55872 Feb 9 11:48 /tmp/toolkit_2",
"-rwxrwxrwx 1 root root 11 Feb 9 11:48 /tmp/file1.txt"
]
}
}
ok: [remhost -> localhost] => (item=/tmp/file1.txt)
An exception occurred during task execution. To see the full traceback, use -vvv. The error was: UnicodeEncodeError: 'utf-8' codec can't encode character '\udcf3' in position 10: surrogates not allowed
failed: [remhost -> localhost] (item=/tmp/25.zip) => {"ansible_loop_var": "item", "changed": false, "item": "/tmp/25.zip", "module_stderr": "Traceback (most recent call last):\n File \"/root/.ansible/tmp/ansible-tmp-1707473267.4003098-161-46575362453121/AnsiballZ_uri.py\", line 107, in <module>\n _ansiballz_main()\n File \"/root/.ansible/tmp/ansible-tmp-1707473267.4003098-161-46575362453121/AnsiballZ_uri.py\", line 99, in _ansiballz_main\n invoke_module(zipped_mod, temp_path, ANSIBALLZ_PARAMS)\n File \"/root/.ansible/tmp/ansible-tmp-1707473267.4003098-161-46575362453121/AnsiballZ_uri.py\", line 47, in invoke_module\n runpy.run_module(mod_name='ansible.modules.uri', init_globals=dict(_module_fqn='ansible.modules.uri', _modlib_path=modlib_path),\n File \"/usr/lib64/python3.8/r…
An exception occurred during task execution. To see the full traceback, use -vvv. The error was: UnicodeEncodeError: 'utf-8' codec can't encode character '\udc8b' in position 1: surrogates not allowed
failed: [remhost -> localhost] (item=/tmp/25.tar.gz) => {"ansible_loop_var": "item", "changed": false, "item": "/tmp/25.tar.gz", "module_stderr": "Traceback (most recent call last):\n File \"/root/.ansible/tmp/ansible-tmp-1707473267.6308842-161-37207543543750/AnsiballZ_uri.py\", line 107, in <module>\n _ansiballz_main()\n File \"/root/.ansible/tmp/ansible-tmp-1707473267.6308842-161-37207543543750/AnsiballZ_uri.py\", line 99, in _ansiballz_main\n invoke_module(zipped_mod, temp_path, ANSIBALLZ_PARAMS)\n File \"/root/.ansible/tmp/ansible-tmp-1707473267.6308842-161-37207543543750/AnsiballZ_uri.py\", line 47, in invoke_module\n runpy.run_module(mod_name='ansible.modules.uri', init_globals=dict(_module_fqn='ansible.modules.uri', _modlib_path=modlib_path),\n File \"/usr/lib64/python…
[WARNING]: Module did not set no_log for password
从输出中可以看到
/tmp/file1.txt
已成功上传。
我也尝试使用
src
属性而不是 body
上传,但这也给我带来了错误。
- name: Upload All to Artifactory
uri:
url: "{{ jfrog_artifact_url }}{{ item | basename }}"
method: PUT
user: "{{ JFrogUser }}"
password: "{{ JFrogUserPassword | replace('~', '=') }}"
src: "{{ item }}"
remote_src: true
status_code: 201 # Adjust based on the expected status code
timeout: 900
return_content: yes
loop:
- "/tmp/{{ build_number | trim }}.zip"
- "/tmp/{{ build_number | trim }}.tar.gz"
输出:
TASK [wifideploy : Upload toolkit_2 to Artifactory] ***
An exception occurred during task execution. To see the full traceback, use -vvv. The error was: TypeError: can't concat str to bytes
fatal: [remhost -> localhost]: FAILED! => {"changed": false, "content": "", "elapsed": 0, "msg": "Status code was -1 and not [201]: An unknown error occurred: can't concat str to bytes", "redirected": false, "status": -1, "url": "https://jfrog.mybank.com/artifactory/raw/mybank/144/toolkit_2"}
Ansible 的
body
模块句柄的 uri
参数需要一个字符串,但是当上传像 .zip
或
.tar.gz
这样的二进制文件时,您实际上是在尝试将二进制数据加载到字符串中,这会导致错误消息中显示的编码问题。对于二进制文件,必须确保数据不被解释或修改,这就是
src
参数的用武之地。但是,
uri
模块并不直接支持使用
src
参数上传二进制文件,就像您在其他模块中可能找到的那样(例如,
copy
)。
作为解决方法,使用 command
shell
模块来执行 curl
命令,该命令能够有效处理二进制数据上传。
- name: Upload Binary File to Artifactory using curl
command: >
curl -u "{{ JFrogUser }}:{{ JFrogUserPassword | replace('~', '=') }}"
-X PUT "{{ jfrog_artifact_url }}{{ item | basename }}"
-T "{{ item }}"
--fail
--silent
--show-error
loop:
- "/tmp/{{ build_number | trim }}.zip"
- "/tmp/{{ build_number | trim }}.tar.gz"
register: curl_upload_result
delegate_to: localhost
ignore_errors: yes
- debug:
var: curl_upload_result
使用 curl
执行文件上传,利用其处理二进制数据的能力,而不会遇到
uri
模块遇到的编码问题。
--fail
、
--silent
和
--show-error
标志用于控制
curl
的输出和错误处理,从而更容易在 Ansible 中进行管理。