diff --git a/.gitignore b/.gitignore index 62ff262..26e7b43 100644 --- a/.gitignore +++ b/.gitignore @@ -2,3 +2,4 @@ *.swp *.retry *.log +/filter_plugins/*.pyc diff --git a/.travis.yml b/.travis.yml index abd8b34..2f1809c 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,17 +1,13 @@ env: - PLATFORM='docker-debian-stretch-php70' ANSIBLE_VERSION='ansible>=2.6,<2.7' - - PLATFORM='docker-debian-stretch-php71' ANSIBLE_VERSION='ansible>=2.6,<2.7' - - PLATFORM='docker-debian-stretch-php72' ANSIBLE_VERSION='ansible>=2.6,<2.7' - - PLATFORM='docker-debian-stretch-php73' ANSIBLE_VERSION='ansible>=2.6,<2.7' - PLATFORM='docker-debian-buster-php73' ANSIBLE_VERSION='ansible>=2.6,<2.7' - PLATFORM='docker-ubuntu-xenial-php70' ANSIBLE_VERSION='ansible>=2.6,<2.7' - PLATFORM='docker-ubuntu-bionic-php72' ANSIBLE_VERSION='ansible>=2.6,<2.7' - PLATFORM='docker-ubuntu-bionic-php72' ANSIBLE_VERSION='ansible>=2.6,<2.7' - PLATFORM='docker-debian-stretch-php70' ANSIBLE_VERSION='ansible>=2.7,<2.8' - - PLATFORM='docker-debian-stretch-php71' ANSIBLE_VERSION='ansible>=2.7,<2.8' - - PLATFORM='docker-debian-stretch-php72' ANSIBLE_VERSION='ansible>=2.7,<2.8' - - PLATFORM='docker-debian-stretch-php73' ANSIBLE_VERSION='ansible>=2.7,<2.8' + - PLATFORM='docker-debian-stretch-php74' ANSIBLE_VERSION='ansible>=2.7,<2.8' - PLATFORM='docker-debian-buster-php73' ANSIBLE_VERSION='ansible>=2.7,<2.8' + - PLATFORM='docker-debian-buster-php74' ANSIBLE_VERSION='ansible>=2.7,<2.8' - PLATFORM='docker-ubuntu-xenial-php70' ANSIBLE_VERSION='ansible>=2.7,<2.8' - PLATFORM='docker-ubuntu-bionic-php72' ANSIBLE_VERSION='ansible>=2.7,<2.8' - PLATFORM='docker-ubuntu-bionic-php72' ANSIBLE_VERSION='ansible>=2.7,<2.8' diff --git a/README.md b/README.md index 07212cf..50479f1 100644 --- a/README.md +++ b/README.md @@ -8,14 +8,14 @@ Install PHP on Debian / Ubuntu / FreeBSD. Manage PHP-FPM, APCu, Opcache and Xdeb Managed OS / Versions --------------------- -| OS | PHP 7.0 | PHP 7.1 | PHP 7.2 | PHP 7.3 | -|:---------------------:|:-------------------:|:--------------------------:|:--------------------------:|:-------------------------:| -| Debian Stretch (9) | :heavy_check_mark: | :heavy_check_mark: (Sury) | :heavy_check_mark: (Sury) | :heavy_check_mark: (Sury) | -| Debian Buster (10) | :x: | :x: | :x: | :heavy_check_mark: | -| Ubuntu Xenial (16.04) | :heavy_check_mark: | :x: | :x: | :x: | -| Ubuntu Bionic (18.04) | :x: | :x: | :heavy_check_mark: | :x: | -| FreeBSD 11 | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | -| FreeBSD 12 | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | +| OS | PHP 7.0 | PHP 7.1 | PHP 7.2 | PHP 7.3 | PHP 7.4 | +|:---------------------:|:-------------------:|:--------------------------:|:--------------------------:|:-------------------------:|:--------------------------: +| Debian Stretch (9) | :heavy_check_mark: | :heavy_check_mark: (Sury) | :heavy_check_mark: (Sury) | :heavy_check_mark: (Sury) | :heavy_check_mark: (Sury) | +| Debian Buster (10) | :x: | :x: | :x: | :heavy_check_mark: | :heavy_check_mark: (Sury) | +| Ubuntu Xenial (16.04) | :heavy_check_mark: | :x: | :x: | :x: | :x: | +| Ubuntu Bionic (18.04) | :x: | :x: | :heavy_check_mark: | :x: | :x: | +| FreeBSD 11 | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | Need tests... | +| FreeBSD 12 | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | Need tests... | Links: - [Sury](https://deb.sury.org/) diff --git a/Vagrantfile b/Vagrantfile index 2ceb8d1..d0b5a26 100644 --- a/Vagrantfile +++ b/Vagrantfile @@ -10,7 +10,9 @@ Vagrant.configure("2") do |config| { :name => "debian-stretch-php71", :box => "debian/stretch64", :vars => { "php_version": '7.1' }}, { :name => "debian-stretch-php72", :box => "debian/stretch64", :vars => { "php_version": '7.2' }}, { :name => "debian-stretch-php73", :box => "debian/stretch64", :vars => { "php_version": '7.3' }}, + { :name => "debian-stretch-php74", :box => "debian/stretch64", :vars => { "php_version": '7.4' }}, { :name => "debian-buster-php73", :box => "debian/buster64", :vars => { }}, + { :name => "debian-buster-php74", :box => "debian/buster64", :vars => { "php_version": '7.4' }}, { :name => "ubuntu-xenial-php70", :box => "ubuntu/xenial64", :vars => { }}, { :name => "ubuntu-bionic-php72", :box => "ubuntu/bionic64", :vars => { }}, ] @@ -25,7 +27,9 @@ Vagrant.configure("2") do |config| { :name => "docker-debian-stretch-php71", :docker => "hanxhx/vagrant-ansible:debian9", :vars => { "php_version": '7.1' }}, { :name => "docker-debian-stretch-php72", :docker => "hanxhx/vagrant-ansible:debian9", :vars => { "php_version": '7.2' }}, { :name => "docker-debian-stretch-php73", :docker => "hanxhx/vagrant-ansible:debian9", :vars => { "php_version": '7.3' }}, + { :name => "docker-debian-stretch-php74", :docker => "hanxhx/vagrant-ansible:debian9", :vars => { "php_version": '7.4' }}, { :name => "docker-debian-buster-php73", :docker => "hanxhx/vagrant-ansible:debian10", :vars => { }}, + { :name => "docker-debian-buster-php74", :docker => "hanxhx/vagrant-ansible:debian10", :vars => { "php_version": '7.4' }}, { :name => "docker-ubuntu-xenial-php70", :docker => "hanxhx/vagrant-ansible:ubuntu16.04", :vars => { }}, { :name => "docker-ubuntu-bionic-php72", :docker => "hanxhx/vagrant-ansible:ubuntu18.04", :vars => { }}, ] diff --git a/defaults/main.yml b/defaults/main.yml index 6cd4fb2..a0c4707 100644 --- a/defaults/main.yml +++ b/defaults/main.yml @@ -90,10 +90,10 @@ php_xdebug_var_display_max_depth: '3' # PHP-FPM php_fpm_poold: - - pool_name: 'www' + - name: 'www' listen: '{{ php_default_fpm_sock }}' pm: 'dynamic' - pm_max_children: 250 + pm_max_children: 100 pm_start_servers: 10 pm_min_spare_servers: 10 pm_max_spare_servers: 20 diff --git a/filter_plugins/__pycache__/php.cpython-37.pyc b/filter_plugins/__pycache__/php.cpython-37.pyc new file mode 100644 index 0000000..0a4d8ec Binary files /dev/null and b/filter_plugins/__pycache__/php.cpython-37.pyc differ diff --git a/filter_plugins/php.py b/filter_plugins/php.py new file mode 100644 index 0000000..4955350 --- /dev/null +++ b/filter_plugins/php.py @@ -0,0 +1,10 @@ +def php_socket(php_version, pool_name): + return '/run/php/php%s-%s-fpm.sock' % (php_version, pool_name) + +class FilterModule(object): + ''' PHP module ''' + + def filters(self): + return { + 'php_socket': php_socket, + } diff --git a/tasks/fpm.yml b/tasks/fpm.yml index 509dd07..d681c60 100644 --- a/tasks/fpm.yml +++ b/tasks/fpm.yml @@ -24,13 +24,13 @@ - name: TEMPLATE | Deploy pool configuration template: src: etc/__php__/fpm/pool.d/pool.conf.j2 - dest: '{{ php_fpm_pool_dir }}/{{ item.pool_name }}.conf' - loop: "{{ php_fpm_poold }}" + dest: '{{ php_fpm_pool_dir }}/{{ item.name }}.conf' + loop: "{{ ansible_local.hanxhx_php.fpm_pool }}" notify: restart php-fpm - name: FILE | Delete default pool if necessary file: path: "{{ php_fpm_pool_dir }}/www.conf" state: absent - when: '"www" not in (php_fpm_poold | map(attribute="pool_name") | list)' + when: '"www" not in (ansible_local.hanxhx_php.fpm_pool | map(attribute="name") | list)' notify: restart php-fpm diff --git a/tasks/main.yml b/tasks/main.yml index 11187b3..21d981c 100644 --- a/tasks/main.yml +++ b/tasks/main.yml @@ -1,10 +1,5 @@ --- -- name: SET_FACT | Bypass https://github.com/ansible/ansible/issues/19874 - set_fact: - ansible_distribution_release: 'buster' - when: ansible_facts.distribution_major_version == "buster/sid" - - name: INCLUDE_VARS | Related to OS family include_vars: "OS_Family_{{ ansible_os_family }}.yml" @@ -15,20 +10,63 @@ - "{{ ansible_distribution }}-{{ ansible_distribution_version }}.yml" - "{{ ansible_distribution }}-{{ ansible_distribution_major_version }}.yml" +- name: SET_FACT | Transform data + set_fact: + __php_fpm_full_pool: | + [ + {% for p in php_fpm_poold %} + { + name: "{{ p.name | default(p.pool_name) }}", + listen: "{{ p.listen | default(php_version | php_socket(p.name | default(p.pool_name))) }}", + user: "{{ p.user | default(php_default_user_group) }}", + group: "{% if p.user is defined %}{{ p.group | default(p.user) }}{% else %}{{ p.group | default(php_default_user_group) }}{% endif %}", + php_value: {% if p.php_value is defined %}{{ p.php_value | to_nice_json }}{% else %}{}{% endif %}, + php_admin_value: {% if p.php_admin_value is defined %}{{ p.php_admin_value | to_nice_json }}{% else %}{}{% endif %}, + {% for k, v in p.items() | list %} + {% if k not in ['name', 'pool_name', 'listen', 'user', 'group', 'php_value', 'php_admin_value'] %} + {{ k }}: "{{ v }}"{% if not loop.last %},{% endif %} + {% endif %} + {% endfor %} + }{% if not loop.last %},{% endif %} + {% endfor %} + ] + +- name: SET_FACT | To YAML + set_fact: + php_fpm_full_pool: "{{ __php_fpm_full_pool | from_yaml }}" + +- name: FILE | Creates ansible facts.d + file: + path: /etc/ansible/facts.d + state: directory + recurse: yes + +- name: COPY | Manage facts + copy: + content: "{ \"fpm_pool\": {{ php_fpm_full_pool | to_nice_json }} }" + dest: /etc/ansible/facts.d/hanxhx_php.fact + register: f + +- name: SETUP | Gathers new facts + setup: + when: f.changed + tags: + - skip_ansible_lint + - name: APT | Install PHP packages apt: - pkg: "{{ item }}" + pkg: "{{ pkgs }}" state: present update_cache: yes cache_valid_time: 3600 - loop: "{{ php_packages + php_extra_packages | flatten }}" + vars: + pkgs: "{{ php_packages + php_extra_packages | flatten }}" notify: restart php-fpm when: ansible_os_family == 'Debian' - name: PKGNG | Install PHP packages pkgng: - name: "{{ item }}" - loop: "{{ php_packages + php_extra_packages | flatten }}" + name: "{{ php_packages + php_extra_packages | flatten | join(',') }}" notify: restart php-fpm when: ansible_os_family == 'FreeBSD' diff --git a/templates/etc/__php__/fpm/pool.d/pool.conf.j2 b/templates/etc/__php__/fpm/pool.d/pool.conf.j2 index da77557..77f7f0a 100644 --- a/templates/etc/__php__/fpm/pool.d/pool.conf.j2 +++ b/templates/etc/__php__/fpm/pool.d/pool.conf.j2 @@ -1,7 +1,7 @@ -; Start a new pool named '{{ item.pool_name }}'. +; Start a new pool named '{{ item.name }}'. ; the variable $pool can we used in any directive and will be replaced by the -; pool name ('{{ item.pool_name }}' here) -[{{ item.pool_name }}] +; pool name ('{{ item.name }}' here) +[{{ item.name }}] ; Per pool prefix ; It only applies on the following directives: @@ -20,8 +20,8 @@ ; Unix user/group of processes ; Note: The user is mandatory. If the group is not set, the default user's group ; will be used. -user = {{ item.user | default(php_default_user_group) }} -group = {{ item.group | default(php_default_user_group) }} +user = {{ item.user }} +group = {{ item.group }} ; The address on which to accept FastCGI requests. ; Valid syntaxes are: @@ -95,7 +95,7 @@ listen.group = {{ item.listen_owner | default(php_default_user_group) }} ; pm.process_idle_timeout - The number of seconds after which ; an idle process will be killed. ; Note: This value is mandatory. -pm = {{ item.pm }} +pm = {{ item.pm | default('dynamic') }} ; The number of child processes to be created when pm is set to 'static' and the ; maximum number of child processes when pm is set to 'dynamic' or 'ondemand'. @@ -106,27 +106,27 @@ pm = {{ item.pm }} ; forget to tweak pm.* to fit your needs. ; Note: Used when pm is set to 'static', 'dynamic' or 'ondemand' ; Note: This value is mandatory. -pm.max_children = {{ item.pm_max_children }} +pm.max_children = {{ item.pm_max_children | default('250') }} ; The number of child processes created on startup. ; Note: Used only when pm is set to 'dynamic' ; Default Value: min_spare_servers + (max_spare_servers - min_spare_servers) / 2 -pm.start_servers = {{ item.pm_start_servers }} +pm.start_servers = {{ item.pm_start_servers | default('10') }} ; The desired minimum number of idle server processes. ; Note: Used only when pm is set to 'dynamic' ; Note: Mandatory when pm is set to 'dynamic' -pm.min_spare_servers = {{ item.pm_min_spare_servers }} +pm.min_spare_servers = {{ item.pm_min_spare_servers | default('10') }} ; The desired maximum number of idle server processes. ; Note: Used only when pm is set to 'dynamic' ; Note: Mandatory when pm is set to 'dynamic' -pm.max_spare_servers = {{ item.pm_max_spare_servers }} +pm.max_spare_servers = {{ item.pm_max_spare_servers | default('20') }} ; The number of seconds after which an idle process will be killed. ; Note: Used only when pm is set to 'ondemand' ; Default Value: 10s -;pm.process_idle_timeout = 10s; +pm.process_idle_timeout = {{ item.pm_process_idle_timeout | default('10s') }}; ; The number of requests each child process should execute before respawning. ; This can be useful to work around memory leaks in 3rd party libraries. For @@ -369,7 +369,7 @@ chdir = / ; Note: on highloaded environement, this can cause some delay in the page ; process time (several ms). ; Default Value: no -;catch_workers_output = yes +catch_workers_output = {{ item.catch_workers_output | default('no') }} ; Clear environment in FPM workers ; Prevents arbitrary environment variables from reaching FPM worker processes @@ -421,12 +421,10 @@ chdir = / ;php_admin_value[error_log] = /var/log/fpm-php.www.log ;php_admin_flag[log_errors] = on ;php_admin_value[memory_limit] = 32M -{% if item.php_flag is defined %} -{% for k, v in item.php_flag.items() %} +{% for k, v in item.php_value.items() | list %} +php_value[{{ k }}] = {{ v }} {% endfor %} -{% endif %} -{% if item.php_admin_flag is defined %} -{% for k, v in item.php_admin_flag.items() %} +{% for k, v in item.php_admin_value.items() | list %} +php_admin_value[{{ k }}] = {{ v }} {% endfor %} -{% endif %} ; vim:filetype=dosini diff --git a/tests/includes/pre_Debian.yml b/tests/includes/pre_Debian.yml index 2eb09bf..546526f 100644 --- a/tests/includes/pre_Debian.yml +++ b/tests/includes/pre_Debian.yml @@ -16,9 +16,10 @@ - curl - lsb-release - nginx + - vim - name: INCLUDE_TASKS | Sury include_tasks: Debian/sury.yml when: - (ansible_distribution_major_version is version('9', 'eq')) and - (php_version is version('7.1', 'ge')) + ((ansible_distribution_major_version is version('9', 'eq')) and (php_version is version('7.1', 'ge'))) or + ((ansible_distribution_major_version is version('10', 'eq')) and (php_version is version('7.4', 'ge'))) diff --git a/tests/templates/nginx.conf.j2 b/tests/templates/nginx.conf.j2 index 80852ab..e5c83fb 100644 --- a/tests/templates/nginx.conf.j2 +++ b/tests/templates/nginx.conf.j2 @@ -15,22 +15,27 @@ http { root /var/www; -{% if php_fpm_poold.0.status_path is defined %} - location = {{ php_fpm_poold.0.status_path }} { +{% if ansible_local.hanxhx_php.fpm_pool.0.status_path is defined %} + location = {{ ansible_local.hanxhx_php.fpm_pool.0.status_path }} { include fastcgi.conf; - fastcgi_pass unix:{{ php_default_fpm_sock }}; + fastcgi_pass unix:{{ ansible_local.hanxhx_php.fpm_pool.0.listen }}; } {% endif %} -{% if php_fpm_poold.0.ping_path is defined %} - location = {{ php_fpm_poold.0.ping_path }} { +{% if ansible_local.hanxhx_php.fpm_pool.0.ping_path is defined %} + location = {{ ansible_local.hanxhx_php.fpm_pool.0.ping_path }} { include fastcgi.conf; - fastcgi_pass unix:{{ php_default_fpm_sock }}; + fastcgi_pass unix:{{ ansible_local.hanxhx_php.fpm_pool.0.listen }}; } {% endif %} + location = /ini.php { + include fastcgi.conf; + fastcgi_pass unix:{{ ansible_local.hanxhx_php.fpm_pool.1.listen }}; + } + location ~ \.php$ { include fastcgi.conf; - fastcgi_pass unix:{{ php_default_fpm_sock }}; + fastcgi_pass unix:{{ ansible_local.hanxhx_php.fpm_pool.0.listen }}; } } } diff --git a/tests/test.yml b/tests/test.yml index 35cfc94..b682eef 100644 --- a/tests/test.yml +++ b/tests/test.yml @@ -4,7 +4,7 @@ vars: vhost: 'test.local' php_extra_packages: - - '{{ php_package_prefix }}recode' + - '{{ php_package_prefix }}pgsql' php_install_xdebug: true php_ini_fpm: display_errors: 'Off' @@ -12,7 +12,7 @@ error_reporting: 'E_ALL' php_fpm_poold: - pool_name: 'test_ansible' - listen: '{{ php_default_fpm_sock }}' + listen: '/run/php/php-ansible1.sock' pm: 'dynamic' pm_max_children: 250 pm_start_servers: 10 @@ -21,16 +21,25 @@ status_path: '/status' ping_path: '/ping' ping_response: 'ok' - php_flag: + - name: 'test_ansible2' + user: 'foo' + php_value: display_errors: 'Off' - php_admin_flag: - memory_limit: '128M' + php_admin_value: + memory_limit: '98M' pre_tasks: - name: INCLUDE_TASKS | Pre tasks related to OS include_tasks: "includes/pre_{{ ansible_os_family }}.yml" + - name: USER | Create PHP user + user: + name: 'foo' + system: yes + create_home: no + shell: '/usr/sbin/nologin' + tasks: - name: TEMPLATE | Nginx site config @@ -112,6 +121,11 @@ dest: /var/www/phpinfo.php content: ' /dev/null | grep h1 | grep -o 'PHP Version {{ php_version }}' | sed -r 's/ /dev/null" + args: + warn: false + changed_when: false + register: c + failed_when: 'php_fpm_poold.1.php_admin_value.memory_limit not in c.stdout' + - name: URI | Check ping uri: url: "http://localhost{{ php_fpm_poold.0.ping_path }}"