Ansible: print list of files that will be copied

Viewed 124

I have a playbook that copy files from different local folders to different remote paths and it works, configured to overwrite the files with backup (with copy module). How to get the list of files that will be copied and overwrite before doing it? I'd like to prevent to copy wrong files.

Example of the copy:

name: Copy all
copy:
  src: scenarios/all_machines/
  dest: /path/to/dest
  backup: yes
  force: yes
  owner: root
  group: root
  mode: 0644
when: ansible_facts.services['crowdsec.service'] is defined

UPDATE

With this local folder:

scenarios/all_machines/
├── wg-sshd-more-logs.yaml
└── wg-x00.yaml

and this remote dir:

test_ansible/
└── wg-x00.yaml

where the wg-x00.yaml file has the same content.

With this playbook (where I changed the '>' char with '<'):

- name: TEST
    synchronize:
      src: scenarios/all_machines/
      dest: test_ansible/
      rsync_opts:
        - --dry-run
    register: result

  - debug:
        var: result.stdout_lines

  - name: TEST 2
    set_fact:
      overwrite: "{{ file_stat|
                     selectattr('stat', 'match', '<f.*')|
                     selectattr('stat', 'ne', '<f+++++++++')|
                     map(attribute='file')|
                     list }}"
    vars:
      file_stat: "{{ result.stdout_lines|
                     map('regex_replace', regex, replace)|
                     map('from_yaml')|
                     list }}"
      regex: '^(.*?) (.*)$'
      replace: '{file: "\2", stat: "\1"}'

  - debug:
      var: overwrite

I have this output:

"result.stdout_lines": [
        ".d..tp..... ./", 
        "<f+++++++++ wg-sshd-more-logs.yaml", 
        "<f..tp..... wg-x00.yaml"
    ]



"overwrite": [
        "wg-x00.yaml"
    ]

So:

  • I changed the the '>' char with '<' because my output is different from your
  • The overwrite variable tells me that the file will be overwritten but they are equal...
1 Answers

Given the directories below for testing

shell> tree scenarios/all_machines/
scenarios/all_machines/
├── file1
├── file2
└── file3

0 directories, 3 files
shell> tree dest/
dest/
└── file1

0 directories, 1 file

the file file1 at dest/ will be replaced. The question is how to find it.

Use synchronize and set 'rsync_opts: --dry-run'

    - synchronize:
        src: scenarios/all_machines/
        dest: dest
        rsync_opts:
          - --dry-run
      register: result

The result will display the status of the files

  result.stdout_lines:
    - .d..t...... ./
    - '>f..t...... file1'
    - '>f+++++++++ file2'
    - '>f+++++++++ file3'

The task below

    - set_fact:
        overwrite: "{{ file_stat|
                       selectattr('stat', 'match', '>f.*')|
                       selectattr('stat', 'ne', '>f+++++++++')|
                       map(attribute='file')|
                       list }}"
      vars:
        file_stat: "{{ result.stdout_lines|
                       map('regex_replace', regex, replace)|
                       map('from_yaml')|
                       list }}"
        regex: '^(.*?) (.*)$'
        replace: '{file: "\2", stat: "\1"}'

will create the list

  file_stat:
    - {file: ./, stat: .d..t......}
    - {file: file1, stat: '>f..t......'}
    - {file: file2, stat: '>f+++++++++'}
    - {file: file3, stat: '>f+++++++++'}

and will select names of the existing files only

  overwrite:
    - file1

See Understanding the output of rsync --itemize-changes.


Notes

    - debug:
        var: file_stat|to_yaml
    - debug:
        var: overwrite|to_nice_yaml
Related