问题描述

在Ansible中,使用get_url模块下载文件时,可能会遇到“目标路径不存在”的错误。这通常是因为指定的本地路径(dest参数)无效或不存在。本文将介绍如何复现该错误、进行故障排除,并修复问题,以成功在目标主机的指定路径中下载文件。

错误复现

以下是一个Ansible playbook示例,用于复现“目标路径不存在”错误:

文件:destinationdoesnotexist_error.yml

---
- name: get_url 模块演示
  hosts: all
  become: false
  vars:
    myurl: "https://releases.ansible.com/ansible/ansible-2.9.25.tar.gz"  # 文件URL
    mycrc: "sha256:https://releases.ansible.com/ansible/ansible-2.9.25.tar.gz.sha"  # 校验和URL
    mydest: "ansible-2.9.25.tar.gz"  # 目标路径
  tasks:
    - name: 下载文件
      ansible.builtin.get_url:
        url: "{{ myurl }}"
        dest: "{{ mydest }}"
        checksum: "{{ mycrc }}"
        mode: '0644'

错误执行

运行playbook时,可能会出现以下错误:

$ ansible-playbook -i inventory destinationdoesnotexist_error.yml

PLAY [get_url 模块演示] ******************************************

TASK [Gathering Facts] ******************************************
ok: [demo.example.com]

TASK [下载文件] *************************************************
fatal: [demo.example.com]: FAILED! => {"changed": false, "checksum_dest": null, "checksum_src": "574e24659f555fe370571167d3d44704671f1773", "dest": "ansible-2.9.25.tar.gz", "elapsed": 3, "msg": "目标路径不存在", "src": "/home/devops/.ansible/tmp/ansible-tmp-1640555219.326019-1431-267536126421544/tmpmx_ra0hd", "url": "https://releases.ansible.com/ansible/ansible-2.9.25.tar.gz"}

PLAY RECAP *******************************************************
demo.example.com           : ok=1    changed=0    unreachable=0    failed=1    skipped=0    rescued=0    ignored=0

错误原因

  1. 目标路径无效:dest参数指定的路径无效或不存在。
  2. 路径权限问题:目标路径可能没有足够的权限来创建文件。
  3. 路径格式错误:dest参数可能缺少必要的路径分隔符或目录结构。

解决方案

修复playbook中的dest参数,确保目标路径有效且存在。可以通过在路径前添加./来指定当前工作目录,或者使用绝对路径。

文件:destinationdoesnotexist_fix.yml

---
- name: get_url 模块演示
  hosts: all
  become: false
  vars:
    myurl: "https://releases.ansible.com/ansible/ansible-2.9.25.tar.gz"  # 文件URL
    mycrc: "sha256:https://releases.ansible.com/ansible/ansible-2.9.25.tar.gz.sha"  # 校验和URL
    mydest: "ansible-2.9.25.tar.gz"  # 目标文件名
  tasks:
    - name: 下载文件
      ansible.builtin.get_url:
        url: "{{ myurl }}"
        dest: "./{{ mydest }}"  # 指定当前工作目录
        checksum: "{{ mycrc }}"
        mode: '0644'

修复执行

运行修复后的playbook:

$ ansible-playbook -i inventory destinationdoesnotexist_fix.yml

PLAY [get_url 模块演示] ******************************************

TASK [Gathering Facts] ******************************************
ok: [demo.example.com]

TASK [下载文件] *************************************************
changed: [demo.example.com]

PLAY RECAP *******************************************************
demo.example.com           : ok=2    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

验证

通过SSH连接到目标主机,检查文件是否成功下载:

$ ssh devops@demo.example.com
[devops@demo ~]$ ls -al
total 13964
drwx------. 4 devops wheel      140 Dec 26 21:47 .
drwxr-xr-x. 5 root   root        50 Dec 15 13:00 ..
drwx------. 3 devops wheel       17 Dec 15 13:00 .ansible
-rw-------. 1 devops wheel      322 Dec 26 21:46 .bash_history
-rw-r--r--. 1 devops wheel       18 Jul 26 09:51 .bash_logout
-rw-r--r--. 1 devops wheel      141 Jul 26 09:51 .bash_profile
-rw-r--r--. 1 devops wheel      376 Jul 26 09:51 .bashrc
drwx------. 2 devops wheel       29 Dec 15 13:00 .ssh
-rw-r--r--. 1 devops wheel 14280306 Dec 26 21:47 ansible-2.9.25.tar.gz

总结

  1. 确保路径有效:在dest参数中指定的目标路径必须有效,可以使用相对路径(如./)或绝对路径。
  2. 检查权限:确保目标路径具有足够的权限,以便Ansible能够创建文件。
  3. 验证URL和校验和:确保文件URL和校验和URL拼写正确且有效。
  4. 使用debug模块:在playbook中加入debug模块,帮助调试路径和文件信息。

通过以上步骤,您可以快速定位并解决“目标路径不存在”错误,确保Ansible playbook能够成功下载文件。