From a739b9c80edb4eee9918a80811fbfd02547bda84 Mon Sep 17 00:00:00 2001
From: Chris Croome <chris@webarchitects.co.uk>
Date: Sun, 29 Jan 2023 21:59:28 +0000
Subject: [PATCH] WIP

---
 defaults/main.yml       |  20 +++++
 meta/argument_specs.yml |  20 +++++
 tasks/checks.yml        | 193 ++++++++++++----------------------------
 tasks/conf.yml          | 106 ++++++++++++++++++++++
 tasks/main.yml          |  26 ++++--
 vars/main.yml           |  15 ++++
 6 files changed, 240 insertions(+), 140 deletions(-)
 create mode 100644 tasks/conf.yml

diff --git a/defaults/main.yml b/defaults/main.yml
index 0f79dc1..d617f31 100644
--- a/defaults/main.yml
+++ b/defaults/main.yml
@@ -11,11 +11,14 @@
 php: true
 # php_alternatives:
 # cat /etc/php/8.1/fpm/php.ini | jc --ini -yp
+php_check_legacy_variables: true
 php_config:
   - name: PHP 8.1 configuration
     version: "8.1"
     state: present
     files:
+      - path: /etc/php/8.1/apache2/php.ini
+        state: absent
       - name: PHP 8.1 FPM configuration
         path: /etc/php/8.1/fpm/php.ini
         state: edited
@@ -27,6 +30,8 @@ php_config:
     version: "7.4"
     state: present
     files:
+      - path: /etc/php/7.4/apache2/php.ini
+        state: absent
       - name: PHP 8.1 FPM configuration
         path: /etc/php/7.4/fpm/php.ini
         state: edited
@@ -34,6 +39,21 @@ php_config:
           PHP:
             max_input_time: "600"
             memory_limit: "512M"
+  - name: PHP 7.3 configuration
+    version: "7.3"
+    state: absent
+  - name: PHP 7.2 configuration
+    version: "7.2"
+    state: absent
+  - name: PHP 7.1 configuration
+    version: "7.1"
+    state: absent
+  - name: PHP 7.0 configuration
+    version: "7.0"
+    state: absent
+  - name: PHP 5.6 configuration
+    version: "5.6"
+    state: absent
 php_sury: true
 php_versions:
   - name: PHP 8.2 packages
diff --git a/meta/argument_specs.yml b/meta/argument_specs.yml
index 659df63..a2aa6aa 100644
--- a/meta/argument_specs.yml
+++ b/meta/argument_specs.yml
@@ -70,6 +70,16 @@ argument_specs:
             type: str
             required: true
             description: The PHP version number.
+            choices:
+              - "8.2"
+              - "8.1"
+              - "8.0"
+              - "7.4"
+              - "7.3"
+              - "7.2"
+              - "7.1"
+              - "7.0"
+              - "5.6"
       php_sury:
         type: bool
         required: false
@@ -105,4 +115,14 @@ argument_specs:
             type: str
             required: true
             description: The PHP version number.
+            choices:
+              - "8.2"
+              - "8.1"
+              - "8.0"
+              - "7.4"
+              - "7.3"
+              - "7.2"
+              - "7.1"
+              - "7.0"
+              - "5.6"
 ...
diff --git a/tasks/checks.yml b/tasks/checks.yml
index 80f604d..8f1a176 100644
--- a/tasks/checks.yml
+++ b/tasks/checks.yml
@@ -2,22 +2,56 @@
 - name: PHP checks
   block:
 
-    - name: Check that depreciated variables are not used
+    - name: Check that depreciated variables are not defined
       ansible.builtin.assert:
         that:
-          - php_allow_local_infile is not defined
-        quiet: "{% if ansible_verbosity == 0 %}true{% else %}false{% endif %}"
-
-    - name: Check that variables are booleans
-      ansible.builtin.assert:
-        that:
-          - php_allow_url_include | type_debug == "bool"
-          - php_mysqli_allow_local_infile | type_debug == "bool"
-          - phpcli_allow_local_infile | type_debug == "bool"
-          - php_opcache_enable | type_debug == "bool"
-          - php_opcache_validate_permission | type_debug == "bool"
-          - php_opcache_validate_root | type_debug == "bool"
+          - php_allow_url_include is not defined
+          - php_apc_shm_size is not defined
+          - phpcli_allow_local_infile is not defined
+          - php_date_timezone is not defined
+          - php_default_socket_timeout is not defined
+          - php_disable_functions is not defined
+          - php_dpkg is not defined
+          - php_log is not defined
+          - php_log_grep is not defined
+          - php_max_execution_time is not defined
+          - php_max_file_uploads is not defined
+          - php_max_input_nesting_level is not defined
+          - php_max_input_time is not defined
+          - php_max_input_vars is not defined
+          - php_memory_limit is not defined
+          - php_mysqli_allow_local_infile is not defined
+          - php_opcache_enable is not defined
+          - php_opcache_interned_strings_buffer is not defined
+          - php_opcache_max_accelerated_files is not defined
+          - php_opcache_memory_consumption is not defined
+          - php_opcache_revalidate_freq is not defined
+          - php_opcache_use_cwd is not defined
+          - php_opcache_validate_permission is not defined
+          - php_opcache_validate_root is not defined
+          - php_opcache_validate_timestamps is not defined
+          - php_output_buffering is not defined
+          - php_packages is not defined
+          - php_phpquery is not defined
+          - php_post_max_size is not defined
+          - php_session_save_path is not defined
+          - php_short_open_tag is not defined
+          - php_upload_max_filesize is not defined
+          - php_versioned_packages is not defined
+          - php_www_pool_enabled is not defined
+          - php_www_pool_ping_path is not defined
+          - php_www_pool_pm is not defined
+          - php_www_pool_pm_max_children is not defined
+          - php_www_pool_pm_max_requests is not defined
+          - php_www_pool_pm_max_spare_servers is not defined
+          - php_www_pool_pm_min_spare_servers is not defined
+          - php_www_pool_pm_process_idle_timeout is not defined
+          - php_www_pool_pm_start_servers is not defined
+          - php_www_pool_pm_status_path is not defined
         quiet: "{% if ansible_verbosity == 0 %}true{% else %}false{% endif %}"
+      when:
+        - php_check_legacy_variables is defined
+        - php_check_legacy_variables | bool
 
     - name: Check that the distro is Debian Bullseye or Buster
       ansible.builtin.assert:
@@ -27,131 +61,20 @@
         quiet: "{% if ansible_verbosity == 0 %}true{% else %}false{% endif %}"
         fail_msg: "The Linux distro {{ ansible_distribution }} {{ ansible_distribution_release }} is not supported by this role"
 
-    - name: Generate an array of existing PHP versions
-      ansible.builtin.set_fact:
-        php_versions_existing: "{{ php_versions_existing | default([]) }} + [ '{{ existing_version.key }}' ]"
-      loop: "{{ ansible_local.phpquery.versions | dict2items }}"
-      loop_control:
-        loop_var: existing_version
-        label: "{{ existing_version.key }}"
-      when:
-        - ansible_local.phpquery.versions is defined
-        - existing_version.value.state == "present"
-
-    - name: Debug php_versions_existing array
-      ansible.builtin.debug:
-        var: php_versions_existing
-        verbosity: 2
-      when: php_versions_existing is defined
-
-    - name: Generate an array of proposed PHP versions
-      ansible.builtin.set_fact:
-        php_versions_proposed: "{{ php_versions_proposed | default([]) }} + [ '{{ proposed_version.key }}' ]"
-      loop: "{{ php_versions | dict2items }}"
-      loop_control:
-        loop_var: proposed_version
-        label: "{{ proposed_version.key }}"
-      when:
-        - php_versions is defined
-        - proposed_version.value.state == "present"
-
-    - name: Proposed PHP versions checks
-      block:
-
-        - name: Debug php_versions_proposed array
-          ansible.builtin.debug:
-            var: php_versions_proposed
-            verbosity: 2
+    - name: Check the PHP versions installed
+      ansible.builtin.command: /usr/sbin/phpquery -V
+      check_mode: false
+      changed_when: false
+      register: php_phpquery_versions
 
-        - name: Check that for each proposed version of PHP there are not packages due to be present and absent at the same time
-          ansible.builtin.include_tasks: pkg_checks.yml
-          loop: "{{ php_versions_proposed }}"
-          loop_control:
-            loop_var: version
-            label: "{{ version }}"
-
-        - name: Debug defined SAPIs for proposed PHP versions
-          ansible.builtin.debug:
-            msg: "SAPI {{ php_versions[version].sapis }} is defined for PHP {{ version }}"
-            verbosity: 3
-          loop: "{{ php_versions_proposed }}"
-          loop_control:
-            loop_var: version
-            label: "{{ version }}"
-          when: php_versions[version].sapis is defined
-
-        - name: Include SAPI checks for proposed PHP versions
-          ansible.builtin.include_tasks: sapi_checks.yml
-          loop: "{{ php_versions_proposed }}"
-          loop_control:
-            loop_var: version
-            label: "{{ version }}"
-          when: php_versions[version].sapis is defined
-
-        - name: Generate an array of PHP versions to remove
-          ansible.builtin.set_fact:
-            php_versions_remove: "{{ php_versions_existing | difference(php_versions_proposed) }}"
-          when:
-            - ( php_versions_existing is defined ) and ( php_versions_existing != [] )
-            - ( php_versions_proposed is defined ) and ( php_versions_proposed != [] )
-
-        - name: Checks for PHP versions due to be removed
-          block:
-
-            - name: Debug php_versions_remove array
-              ansible.builtin.debug:
-                var: php_versions_remove
-                verbosity: 2
-
-            - name: Include SAPI checks for PHP versions due to be removed
-              ansible.builtin.include_tasks: sapi_absent_checks.yml
-              loop: "{{ php_versions_remove }}"
-              loop_control:
-                loop_var: version
-                label: "{{ version }}"
-              when: php_versions[version].sapis is defined
-
-          when: ( php_versions_remove is defined ) and ( php_versions_remove != [] )
-
-      when: ( php_versions_proposed is defined ) and ( php_versions_proposed != [] )
-
-    - name: Generate an array of absent PHP versions
+    - name: Set a fact for the PHP versions installed
       ansible.builtin.set_fact:
-        php_versions_absent: "{{ php_versions_absent | default([]) }} + [ '{{ absent_version.key }}' ]"
-      loop: "{{ php_versions | dict2items }}"
-      loop_control:
-        loop_var: absent_version
-        label: "{{ absent_version.key }}"
-      when: absent_version.value.state == "absent"
-
-    - name: Absent PHP versions checks
-      block:
-
-        - name: Debug php_versions_absent array
-          ansible.builtin.debug:
-            var: php_versions_absent
-            verbosity: 2
+        php_ver_installed: "{{ php_phpquery_versions.stdout_lines }}"
 
-        - name: Include SAPI checks for PHP versions due to be absent
-          ansible.builtin.include_tasks: sapi_absent_checks.yml
-          loop: "{{ php_versions_absent }}"
-          loop_control:
-            loop_var: version
-            label: "{{ version }}"
-          when: php_versions[version].sapis is defined
-
-      when: ( php_versions_absent is defined ) and ( php_versions_absent != [] )
-
-    # - name: Include www pool server variable checks
-    #   ansible.builtin.include_tasks: pool_check.yml
-    #   when: php_www_pool_pm == "dynamic"
-    #   vars:
-    #     php_pm: "{{ php_www_pool_pm }}"
-    #     php_pm_max_children: "{{ php_www_pool_pm_max_children }}"
-    #     php_pm_start_servers: "{{ php_www_pool_pm_start_servers }}"
-    #     php_pm_min_spare_servers: "{{ php_www_pool_pm_min_spare_servers }}"
-    #     php_pm_max_spare_servers: "{{ php_www_pool_pm_max_spare_servers }}"
-    #   when: ( php_www_pool_enabled is not defined ) or ( php_www_pool_enabled is defined and php_www_pool_enabled )
+    - name: Debug PHP versions installed
+      ansible.builtin.debug:
+        var: php_ver_installed
+        verbosity: "{% if ansible_check_mode | bool %}0{% else %}1{% endif %}"
 
   tags:
     - php
diff --git a/tasks/conf.yml b/tasks/conf.yml
new file mode 100644
index 0000000..00ddbb4
--- /dev/null
+++ b/tasks/conf.yml
@@ -0,0 +1,106 @@
+# Copyright 2019-2023 Chris Croome
+#
+# This file is part of the Webarchitects PHP Ansible role.
+#
+# The Webarchitects PHP Ansible role is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
+#
+# The Webarchitects PHP Ansible role is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License along with the Webarchitects PHP Ansible role. If not, see <https://www.gnu.org/licenses/>.
+---
+- name: PHP configuration
+  block:
+
+    - name: Find the existing PHP versions directories
+      ansible.builtin.find:
+        paths: /etc/php
+        file_type: directory
+        recurse: false
+      register: php_etc_php_find_dirs
+
+    - name: Debug the existing PHP versions directories found
+      ansible.builtin.debug:
+        var: php_etc_php_find_dirs
+        verbosity: "{% if ansible_check_mode | bool %}1{% else %}2{% endif %}"
+
+    - name: Set a fact for the existing PHP version directories
+      ansible.builtin.set_fact:
+        php_conf_dirs_existing: "{{ php_etc_php_find_dirs | community.general.json_query('files[].path') }}"
+
+    - name: Debug existing PHP versions directories
+      ansible.builtin.debug:
+        var: php_conf_dirs_existing
+        verbosity: "{% if ansible_check_mode | bool %}0{% else %}1{% endif %}"
+
+    - name: Debug PHP version configuration directories which should be absent
+      ansible.builtin.debug:
+        var: php_conf_dirs_absent
+        verbosity: "{% if ansible_check_mode | bool %}0{% else %}1{% endif %}"
+
+    - name: Set a fact for existing PHP version configuration directories which should be absent
+      ansible.builtin.set_fact:
+        php_conf_dirs_remove: "{{ php_conf_dirs_existing | ansible.builtin.intersect(php_conf_dirs_absent) }}"
+
+    - name: Debug existing PHP versions configuration directories to be deleted
+      ansible.builtin.debug:
+        var: php_conf_dirs_remove
+        verbosity: "{% if ansible_check_mode | bool %}0{% else %}1{% endif %}"
+
+    - name: Find the existing PHP configuration files
+      ansible.builtin.find:
+        paths: /etc/php
+        file_type: file
+        recurse: true
+        patterns: '*.ini'
+      register: php_etc_php_find_files
+
+    - name: Debug existing PHP configuration files
+      ansible.builtin.debug:
+        var: php_etc_php_find_files
+        verbosity: "{% if ansible_check_mode | bool %}1{% else %}2{% endif %}"
+
+    - name: Set a fact for the existing PHP configuration files
+      ansible.builtin.set_fact:
+        php_conf_files_existing: "{{ php_etc_php_find_files | community.general.json_query('files[].path') }}"
+
+    - name: Debug existing PHP configuration files
+      ansible.builtin.debug:
+        var: php_conf_files_existing
+        verbosity: "{% if ansible_check_mode | bool %}0{% else %}1{% endif %}"
+
+    - name: Debug PHP configuration files which should be absent
+      ansible.builtin.debug:
+        var: php_conf_files_absent
+        verbosity: "{% if ansible_check_mode | bool %}0{% else %}1{% endif %}"
+
+    - name: Set a fact for existing PHP configuration files that should be absent
+      ansible.builtin.set_fact:
+        php_conf_files_remove: "{{ php_conf_files_existing | ansible.builtin.intersect(php_conf_files_absent) }}"
+
+    - name: Debug existing PHP configuration files to be deleted
+      ansible.builtin.debug:
+        var: php_conf_files_remove
+        verbosity: "{% if ansible_check_mode | bool %}0{% else %}1{% endif %}"
+
+    - name: Set a fact for existing PHP configuration files and directories to be deleted
+      ansible.builtin.set_fact:
+        php_conf_rm: "{{ php_conf_dirs_remove + php_conf_files_remove }}"
+
+    - name: Debug PHP configuration paths to be deleted
+      ansible.builtin.debug:
+        var: php_conf_rm
+        verbosity: "{% if ansible_check_mode | bool %}0{% else %}1{% endif %}"
+
+    - name: PHP configuration paths absent
+      ansible.builtin.file:
+        path: "{{ php_conf_rm }}"
+        state: absent
+      register: php_conf_removed
+      when:
+        - php_conf_rm is defined
+        - php_conf_rm != []
+
+  tags:
+    - php
+    - php_conf
+...
diff --git a/tasks/main.yml b/tasks/main.yml
index 925988e..ddb9adb 100644
--- a/tasks/main.yml
+++ b/tasks/main.yml
@@ -1,3 +1,12 @@
+# Copyright 2019-2023 Chris Croome
+#
+# This file is part of the Webarchitects PHP Ansible role.
+#
+# The Webarchitects PHP Ansible role is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
+#
+# The Webarchitects PHP Ansible role is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License along with the Webarchitects PHP Ansible role. If not, see <https://www.gnu.org/licenses/>.
 ---
 - name: PHP
   block:
@@ -10,6 +19,13 @@
         ( ansible_local.dpkg.arch is not defined ) or
         ( ansible_local.gpg.version is not defined ) or
         ( ansible_local.bash.path is not defined )
+      tags:
+        - php_apt
+
+    - name: Include PHP check tasks
+      ansible.builtin.include_tasks: checks.yml
+      tags:
+        - php_conf
 
     - name: Include Sury PHP apt repo tasks
       ansible.builtin.include_tasks: apt.yml
@@ -23,11 +39,11 @@
       tags:
         - php_pkg
 
-#    - name: Include PHP config tasks
-#      ansible.builtin.include_tasks: conf.yml
-#      when: php_config is defined
-#      tags:
-#        - php_config
+    - name: Include PHP configuration tasks
+      ansible.builtin.include_tasks: conf.yml
+      when: php_config is defined
+      tags:
+        - php_conf
 
 # - name: Install and configure PHP
 #   block:
diff --git a/vars/main.yml b/vars/main.yml
index 3ef0751..ea9904b 100644
--- a/vars/main.yml
+++ b/vars/main.yml
@@ -25,6 +25,21 @@ php_pkg_absent: "{{ php_versions | ansible.builtin.json_query('[?state==`present
 # cat defaults/main.yml | yq -o=json | jp "php_versions[?state=='present'].pkg_present[]" | sort -u
 php_pkg_present: "{{ php_versions | ansible.builtin.json_query('[?state==`present`].pkg_present[]') | ansible.builtin.unique | sort }}"
 
+# PHP versions configuration absent
+# cat defaults/main.yml | yq -o=json | jp "php_config[?state=='absent'].version"
+php_conf_ver_absent: "{{ php_config | ansible.builtin.json_query('[?state==`absent`].version') | sort }}"
+
+# PHP versions configuration directories absent
+php_conf_dirs_absent: "{{ php_config | ansible.builtin.json_query('[?state==`absent`].version') | map('regex_replace', '^', '/etc/php/') | sort }}"
+
+# PHP versions configuration directories present
+# cat defaults/main.yml | yq -o=json | jp "php_config[?state=='present'].version"
+php_conf_dirs_present: "{{ php_config | ansible.builtin.json_query('[?state==`present`].version') | sort }}"
+
+# PHP versions present files absent
+# cat defaults/main.yml | yq -o=json | jp "php_config[?state=='present'].files[]|[?state=='absent'].path"
+php_conf_files_absent: "{{ php_config | ansible.builtin.json_query('[?state==`present`].files[]|[?state==`absent`].path') | sort }}"
+
 # GPG public key URL linked from
 # https://packages.sury.org/php/
 php_gpg_url: https://packages.sury.org/php/apt.gpg
-- 
GitLab