ansible-निर्देशिका से अप्रबंधित फ़ाइलों को हटाएं?




ansible-template (5)

मैं एक निर्देशिका पर पुनरावर्ती रूप से कॉपी करना चाहता हूं और सभी .j2 फ़ाइलों को टेम्प्लेट के रूप में प्रस्तुत करना चाहता हूं। इसके लिए मैं वर्तमान में निम्नलिखित पंक्तियों का उपयोग कर रहा हूं:

- template: >
            src=/src/conf.d/{{ item }}
            dest=/dest/conf.d/{{ item|replace('.j2','') }}
  with_lines: find /src/conf.d/ -type f -printf "%P\n"

अब मैं इस निर्देशिका से अप्रबंधित फ़ाइलों को हटाने का एक तरीका ढूंढ रहा हूं। उदाहरण के लिए यदि मैं /src/conf.d/ से एक फ़ाइल / टेम्पलेट /src/conf.d/ हूं, तो मैं चाहता हूं कि इसे /dest/conf.d/ से भी हटा दिया /dest/conf.d/

क्या ऐसा करने का कोई तरीका है? मैंने rsync --delete साथ इधर-उधर की कोशिश की, लेकिन वहां मुझे खाके के साथ एक समस्या मिली, जो उनके प्रत्यय को .j2 हटा दिया गया।


आमतौर पर मैं फाइलें नहीं निकालता, लेकिन मैं इसके नाम के लिए -unmanaged प्रत्यय जोड़ता -unmanaged । नमूना कार्य:

- name: Get sources.list.d files
  shell: grep -r --include=\*.list -L '^# Ansible' /etc/apt/sources.list.d || true
  register: grep_unmanaged
  changed_when: grep_unmanaged.stdout_lines

- name: Add '-unmanaged' suffix
  shell: rename 's/$/-unmanaged/' {{ item }}
  with_items: grep_unmanaged.stdout_lines

व्याख्या

Grep कमांड उपयोग करता है:

  • -r to पुनरावर्ती खोज
  • --include=\*.list - केवल पुनरावर्ती खोज के दौरान .list एक्सटेंशन के साथ फाइलें ले लो
  • -L '^# Ansible' - '# Ansible' के साथ शुरू होने वाली फ़ाइल नाम प्रदर्शित न करें
  • || true || true - इसका उपयोग त्रुटियों को अनदेखा करने के लिए किया जाता है। Ansible की ignore_errors भी काम करती है लेकिन त्रुटि को अनदेखा करने से पहले ansible-playbook चलाने के दौरान इसे लाल रंग में दिखाया जाएगा जो अवांछित है (कम से कम मेरे लिए)।

फिर मैं एक चर के रूप में grep कमांड का आउटपुट रजिस्टर करता हूं। जब grep किसी भी आउटपुट को प्रदर्शित करता है जो मैंने इस कार्य को बदल दिया है (इसके लिए लाइन changed_when जिम्मेदार है)।

अगले कार्य में मैंने grep आउटपुट (यानी grep द्वारा लौटाए गए फ़ाइल नाम) को पुन: टाइप किया और प्रत्येक फ़ाइल में प्रत्यय जोड़ने के लिए नाम बदलें कमांड को चलाया।

बस इतना ही। अगली बार जब आप कमांड चलाते हैं तो पहला काम हरे रंग का होना चाहिए और दूसरा स्किप होना चाहिए।


इसे संभालने के कुछ तरीके हो सकते हैं, लेकिन क्या टेंपरेचर स्टेप से पहले किसी टास्क में टारगेट डायरेक्टरी को पूरी तरह से खाली करना संभव होगा? या हो सकता है कि टेम्पर्ड फ़ाइलों को एक अस्थायी निर्देशिका में छोड़ दें और फिर बाद के चरण में + नाम बदलें?


मैं इस मामले के साथ अपना अनुभव साझा करना चाहता हूं।

2.2 से उत्तर देने योग्य है with_filetree लूप dirs, लिंक, स्थिर फ़ाइलों और यहां तक ​​कि () टेम्प्लेट अपलोड करने का सरल तरीका प्रदान करता है। यह मेरे config dir को सिंक्रनाइज़ रखने का सबसे अच्छा तरीका है।

- name: etc config - Create directories
  file:
    path: "{{ nginx_conf_dir }}/{{ item.path }}"
    state: directory
    mode: 0755
  with_filetree: etc/nginx
  when: item.state == 'directory'

- name: etc config - Creating configuration files from templates
  template:
    src: "{{ item.src }}"
    dest: "{{ nginx_conf_dir }}/{{ item.path | regex_replace('\\.j2$', '') }}"
    mode: 0644
  with_filetree: etc/nginx
  when:
    - item.state == "file"
    - item.path | match('.+\.j2$') | bool

- name: etc config - Creating staic configuration files
  copy:
    src: "{{ item.src }}"
    dest: "{{ nginx_conf_dir }}/{{ item.path }}"
    mode: 0644
  with_filetree: etc/nginx
  when:
    - item.state == "file"
    - not (item.path | match('.+\.j2$') | bool)

- name: etc config - Recreate symlinks
  file:
    src: "{{ item.src }}"
    dest: "{{ nginx_conf_dir }}/{{ item.path }}"
    state: link
    force: yes
    mode: "{{ item.mode }}"
  with_filetree: etc/nginx
  when: item.state == "link"

अगला हम config dir से अप्रयुक्त फ़ाइलों को हटाना चाहते हैं। यह आसान है। हम दूरस्थ सर्वर पर अपलोड की गई फ़ाइलों और फ़ाइलों की सूची को इकट्ठा करते हैं, अगले विवर्तन को हटाते हैं।

लेकिन हम config dir में अप्रबंधित फ़ाइलें रखना चाहते हैं। मैंने अप्रबंधित फ़ाइलों के साथ फ़ोल्डरों को साफ़ करने से बचने के लिए find कार्यक्षमता का उपयोग किया है।

पीएस _ (वाई) _ यकीन है कि मैं कुछ अप्रबंधित फ़ाइलों को हटा दिया है के बाद

- name: etc config - Gathering managed files
  set_fact:
    __managed_file_path: "{{ nginx_conf_dir }}/{{ item.path | regex_replace('\\.j2$', '') }}"
  with_filetree: etc/nginx
  register: __managed_files

- name: etc config - Convert managed files to list
  set_fact: managed_files="{{ __managed_files.results | map(attribute='ansible_facts.__managed_file_path') | list }}"

- name: etc config - Gathering exist files (excluding .ansible_keep-content dirs)
  shell: find /etc/nginx -mindepth 1 -type d -exec test -e '{}/.ansible_keep-content' \; -prune -o -print
  register: exist_files
  changed_when: False

- name: etc config - Delete unmanaged files
  file: path="{{ item }}" state=absent
  with_items: "{{ exist_files.stdout_lines }}"
  when:
    - item not in managed_files

मैं इसे इस तरह से करूंगा, एक चर को 'मैनेज_फाइल्स' के रूप में परिभाषित किया गया, जो एक सूची है।

- shell: ls -1 /some/dir
  register: contents

- file: path=/some/dir/{{ item }} state=absent
  with_items: contents.stdout_lines
  when: item not in managed_files

हम अपनी nginx फ़ाइलों के साथ ऐसा करते हैं, क्योंकि हम चाहते हैं कि वे एक विशेष क्रम में हों, टेम्प्लेट से आएं, लेकिन अप्रबंधित कार्यों को हटा दें:

  # loop through the nginx sites array and create a conf for each file in order
  # file will be name 01_file.conf, 02_file.conf etc
  - name: nginx_sites conf
    template: >
      src=templates/nginx/{{ item.1.template }}
      dest={{ nginx_conf_dir }}/{{ '%02d' % item.0 }}_{{ item.1.conf_name|default(item.1.template) }}
      owner={{ user }}
      group={{ group }}
      mode=0660
    with_indexed_items: nginx_sites
    notify:
      - restart nginx
    register: nginx_sites_confs

  # flatten and map the results into simple list
  # unchanged files have attribute dest, changed have attribute path
  - set_fact:
      nginx_confs: "{{ nginx_sites_confs.results|selectattr('dest', 'string')|map(attribute='dest')|list + nginx_sites_confs.results|selectattr('path', 'string')|map(attribute='path')|select|list }}"
    when: nginx_sites

  # get contents of conf dir
  - shell: ls -1 {{ nginx_conf_dir }}/*.conf
    register: contents
    when: nginx_sites

  # so we can delete the ones we don't manage
  - name: empty old confs
    file: path="{{ item }}" state=absent
    with_items: contents.stdout_lines
    when: nginx_sites and item not in nginx_confs

चाल (जैसा कि आप देख सकते हैं) यह है कि रजिस्टर परिणामों में टेम्पलेट और with_items की अलग-अलग विशेषताएं हैं। फिर आप उन्हें उन फ़ाइलों की सूची में बदल देते हैं जिन्हें आप प्रबंधित करते हैं और फिर निर्देशिका की एक सूची प्राप्त करते हैं और उन सूची में नहीं हटाए जाते हैं।

यदि आपके पास पहले से ही फ़ाइलों की सूची है, तो कम कोड के साथ किया जा सकता है। लेकिन इस मामले में मैं एक अनुक्रमित सूची बना रहा हूं, इसलिए सूची को मानचित्र के साथ बनाने की आवश्यकता है।





ansible-template