无法使用ansible uri模块上传特定文件

问题描述 投票:0回答:1

我可以使用 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"}
file-upload ansible runtime-error uri artifactory
1个回答
0
投票

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 中进行管理。

© www.soinside.com 2019 - 2024. All rights reserved.