Copy local file if exists, using ansible

2019-03-23 10:49发布

问题:

I'm working in a project, and we use ansible to create a deploy a cluster of servers. One of the tasks that I've to implement, is to copy a local file to the remote host, only if that file exists locally. Now I'm trying to solve this problem using this

- hosts: 127.0.0.1 
  connection: local
  tasks:
    - name: copy local filetocopy.zip to remote if exists
    - shell: if [[ -f "../filetocopy.zip" ]]; then /bin/true; else /bin/false; fi;
      register: result    
    - copy: src=../filetocopy.zip dest=/tmp/filetocopy.zip
      when: result|success

Bu this is failing with the following message: ERROR: 'action' or 'local_action' attribute missing in task "copy local filetocopy.zip to remote if exists"

I've tried to create this if with command task. I've already tried to create this task with a local_action, but I couldn't make it work. All samples that I've found, doesn't consider a shell into local_action, there are only samples of command, and neither of them have anything else then a command. Is there a way to do this task using ansible?

回答1:

Change your first step into the following on

- name: copy local filetocopy.zip to remote if exists
  local_action: stat path="../filetocopy.zip"
  register: result    


回答2:

A more comprehensive answer:

If you want to check the existence of a local file before performing some task, here is the comprehensive snippet:

- name: get file stat to be able to perform a check in the following task
  local_action: stat path=/path/to/file
  register: file

- name: copy file if it exists
  copy: src=/path/to/file dest=/destination/path
  when: file.stat.exists

If you want to check the existence of a remote file before performing some task, this is the way to go:

- name: get file stat to be able to perform check in the following task
  stat: path=/path/to/file
  register: file

- name: copy file if it exists
  copy: src=/path/to/file dest=/destination/path
  when: file.stat.exists


回答3:

If you don't wont to set up two tasks, you could use is_file to check if local files exists:

tasks:
- copy: src=/a/b/filetocopy.zip dest=/tmp/filetocopy.zip
  when: '/a/b/filetocopy.zip' | is_file

The path is relative to the playbook directory, so using the magic variable role_path is recommended if you are referring to files inside the role directory.

Ref: http://docs.ansible.com/ansible/latest/playbooks_tests.html#testing-paths



回答4:

Fileglob permits a lookup of an eventually present file.

- name: copy file if it exists
  copy: src="{{ item }}" dest=/destination/path
  with_fileglob: "/path/to/file"


回答5:

How about this?

tasks:
- copy: src=../filetocopy.zip dest=/tmp/filetocopy.zip
  failed_when: false

This will copy the file to the target if it exists locally. If it does not exists, it simply does nothing since the error is ignored.