簡體   English   中英

Ansible - 尋找文件並比較他們的 hash

[英]Ansible - Looking for files and compare their hash

實踐:

我有文件files.yml和文件列表及其各自的 md5_sum hash,例如:

files:
  - name: /opt/file_compare1.tar
    hash: 9cd599a3523898e6a12e13ec787da50a  /opt/file_compare1.tar
  - name: /opt/file_compare2tar.gz
    hash: d41d8cd98f00b204e9800998ecf8427e  /opt/file_compare2.tar.gz 

如果當前的 hash 相同或已更改,我需要創建一個劇本來檢查此文件列表,那么劇本應該有如下調試消息:

---
- hosts: localhost
  connection: local
  vars_files:
    - files.yml 
  tasks: 
    - name: Use md5 to calculate checksum
      stat:
        path: "{{ item.name }}"
        checksum_algorithm: md5
      register: hash_check
      with_items:
        - "{{ files }}"

    - name: Debug files - Different 
      debug:
        msg: | 
          "Hash changed: {{  item.name  }}"
      when: 
        - item.hash != hash_check 
      with_items:
        - "{{ files }}"

    - name: Debug files - Equal
      debug:
        msg: | 
          "Hash NOT changed: {{  item.name  }}"
      when: 
        - item.hash == hash_check 
      with_items:
        - "{{ files }}"
    
    - debug:
        msg: | 
          -  "{{ hash_check }}  {{ item.name }}"
      with_items:
        - "{{ files }}"

例如,給定文件

    files:
      - name: /scratch/file_compare1.tar
        hash: 4f8805b4b64dcc575547ec1c63793aec  /scratch/file_compare1.tar
      - name: /scratch/file_compare2.tar.gz
        hash: 2dc4f1e9ca4081cc49d25195627982ef  /scratch/file_compare2.tar.gz

下面的任務

    - name: Use md5 to calculate checksum
      stat:
        path: "{{ item.name }}"
        checksum_algorithm: md5
      register: hash_check
      loop: "{{ files }}"

    - name: Debug files - Different
      debug:
        msg: |
          Hash NOT changed: {{ item.0.name }}
          {{ item.0.hash.split()|first }}
          {{ item.1 }}
      with_together:
        - "{{ files }}"
        - "{{ hash_check.results|map(attribute='stat.checksum')|list }}"
      when: item.0.hash.split()|first == item.1

  msg: |-
    Hash NOT changed: /scratch/file_compare1.tar
    4f8805b4b64dcc575547ec1c63793aec
    4f8805b4b64dcc575547ec1c63793aec

  msg: |-
    Hash NOT changed: /scratch/file_compare2.tar.gz
    2dc4f1e9ca4081cc49d25195627982ef
    2dc4f1e9ca4081cc49d25195627982ef

一個更強大的選擇是使用計算的哈希創建一個字典

    - name: Use md5 to calculate checksum
      stat:
        path: "{{ item.name }}"
        checksum_algorithm: md5
      register: hash_check
      loop: "{{ files }}"

    - set_fact:
        path_hash: "{{ dict(_path|zip(_hash)) }}"
      vars:
        _path: "{{ hash_check.results|map(attribute='stat.path')|list }}"
        _hash: "{{ hash_check.results|map(attribute='stat.checksum')|list }}"

  path_hash:
    /scratch/file_compare1.tar: 4f8805b4b64dcc575547ec1c63793aec
    /scratch/file_compare2.tar.gz: 2dc4f1e9ca4081cc49d25195627982ef

然后使用這個字典來比較哈希。 例如,下面的任務給出了相同的結果

    - name: Debug files - Different
      debug:
        msg: |
          Hash NOT changed: {{ item.name }}
          {{ item.hash.split()|first }}
          {{ path_hash[item.name] }}
      loop: "{{ files }}"
      when: item.hash.split()|first == path_hash[item.name]

下一個選項是使用原始哈希以及原始哈希列表和計算哈希列表創建一個字典

    - name: Use md5 to calculate checksum
      stat:
        path: "{{ item.name }}"
        checksum_algorithm: md5
      register: hash_check
      loop: "{{ files }}"

    - set_fact:
        hash_name: "{{ dict(_hash|zip(_name)) }}"
        hash_orig: "{{ _hash }}"
        hash_stat: "{{ hash_check.results|map(attribute='stat.checksum')|list }}"
      vars:
        _hash: "{{ files|map(attribute='hash')|map('split')|map('first')|list }}"
        _name: "{{ files|map(attribute='name')|list }}"

  hash_name:
    2dc4f1e9ca4081cc49d25195627982ef: /scratch/file_compare2.tar.gz
    4f8805b4b64dcc575547ec1c63793aec: /scratch/file_compare1.tar

  hash_orig:
  - 4f8805b4b64dcc575547ec1c63793aec
  - 2dc4f1e9ca4081cc49d25195627982ef

  hash_stat:
  - 4f8805b4b64dcc575547ec1c63793aec
  - 2dc4f1e9ca4081cc49d25195627982ef

然后計算列表的差異並使用它來提取更改和未更改文件的列表

    - set_fact:
        files_diff: "{{ _diff|map('extract', hash_name)|list }}"
        files_orig: "{{ _orig|map('extract', hash_name)|list }}"
      vars:
        _diff: "{{ hash_orig|difference(hash_stat) }}"
        _orig: "{{ hash_orig|difference(_diff) }}"
    - name: Debug files changed
      debug:
        var: files_diff
    - name: Debug files NOT changed
      debug:
        var: files_orig

  files_diff: []

  files_orig:
  - /scratch/file_compare1.tar
  - /scratch/file_compare2.tar.gz

我用你的建議來補充劇本,它現在正在工作。

這個想法是獲取文件列表,讀取每個文件並與 hash、文件和當前 hash 進行比較。

---
- hosts: localhost
  connection: local
  gather_facts: false
  vars_files:
    - files3.yml
  tasks:
    - stat:
        path: "{{ item.file }}"
        checksum_algorithm: md5
      loop: "{{ files }}"
      register: stat_results

    - name: NOT changed files
      debug:
        msg: "NOT changed: {{ item.stat.path }}"
      when: item.stat.checksum ==  item.item.checksum.split()|first
      loop: "{{ stat_results.results }}"
      loop_control:
        label: "{{ item.stat.path }}"

    - name: Changed files
      debug:
        msg: "CHANGED: {{ item.stat.path }}"
      when: item.stat.checksum != item.item.checksum.split()|first
      loop: "{{ stat_results.results }}"
      loop_control:
        label: "{{ item.stat.path }}"

結果:

>> ansible-playbook playbooks/check-file3.yml 

PLAY [localhost] ********************************************************************************************************************************************************************************************************************

TASK [stat] *************************************************************************************************************************************************************************************************************************
ok: [localhost] => (item={'file': '/opt/file_compare1.tar', 'checksum': '9cd599a3523898e6a12e13ec787da50a  /opt/file_compare1.tar'})
ok: [localhost] => (item={'file': '/opt/file_compare2.tar.gz', 'checksum': 'd41d8cd98f00b204e9800998ecf8427e  /opt/file_compare2.tar.gz'})

TASK [NOT changed files] ************************************************************************************************************************************************************************************************************
skipping: [localhost] => (item=/opt/file_compare1.tar) 
ok: [localhost] => (item=/opt/file_compare2.tar.gz) => {
    "msg": "NOT changed: /opt/file_compare2.tar.gz"
}

TASK [Changed files] ****************************************************************************************************************************************************************************************************************
ok: [localhost] => (item=/opt/file_compare1.tar) => {
    "msg": "CHANGED: /opt/file_compare1.tar"
}
skipping: [localhost] => (item=/opt/file_compare2.tar.gz) 

PLAY RECAP **************************************************************************************************************************************************************************************************************************
localhost                  : ok=3    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0 

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM