Home > Enterprise >  Ansible: delete files on disk that are not defined in the yaml configuration
Ansible: delete files on disk that are not defined in the yaml configuration

Time:11-30

I have Ansible PHP role with defined versions and pools:

php_versions:
  - 8.0
  - 8.1

php_pools:
  - name: wiki
    version: 8.0
    #...

  - name: mail
    version: 8.1
    #...  

It produces files /etc/php/8.0/fpm/pool.d/wiki.conf and /etc/php/8.1/fpm/pool.d/mail.conf plus /etc/php/*/fpm/pool.d/_default_pool.conf which role creates by default for every defined PHP version.

Everything works great except deleting and moving pools. If I need to switch the pool wiki from version 8.0 to version 8.1, it crashes. Because the old file /etc/php/8.0/fpm/pool.d/wiki.conf stay on the disk and the new file /etc/php/8.1/fpm/pool.d/wiki.conf will be created in different PHP directory - it crashes on the IP:port conflict (already used by old PHP version).

I need to delete all pools on the disk that are not defined in ansible except _default_pool.conf. Default pools must stay.

I tried:

# main.yml
- name: php versions
  include_tasks: php.yml
  loop: "{{ php_versions }}"
  loop_control:
    loop_var: php_version

# php.yml
- name: delete non-ansible pools
  become: True
  block:
    - name: find all exiting php pool files
      become: True
      find:
        paths: "/etc/php/{{ inner_item.php_version }}/fpm/pool.d/"
        patterns: '\/etc\/php\/[0-9]\.[0-9]\/fpm\/pool\.d\/(. (?<!_default_pool))\.conf$'
        use_regex: True
      register: existing_pool_files

    - name: delete non-ansible pool files
      become: True
      file:
        state: absent
        path: "{{ item['path'] }}"
      with_items:
        - "{{ existing_pool_files['files'] | intersect(inner_item.name) }}"
      notify: restart PHP

but it doesn't work.

I can delete all pool files on disk and recreate them. But it sounds stupid.

How can I fix it? After a few hours of debugging, I'm out of ideas :-(

CodePudding user response:

For example, given the lists

  php_versions: [8.0, 8.1]
  php_pools:
    - {version: 8.0, name: wiki}
    - {version: 8.1, name: mail}

and the tree

shell> tree /etc/php
/etc/php
├── 7.4
│   └── fpm
│       └── pool.d
│           └── keep_this.conf
├── 8.0
│   └── fpm
│       └── pool.d
│           ├── _default_pool.conf
│           ├── mail.conf
│           ├── trash.conf
│           └── wiki.conf
└── 8.1
    └── fpm
        └── pool.d
            ├── _default_pool.conf
            ├── mail.conf
            ├── trash.conf
            └── wiki.conf
  1. Create the list of paths you want to maintain
  present_paths_str: |
    {% for ver in php_versions %}
    - /etc/php/{{ ver }}/fpm/pool.d/
    {% endfor %}
  present_paths: "{{ present_paths_str|from_yaml }}"

gives

  present_paths:
  - /etc/php/8.0/fpm/pool.d/
  - /etc/php/8.1/fpm/pool.d/
  1. Create the list of present files
  php_groups: "{{ dict(php_pools|groupby('version')) }}"
  present_pool_files_str: |
    {% for ver in php_versions %}
    - /etc/php/{{ ver }}/fpm/pool.d/_default_pool.conf
    {% for i in php_groups[ver] %}
    - /etc/php/{{ ver }}/fpm/pool.d/{{ i.name }}.conf
    {% endfor %}
    {% endfor %}
  present_pool_files: "{{ present_pool_files_str|from_yaml }}"

gives

  present_pool_files:
  - /etc/php/8.0/fpm/pool.d/_default_pool.conf
  - /etc/php/8.0/fpm/pool.d/wiki.conf
  - /etc/php/8.1/fpm/pool.d/_default_pool.conf
  - /etc/php/8.1/fpm/pool.d/mail.conf
  1. Declare variables
  existing_pool_files: "{{ existing_pool.files|map(attribute='path')|list }}"
  delete_pool_files: "{{ existing_pool_files|difference(present_pool_files) }}"

and find files

    - name: find all exiting php pool files
      become: True
      find:
        paths: "{{ present_paths }}"
        patterns: '*.conf'
      register: existing_pool

gives

  existing_pool_files:
  - /etc/php/8.0/fpm/pool.d/wiki.conf
  - /etc/php/8.0/fpm/pool.d/_default_pool.conf
  - /etc/php/8.0/fpm/pool.d/trash.conf
  - /etc/php/8.0/fpm/pool.d/mail.conf
  - /etc/php/8.1/fpm/pool.d/wiki.conf
  - /etc/php/8.1/fpm/pool.d/_default_pool.conf
  - /etc/php/8.1/fpm/pool.d/trash.conf
  - /etc/php/8.1/fpm/pool.d/mail.conf
  delete_pool_files:
  - /etc/php/8.0/fpm/pool.d/trash.conf
  - /etc/php/8.0/fpm/pool.d/mail.conf
  - /etc/php/8.1/fpm/pool.d/wiki.conf
  - /etc/php/8.1/fpm/pool.d/trash.conf
  1. Delete the redundant files
    - name: delete non-ansible pool files
      become: True
      file:
        state: absent
        path: "{{ item }}"
      loop: "{{ delete_files }}"
      notify: restart PHP

Example of a complete playbook for testing

- hosts: localhost

  vars:

    php_versions: [8.0, 8.1]
    php_pools:
      - {version: 8.0, name: wiki}
      - {version: 8.1, name: mail}

    present_paths_str: |
      {% for ver in php_versions %}
      - /etc/php/{{ ver }}/fpm/pool.d/
      {% endfor %}
    present_paths: "{{ present_paths_str|from_yaml }}"

    php_groups: "{{ dict(php_pools|groupby('version')) }}"
    present_pool_files_str: |
      {% for ver in php_versions %}
      - /etc/php/{{ ver }}/fpm/pool.d/_default_pool.conf
      {% for i in php_groups[ver] %}
      - /etc/php/{{ ver }}/fpm/pool.d/{{ i.name }}.conf
      {% endfor %}
      {% endfor %}
    present_pool_files: "{{ present_pool_files_str|from_yaml }}"

    existing_pool_files: "{{ existing_pool.files|map(attribute='path')|list }}"
    delete_pool_files: "{{ existing_pool_files|difference(present_pool_files) }}"

  tasks:

    - debug:
        var: php_groups
    - debug:
        var: present_paths
    - debug:
        var: present_pool_files

    - name: find all exiting php pool files
      become: True
      find:
        paths: "{{ present_paths }}"
        patterns: '*.conf'
      register: existing_pool
    - debug:
        var: existing_pool_files
    - debug:
        var: delete_pool_files

    - name: delete non-ansible pool files
      become: True
      file:
        state: absent
        path: "{{ item }}"
      loop: "{{ delete_files }}"
      notify: restart PHP
  • Related