如何管理文件的修改副本?

如何管理文件的修改副本?

下列的這個答案,我想複製 OpenSSL 的配置,並進行一組特定的變更。原始文件不受我的控制,因此我無法將其設為模板。

目前我有:

  - name: Make a copy
    copy:
      src: original.cnf
      dest: copy.cnf
      force: no
  - name: Modify
    ini_file:
      path: copy.cnf
      section: ...
      option: ...
      value: ...

此更改序列是冪等的,但如果原始檔案發生更改,則更改不會傳播到副本。如果我將其更改為force: yes,則原始更改將被傳播,但每次運行劇本時都會執行更改。這是有問題的,因為我需要在發生更改時重新啟動依賴的服務,但顯然這不能每次都發生。

有沒有一種方法可以維護副本,以便當且僅當需要時才修改目標檔案?

答案1

- block:
  name: These two are changed every time as modifications are not in original.cnf
  - name: Make a temporary copy
    copy:
      src: original.cnf
      dest: temp.cnf
      force: yes
  - name: Modify temporary copy
    ini_file:
      path: temp.cnf
      section: ...
      option: ...
      value: ...

- block:
  name: With same original.cnf and same modifications, the result will be already installed
  - name: Idempotent copy into place
    register: openssl_config_install
    copy:
      src: temp.cnf
      dest: copy.cnf
      force: yes


- assert:
    that:
      - openssl_config_install is not changed

答案2

根據約翰的回答,我最終得到了以下劇本片段。重要的部分是changed_when: False,它確保只有修改目標設定檔副本的步驟才算是更改。

- name: Create OpenSSL config copy
  block:
  - name: Create temporary file for the config's copy
    tempfile:
    register: tempfile
    changed_when: False
  - name: Copy openssl.cnf to the temporary file
    copy:
      src: "{{ openssl_cnf_source }}"
      dest: "{{ tempfile.path }}"
      mode: 0644  # Without this the next `copy` task can have issues reading the file.
    changed_when: False
  - name: Modify openssl.cnf in the temporary file
    ini_file:
      path: "{{ tempfile.path }}"
      section: ...
      option: ...
      value: ...
    changed_when: False
  - name: Copy the temporary file to the target OpenSSL config
    copy:
      src: "{{ tempfile.path }}"
      dest: "{{ openssl_cnf_copy }}"
      mode: 0644
      owner: ...
    notify:
      - ...
  - name: Delete the temporary file
    file:
      path: "{{ tempfile.path }}"
      state: absent
    changed_when: False

相關內容