user855443
user855443

Reputation: 2940

detect file difference (change) with `ansible`

In this task I found a roundabout method to compare two files (dconfDump and dconfDumpLocalCurrent) and to set a variable (previously defined as false) to true if the two files differ.

The solution seem to work, but it looks ugly and, as a beginner with ansible, I have the impression a better solution should be existing.

---
# vars file for dconfLoad
local_changed : false
target_changed : false

---

- name: local changed is true when previous target different then local current  
  shell:  diff /home/frank/dconfDump /home/frank/dconfDumpLocalCurrent
  register: diff_oldtarget_localCurrent
  register: local_changed  
  ignore_errors: true
- debug:
    msg: CHANGED LOCALLY 
  when: local_changed 

Some background to the task, which is an attempt to synchronize files: A file LocalCurrent is compared with LocalOld and CurrentTarget, to determine if the LocalCurrent is changed and if it is different than currentTarget. If LocalCurrent is not changed and CurrentTarget is changed, then apply the change (and set LocalOld to CurrentTarget); if LocalCurrent is changed then upload to controller.

What is the appropriate approach with ansible? Thank you for help!

Upvotes: 1

Views: 2495

Answers (2)

Vladimir Botka
Vladimir Botka

Reputation: 67984

Use stat and create dictionary of checksums. For example

    - stat:
        path: "{{ item }}"
      loop:
        - LocalOld
        - LocalCurrent
        - CurrentTarget
      register: result
    - set_fact:
        my_files: "{{ dict(paths|zip(chkms)) }}"
      vars:
        paths: "{{ result.results|map(attribute='stat.path')|list }}"
        chkms: "{{ result.results|map(attribute='stat.checksum')|list }}"
    - debug:
        var: my_files

gives (abridged) if all files are the same

  my_files:
    CurrentTarget: 7c73e9f589ca1f0a1372aa4cd6944feec459c4a8
    LocalCurrent: 7c73e9f589ca1f0a1372aa4cd6944feec459c4a8
    LocalOld: 7c73e9f589ca1f0a1372aa4cd6944feec459c4a8

Then use the dictionary to compare the checksums and copy files. For example

    # If LocalCurrent is not changed and CurrentTarget is changed,
    # then apply the change (and set LocalOld to CurrentTarget)

    - debug:
        msg: Set LocalOld to CurrentTarget
      when:
        - my_files['LocalCurrent'] == my_files['LocalOld'] 
        - my_files['LocalCurrent'] != my_files['CurrentTarget'] 

    - debug:
        msg: Do not copy anything
      when:
        - my_files['LocalCurrent'] == my_files['LocalOld'] 
        - my_files['LocalCurrent'] == my_files['CurrentTarget']

gives

TASK [debug] ****
skipping: [localhost]

TASK [debug] ****
ok: [localhost] => 
  msg: Do not copy anything

Upvotes: 1

Smily
Smily

Reputation: 2568

You can use stat to get the checksum and then compare it. Please see below.

   tasks:
   - name: Stat of dconfDump
     stat:
      path : "/tmp/dconfDump"
     register: dump

   - name: SHA1 of dconfDump
     set_fact:
      dump_sha1: "{{ dump.stat.checksum }}"

   - name: Stat of dconfDumpLocalCurrent
     stat:
      path : "/tmp/dconfDumpLocalCurrent"
     register: dump_local

   - name: SHA1 of dconfDumpLocalCurrent
     set_fact:
      local_sha1: "{{ dump_local.stat.checksum }}"

   - name: Same
     set_fact:
      val: "False"
     when:  dump_sha1 != local_sha1

   - name: Different
     set_fact:
      val: "True"
     when:  dump_sha1 == local_sha1

   - name: Print
     debug:
      msg: "{{val}}"

Upvotes: 1

Related Questions