diff --git a/.gitmodules b/.gitmodules index 1226ba308c0c5af4005da3adc87cadd9d481ac75..688e2be1897f22de596e5bc000e949236a6fe30e 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,3 +1,7 @@ [submodule "www/static/pi-billion"] path = www/static/pi-billion url = https://git.laquadrature.net/lqdn-interne/pi-billion.git +[submodule "ansible/don-lqdn"] + path = ansible/don-lqdn + url = https://git.laquadrature.net/lqdn-interne/piops-roles/don-lqdn + branch = main diff --git a/Makefile b/Makefile index b6e2ce912578cb38f2b1c40ac4d8ba5e8e517ad9..ad804b5ff95e0aae331eeea16ce2b4a9af4135c3 100644 --- a/Makefile +++ b/Makefile @@ -6,7 +6,7 @@ include app/env export $(shell sed 's/=.*//' app/env) endif -MYSQL_CONNECTION_STRING = --host=$(SQL_HOST) --user=$(SQL_USER) +MYSQL_CONNECTION_STRING = --user=$(SQL_USER) ifdef SQL_PASSWORD MYSQL_CONNECTION_STRING += --password=$(SQL_PASSWORD) endif @@ -67,12 +67,12 @@ coverage: ## Launch functional tests with coverage. @./vendor/bin/codecept run functional --coverage-html server-start: server-stop ## Launch a local server - @php -S 127.0.0.1:8000 -t ./www/ >> ./log/server.log & - @echo "\033[32mServer running. (http://127.0.0.1:8000)\033[0m" + @php -S 0.0.0.0:8000 -t ./www/ >> ./log/server.log & + @echo "\033[32mServer running. (http://0.0.0.0:8000)\033[0m" server-stop: ## Stop local server if running - -@ps -aux | grep "[p]hp -S 127.0.0.1:8000" | grep -v grep | awk '{print $$2}' | xargs -r -n 1 kill - @echo "\033[32mServer stopped. (http://127.0.0.1:8000)\033[0m" + -@ps -aux | grep "[p]hp -S 0.0.0.0:8000" | grep -v grep | awk '{print $$2}' | xargs -r -n 1 kill + @echo "\033[32mServer stopped. (http://0.0.0.0:8000)\033[0m" cs-fix: ## Fix CS @vendor/bin/php-cs-fixer fix diff --git a/README.en.md b/README.en.md new file mode 100644 index 0000000000000000000000000000000000000000..737686a020a3b8f1b4fe6512d0d6f7dbf699c1bf --- /dev/null +++ b/README.en.md @@ -0,0 +1 @@ +We're looking for contributors to help us translate the French version of the README. If you want to help, send us an email or open a pull request. Thanks :D diff --git a/README.md b/README.md index f911807dbdd0a01de51b6899432021d2b0315105..2d63db75f5a016a96aa5f153556f36473cda3869 100644 --- a/README.md +++ b/README.md @@ -1,75 +1,100 @@ -# LQDN soutien +# ![](www/static/img/cochon-01.png) Site de Don de La Quadrature Du Net -This is a php application based on Fat-Free-Framework and a MySQL database that handles donations and presents offered to donors to La Quadrature du Net +Ce site web, écrit en PHP avec le framework Fat-Free-Framework pour nous permettre de gérer les donnations et les contreparties pour La Quadrature Du Net. ( English below ) -It's used as our primary donation platform, and uses our bank's payment system (cheaper) to get one-time or recurring payments recorded into the donation platform. +## Conception -## Installation (quick) +Ce site à été conçu de zéro, par des bénévoles, des salariés et des membres de La Quadrature Du Net. -In order to install this project, run `make doctor` to check that everything is fine. +## Installation -Then you can run `make install` to install the project. Follow instructions if needed. -To install the DB, you need to run `make reset-db` (it will remove your local DB if it exists). +Vous aurez besoin de ; -Once everything if fine, you can run a simple PHP server with `make server-start` +- Un serveur Linux ( Debian de préférence ), avec... + - PHP 7.4+ + - Mysql/MariaDB -You have those accounts to test: +Cela n'est pas nécessaire pour le développement du site. -* alice@example.org / password -* bob@example.org / password +### En production -To access to the admin (`/admin`) use `admin`/`password` +Afin de faciliter le déployement, vous pouvez utiliser une recette Ansible pour le déployement en production. [Vous pouvez la consulter ici](https://git.laquadrature.net/lqdn-interne/piops-roles/don-lqdn). -## Contributing +Autrement, vous aurez besoin de : -Before submitting a PR, makes sure tests are OK: `make test` +##### Téléchargement -# Detailed dependencies, installation ... +Vous pouvez obtenir les dernières version du site de don sur [la page des publication.](https://git.laquadrature.net/lqdn-interne/don/-/releases) -## Dependencies +##### Configuration du serveur -This software depends on a few software : +L'installation des dépendances se fait via [Composer](https://getcomposer.org/). -* **composer** (to install php dependencies) see https://getcomposer.org/ -* a **mysql client** (to inject the database schema) -* a **mysql server** (no need for it to be local) -* **pdftk** to generate pi-plomes (pdf with pi's decimals offered to our donors) -* **texlive-latex-base** for the `pdflatex` binary for the piplomes (only required in production or for people debugging the piplomes code) +##### Configuration des paramètres du site web -and for developers you may also need : +Vous aurez besoin de remplir les variables du fichier `.env` dans le dossier `app/`. Dupliquez le fichier `env.sample`, renommez le en `.env` et remplissez le. -* **xgettext** to manage translations, use: - * `make messages.pot` to update PO files from source code. - * `make translations` to compile MO files from PO files when translations are ready. +##### Serveur web -This software uses: +Vous pouvez vous inspirer de la configuration décrite dans `ansible/configuration.test.yml` pour votre serveur Nginx. -* **PHP7.3** -* **phinx** to inject database schema and initial data / accounts into MySQL see https://phinx.org/ -* **php-cs-fixer** to check php code for errors and fix coding standard issues, see https://github.com/FriendsOfPHP/PHP-CS-Fixer -* **doctrine/dbal** as ORM see https://github.com/doctrine/dbal -* **f3 framework** as main view / controller framework. see https://fatfreeframework.com/ +##### Connexion à la banque -Look at `app/` folder for most Controllers, and `app/routes.ini` for the application routes (the URLs) +> À completer -# Production deployment (not finished) +##### Gestion -* `app/env` must contains the proper values : database connection, bank visa payment codes, and ENV=production at the bottom. -* point your Nginx or Apache with PHP5.6 to the `www/` folder, and either allow Rewrite Rules (a2enmod rewrite) or point every URL not being a file to index.php (see below for an nginx sample) -* use AND FORCE https usage, it's 2018, people ;) +Il existe des comptes de test par défaut, n'oubliez pas de les supprimer avant la mise en production ! -Nginx configuration sample: +- `alice@example.org` : `password` + +- `bob@example.org` : `password` + +Il existe aussi un compte administrateur de test. Vous pouvez accéder à l'interface d'administration via le chemin `https:///admin`. + +* `admin` : `password` + +### En test + +Afin de faciliter les test, nous avons inclus un fichier Vagrant, qui permet de lancer une machine virtuelle pré-configurée avec toutes les dépendances nécessaire pour tester le site de don, à l'exception du mode de banque pour le moment ( mais rien n'empêche que vous le mettiez en place. ) + +Afin de lancer la machine de développement, vous pouvez ; + +- Installer Vagrant si ce n'est pas déjà fait, +- Lancer `vagrant up`. Ça prendra un peu de temps la première fois. +- Vous avez maintenant une machine virtuelle accessible via ssh avec `vagrant ssh`, et vous pouvez voir le site de don sur `localhost:8282`. +- Vous pouvez faire vos modifications directement dans le dossier du dépôt, car il est lié sur la machine virtuelle, sous le chemin `/vagrant`. + +Le déployement se fait dans la machine virtuelle de test, au moyen de la recette ansible [don-lqdn](https://git.laquadrature.net/lqdn-interne/piops-roles/don-lqdn), que vous pouvez lire directement dans le dossier `ansible/` + +## Développement + +Quand vous lancez les tests avec Vagrant, vous avez accès au site de don dans sa version définie par le playbook. Par défaut, c'est la version sur `master`. + +Vous pouvez aussi travailer sur votre version locale en modifiant les variables du playbook dans `ansible/configuration.test.yml`. Modifiez la variable `root` de la configuration nginx de la façon suivante ; ``` -location ~ \.php$ { - include fastcgi_params; - fastcgi_read_timeout 1d; #avoid timeout when importing bank data - fastcgi_pass unix:/run/php7.3.sock; -} -location / { - # try to serve file directly, fallback to index.php - try_files $uri /index.php$is_args$args; -} -``` +root: /vagrant/www +``` + +### Documentation + +Vous pouvez consulter la documentation relative au développement et au déployement de ce site web dans le dossier `doc/` ou en [cliquant ici.](doc/README.md) + +## Contributions + +Les contributions sont bienvenues ! Pour commencer, vous pouvez regarder les tickets ouvert sur le dépôt. Certaines sont marqués comme étant "besoin d'aide", et ne demandent que vous pour être résoluts ! + +Afin de faciliter le développement collaboratif, vous pouvez commencer par commenter le ticket qui vous intéresse, et expliquer ce que vous comptez faire. + +Sinon, vous pouvez aussi ouvrir un ticket pour proposer des améliorations, des suggestions, ou autre. + +Vous pouvez ensuite ouvrir une merge request, et une fois relue, elle sera mise en place ! À ce stade, merci beaucoup :) + +## Licence + +Ce site web est placé sur licence *GNU Affero General Public License v3.0.*. +---- +[ 🇬🇧 Read the english version by clicking this link.](README.en.md) diff --git a/Vagrantfile b/Vagrantfile index 6a8dae937c562a07fcf51e22e4b93115b38ab892..cc9fb186f9f965a8445bf03ba10c7de2d832e7e1 100644 --- a/Vagrantfile +++ b/Vagrantfile @@ -13,6 +13,8 @@ Vagrant.configure("2") do |config| # Every Vagrant development environment requires a box. You can search for # boxes at https://vagrantcloud.com/search. config.vm.box = "debian/bullseye64" + + config.vm.define "don-debian64" # Disable automatic box update checking. If you disable this, then # boxes will only be checked for updates when the user runs @@ -23,16 +25,17 @@ Vagrant.configure("2") do |config| # within the machine from a port on the host machine. In the example below, # accessing "localhost:8080" will access port 80 on the guest machine. # NOTE: This will enable public access to the opened port - config.vm.network "forwarded_port", guest: 8000, host: 8383 + # config.vm.network "forwarded_port", guest: 80, host: 3141 + # config.vm.network "forwarded_port", guest: 8000, host: 3141 # Create a forwarded port mapping which allows access to a specific port # within the machine from a port on the host machine and only allow access # via 127.0.0.1 to disable public access - # config.vm.network "forwarded_port", guest: 80, host: 8080, host_ip: "127.0.0.1" + config.vm.network "forwarded_port", guest: 80, host: 8282, host_ip: "127.0.0.1" # Create a private network, which allows host-only access to the machine # using a specific IP. - config.vm.network "private_network", ip: "192.168.56.1" + # config.vm.network "private_network", ip: "192.168.56.42" # Create a public network, which generally matched to bridged network. # Bridged networks make the machine appear as another physical device on @@ -43,28 +46,15 @@ Vagrant.configure("2") do |config| # the path on the host to the actual folder. The second argument is # the path on the guest to mount the folder. And the optional third # argument is a set of non-required options. - # config.vm.synced_folder "../data", "/vagrant_data" - # Provider-specific configuration so you can fine-tune various - # backing providers for Vagrant. These expose provider-specific options. - # Example for VirtualBox: - # - # config.vm.provider "virtualbox" do |vb| - # # Display the VirtualBox GUI when booting the machine - # vb.gui = true - # - # # Customize the amount of memory on the VM: - # vb.memory = "1024" - # end - # - # View the documentation for the provider you are using for more - # information on available options. + # Si vous voulez avoir la possibilité de faire des modifications directement + # dans le dossier local, et voir les modifications sans avoir besoin de faire + # `vagrant provision`, vous pouvez décommenter la ligne ci-dessous avant de + # faire `vagrant up && vagrant provision`. - # Enable provisioning with a shell script. Additional provisioners such as - # Ansible, Chef, Docker, Puppet and Salt are also available. Please see the - # documentation for more information about their specific syntax and use. - # config.vm.provision "shell", inline: <<-SHELL - # apt-get update - # apt-get install -y apache2 - # SHELL + config.vm.synced_folder "./", "/home/don/don", owner: 998, group: 33 + + config.vm.provision "ansible" do |ansible| + ansible.playbook = "ansible/playbook.yml" + end end diff --git a/ansible/ansible-role-nginx/.ansible-lint b/ansible/ansible-role-nginx/.ansible-lint new file mode 100644 index 0000000000000000000000000000000000000000..acc82551f3082882271ee61774c60656278aa413 --- /dev/null +++ b/ansible/ansible-role-nginx/.ansible-lint @@ -0,0 +1,3 @@ +skip_list: + - 'yaml' + - 'role-name' diff --git a/ansible/ansible-role-nginx/.github/FUNDING.yml b/ansible/ansible-role-nginx/.github/FUNDING.yml new file mode 100644 index 0000000000000000000000000000000000000000..96b493831070d8a9ebee64c8405698aba8718f91 --- /dev/null +++ b/ansible/ansible-role-nginx/.github/FUNDING.yml @@ -0,0 +1,4 @@ +# These are supported funding model platforms +--- +github: geerlingguy +patreon: geerlingguy diff --git a/ansible/ansible-role-nginx/.github/stale.yml b/ansible/ansible-role-nginx/.github/stale.yml new file mode 100644 index 0000000000000000000000000000000000000000..3cc6ec313aeff60d13865c4709cc223de435aa7c --- /dev/null +++ b/ansible/ansible-role-nginx/.github/stale.yml @@ -0,0 +1,57 @@ +# Configuration for probot-stale - https://github.com/probot/stale + +# Number of days of inactivity before an Issue or Pull Request becomes stale +daysUntilStale: 90 + +# Number of days of inactivity before an Issue or Pull Request with the stale label is closed. +# Set to false to disable. If disabled, issues still need to be closed manually, but will remain marked as stale. +daysUntilClose: 30 + +# Only issues or pull requests with all of these labels are check if stale. Defaults to `[]` (disabled) +onlyLabels: [] + +# Issues or Pull Requests with these labels will never be considered stale. Set to `[]` to disable +exemptLabels: + - bug + - pinned + - security + - planned + +# Set to true to ignore issues in a project (defaults to false) +exemptProjects: false + +# Set to true to ignore issues in a milestone (defaults to false) +exemptMilestones: false + +# Set to true to ignore issues with an assignee (defaults to false) +exemptAssignees: false + +# Label to use when marking as stale +staleLabel: stale + +# Limit the number of actions per hour, from 1-30. Default is 30 +limitPerRun: 30 + +pulls: + markComment: |- + This pull request has been marked 'stale' due to lack of recent activity. If there is no further activity, the PR will be closed in another 30 days. Thank you for your contribution! + + Please read [this blog post](https://www.jeffgeerling.com/blog/2020/enabling-stale-issue-bot-on-my-github-repositories) to see the reasons why I mark pull requests as stale. + + unmarkComment: >- + This pull request is no longer marked for closure. + + closeComment: >- + This pull request has been closed due to inactivity. If you feel this is in error, please reopen the pull request or file a new PR with the relevant details. + +issues: + markComment: |- + This issue has been marked 'stale' due to lack of recent activity. If there is no further activity, the issue will be closed in another 30 days. Thank you for your contribution! + + Please read [this blog post](https://www.jeffgeerling.com/blog/2020/enabling-stale-issue-bot-on-my-github-repositories) to see the reasons why I mark issues as stale. + + unmarkComment: >- + This issue is no longer marked for closure. + + closeComment: >- + This issue has been closed due to inactivity. If you feel this is in error, please reopen the issue or file a new issue with the relevant details. diff --git a/ansible/ansible-role-nginx/.github/workflows/ci.yml b/ansible/ansible-role-nginx/.github/workflows/ci.yml new file mode 100644 index 0000000000000000000000000000000000000000..5517ecb844f9e70f281fe8550125558179db6fdf --- /dev/null +++ b/ansible/ansible-role-nginx/.github/workflows/ci.yml @@ -0,0 +1,68 @@ +--- +name: CI +'on': + pull_request: + push: + branches: + - master + schedule: + - cron: "0 6 * * 3" + +defaults: + run: + working-directory: 'geerlingguy.nginx' + +jobs: + + lint: + name: Lint + runs-on: ubuntu-latest + steps: + - name: Check out the codebase. + uses: actions/checkout@v2 + with: + path: 'geerlingguy.nginx' + + - name: Set up Python 3. + uses: actions/setup-python@v2 + with: + python-version: '3.x' + + - name: Install test dependencies. + run: pip3 install yamllint + + - name: Lint code. + run: | + yamllint . + + molecule: + name: Molecule + runs-on: ubuntu-latest + strategy: + matrix: + distro: + - rockylinux8 + - ubuntu2004 + - ubuntu1804 + - debian10 + + steps: + - name: Check out the codebase. + uses: actions/checkout@v2 + with: + path: 'geerlingguy.nginx' + + - name: Set up Python 3. + uses: actions/setup-python@v2 + with: + python-version: '3.x' + + - name: Install test dependencies. + run: pip3 install ansible molecule[docker] docker + + - name: Run Molecule tests. + run: molecule test + env: + PY_COLORS: '1' + ANSIBLE_FORCE_COLOR: '1' + MOLECULE_DISTRO: ${{ matrix.distro }} diff --git a/ansible/ansible-role-nginx/.github/workflows/release.yml b/ansible/ansible-role-nginx/.github/workflows/release.yml new file mode 100644 index 0000000000000000000000000000000000000000..3807ec24998064203a664afca8736e5b819c2d82 --- /dev/null +++ b/ansible/ansible-role-nginx/.github/workflows/release.yml @@ -0,0 +1,40 @@ +--- +# This workflow requires a GALAXY_API_KEY secret present in the GitHub +# repository or organization. +# +# See: https://github.com/marketplace/actions/publish-ansible-role-to-galaxy +# See: https://github.com/ansible/galaxy/issues/46 + +name: Release +'on': + push: + tags: + - '*' + +defaults: + run: + working-directory: 'geerlingguy.nginx' + +jobs: + + release: + name: Release + runs-on: ubuntu-latest + steps: + - name: Check out the codebase. + uses: actions/checkout@v2 + with: + path: 'geerlingguy.nginx' + + - name: Set up Python 3. + uses: actions/setup-python@v2 + with: + python-version: '3.x' + + - name: Install Ansible. + run: pip3 install ansible-core + + - name: Trigger a new import on Galaxy. + run: >- + ansible-galaxy role import --api-key ${{ secrets.GALAXY_API_KEY }} + $(echo ${{ github.repository }} | cut -d/ -f1) $(echo ${{ github.repository }} | cut -d/ -f2) diff --git a/ansible/ansible-role-nginx/.gitignore b/ansible/ansible-role-nginx/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..8840c8f0279f648c413926f94d1039e0c4bfdd92 --- /dev/null +++ b/ansible/ansible-role-nginx/.gitignore @@ -0,0 +1,5 @@ +*.retry +*/__pycache__ +*.pyc +.cache + diff --git a/ansible/ansible-role-nginx/.yamllint b/ansible/ansible-role-nginx/.yamllint new file mode 100644 index 0000000000000000000000000000000000000000..f2033dd21ac9da2cf88fd6fda110b6f845cdb527 --- /dev/null +++ b/ansible/ansible-role-nginx/.yamllint @@ -0,0 +1,11 @@ +--- +extends: default + +rules: + line-length: + max: 120 + level: warning + +ignore: | + .github/stale.yml + .travis.yml diff --git a/ansible/ansible-role-nginx/LICENSE b/ansible/ansible-role-nginx/LICENSE new file mode 100644 index 0000000000000000000000000000000000000000..4275cf3c10aae9c3992998fbf54f90bae9615960 --- /dev/null +++ b/ansible/ansible-role-nginx/LICENSE @@ -0,0 +1,20 @@ +The MIT License (MIT) + +Copyright (c) 2017 Jeff Geerling + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/ansible/ansible-role-nginx/README.md b/ansible/ansible-role-nginx/README.md new file mode 100644 index 0000000000000000000000000000000000000000..08dfeefdf036b9abaf16f2d344d46d50e88b3490 --- /dev/null +++ b/ansible/ansible-role-nginx/README.md @@ -0,0 +1,246 @@ +# Ansible Role: Nginx + +[![CI](https://github.com/geerlingguy/ansible-role-nginx/workflows/CI/badge.svg?event=push)](https://github.com/geerlingguy/ansible-role-nginx/actions?query=workflow%3ACI) + +**Note:** Please consider using the official [NGINX Ansible role](https://github.com/nginxinc/ansible-role-nginx) from NGINX, Inc. + +Installs Nginx on RedHat/CentOS, Debian/Ubuntu, Archlinux, FreeBSD or OpenBSD servers. + +This role installs and configures the latest version of Nginx from the Nginx yum repository (on RedHat-based systems), apt (on Debian-based systems), pacman (Archlinux), pkgng (on FreeBSD systems) or pkg_add (on OpenBSD systems). You will likely need to do extra setup work after this role has installed Nginx, like adding your own [virtualhost].conf file inside `/etc/nginx/conf.d/`, describing the location and options to use for your particular website. + +## Requirements + +None. + +## Role Variables + +Available variables are listed below, along with default values (see `defaults/main.yml`): + + + nginx_listen_ipv6: true + +Whether or not to listen on IPv6 (applied to all vhosts managed by this role). + + nginx_vhosts: [] + +A list of vhost definitions (server blocks) for Nginx virtual hosts. Each entry will create a separate config file named by `server_name`. If left empty, you will need to supply your own virtual host configuration. See the commented example in `defaults/main.yml` for available server options. If you have a large number of customizations required for your server definition(s), you're likely better off managing the vhost configuration file yourself, leaving this variable set to `[]`. + + nginx_vhosts: + - listen: "443 ssl http2" + server_name: "example.com" + server_name_redirect: "www.example.com" + root: "/var/www/example.com" + index: "index.php index.html index.htm" + error_page: "" + access_log: "" + error_log: "" + state: "present" + template: "{{ nginx_vhost_template }}" + filename: "example.com.conf" + extra_parameters: | + location ~ \.php$ { + fastcgi_split_path_info ^(.+\.php)(/.+)$; + fastcgi_pass unix:/var/run/php5-fpm.sock; + fastcgi_index index.php; + fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; + include fastcgi_params; + } + ssl_certificate /etc/ssl/certs/ssl-cert-snakeoil.pem; + ssl_certificate_key /etc/ssl/private/ssl-cert-snakeoil.key; + ssl_protocols TLSv1.1 TLSv1.2; + ssl_ciphers HIGH:!aNULL:!MD5; + +An example of a fully-populated nginx_vhosts entry, using a `|` to declare a block of syntax for the `extra_parameters`. + +Please take note of the indentation in the above block. The first line should be a normal 2-space indent. All other lines should be indented normally relative to that line. In the generated file, the entire block will be 4-space indented. This style will ensure the config file is indented correctly. + + - listen: "80" + server_name: "example.com www.example.com" + return: "301 https://example.com$request_uri" + filename: "example.com.80.conf" + +An example of a secondary vhost which will redirect to the one shown above. + +*Note: The `filename` defaults to the first domain in `server_name`, if you have two vhosts with the same domain, eg. a redirect, you need to manually set the `filename` so the second one doesn't override the first one* + + nginx_remove_default_vhost: false + +Whether to remove the 'default' virtualhost configuration supplied by Nginx. Useful if you want the base `/` URL to be directed at one of your own virtual hosts configured in a separate .conf file. + + nginx_upstreams: [] + +If you are configuring Nginx as a load balancer, you can define one or more upstream sets using this variable. In addition to defining at least one upstream, you would need to configure one of your server blocks to proxy requests through the defined upstream (e.g. `proxy_pass http://myapp1;`). See the commented example in `defaults/main.yml` for more information. + + nginx_user: "nginx" + +The user under which Nginx will run. Defaults to `nginx` for RedHat, `www-data` for Debian and `www` on FreeBSD and OpenBSD. + + nginx_worker_processes: "{{ ansible_processor_vcpus|default(ansible_processor_count) }}" + nginx_worker_connections: "1024" + nginx_multi_accept: "off" + +`nginx_worker_processes` should be set to the number of cores present on your machine (if the default is incorrect, find this number with `grep processor /proc/cpuinfo | wc -l`). `nginx_worker_connections` is the number of connections per process. Set this higher to handle more simultaneous connections (and remember that a connection will be used for as long as the keepalive timeout duration for every client!). You can set `nginx_multi_accept` to `on` if you want Nginx to accept all connections immediately. + + nginx_error_log: "/var/log/nginx/error.log warn" + nginx_access_log: "/var/log/nginx/access.log main buffer=16k flush=2m" + +Configuration of the default error and access logs. Set to `off` to disable a log entirely. + + nginx_sendfile: "on" + nginx_tcp_nopush: "on" + nginx_tcp_nodelay: "on" + +TCP connection options. See [this blog post](https://t37.net/nginx-optimization-understanding-sendfile-tcp_nodelay-and-tcp_nopush.html) for more information on these directives. + + nginx_keepalive_timeout: "65" + nginx_keepalive_requests: "100" + +Nginx keepalive settings. Timeout should be set higher (10s+) if you have more polling-style traffic (AJAX-powered sites especially), or lower (<10s) if you have a site where most users visit a few pages and don't send any further requests. + + nginx_server_tokens: "on" + +Nginx server_tokens settings. Controls whether nginx responds with it's version in HTTP headers. Set to `"off"` to disable. + + nginx_client_max_body_size: "64m" + +This value determines the largest file upload possible, as uploads are passed through Nginx before hitting a backend like `php-fpm`. If you get an error like `client intended to send too large body`, it means this value is set too low. + + nginx_server_names_hash_bucket_size: "64" + +If you have many server names, or have very long server names, you might get an Nginx error on startup requiring this value to be increased. + + nginx_proxy_cache_path: "" + +Set as the `proxy_cache_path` directive in the `nginx.conf` file. By default, this will not be configured (if left as an empty string), but if you wish to use Nginx as a reverse proxy, you can set this to a valid value (e.g. `"/var/cache/nginx keys_zone=cache:32m"`) to use Nginx's cache (further proxy configuration can be done in individual server configurations). + + nginx_extra_http_options: "" + +Extra lines to be inserted in the top-level `http` block in `nginx.conf`. The value should be defined literally (as you would insert it directly in the `nginx.conf`, adhering to the Nginx configuration syntax - such as `;` for line termination, etc.), for example: + + nginx_extra_http_options: | + proxy_buffering off; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Scheme $scheme; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header Host $http_host; + +See the template in `templates/nginx.conf.j2` for more details on the placement. + + nginx_extra_conf_options: "" + +Extra lines to be inserted in the top of `nginx.conf`. The value should be defined literally (as you would insert it directly in the `nginx.conf`, adhering to the Nginx configuration syntax - such as `;` for line termination, etc.), for example: + + nginx_extra_conf_options: | + worker_rlimit_nofile 8192; + +See the template in `templates/nginx.conf.j2` for more details on the placement. + + nginx_log_format: |- + '$remote_addr - $remote_user [$time_local] "$request" ' + '$status $body_bytes_sent "$http_referer" ' + '"$http_user_agent" "$http_x_forwarded_for"' + +Configures Nginx's [`log_format`](http://nginx.org/en/docs/http/ngx_http_log_module.html#log_format). options. + + nginx_default_release: "" + +(For Debian/Ubuntu only) Allows you to set a different repository for the installation of Nginx. As an example, if you are running Debian's wheezy release, and want to get a newer version of Nginx, you can install the `wheezy-backports` repository and set that value here, and Ansible will use that as the `-t` option while installing Nginx. + + nginx_ppa_use: false + nginx_ppa_version: stable + +(For Ubuntu only) Allows you to use the official Nginx PPA instead of the system's package. You can set the version to `stable` or `development`. + + nginx_yum_repo_enabled: true + +(For RedHat/CentOS only) Set this to `false` to disable the installation of the `nginx` yum repository. This could be necessary if you want the default OS stable packages, or if you use Satellite. + + nginx_service_state: started + nginx_service_enabled: yes + +By default, this role will ensure Nginx is running and enabled at boot after Nginx is configured. You can use these variables to override this behavior if installing in a container or further control over the service state is required. + +## Overriding configuration templates + +If you can't customize via variables because an option isn't exposed, you can override the template used to generate the virtualhost configuration files or the `nginx.conf` file. + +```yaml +nginx_conf_template: "nginx.conf.j2" +nginx_vhost_template: "vhost.j2" +``` + +If necessary you can also set the template on a per vhost basis. + +```yaml +nginx_vhosts: + - listen: "80 default_server" + server_name: "site1.example.com" + root: "/var/www/site1.example.com" + index: "index.php index.html index.htm" + template: "{{ playbook_dir }}/templates/site1.example.com.vhost.j2" + - server_name: "site2.example.com" + root: "/var/www/site2.example.com" + index: "index.php index.html index.htm" + template: "{{ playbook_dir }}/templates/site2.example.com.vhost.j2" +``` + +You can either copy and modify the provided template, or extend it with [Jinja2 template inheritance](http://jinja.pocoo.org/docs/2.9/templates/#template-inheritance) and override the specific template block you need to change. + +### Example: Configure gzip in nginx configuration + +Set the `nginx_conf_template` to point to a template file in your playbook directory. + +```yaml +nginx_conf_template: "{{ playbook_dir }}/templates/nginx.conf.j2" +``` + +Create the child template in the path you configured above and extend `geerlingguy.nginx` template file relative to your `playbook.yml`. + +``` +{% extends 'roles/geerlingguy.nginx/templates/nginx.conf.j2' %} + +{% block http_gzip %} + gzip on; + gzip_proxied any; + gzip_static on; + gzip_http_version 1.0; + gzip_disable "MSIE [1-6]\."; + gzip_vary on; + gzip_comp_level 6; + gzip_types + text/plain + text/css + text/xml + text/javascript + application/javascript + application/x-javascript + application/json + application/xml + application/xml+rss + application/xhtml+xml + application/x-font-ttf + application/x-font-opentype + image/svg+xml + image/x-icon; + gzip_buffers 16 8k; + gzip_min_length 512; +{% endblock %} +``` + +## Dependencies + +None. + +## Example Playbook + + - hosts: server + roles: + - { role: geerlingguy.nginx } + +## License + +MIT / BSD + +## Author Information + +This role was created in 2014 by [Jeff Geerling](https://www.jeffgeerling.com/), author of [Ansible for DevOps](https://www.ansiblefordevops.com/). diff --git a/ansible/ansible-role-nginx/defaults/main.yml b/ansible/ansible-role-nginx/defaults/main.yml new file mode 100644 index 0000000000000000000000000000000000000000..3178cd56221e045ac93d9a5ffe0c086f4f506566 --- /dev/null +++ b/ansible/ansible-role-nginx/defaults/main.yml @@ -0,0 +1,93 @@ +--- +# Used only for Debian/Ubuntu installation, as the -t option for apt. +nginx_default_release: "" + +# Used only for Redhat installation, enables source Nginx repo. +nginx_yum_repo_enabled: true + +# Use the official Nginx PPA for Ubuntu, and the version to use if so. +nginx_ppa_use: false +nginx_ppa_version: stable + +# The name of the nginx package to install. +nginx_package_name: "nginx" + +nginx_service_state: started +nginx_service_enabled: true + +nginx_conf_template: "nginx.conf.j2" +nginx_vhost_template: "vhost.j2" + +nginx_worker_processes: >- + "{{ ansible_processor_vcpus | default(ansible_processor_count) }}" +nginx_worker_connections: "1024" +nginx_multi_accept: "off" + +nginx_error_log: "/var/log/nginx/error.log warn" +nginx_access_log: "/var/log/nginx/access.log main buffer=16k flush=2m" + +nginx_sendfile: "on" +nginx_tcp_nopush: "on" +nginx_tcp_nodelay: "on" + +nginx_keepalive_timeout: "65" +nginx_keepalive_requests: "100" + +nginx_server_tokens: "on" + +nginx_client_max_body_size: "64m" + +nginx_server_names_hash_bucket_size: "64" + +nginx_proxy_cache_path: "" + +nginx_extra_conf_options: "" +# Example extra main options, used within the main nginx's context: +# nginx_extra_conf_options: | +# env VARIABLE; +# include /etc/nginx/main.d/*.conf; + +nginx_extra_http_options: "" +# Example extra http options, printed inside the main server http config: +# nginx_extra_http_options: | +# proxy_buffering off; +# proxy_set_header X-Real-IP $remote_addr; +# proxy_set_header X-Scheme $scheme; +# proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; +# proxy_set_header Host $http_host; + +nginx_remove_default_vhost: false + +# Listen on IPv6 (default: true) +nginx_listen_ipv6: true + +nginx_vhosts: [] +# Example vhost below, showing all available options: +# - listen: "80" # default: "80" +# server_name: "example.com" # default: N/A +# root: "/var/www/example.com" # default: N/A +# index: "index.html index.htm" # default: "index.html index.htm" +# filename: "example.com.conf" # Can be used to set the vhost filename. +# +# # Properties that are only added if defined: +# server_name_redirect: "www.example.com" # default: N/A +# error_page: "" +# access_log: "" +# error_log: "" +# extra_parameters: "" # Can be used to add extra config blocks (multiline). +# template: "" # Can be used to override the `nginx_vhost_template` per host. +# state: "absent" # To remove the vhost configuration. + +nginx_upstreams: [] +# - name: myapp1 +# strategy: "ip_hash" # "least_conn", etc. +# keepalive: 16 # optional +# servers: +# - "srv1.example.com" +# - "srv2.example.com weight=3" +# - "srv3.example.com" + +nginx_log_format: |- + '$remote_addr - $remote_user [$time_local] "$request" ' + '$status $body_bytes_sent "$http_referer" ' + '"$http_user_agent" "$http_x_forwarded_for"' diff --git a/ansible/ansible-role-nginx/handlers/main.yml b/ansible/ansible-role-nginx/handlers/main.yml new file mode 100644 index 0000000000000000000000000000000000000000..2db781ee4110ed78ff790e52d1689de6443c3863 --- /dev/null +++ b/ansible/ansible-role-nginx/handlers/main.yml @@ -0,0 +1,10 @@ +--- +- name: restart nginx + service: name=nginx state=restarted + +- name: validate nginx configuration + command: nginx -t -c /etc/nginx/nginx.conf + changed_when: false + +- name: reload nginx + service: name=nginx state=reloaded diff --git a/ansible/ansible-role-nginx/meta/main.yml b/ansible/ansible-role-nginx/meta/main.yml new file mode 100644 index 0000000000000000000000000000000000000000..0033d24cbd79b2f2aa72e2fb8d2c0aca776f79fc --- /dev/null +++ b/ansible/ansible-role-nginx/meta/main.yml @@ -0,0 +1,45 @@ +--- +dependencies: [] + +galaxy_info: + role_name: nginx + author: geerlingguy + description: Nginx installation for Linux, FreeBSD and OpenBSD. + company: "Midwestern Mac, LLC" + license: "license (BSD, MIT)" + min_ansible_version: 2.4 + platforms: + - name: EL + versions: + - 7 + - 8 + - name: Debian + versions: + - all + - name: Ubuntu + versions: + - trusty + - xenial + - focal + - name: Archlinux + versions: + - all + - name: FreeBSD + versions: + - 10.3 + - 10.2 + - 10.1 + - 10.0 + - 9.3 + - name: OpenBSD + versions: + - 5.9 + - 6.0 + galaxy_tags: + - development + - web + - nginx + - reverse + - proxy + - load + - balancer diff --git a/ansible/ansible-role-nginx/molecule/default/converge.yml b/ansible/ansible-role-nginx/molecule/default/converge.yml new file mode 100644 index 0000000000000000000000000000000000000000..ee651977b77257d066204139a32135f48a1ecad0 --- /dev/null +++ b/ansible/ansible-role-nginx/molecule/default/converge.yml @@ -0,0 +1,19 @@ +--- +- name: Converge + hosts: all + + vars: + nginx_use_ppa: true + nginx_remove_default_vhost: true + nginx_vhosts: + - server_name: "test.dev" + root: "/var/www/test" + + pre_tasks: + - name: Update apt cache. + apt: update_cache=yes cache_valid_time=600 + when: ansible_os_family == 'Debian' + changed_when: false + + roles: + - role: geerlingguy.nginx diff --git a/ansible/ansible-role-nginx/molecule/default/molecule.yml b/ansible/ansible-role-nginx/molecule/default/molecule.yml new file mode 100644 index 0000000000000000000000000000000000000000..74907107f67bb0d2b45d0fcb7271a8da477dc548 --- /dev/null +++ b/ansible/ansible-role-nginx/molecule/default/molecule.yml @@ -0,0 +1,17 @@ +--- +dependency: + name: galaxy +driver: + name: docker +platforms: + - name: instance + image: "geerlingguy/docker-${MOLECULE_DISTRO:-centos7}-ansible:latest" + command: ${MOLECULE_DOCKER_COMMAND:-""} + volumes: + - /sys/fs/cgroup:/sys/fs/cgroup:ro + privileged: true + pre_build_image: true +provisioner: + name: ansible + playbooks: + converge: ${MOLECULE_PLAYBOOK:-converge.yml} diff --git a/ansible/ansible-role-nginx/tasks/main.yml b/ansible/ansible-role-nginx/tasks/main.yml new file mode 100644 index 0000000000000000000000000000000000000000..bcf3ccec5272a78e310103032ccc4539de54f50f --- /dev/null +++ b/ansible/ansible-role-nginx/tasks/main.yml @@ -0,0 +1,48 @@ +--- +# Variable setup. +- name: Include OS-specific variables. + include_vars: "{{ ansible_os_family }}.yml" + +- name: Define nginx_user. + set_fact: + nginx_user: "{{ __nginx_user }}" + when: nginx_user is not defined + +# Setup/install tasks. +- include_tasks: setup-RedHat.yml + when: ansible_os_family == 'RedHat' or ansible_os_family == 'Rocky' + +- include_tasks: setup-Ubuntu.yml + when: ansible_distribution == 'Ubuntu' + +- include_tasks: setup-Debian.yml + when: ansible_os_family == 'Debian' + +- include_tasks: setup-FreeBSD.yml + when: ansible_os_family == 'FreeBSD' + +- include_tasks: setup-OpenBSD.yml + when: ansible_os_family == 'OpenBSD' + +- include_tasks: setup-Archlinux.yml + when: ansible_os_family == 'Archlinux' + +# Vhost configuration. +- import_tasks: vhosts.yml + +# Nginx setup. +- name: Copy nginx configuration in place. + template: + src: "{{ nginx_conf_template }}" + dest: "{{ nginx_conf_file_path }}" + owner: root + group: "{{ root_group }}" + mode: 0644 + notify: + - reload nginx + +- name: Ensure nginx service is running as configured. + service: + name: nginx + state: "{{ nginx_service_state }}" + enabled: "{{ nginx_service_enabled }}" diff --git a/ansible/ansible-role-nginx/tasks/setup-Archlinux.yml b/ansible/ansible-role-nginx/tasks/setup-Archlinux.yml new file mode 100644 index 0000000000000000000000000000000000000000..46e1f5bdf85a8db5a7f177401fed17a803b43514 --- /dev/null +++ b/ansible/ansible-role-nginx/tasks/setup-Archlinux.yml @@ -0,0 +1,5 @@ +--- +- name: Ensure nginx is installed. + pacman: + name: "{{ nginx_package_name }}" + state: present diff --git a/ansible/ansible-role-nginx/tasks/setup-Debian.yml b/ansible/ansible-role-nginx/tasks/setup-Debian.yml new file mode 100644 index 0000000000000000000000000000000000000000..554dc2e7778bf037179c23bb34be528d98ba2936 --- /dev/null +++ b/ansible/ansible-role-nginx/tasks/setup-Debian.yml @@ -0,0 +1,10 @@ +--- +- name: Update apt cache. + apt: update_cache=yes cache_valid_time=86400 + changed_when: false + +- name: Ensure nginx is installed. + apt: + name: "{{ nginx_package_name }}" + state: present + default_release: "{{ nginx_default_release }}" diff --git a/ansible/ansible-role-nginx/tasks/setup-FreeBSD.yml b/ansible/ansible-role-nginx/tasks/setup-FreeBSD.yml new file mode 100644 index 0000000000000000000000000000000000000000..637c5202d3fe92067c07656a7dc87c35cfe1578c --- /dev/null +++ b/ansible/ansible-role-nginx/tasks/setup-FreeBSD.yml @@ -0,0 +1,17 @@ +--- +- name: Update pkg cache. + command: pkg update -f + environment: + ASSUME_ALWAYS_YES: "yes" + tags: ['skip_ansible_lint'] + +- name: Ensure nginx is installed. + pkgng: + name: "{{ nginx_package_name }}" + state: present + +- name: Create logs directory. + file: + path: /var/log/nginx + state: directory + mode: 0755 diff --git a/ansible/ansible-role-nginx/tasks/setup-OpenBSD.yml b/ansible/ansible-role-nginx/tasks/setup-OpenBSD.yml new file mode 100644 index 0000000000000000000000000000000000000000..c75c27e4daec311359494280db31e8a7be41f192 --- /dev/null +++ b/ansible/ansible-role-nginx/tasks/setup-OpenBSD.yml @@ -0,0 +1,11 @@ +--- +- name: Ensure nginx is installed. + openbsd_pkg: + name: "{{ nginx_package_name }}" + state: present + +- name: Create logs directory. + file: + path: /var/log/nginx + state: directory + mode: 0755 diff --git a/ansible/ansible-role-nginx/tasks/setup-RedHat.yml b/ansible/ansible-role-nginx/tasks/setup-RedHat.yml new file mode 100644 index 0000000000000000000000000000000000000000..250739784259df33373f0773c98b16d39bb34d1d --- /dev/null +++ b/ansible/ansible-role-nginx/tasks/setup-RedHat.yml @@ -0,0 +1,14 @@ +--- +- name: Enable nginx repo. + template: + src: nginx.repo.j2 + dest: /etc/yum.repos.d/nginx.repo + owner: root + group: "{{ root_group }}" + mode: 0644 + when: nginx_yum_repo_enabled | bool + +- name: Ensure nginx is installed. + package: + name: "{{ nginx_package_name }}" + state: present diff --git a/ansible/ansible-role-nginx/tasks/setup-Ubuntu.yml b/ansible/ansible-role-nginx/tasks/setup-Ubuntu.yml new file mode 100644 index 0000000000000000000000000000000000000000..c608d25b9cce6c790e4a3d24f0be94afaeddc70c --- /dev/null +++ b/ansible/ansible-role-nginx/tasks/setup-Ubuntu.yml @@ -0,0 +1,20 @@ +--- +- name: Ensure dirmngr is installed (gnupg dependency). + apt: + name: dirmngr + state: present + +- name: Add PPA for Nginx (if configured). + apt_repository: + repo: 'ppa:nginx/{{ nginx_ppa_version }}' + state: present + update_cache: true + register: nginx_ppa_added + when: nginx_ppa_use | bool + +- name: Ensure nginx will reinstall if the PPA was just added. + apt: + name: nginx + state: absent + when: nginx_ppa_added is changed + tags: ['skip_ansible_lint'] diff --git a/ansible/ansible-role-nginx/tasks/vhosts.yml b/ansible/ansible-role-nginx/tasks/vhosts.yml new file mode 100644 index 0000000000000000000000000000000000000000..8f990fb0026375deb83c3b3011729fab1486cc65 --- /dev/null +++ b/ansible/ansible-role-nginx/tasks/vhosts.yml @@ -0,0 +1,44 @@ +--- +- name: Remove default nginx vhost config file (if configured). + file: + path: "{{ nginx_default_vhost_path }}" + state: absent + when: nginx_remove_default_vhost | bool + notify: restart nginx + +- name: Ensure nginx_vhost_path exists. + file: + path: "{{ nginx_vhost_path }}" + state: directory + mode: 0755 + notify: reload nginx + +- name: Add managed vhost config files. + template: + src: "{{ item.template|default(nginx_vhost_template) }}" + dest: "{{ nginx_vhost_path }}/{{ item.filename|default(item.server_name.split(' ')[0] ~ '.conf') }}" + force: true + owner: root + group: "{{ root_group }}" + mode: 0644 + when: item.state|default('present') != 'absent' + with_items: "{{ nginx_vhosts }}" + notify: reload nginx + tags: + - skip_ansible_lint + +- name: Remove managed vhost config files. + file: + path: "{{ nginx_vhost_path }}/{{ item.filename|default(item.server_name.split(' ')[0] ~ '.conf') }}" + state: absent + when: item.state|default('present') == 'absent' + with_items: "{{ nginx_vhosts }}" + notify: reload nginx + tags: + - skip_ansible_lint + +- name: Remove legacy vhosts.conf file. + file: + path: "{{ nginx_vhost_path }}/vhosts.conf" + state: absent + notify: reload nginx diff --git a/ansible/ansible-role-nginx/templates/nginx.conf.j2 b/ansible/ansible-role-nginx/templates/nginx.conf.j2 new file mode 100644 index 0000000000000000000000000000000000000000..7cdec60283cbda86e3d8a17a831537fe4ee4fa88 --- /dev/null +++ b/ansible/ansible-role-nginx/templates/nginx.conf.j2 @@ -0,0 +1,81 @@ +user {{ nginx_user }}; + +error_log {{ nginx_error_log }}; +pid {{ nginx_pidfile }}; + +{% block worker %} +worker_processes {{ nginx_worker_processes }}; +{% endblock %} + +{% if nginx_extra_conf_options %} +{{ nginx_extra_conf_options }} +{% endif %} + +{% block events %} +events { + worker_connections {{ nginx_worker_connections }}; + multi_accept {{ nginx_multi_accept }}; +} +{% endblock %} + +http { + {% block http_begin %}{% endblock %} + +{% block http_basic %} + include {{ nginx_mime_file_path }}; + default_type application/octet-stream; + + server_names_hash_bucket_size {{ nginx_server_names_hash_bucket_size }}; + + client_max_body_size {{ nginx_client_max_body_size }}; + + log_format main {{ nginx_log_format|indent(23) }}; + + access_log {{ nginx_access_log }}; + + sendfile {{ nginx_sendfile }}; + tcp_nopush {{ nginx_tcp_nopush }}; + tcp_nodelay {{ nginx_tcp_nodelay }}; + + keepalive_timeout {{ nginx_keepalive_timeout }}; + keepalive_requests {{ nginx_keepalive_requests }}; + + server_tokens {{ nginx_server_tokens }}; +{% if nginx_proxy_cache_path %} + proxy_cache_path {{ nginx_proxy_cache_path }}; +{% endif %} +{% endblock %} + +{% block http_gzip %} + # gzip on; +{% endblock %} + +{% if nginx_extra_http_options %} + {{ nginx_extra_http_options|indent(4, False) }} +{% endif %} + +{% block http_upstream %} +{% for upstream in nginx_upstreams %} + upstream {{ upstream.name }} { +{% if upstream.strategy is defined %} + {{ upstream.strategy }}; +{% endif %} +{% for server in upstream.servers %} + server {{ server }}; +{% endfor %} +{% if upstream.keepalive is defined %} + keepalive {{ upstream.keepalive }}; +{% endif %} + } +{% endfor %} +{% endblock %} + +{% block http_includes %} + include {{ nginx_conf_path }}/*.conf; +{% if nginx_conf_path != nginx_vhost_path %} + include {{ nginx_vhost_path }}/*; +{% endif %} +{% endblock %} + + {% block http_end %}{% endblock %} +} diff --git a/ansible/ansible-role-nginx/templates/nginx.repo.j2 b/ansible/ansible-role-nginx/templates/nginx.repo.j2 new file mode 100644 index 0000000000000000000000000000000000000000..9a853b70b03cd07925b1c2e61198ebd4321dff06 --- /dev/null +++ b/ansible/ansible-role-nginx/templates/nginx.repo.j2 @@ -0,0 +1,5 @@ +[nginx] +name=nginx repo +baseurl=http://nginx.org/packages/centos/{{ ansible_distribution_major_version }}/$basearch/ +gpgcheck=0 +enabled=1 diff --git a/ansible/ansible-role-nginx/templates/vhost.j2 b/ansible/ansible-role-nginx/templates/vhost.j2 new file mode 100644 index 0000000000000000000000000000000000000000..f419a0a02c5ff4f92e2098deb16773a80e8908cc --- /dev/null +++ b/ansible/ansible-role-nginx/templates/vhost.j2 @@ -0,0 +1,53 @@ +{% block server_redirect %} +{% if item.server_name_redirect is defined %} +server { + listen {{ item.listen | default('80') }}; +{% if nginx_listen_ipv6 %} + listen [::]:{{item.listen | default('80') }}; +{% endif %} + server_name {{ item.server_name_redirect }}; + return 301 $scheme://{{ item.server_name.split(' ')[0] }}$request_uri; +} +{% endif %} +{% endblock %} + +server { + {% block server_begin %}{% endblock %} + + {% block server_basic -%} + listen {{ item.listen | default('80') }}; +{% if nginx_listen_ipv6 %} + listen [::]:{{item.listen | default('80') }}; +{% endif %} + +{% if item.server_name is defined %} + server_name {{ item.server_name }}; +{% endif %} + +{% if item.root is defined %} + root {{ item.root }}; +{% endif %} + + index {{ item.index | default('index.html index.htm') }}; + +{% if item.error_page is defined %} + error_page {{ item.error_page }}; +{% endif %} +{% if item.access_log is defined %} + access_log {{ item.access_log }}; +{% endif %} +{% if item.error_log is defined %} + error_log {{ item.error_log }} error; +{% endif %} + +{% if item.return is defined %} + return {{ item.return }}; +{% endif %} + {% endblock %} + + {% block server_end %}{% endblock %} + +{% if item.extra_parameters is defined %} + {{ item.extra_parameters|indent(4) }} +{% endif %} +} diff --git a/ansible/ansible-role-nginx/vars/Archlinux.yml b/ansible/ansible-role-nginx/vars/Archlinux.yml new file mode 100644 index 0000000000000000000000000000000000000000..593e100f147f34608377e12c8a37ae73ce39732a --- /dev/null +++ b/ansible/ansible-role-nginx/vars/Archlinux.yml @@ -0,0 +1,9 @@ +--- +root_group: root +nginx_conf_path: /etc/nginx/conf.d +nginx_conf_file_path: /etc/nginx/nginx.conf +nginx_mime_file_path: /etc/nginx/mime.types +nginx_pidfile: /run/nginx.pid +nginx_vhost_path: /etc/nginx/sites-enabled +nginx_default_vhost_path: /etc/nginx/sites-enabled/default +__nginx_user: "http" diff --git a/ansible/ansible-role-nginx/vars/Debian.yml b/ansible/ansible-role-nginx/vars/Debian.yml new file mode 100644 index 0000000000000000000000000000000000000000..cb127706c59176a03df342a030e403d798c0bd51 --- /dev/null +++ b/ansible/ansible-role-nginx/vars/Debian.yml @@ -0,0 +1,9 @@ +--- +root_group: root +nginx_conf_path: /etc/nginx/conf.d +nginx_conf_file_path: /etc/nginx/nginx.conf +nginx_mime_file_path: /etc/nginx/mime.types +nginx_pidfile: /run/nginx.pid +nginx_vhost_path: /etc/nginx/sites-enabled +nginx_default_vhost_path: /etc/nginx/sites-enabled/default +__nginx_user: "www-data" diff --git a/ansible/ansible-role-nginx/vars/FreeBSD.yml b/ansible/ansible-role-nginx/vars/FreeBSD.yml new file mode 100644 index 0000000000000000000000000000000000000000..b032f98bca68d38662b608401433a19f222bd7d2 --- /dev/null +++ b/ansible/ansible-role-nginx/vars/FreeBSD.yml @@ -0,0 +1,9 @@ +--- +root_group: wheel +nginx_conf_path: /usr/local/etc/nginx/conf.d +nginx_conf_file_path: /usr/local/etc/nginx/nginx.conf +nginx_mime_file_path: /usr/local/etc/nginx/mime.types +nginx_pidfile: /var/run/nginx.pid +nginx_vhost_path: /usr/local/etc/nginx/sites-enabled +nginx_default_vhost_path: /usr/local/etc/nginx/sites-enabled/default +__nginx_user: "www" diff --git a/ansible/ansible-role-nginx/vars/OpenBSD.yml b/ansible/ansible-role-nginx/vars/OpenBSD.yml new file mode 100644 index 0000000000000000000000000000000000000000..a5a5c9dc272fc9bfff82b0306dabf7a02d02ffff --- /dev/null +++ b/ansible/ansible-role-nginx/vars/OpenBSD.yml @@ -0,0 +1,10 @@ +--- +root_group: wheel +nginx_conf_path: /etc/nginx/conf.d +nginx_conf_file_path: /etc/nginx/nginx.conf +nginx_mime_file_path: /etc/nginx/mime.types +nginx_pidfile: /var/run/nginx.pid +nginx_vhost_path: /etc/nginx/sites-enabled +nginx_default_vhost_path: /etc/nginx/sites-enabled/default +nginx_package_name: "nginx--" +__nginx_user: "www" diff --git a/ansible/ansible-role-nginx/vars/RedHat.yml b/ansible/ansible-role-nginx/vars/RedHat.yml new file mode 100644 index 0000000000000000000000000000000000000000..0138f8daabba7fb28b6a0cd873cf70582d7c8639 --- /dev/null +++ b/ansible/ansible-role-nginx/vars/RedHat.yml @@ -0,0 +1,9 @@ +--- +root_group: root +nginx_conf_path: /etc/nginx/conf.d +nginx_conf_file_path: /etc/nginx/nginx.conf +nginx_mime_file_path: /etc/nginx/mime.types +nginx_pidfile: /var/run/nginx.pid +nginx_vhost_path: /etc/nginx/conf.d +nginx_default_vhost_path: /etc/nginx/conf.d/default.conf +__nginx_user: "nginx" diff --git a/ansible/ansible-role-nginx/vars/Rocky.yml b/ansible/ansible-role-nginx/vars/Rocky.yml new file mode 100644 index 0000000000000000000000000000000000000000..0138f8daabba7fb28b6a0cd873cf70582d7c8639 --- /dev/null +++ b/ansible/ansible-role-nginx/vars/Rocky.yml @@ -0,0 +1,9 @@ +--- +root_group: root +nginx_conf_path: /etc/nginx/conf.d +nginx_conf_file_path: /etc/nginx/nginx.conf +nginx_mime_file_path: /etc/nginx/mime.types +nginx_pidfile: /var/run/nginx.pid +nginx_vhost_path: /etc/nginx/conf.d +nginx_default_vhost_path: /etc/nginx/conf.d/default.conf +__nginx_user: "nginx" diff --git a/ansible/ansible-role-php/.ansible-lint b/ansible/ansible-role-php/.ansible-lint new file mode 100644 index 0000000000000000000000000000000000000000..8d58b475f831815537560213adb8551837487d10 --- /dev/null +++ b/ansible/ansible-role-php/.ansible-lint @@ -0,0 +1,5 @@ +skip_list: + - 'yaml' + - 'risky-shell-pipe' + - 'no-handler' + - 'role-name' diff --git a/ansible/ansible-role-php/.github/FUNDING.yml b/ansible/ansible-role-php/.github/FUNDING.yml new file mode 100644 index 0000000000000000000000000000000000000000..96b493831070d8a9ebee64c8405698aba8718f91 --- /dev/null +++ b/ansible/ansible-role-php/.github/FUNDING.yml @@ -0,0 +1,4 @@ +# These are supported funding model platforms +--- +github: geerlingguy +patreon: geerlingguy diff --git a/ansible/ansible-role-php/.github/stale.yml b/ansible/ansible-role-php/.github/stale.yml new file mode 100644 index 0000000000000000000000000000000000000000..3cc6ec313aeff60d13865c4709cc223de435aa7c --- /dev/null +++ b/ansible/ansible-role-php/.github/stale.yml @@ -0,0 +1,57 @@ +# Configuration for probot-stale - https://github.com/probot/stale + +# Number of days of inactivity before an Issue or Pull Request becomes stale +daysUntilStale: 90 + +# Number of days of inactivity before an Issue or Pull Request with the stale label is closed. +# Set to false to disable. If disabled, issues still need to be closed manually, but will remain marked as stale. +daysUntilClose: 30 + +# Only issues or pull requests with all of these labels are check if stale. Defaults to `[]` (disabled) +onlyLabels: [] + +# Issues or Pull Requests with these labels will never be considered stale. Set to `[]` to disable +exemptLabels: + - bug + - pinned + - security + - planned + +# Set to true to ignore issues in a project (defaults to false) +exemptProjects: false + +# Set to true to ignore issues in a milestone (defaults to false) +exemptMilestones: false + +# Set to true to ignore issues with an assignee (defaults to false) +exemptAssignees: false + +# Label to use when marking as stale +staleLabel: stale + +# Limit the number of actions per hour, from 1-30. Default is 30 +limitPerRun: 30 + +pulls: + markComment: |- + This pull request has been marked 'stale' due to lack of recent activity. If there is no further activity, the PR will be closed in another 30 days. Thank you for your contribution! + + Please read [this blog post](https://www.jeffgeerling.com/blog/2020/enabling-stale-issue-bot-on-my-github-repositories) to see the reasons why I mark pull requests as stale. + + unmarkComment: >- + This pull request is no longer marked for closure. + + closeComment: >- + This pull request has been closed due to inactivity. If you feel this is in error, please reopen the pull request or file a new PR with the relevant details. + +issues: + markComment: |- + This issue has been marked 'stale' due to lack of recent activity. If there is no further activity, the issue will be closed in another 30 days. Thank you for your contribution! + + Please read [this blog post](https://www.jeffgeerling.com/blog/2020/enabling-stale-issue-bot-on-my-github-repositories) to see the reasons why I mark issues as stale. + + unmarkComment: >- + This issue is no longer marked for closure. + + closeComment: >- + This issue has been closed due to inactivity. If you feel this is in error, please reopen the issue or file a new issue with the relevant details. diff --git a/ansible/ansible-role-php/.github/workflows/ci.yml b/ansible/ansible-role-php/.github/workflows/ci.yml new file mode 100644 index 0000000000000000000000000000000000000000..96a41a6536b2074783a416f9b96275d4ae7646b7 --- /dev/null +++ b/ansible/ansible-role-php/.github/workflows/ci.yml @@ -0,0 +1,82 @@ +--- +name: CI +'on': + pull_request: + push: + branches: + - master + schedule: + - cron: "0 4 * * 4" + +defaults: + run: + working-directory: 'geerlingguy.php' + +jobs: + + lint: + name: Lint + runs-on: ubuntu-latest + steps: + - name: Check out the codebase. + uses: actions/checkout@v2 + with: + path: 'geerlingguy.php' + + - name: Set up Python 3. + uses: actions/setup-python@v2 + with: + python-version: '3.x' + + - name: Install test dependencies. + run: pip3 install yamllint + + - name: Lint code. + run: | + yamllint . + + molecule: + name: Molecule + runs-on: ubuntu-latest + strategy: + matrix: + include: + - distro: centos8 + playbook: converge.yml + - distro: centos7 + playbook: converge.yml + - distro: ubuntu2004 + playbook: converge.yml + - distro: ubuntu1804 + playbook: converge.yml + - distro: debian11 + playbook: converge.yml + - distro: debian10 + playbook: converge.yml + - distro: debian9 + playbook: converge.yml + + - distro: centos7 + playbook: source-install.yml + + steps: + - name: Check out the codebase. + uses: actions/checkout@v2 + with: + path: 'geerlingguy.php' + + - name: Set up Python 3. + uses: actions/setup-python@v2 + with: + python-version: '3.x' + + - name: Install test dependencies. + run: pip3 install ansible molecule[docker] docker + + - name: Run Molecule tests. + run: molecule test + env: + PY_COLORS: '1' + ANSIBLE_FORCE_COLOR: '1' + MOLECULE_DISTRO: ${{ matrix.distro }} + MOLECULE_PLAYBOOK: ${{ matrix.playbook }} diff --git a/ansible/ansible-role-php/.github/workflows/release.yml b/ansible/ansible-role-php/.github/workflows/release.yml new file mode 100644 index 0000000000000000000000000000000000000000..36cb2b5487fc492bbef04a22889a41b365c77605 --- /dev/null +++ b/ansible/ansible-role-php/.github/workflows/release.yml @@ -0,0 +1,40 @@ +--- +# This workflow requires a GALAXY_API_KEY secret present in the GitHub +# repository or organization. +# +# See: https://github.com/marketplace/actions/publish-ansible-role-to-galaxy +# See: https://github.com/ansible/galaxy/issues/46 + +name: Release +'on': + push: + tags: + - '*' + +defaults: + run: + working-directory: 'geerlingguy.php' + +jobs: + + release: + name: Release + runs-on: ubuntu-latest + steps: + - name: Check out the codebase. + uses: actions/checkout@v2 + with: + path: 'geerlingguy.php' + + - name: Set up Python 3. + uses: actions/setup-python@v2 + with: + python-version: '3.x' + + - name: Install Ansible. + run: pip3 install ansible-core + + - name: Trigger a new import on Galaxy. + run: >- + ansible-galaxy role import --api-key ${{ secrets.GALAXY_API_KEY }} + $(echo ${{ github.repository }} | cut -d/ -f1) $(echo ${{ github.repository }} | cut -d/ -f2) diff --git a/ansible/ansible-role-php/.gitignore b/ansible/ansible-role-php/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..8840c8f0279f648c413926f94d1039e0c4bfdd92 --- /dev/null +++ b/ansible/ansible-role-php/.gitignore @@ -0,0 +1,5 @@ +*.retry +*/__pycache__ +*.pyc +.cache + diff --git a/ansible/ansible-role-php/.yamllint b/ansible/ansible-role-php/.yamllint new file mode 100644 index 0000000000000000000000000000000000000000..f2033dd21ac9da2cf88fd6fda110b6f845cdb527 --- /dev/null +++ b/ansible/ansible-role-php/.yamllint @@ -0,0 +1,11 @@ +--- +extends: default + +rules: + line-length: + max: 120 + level: warning + +ignore: | + .github/stale.yml + .travis.yml diff --git a/ansible/ansible-role-php/LICENSE b/ansible/ansible-role-php/LICENSE new file mode 100644 index 0000000000000000000000000000000000000000..4275cf3c10aae9c3992998fbf54f90bae9615960 --- /dev/null +++ b/ansible/ansible-role-php/LICENSE @@ -0,0 +1,20 @@ +The MIT License (MIT) + +Copyright (c) 2017 Jeff Geerling + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/ansible/ansible-role-php/README.md b/ansible/ansible-role-php/README.md new file mode 100644 index 0000000000000000000000000000000000000000..7e7707efb82da8b6696dce7d520d2dbaca5aa60c --- /dev/null +++ b/ansible/ansible-role-php/README.md @@ -0,0 +1,247 @@ +# Ansible Role: PHP + +[![CI](https://github.com/geerlingguy/ansible-role-php/workflows/CI/badge.svg?event=push)](https://github.com/geerlingguy/ansible-role-php/actions?query=workflow%3ACI) + +Installs PHP on RedHat/CentOS and Debian/Ubuntu servers. + +## Requirements + +If you're using an older LTS release of Ubuntu or RHEL, with an old/outdated version of PHP, you need to use a repo or PPA with a maintained PHP version, as this role only works with [PHP versions that are currently supported](http://php.net/supported-versions.php) by the PHP community. + +## Role Variables + +Available variables are listed below, along with default values (see `defaults/main.yml`): + + php_packages: [] + +A list of the PHP packages to install (OS-specific by default). You'll likely want to install common packages like `php`, `php-cli`, `php-devel` and `php-pdo`, and you can add in whatever other packages you'd like (for example, `php-gd` for image manipulation, or `php-ldap` if you need to connect to an LDAP server for authentication). + +_Note: If you're using Debian/Ubuntu, you also need to install `libapache2-mod-fastcgi` (for cgi/PHP-FPM) or `libapache2-mod-php7.0` (or a similar package depending on PHP version) if you want to use `mod_php` with Apache._ + + php_packages_extra: [] + +A list of extra PHP packages to install without overriding the default list. + + php_enable_webserver: true + +If your usage of PHP is tied to a web server (e.g. Apache or Nginx), leave this default value. If you are using PHP server-side or to run some small application, set this value to `false` so this role doesn't attempt to interact with a web server. + + php_webserver_daemon: "httpd" + +The default values for the HTTP server deamon are `httpd` (used by Apache) for RedHat/CentOS, or `apache2` (also used by Apache) for Debian/Ubuntu. If you are running another webserver (for example, `nginx`), change this value to the name of the daemon under which the webserver runs. + + php_enablerepo: "" + +(RedHat/CentOS only) If you have enabled any additional repositories (might I suggest [geerlingguy.repo-epel](https://github.com/geerlingguy/ansible-role-repo-epel) or [geerlingguy.repo-remi](https://github.com/geerlingguy/ansible-role-repo-remi)), those repositories can be listed under this variable (e.g. `remi-php70,epel`). This can be handy, as an example, if you want to install the latest version of PHP 7.0, which is in the Remi repository. + + php_default_version_debian: "" + +(Debian/Ubuntu only) The default version of PHP in the given OS version repositories. The specific version is set per distro and per version, but you can override it by providing a value here, like `"7.4"`. + +**If you'd like to be able to switch PHP versions easily, or use a version that's not available in system packages**: You can use the [`geerlingguy.php-versions`](https://galaxy.ansible.com/geerlingguy/php-versions/) role to more easily switch between major PHP versions (e.g. 5.6, 7.1, 7.2). + + php_packages_state: "present" + +If you have enabled any additional repositories such as [geerlingguy.repo-epel](https://github.com/geerlingguy/ansible-role-repo-epel) or [geerlingguy.repo-remi](https://github.com/geerlingguy/ansible-role-repo-remi), you may want an easy way to swap PHP versions on the fly. By default, this is set to `"present"`. You can override this variable to `"latest"` to upgrade to the latest available version. Combined with `php_enablerepo`, a user now doesn't need to manually uninstall the existing PHP packages before installing them from a different repository. + + php_install_recommends: true + +(Debian/Ubuntu only) Whether to install recommended packages when installing `php_packages`; you might want to set this to `no` explicitly if you're installing a PPA that recommends certain packages you don't want (e.g. Ondrej's `php` PPA will install `php7.0-cli` if you install `php-pear` alongside `php5.6-cli`... which is often not desired!). + + php_executable: "php" + +The executable to run when calling PHP from the command line. You should only change this if running `php` on your server doesn't target the correct executable, or if you're using software collections on RHEL/CentOS and need to target a different version of PHP. + +### PHP-FPM + +PHP-FPM is a simple and robust FastCGI Process Manager for PHP. It can dramatically ease scaling of PHP apps and is the normal way of running PHP-based sites and apps when using a webserver like Nginx (though it can be used with other webservers just as easily). + +When using this role with PHP running as `php-fpm` instead of as a process inside a webserver (e.g. Apache's `mod_php`), you need to set the following variable to `true`: + + php_enable_php_fpm: false + +If you're using Apache, you can easily get it configured to work with PHP-FPM using the [geerlingguy.apache-php-fpm](https://github.com/geerlingguy/ansible-role-apache-php-fpm) role. + + php_fpm_state: started + php_fpm_enabled_on_boot: true + +Control over the fpm daemon's state; set these to `stopped` and `false` if you want FPM to be installed and configured, but not running (e.g. when installing in a container). + + php_fpm_handler_state: restarted + +The handler restarts PHP-FPM by default. Setting the value to `reloaded` will reload the service, intead of restarting it. + + + php_fpm_pools: + - pool_name: www + pool_template: www.conf.j2 + pool_listen: "127.0.0.1:9000" + pool_listen_allowed_clients: "127.0.0.1" + pool_pm: dynamic + pool_pm_max_children: 5 + pool_pm_start_servers: 2 + pool_pm_min_spare_servers: 1 + pool_pm_max_spare_servers: 3 + pool_pm_max_requests: 500 + +List of PHP-FPM pool to create. By default, www pool is created. To setup a new pool, add an item to php_fpm_pools list. + +Specific settings inside the default `www.conf.j2` PHP-FPM pool. If you'd like to manage additional settings, you can do so either by replacing the file with your own template using `pool_template`. + +### php.ini settings + + php_use_managed_ini: true + +By default, all the extra defaults below are applied through the php.ini included with this role. You can self-manage your php.ini file (if you need more flexility in its configuration) by setting this to `false` (in which case all the below variables will be ignored). + + php_fpm_pool_user: "[apache|nginx|other]" # default varies by OS + php_fpm_pool_group: "[apache|nginx|other]" # default varies by OS + php_memory_limit: "256M" + php_max_execution_time: "60" + php_max_input_time: "60" + php_max_input_vars: "1000" + php_realpath_cache_size: "32K" + php_file_uploads: "On" + php_upload_max_filesize: "64M" + php_max_file_uploads: "20" + php_post_max_size: "32M" + php_date_timezone: "America/Chicago" + php_allow_url_fopen: "On" + php_sendmail_path: "/usr/sbin/sendmail -t -i" + php_output_buffering: "4096" + php_short_open_tag: false + php_error_reporting: "E_ALL & ~E_DEPRECATED & ~E_STRICT" + php_display_errors: "Off" + php_display_startup_errors: "On" + php_expose_php: "On" + php_session_cookie_lifetime: 0 + php_session_gc_probability: 1 + php_session_gc_divisor: 1000 + php_session_gc_maxlifetime: 1440 + php_session_save_handler: files + php_session_save_path: '' + php_disable_functions: [] + php_precision: 14 + php_serialize_precision: "-1" + +Various defaults for PHP. Only used if `php_use_managed_ini` is set to `true`. + +### OpCache-related Variables + +The OpCache is included in PHP starting in version 5.5, and the following variables will only take effect if the version of PHP you have installed is 5.5 or greater. + + php_opcache_zend_extension: "opcache.so" + php_opcache_enable: "1" + php_opcache_enable_cli: "0" + php_opcache_memory_consumption: "96" + php_opcache_interned_strings_buffer: "16" + php_opcache_max_accelerated_files: "4096" + php_opcache_max_wasted_percentage: "5" + php_opcache_validate_timestamps: "1" + php_opcache_revalidate_path: "0" + php_opcache_revalidate_freq: "2" + php_opcache_max_file_size: "0" + +OpCache ini directives that are often customized on a system. Make sure you have enough memory and file slots allocated in the OpCache (`php_opcache_memory_consumption`, in MB, and `php_opcache_max_accelerated_files`) to contain all the PHP code you are running. If not, you may get less-than-optimal performance! + +For custom opcache.so location provide full path with `php_opcache_zend_extension`. + + php_opcache_conf_filename: [platform-specific] + +The platform-specific opcache configuration filename. Generally the default should work, but in some cases, you may need to override the filename. + +### APCu-related Variables + + php_enable_apc: true + +Whether to enable APCu. Other APCu variables will be ineffective if this is set to false. + + php_apc_shm_size: "96M" + php_apc_enable_cli: "0" + +APCu ini directives that are often customized on a system. Set the `php_apc_shm_size` so it will hold all cache entries in memory with a little overhead (fragmentation or APC running out of memory will slow down PHP *dramatically*). + + php_apc_conf_filename: [platform-specific] + +The platform-specific APC configuration filename. Generally the default should work, but in some cases, you may need to override the filename. + +#### Ensuring APC is installed + +If you use APC, you will need to make sure APC is installed (it is installed by default, but if you customize the `php_packages` list, you need to include APC in the list): + + - *On RHEL/CentOS systems*: Make sure `php-pecl-apcu` is in the list of `php_packages`. + - *On Debian/Ubuntu systems*: Make sure `php-apcu` is in the list of `php_packages`. + +### Installing from Source + +If you need a specific version of PHP, or would like to test the latest (e.g. master) version of PHP, there's a good chance there's no suitable package already available in your platform's package manager. In these cases, you may choose to install PHP from source by compiling it directly. + +Note that source compilation takes *much* longer than installing from packages (PHP HEAD takes 5+ minutes to compile on a modern quad-core computer, just as a point of reference). + + php_install_from_source: false + +Set this to `true` to install PHP from source instead of installing from packages. + + php_source_version: "master" + +The version of PHP to install from source (a git branch, tag, or commit hash). + + php_source_clone_dir: "~/php-src" + php_source_clone_depth: 1 + php_source_install_path: "/opt/php" + php_source_install_gmp_path: "/usr/include/x86_64-linux-gnu/gmp.h" + php_source_mysql_config: "/usr/bin/mysql_config" + +Location where source will be cloned and installed, and the location of the GMP header file (which can be platform/distribution specific), and `mysql_config` binary (this may be `mariadb_config` in newer operating system versions). + + php_source_make_command: "make" + +Set the `make` command to `make --jobs=X` where `X` is the number of cores present on the server where PHP is being compiled. Will speed up compilation times dramatically if you have multiple cores. + + php_source_configure_command: > + [...] + +The `./configure` command that will build the Makefile to be used for PHP compilation. Add in all the options you need for your particular environment. Using a folded scalar (`>`) allows you to define the variable over multiple lines, which is extremely helpful for legibility and source control! + +A few other notes/caveats for specific configurations: + + - **Apache with `mpm_prefork`**: If you're using Apache with prefork as a webserver for PHP, you will need to make sure `apxs2` is available on your system (e.g. by installing `apache2-prefork-dev` in Ubuntu), and you will need to make sure the option `--with-apxs2` is defined in `php_source_configure_command`. Finally, you will need to make sure the `mpm_prefork` module is loaded instead of `mpm_worker` or `mpm_event`, and likely add a `phpX.conf` (where `X` is the major version of PHP) configuration file to the Apache module config folder with contents like [`php7.conf`](https://gist.github.com/geerlingguy/5ae5445f28e71264e8c1). + - **Apache with `mpm_event` or `mpm_worker`**: If you're using Apache with event or worker as a webserver for PHP, you will need to compile PHP with FPM. Make sure the option `--enable-fpm` is defined in `php_source_configure_command`. You'll also need to make sure Apache's support for CGI and event is installed (e.g. by installing `apache2-mpm-event` and `libapache2-mod-fastcgi`) and the `mpm_event` module is loaded. + - **Nginx**: If you're using Nginx as a webserver for PHP, you will need to compile PHP with FPM. Make sure the option `--enable-fpm` is defined in `php_source_configure_command`. + +## Dependencies + +None. + +## Example Playbook + + - hosts: webservers + vars_files: + - vars/main.yml + roles: + - { role: geerlingguy.php } + +*Inside `vars/main.yml`*: + + php_memory_limit: "128M" + php_max_execution_time: "90" + php_upload_max_filesize: "256M" + php_packages: + - php + - php-cli + - php-common + - php-devel + - php-gd + - php-mbstring + - php-pdo + - php-pecl-apcu + - php-xml + ... + +## License + +MIT / BSD + +## Author Information + +This role was created in 2014 by [Jeff Geerling](https://www.jeffgeerling.com/), author of [Ansible for DevOps](https://www.ansiblefordevops.com/). diff --git a/ansible/ansible-role-php/defaults/main.yml b/ansible/ansible-role-php/defaults/main.yml new file mode 100644 index 0000000000000000000000000000000000000000..a19fa2548ff7c1fe2987f289da27b8fe3af5f4ad --- /dev/null +++ b/ansible/ansible-role-php/defaults/main.yml @@ -0,0 +1,154 @@ +--- +# Pass in a comma-separated list of repos to use (e.g. "remi,epel"). Used only +# for RHEL/CentOS. +php_enablerepo: "" + +# Extra packages to install (in addition to distro-specific default lists). +php_packages_extra: [] + +# Default PHP version to install on Debian-based OSes (OS-specific). +# php_default_version_debian: "" + +# PHP package state; use 'present' to make sure it's installed, or 'latest' if +# you want to upgrade or switch versions using a new repo. +php_packages_state: present + +# Whether to install recommended packages. Used only for Debian/Ubuntu. +php_install_recommends: true + +# Set this to false if you're not using PHP with Apache/Nginx/etc. +php_enable_webserver: true + +# PHP-FPM configuration. +php_enable_php_fpm: false +php_fpm_state: started +php_fpm_handler_state: restarted +php_fpm_enabled_on_boot: true +php_fpm_listen: "127.0.0.1:9000" +php_fpm_listen_allowed_clients: "127.0.0.1" +php_fpm_pm_max_children: 50 +php_fpm_pm_start_servers: 5 +php_fpm_pm_min_spare_servers: 5 +php_fpm_pm_max_spare_servers: 5 +php_fpm_pm_max_requests: 0 + +# PHP-FPM pool configuration. +php_fpm_pools: + - pool_name: www + pool_template: www.conf.j2 + pool_listen: "{{ php_fpm_listen }}" + pool_listen_allowed_clients: "{{ php_fpm_listen_allowed_clients }}" + pool_pm: dynamic + pool_pm_max_children: "{{ php_fpm_pm_max_children }}" + pool_pm_start_servers: "{{ php_fpm_pm_start_servers }}" + pool_pm_min_spare_servers: "{{ php_fpm_pm_min_spare_servers }}" + pool_pm_max_spare_servers: "{{ php_fpm_pm_max_spare_servers }}" + pool_php_fpm_pm_max_requests: "{{ php_fpm_pm_max_requests }}" + +# The executable to run when calling PHP from the command line. +php_executable: "php" + +# OpCache settings. +php_opcache_zend_extension: "opcache.so" +php_opcache_enable: "1" +php_opcache_enable_cli: "0" +php_opcache_memory_consumption: "96" +php_opcache_interned_strings_buffer: "16" +php_opcache_max_accelerated_files: "4096" +php_opcache_max_wasted_percentage: "5" +php_opcache_validate_timestamps: "1" +php_opcache_revalidate_path: "0" +php_opcache_revalidate_freq: "2" +php_opcache_max_file_size: "0" +php_opcache_blacklist_filename: "" + +# APCu settings. +php_enable_apc: true +php_apc_shm_size: "96M" +php_apc_enable_cli: "0" + +# If this is set to false, none of the following options will have any effect. +# Any and all changes to /etc/php.ini will be your responsibility. +php_use_managed_ini: true + +php_expose_php: "On" +php_memory_limit: "256M" +php_max_execution_time: "60" +php_max_input_time: "60" +php_max_input_vars: "1000" +php_realpath_cache_size: "32K" + +php_file_uploads: "On" +php_upload_max_filesize: "64M" +php_max_file_uploads: "20" + +php_post_max_size: "32M" +php_date_timezone: "America/Chicago" +php_allow_url_fopen: "On" + +php_sendmail_path: "/usr/sbin/sendmail -t -i" +php_output_buffering: "4096" +php_short_open_tag: "Off" +php_disable_functions: [] +php_precision: 14 +php_serialize_precision: "-1" + +php_session_cookie_lifetime: 0 +php_session_gc_probability: 1 +php_session_gc_divisor: 1000 +php_session_gc_maxlifetime: 1440 +php_session_save_handler: files +php_session_save_path: '' + +php_error_reporting: "E_ALL & ~E_DEPRECATED & ~E_STRICT" +php_display_errors: "Off" +php_display_startup_errors: "Off" + +# Install PHP from source (instead of using a package manager) with these vars. +php_install_from_source: false +php_source_repo: "https://github.com/php/php-src.git" +php_source_version: "master" +php_source_clone_dir: "~/php-src" +php_source_clone_depth: 1 +php_source_install_path: "/opt/php" +php_source_install_gmp_path: "/usr/include/x86_64-linux-gnu/gmp.h" +php_source_mysql_config: "/usr/bin/mysql_config" +# For faster compile time: "make --jobs=X" where X is # of cores present. +php_source_make_command: "make" +php_source_configure_command: > + ./configure + --prefix={{ php_source_install_path }} + --with-config-file-path={{ php_conf_paths | first }} + --enable-mbstring + --enable-zip + --enable-bcmath + --enable-pcntl + --enable-ftp + --enable-exif + --enable-calendar + --enable-opcache + --enable-pdo + --enable-sysvmsg + --enable-sysvsem + --enable-sysvshm + --enable-wddx + --with-curl + --with-mcrypt + --with-iconv + --with-gmp + --with-pspell + --with-gd + --with-jpeg-dir=/usr + --with-png-dir=/usr + --with-zlib-dir=/usr + --with-xpm-dir=/usr + --with-freetype-dir=/usr + --enable-gd-native-ttf + --enable-gd-jis-conv + --with-openssl + --with-pdo-mysql=/usr + --with-gettext=/usr + --with-zlib=/usr + --with-bz2=/usr + --with-recode=/usr + --with-mysqli={{ php_source_mysql_config }} diff --git a/ansible/ansible-role-php/handlers/main.yml b/ansible/ansible-role-php/handlers/main.yml new file mode 100644 index 0000000000000000000000000000000000000000..e0d0a292c6337512a45dd4b191573c02a5549d71 --- /dev/null +++ b/ansible/ansible-role-php/handlers/main.yml @@ -0,0 +1,15 @@ +--- +- name: restart webserver + service: + name: "{{ php_webserver_daemon }}" + state: restarted + notify: restart php-fpm + when: php_enable_webserver + +- name: restart php-fpm + service: + name: "{{ php_fpm_daemon }}" + state: "{{ php_fpm_handler_state }}" + when: + - php_enable_php_fpm + - php_fpm_state == 'started' diff --git a/ansible/ansible-role-php/meta/main.yml b/ansible/ansible-role-php/meta/main.yml new file mode 100644 index 0000000000000000000000000000000000000000..e3ade6fb4eb75e1d2adaca957f9cee8d46567c27 --- /dev/null +++ b/ansible/ansible-role-php/meta/main.yml @@ -0,0 +1,36 @@ +--- +dependencies: [] + +galaxy_info: + role_name: php + author: geerlingguy + description: PHP for RedHat/CentOS/Fedora/Debian/Ubuntu. + company: "Midwestern Mac, LLC" + license: "license (BSD, MIT)" + min_ansible_version: 2.8 + platforms: + - name: EL + versions: + - 7 + - 8 + - name: Fedora + versions: + - all + - name: Debian + versions: + - all + - name: Ubuntu + versions: + - trusty + - xenial + - bionic + galaxy_tags: + - development + - web + - php + - language + - fpm + - drupal + - wordpress + - joomla + - magento diff --git a/ansible/ansible-role-php/molecule/default/converge.yml b/ansible/ansible-role-php/molecule/default/converge.yml new file mode 100644 index 0000000000000000000000000000000000000000..41ae7c192dc5798b7ffe7e6c9782c60a60b60670 --- /dev/null +++ b/ansible/ansible-role-php/molecule/default/converge.yml @@ -0,0 +1,70 @@ +--- +- name: Converge + hosts: all + become: true + + vars: + php_enable_webserver: false + php_enable_php_fpm: true + php_memory_limit: "192M" + php_enablerepo: "remi,remi-php70" + php_install_recommends: false + + handlers: + - name: update apt cache + apt: update_cache=true + when: ansible_os_family == 'Debian' + + pre_tasks: + - name: Update apt cache. + apt: update_cache=true cache_valid_time=600 + when: ansible_os_family == 'Debian' + changed_when: false + + # Ubuntu-specific tasks. + - name: Ensure dirmngr is installed (gnupg dependency). + apt: + name: dirmngr + state: present + when: ansible_os_family == 'Debian' + + - name: Add repository for PHP 7. + apt_repository: repo='ppa:ondrej/php' + when: ansible_distribution == 'Ubuntu' + + # Debian-specific tasks. + - name: Add dependencies for PHP versions (Debian). + apt: + name: + - apt-transport-https + - ca-certificates + - gnupg2 + state: present + when: ansible_distribution == "Debian" + + - name: Add Ondrej Sury's apt key (Debian). + apt_key: + url: https://packages.sury.org/php/apt.gpg + state: present + when: ansible_distribution == "Debian" + + - name: Add Ondrej Sury's repo (Debian). + apt_repository: + repo: "deb https://packages.sury.org/php/ {{ ansible_distribution_release }} main" + state: present + when: ansible_distribution == "Debian" + notify: update apt cache + + - meta: flush_handlers + + roles: + - role: geerlingguy.repo-remi + when: + - ansible_os_family == 'RedHat' + - ansible_distribution != 'Fedora' + - role: geerlingguy.php + + post_tasks: + - name: Confirm PHP configuration is correct. + shell: php -i | grep 'memory_limit.*192' + changed_when: false diff --git a/ansible/ansible-role-php/molecule/default/molecule.yml b/ansible/ansible-role-php/molecule/default/molecule.yml new file mode 100644 index 0000000000000000000000000000000000000000..74907107f67bb0d2b45d0fcb7271a8da477dc548 --- /dev/null +++ b/ansible/ansible-role-php/molecule/default/molecule.yml @@ -0,0 +1,17 @@ +--- +dependency: + name: galaxy +driver: + name: docker +platforms: + - name: instance + image: "geerlingguy/docker-${MOLECULE_DISTRO:-centos7}-ansible:latest" + command: ${MOLECULE_DOCKER_COMMAND:-""} + volumes: + - /sys/fs/cgroup:/sys/fs/cgroup:ro + privileged: true + pre_build_image: true +provisioner: + name: ansible + playbooks: + converge: ${MOLECULE_PLAYBOOK:-converge.yml} diff --git a/ansible/ansible-role-php/molecule/default/requirements.yml b/ansible/ansible-role-php/molecule/default/requirements.yml new file mode 100644 index 0000000000000000000000000000000000000000..809b89be8a49d51f5b8e802a4681de756428350d --- /dev/null +++ b/ansible/ansible-role-php/molecule/default/requirements.yml @@ -0,0 +1,3 @@ +--- +- src: geerlingguy.repo-remi +- src: geerlingguy.git diff --git a/ansible/ansible-role-php/molecule/default/source-install.yml b/ansible/ansible-role-php/molecule/default/source-install.yml new file mode 100644 index 0000000000000000000000000000000000000000..d9ad0f95d457b929961c6a232d750280d38e18d7 --- /dev/null +++ b/ansible/ansible-role-php/molecule/default/source-install.yml @@ -0,0 +1,32 @@ +--- +- name: Converge + hosts: all + become: true + + vars: + php_enable_webserver: false + php_install_from_source: true + php_source_clone_dir: /root/php-src + php_source_make_command: "make --jobs=2" + php_version: "7.4.8" + php_source_version: "php-{{ php_version }}" + php_memory_limit: "192M" + + pre_tasks: + - name: Update apt cache. + apt: update_cache=true cache_valid_time=600 + when: ansible_os_family == 'Debian' + changed_when: false + + roles: + - role: geerlingguy.git + - role: geerlingguy.php + + post_tasks: + - name: Confirm PHP configuration is correct. + shell: php -i | grep 'memory_limit.*192' + changed_when: false + + - name: Check the installed PHP version. + shell: '/usr/bin/php --version | grep -qF "PHP {{ php_version }}"' + changed_when: false diff --git a/ansible/ansible-role-php/tasks/configure-apcu.yml b/ansible/ansible-role-php/tasks/configure-apcu.yml new file mode 100644 index 0000000000000000000000000000000000000000..a29f8d63482b4cb589a7151233563f7a8e9ce94e --- /dev/null +++ b/ansible/ansible-role-php/tasks/configure-apcu.yml @@ -0,0 +1,37 @@ +--- +- name: Check for existing APCu config files. + find: + paths: "{{ item }}" + contains: 'extension(\s+)?=(\s+)?apc[u]?\.so' + register: php_installed_apc_confs + with_items: "{{ php_extension_conf_paths }}" + +- name: Remove any non-role-supplied APCu config files. + file: + path: "{{ item.1.path }}" + state: absent + when: php_apc_conf_filename != (item.1.path.split('/') | last) + with_subelements: + - "{{ php_installed_apc_confs.results }}" + - files + notify: restart webserver + +- name: Ensure APCu config file is present. + template: + src: apc.ini.j2 + dest: "{{ item }}/{{ php_apc_conf_filename }}" + owner: root + group: root + force: true + mode: 0644 + with_items: "{{ php_extension_conf_paths }}" + when: php_enable_apc + notify: restart webserver + +- name: Remove APCu config file if APC is disabled. + file: + path: "{{ item }}/{{ php_apc_conf_filename }}" + state: absent + with_items: "{{ php_extension_conf_paths }}" + when: not php_enable_apc + notify: restart webserver diff --git a/ansible/ansible-role-php/tasks/configure-fpm.yml b/ansible/ansible-role-php/tasks/configure-fpm.yml new file mode 100644 index 0000000000000000000000000000000000000000..28135208fe10f270c1191bdb5ae39cc143e0b293 --- /dev/null +++ b/ansible/ansible-role-php/tasks/configure-fpm.yml @@ -0,0 +1,53 @@ +--- +- name: Define php_fpm_daemon. + set_fact: + php_fpm_daemon: "{{ __php_fpm_daemon }}" + when: php_fpm_daemon is not defined + +- name: Define php_fpm_pool_conf_path. + set_fact: + php_fpm_pool_conf_path: "{{ __php_fpm_pool_conf_path }}" + when: php_fpm_pool_conf_path is not defined + +- name: Define php_fpm_pool_user. + set_fact: + php_fpm_pool_user: "{{ __php_fpm_pool_user }}" + when: php_fpm_pool_user is not defined + +- name: Define php_fpm_pool_group. + set_fact: + php_fpm_pool_group: "{{ __php_fpm_pool_group }}" + when: php_fpm_pool_group is not defined + +- name: Stat php_fpm_pool_conf_path + stat: + path: "{{ php_fpm_pool_conf_path | dirname }}" + register: php_fpm_pool_conf_path_dir_stat + +- name: Ensure the default pool directory exists. + file: + path: "{{ php_fpm_pool_conf_path | dirname }}" + state: directory + owner: root + group: root + mode: 0755 + when: php_fpm_pool_conf_path_dir_stat.stat.islnk is not defined + +- name: Create fpm pools. + template: + src: "{{ item.pool_template | default('www.conf.j2', true) }}" + dest: "{{ php_fpm_pool_conf_path | dirname }}/{{ item.pool_name }}.conf" + owner: root + group: root + mode: 0644 + force: true + loop: "{{ php_fpm_pools | default([], true) }}" + when: php_enable_php_fpm + notify: restart php-fpm + +- name: Ensure php-fpm is started and enabled at boot (if configured). + service: + name: "{{ php_fpm_daemon }}" + state: "{{ php_fpm_state }}" + enabled: "{{ php_fpm_enabled_on_boot }}" + when: php_enable_php_fpm and ansible_distribution != "Debian" diff --git a/ansible/ansible-role-php/tasks/configure-opcache.yml b/ansible/ansible-role-php/tasks/configure-opcache.yml new file mode 100644 index 0000000000000000000000000000000000000000..fc043d0c623a85f8dcc7d9d7aa3666ba8aa7774e --- /dev/null +++ b/ansible/ansible-role-php/tasks/configure-opcache.yml @@ -0,0 +1,37 @@ +--- +- name: Check for existing OpCache config files. + find: + paths: "{{ item }}" + contains: 'zend_extension(\s+)?=(\s+)?opcache\.so' + register: php_installed_opcache_confs + with_items: "{{ php_extension_conf_paths }}" + +- name: Remove any non-role-supplied OpCache config files. + file: + path: "{{ item.1.path }}" + state: absent + when: php_opcache_conf_filename != (item.1.path.split('/') | last) + with_subelements: + - "{{ php_installed_opcache_confs.results }}" + - files + notify: restart webserver + +- name: Ensure OpCache config file is present. + template: + src: opcache.ini.j2 + dest: "{{ item }}/{{ php_opcache_conf_filename }}" + owner: root + group: root + force: true + mode: 0644 + with_items: "{{ php_extension_conf_paths }}" + when: php_opcache_enable | bool + notify: restart webserver + +- name: Remove OpCache config file if OpCache is disabled. + file: + path: "{{ item }}/{{ php_opcache_conf_filename }}" + state: absent + with_items: "{{ php_extension_conf_paths }}" + when: not php_opcache_enable | bool + notify: restart webserver diff --git a/ansible/ansible-role-php/tasks/configure.yml b/ansible/ansible-role-php/tasks/configure.yml new file mode 100644 index 0000000000000000000000000000000000000000..e0e1434bc5d658a773279b208ec97a068a45b661 --- /dev/null +++ b/ansible/ansible-role-php/tasks/configure.yml @@ -0,0 +1,21 @@ +--- +- name: Ensure configuration directories exist. + file: + path: "{{ item }}" + state: directory + follow: true + mode: 0755 + with_flattened: + - "{{ php_conf_paths }}" + - "{{ php_extension_conf_paths }}" + +- name: Place PHP configuration file in place. + template: + src: php.ini.j2 + dest: "{{ item }}/php.ini" + owner: root + group: root + mode: 0644 + with_items: "{{ php_conf_paths }}" + notify: restart webserver + when: php_use_managed_ini diff --git a/ansible/ansible-role-php/tasks/install-from-source.yml b/ansible/ansible-role-php/tasks/install-from-source.yml new file mode 100644 index 0000000000000000000000000000000000000000..cd18daacf6042995521832f96c45e50f4fda0a36 --- /dev/null +++ b/ansible/ansible-role-php/tasks/install-from-source.yml @@ -0,0 +1,158 @@ +--- +- name: Ensure dependencies for building from source are installed (RedHat). + package: + name: + - autoconf + - automake + - libtool + - bison + - make + - re2c + - sqlite-devel + - oniguruma-devel + - curl-devel + - recode-devel + - aspell-devel + - libxml2-devel + - pkgconfig + - libmcrypt-devel + - t1lib-devel + - libXpm-devel + - libpng-devel + - libjpeg-turbo-devel + - bzip2-devel + - openssl-devel + - freetype-devel + - libicu-devel + - mariadb-devel + - gmp-devel + state: present + when: ansible_os_family == 'RedHat' + +- name: Update apt cache (Debian). + apt: update_cache=yes cache_valid_time=86400 + when: ansible_os_family == 'Debian' + +- name: Ensure dependencies for building from source are installed (Debian). + apt: + name: + - build-essential + - autoconf + - automake + - libtool + - bison + - pkg-config + - re2c + - libsqlite3-dev + - libonig-dev + - libxml2-dev + - libcurl4-openssl-dev + - libbz2-dev + - libjpeg-dev + - libpng-dev + - libxpm-dev + - libfreetype6-dev + - libgmp3-dev + - libmcrypt-dev + - libmariadbclient-dev + - libpspell-dev + - librecode-dev + - libssl-dev + state: present + when: ansible_os_family == 'Debian' + +- name: Define php_fpm_daemon (if not defined already). + set_fact: + php_fpm_daemon: "php-fpm" + when: php_fpm_daemon is not defined + +- name: Check if gmp.h is already in a location accessible to gcc. + stat: path=/usr/include/gmp.h + register: gmp_file + +- name: Ensure gmp.h is symlinked into a location accessible to gcc. + file: # noqa 208 + src: "{{ php_source_install_gmp_path }}" + dest: /usr/include/gmp.h + state: link + when: not gmp_file.stat.exists + +- name: Check if PHP is installed. + command: which php + changed_when: false + failed_when: false + register: php_installed + +- name: Clone the PHP repository. + git: + repo: "{{ php_source_repo }}" + dest: "{{ php_source_clone_dir }}" + version: "{{ php_source_version }}" + accept_hostkey: true + depth: "{{ php_source_clone_depth }}" + when: php_installed.rc != 0 + +- name: Ensure PHP installation path exists. + file: + path: "{{ php_source_install_path }}" + state: directory + mode: 0755 + when: php_installed.rc != 0 + +- name: Build configure script. + command: > + ./buildconf --force + chdir={{ php_source_clone_dir }} + when: php_installed.rc != 0 + +- name: Run configure script. + command: > + {{ php_source_configure_command }} + chdir={{ php_source_clone_dir }} + when: php_installed.rc != 0 + +- name: Make and install PHP. + command: > + {{ item }} + chdir={{ php_source_clone_dir }} + with_items: + - "{{ php_source_make_command }}" + - make install + when: php_installed.rc != 0 + +- name: Ensure php executable is symlinked into a standard path. + file: # noqa 208 + src: "{{ php_source_install_path }}/bin/php" + dest: /usr/bin/php + state: link + +# PHP FPM configuration. +- name: Ensure php-fpm executable is symlinked into a standard path. + file: # noqa 208 + src: "{{ php_source_install_path }}/sbin/php-fpm" + dest: "/usr/sbin/{{ php_fpm_daemon }}" + state: link + when: "'--enable-fpm' in php_source_configure_command" + +- name: Ensure php-fpm init script is installed. + template: + src: fpm-init.j2 + dest: "/etc/init.d/{{ php_fpm_daemon }}" + mode: 0755 + when: "'--enable-fpm' in php_source_configure_command" + notify: restart php-fpm + +- name: Ensure php-fpm config directory exists. + file: + path: "{{ php_fpm_conf_path }}" + state: directory + mode: 0755 + when: "'--enable-fpm' in php_source_configure_command" + +- name: Ensure php-fpm config file is installed. + template: + src: php-fpm.conf.j2 + dest: "{{ php_fpm_conf_path }}/php-fpm.conf" + mode: 0644 + when: "'--enable-fpm' in php_source_configure_command" + notify: restart php-fpm diff --git a/ansible/ansible-role-php/tasks/main.yml b/ansible/ansible-role-php/tasks/main.yml new file mode 100644 index 0000000000000000000000000000000000000000..dbad765954fe05f28e46d43fd8fc2245232f335f --- /dev/null +++ b/ansible/ansible-role-php/tasks/main.yml @@ -0,0 +1,77 @@ +--- +# Variable setup. +- name: Include distribution and version-specific vars. + include_vars: "{{ item }}" + with_first_found: + - files: + - "{{ ansible_distribution }}-{{ ansible_distribution_major_version }}.yml" + skip: true + +- name: Set the default PHP version for Debian-based OSes. + set_fact: + php_default_version_debian: "{{ __php_default_version_debian }}" + when: php_default_version_debian is not defined and ansible_os_family == 'Debian' + +- name: Include OS-specific variables. + include_vars: "{{ ansible_os_family }}.yml" + +- name: Define php_packages. + set_fact: + php_packages: "{{ __php_packages | list }}" + when: php_packages is not defined + +- name: Define php_webserver_daemon. + set_fact: + php_webserver_daemon: "{{ __php_webserver_daemon }}" + when: php_webserver_daemon is not defined + +- name: Define php_conf_paths. + set_fact: + php_conf_paths: "{{ __php_conf_paths }}" + when: php_conf_paths is not defined + +- name: Define php_extension_conf_paths. + set_fact: + php_extension_conf_paths: "{{ __php_extension_conf_paths }}" + when: php_extension_conf_paths is not defined + +- name: Define php_apc_conf_filename. + set_fact: + php_apc_conf_filename: "{{ __php_apc_conf_filename }}" + when: php_apc_conf_filename is not defined + +- name: Define php_opcache_conf_filename (Ubuntu 16.04). + set_fact: + php_opcache_conf_filename: "10-opcache.ini" + when: php_opcache_conf_filename is not defined and ansible_distribution_version == "16.04" + +- name: Define php_opcache_conf_filename. + set_fact: + php_opcache_conf_filename: "{{ __php_opcache_conf_filename }}" + when: php_opcache_conf_filename is not defined + +- name: Define php_fpm_conf_path. + set_fact: + php_fpm_conf_path: "{{ __php_fpm_conf_path }}" + when: php_fpm_conf_path is not defined + +# Setup/install tasks. +- include_tasks: setup-RedHat.yml + when: + - not php_install_from_source + - ansible_os_family == 'RedHat' + +- include_tasks: setup-Debian.yml + when: + - not php_install_from_source + - ansible_os_family == 'Debian' + +# Install PHP from source when php_install_from_source is true. +- include_tasks: install-from-source.yml + when: php_install_from_source + +# Configure PHP. +- include_tasks: configure.yml +- include_tasks: configure-apcu.yml +- include_tasks: configure-opcache.yml +- include_tasks: configure-fpm.yml diff --git a/ansible/ansible-role-php/tasks/setup-Debian.yml b/ansible/ansible-role-php/tasks/setup-Debian.yml new file mode 100644 index 0000000000000000000000000000000000000000..a6657be287fe39b6d53c0ca48e6bc0f33b523e12 --- /dev/null +++ b/ansible/ansible-role-php/tasks/setup-Debian.yml @@ -0,0 +1,27 @@ +--- +- name: Update apt cache. + apt: update_cache=yes cache_valid_time=86400 + +- name: Ensure PHP packages are installed. + apt: + name: "{{ php_packages + php_packages_extra }}" + state: "{{ php_packages_state }}" + install_recommends: "{{ php_install_recommends }}" + register: php_package_install + notify: restart webserver + +- name: Delete APCu configuration file if this role will provide one. + file: + path: "{{ item }}/{{ php_apc_conf_filename }}" + state: absent + with_items: "{{ php_extension_conf_paths }}" + when: php_enable_apc and php_package_install.changed + notify: restart webserver + +- name: Delete OpCache configuration file if this role will provide one. + file: + path: "{{ item }}/{{ php_opcache_conf_filename }}" + state: absent + with_items: "{{ php_extension_conf_paths }}" + when: php_opcache_enable | bool and php_package_install.changed + notify: restart webserver diff --git a/ansible/ansible-role-php/tasks/setup-RedHat.yml b/ansible/ansible-role-php/tasks/setup-RedHat.yml new file mode 100644 index 0000000000000000000000000000000000000000..1d76b331b5f13f165876688271bc780f21993590 --- /dev/null +++ b/ansible/ansible-role-php/tasks/setup-RedHat.yml @@ -0,0 +1,7 @@ +--- +- name: Ensure PHP packages are installed. + package: + name: "{{ php_packages + php_packages_extra }}" + state: "{{ php_packages_state }}" + enablerepo: "{{ php_enablerepo | default(omit, true) }}" + notify: restart webserver diff --git a/ansible/ansible-role-php/templates/apc.ini.j2 b/ansible/ansible-role-php/templates/apc.ini.j2 new file mode 100644 index 0000000000000000000000000000000000000000..bfd5706461c44775495697a017e2820be65fe43d --- /dev/null +++ b/ansible/ansible-role-php/templates/apc.ini.j2 @@ -0,0 +1,4 @@ +extension=apcu.so +apc.shm_size={{ php_apc_shm_size }} +apc.enable_cli={{ php_apc_enable_cli }} +apc.rfc1867=1 diff --git a/ansible/ansible-role-php/templates/fpm-init.j2 b/ansible/ansible-role-php/templates/fpm-init.j2 new file mode 100644 index 0000000000000000000000000000000000000000..4d6a6d5dc155f688118a445d7763b1fb5bd615ba --- /dev/null +++ b/ansible/ansible-role-php/templates/fpm-init.j2 @@ -0,0 +1,170 @@ +#!/bin/sh +### BEGIN INIT INFO +# Provides: php-fpm {{ php_fpm_daemon }} +# Required-Start: $remote_fs $network +# Required-Stop: $remote_fs $network +# Default-Start: 2 3 4 5 +# Default-Stop: 0 1 6 +# Short-Description: starts {{ php_fpm_daemon }} +# Description: Starts The PHP FastCGI Process Manager Daemon +### END INIT INFO + +# Author: Ondrej Sury + +PATH=/sbin:/usr/sbin:/bin:/usr/bin +DESC="PHP FastCGI Process Manager" +NAME={{ php_fpm_daemon }} +DAEMON=/usr/sbin/$NAME +DAEMON_ARGS="--daemonize --fpm-config {{ php_fpm_conf_path }}/php-fpm.conf" +PIDFILE=/var/run/{{ php_fpm_daemon }}.pid +TIMEOUT=2 +SCRIPTNAME=/etc/init.d/$NAME + +# Exit if the package is not installed +[ -x "$DAEMON" ] || exit 0 + +# Read configuration variable file if it is present +[ -r /etc/default/$NAME ] && . /etc/default/$NAME + +# Load the VERBOSE setting and other rcS variables +. /lib/init/vars.sh + +# Define LSB log_* functions. +# Depend on lsb-base (>= 3.0-6) to ensure that this file is present. +. /lib/lsb/init-functions + +# Don't run if we are running upstart +if init_is_upstart; then + exit 1 +fi + +# +# Function to check the correctness of the config file +# +do_check() +{ + /usr/lib/php5/php5-fpm-checkconf || return 1 + return 0 +} + +# +# Function that starts the daemon/service +# +do_start() +{ + # Return + # 0 if daemon has been started + # 1 if daemon was already running + # 2 if daemon could not be started + start-stop-daemon --start --quiet --pidfile $PIDFILE --exec $DAEMON --test > /dev/null \ + || return 1 + start-stop-daemon --start --quiet --pidfile $PIDFILE --exec $DAEMON -- \ + $DAEMON_ARGS 2>/dev/null \ + || return 2 + # Add code here, if necessary, that waits for the process to be ready + # to handle requests from services started subsequently which depend + # on this one. As a last resort, sleep for some time. +} + +# +# Function that stops the daemon/service +# +do_stop() +{ + # Return + # 0 if daemon has been stopped + # 1 if daemon was already stopped + # 2 if daemon could not be stopped + # other if a failure occurred + start-stop-daemon --stop --quiet --retry=QUIT/$TIMEOUT/TERM/5/KILL/5 --pidfile $PIDFILE --name $NAME + RETVAL="$?" + [ "$RETVAL" = 2 ] && return 2 + # Wait for children to finish too if this is a daemon that forks + # and if the daemon is only ever run from this initscript. + # If the above conditions are not satisfied then add some other code + # that waits for the process to drop all resources that could be + # needed by services started subsequently. A last resort is to + # sleep for some time. + start-stop-daemon --stop --quiet --oknodo --retry=0/$TIMEOUT/TERM/5/KILL/5 --exec $DAEMON + [ "$?" = 2 ] && return 2 + # Many daemons don't delete their pidfiles when they exit. + rm -f $PIDFILE + return "$RETVAL" +} + +# +# Function that sends a SIGHUP to the daemon/service +# +do_reload() { + # + # If the daemon can reload its configuration without + # restarting (for example, when it is sent a SIGHUP), + # then implement that here. + # + start-stop-daemon --stop --signal USR2 --quiet --pidfile $PIDFILE --name $NAME + return 0 +} + +case "$1" in + start) + [ "$VERBOSE" != no ] && log_daemon_msg "Starting $DESC" "$NAME" + do_start + case "$?" in + 0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;; + 2) [ "$VERBOSE" != no ] && log_end_msg 1 ;; + esac + ;; + stop) + [ "$VERBOSE" != no ] && log_daemon_msg "Stopping $DESC" "$NAME" + do_stop + case "$?" in + 0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;; + 2) [ "$VERBOSE" != no ] && log_end_msg 1 ;; + esac + ;; + status) + status_of_proc "$DAEMON" "$NAME" && exit 0 || exit $? + ;; + check) + do_check yes + ;; + reload|force-reload) + log_daemon_msg "Reloading $DESC" "$NAME" + do_reload + log_end_msg $? + ;; + reopen-logs) + log_daemon_msg "Reopening $DESC logs" $NAME + if start-stop-daemon --stop --signal USR1 --oknodo --quiet \ + --pidfile $PIDFILE --exec $DAEMON + then + log_end_msg 0 + else + log_end_msg 1 + fi + ;; + restart) + log_daemon_msg "Restarting $DESC" "$NAME" + do_stop + case "$?" in + 0|1) + do_start + case "$?" in + 0) log_end_msg 0 ;; + 1) log_end_msg 1 ;; # Old process is still running + *) log_end_msg 1 ;; # Failed to start + esac + ;; + *) + # Failed to stop + log_end_msg 1 + ;; + esac + ;; + *) + echo "Usage: $SCRIPTNAME {start|stop|status|restart|reload|force-reload}" >&2 + exit 1 + ;; +esac + +: diff --git a/ansible/ansible-role-php/templates/opcache.ini.j2 b/ansible/ansible-role-php/templates/opcache.ini.j2 new file mode 100644 index 0000000000000000000000000000000000000000..61464539f0d3a582cf5fbe7e3b49f567e3c90c7b --- /dev/null +++ b/ansible/ansible-role-php/templates/opcache.ini.j2 @@ -0,0 +1,14 @@ +zend_extension={{ php_opcache_zend_extension }} +opcache.enable={{ php_opcache_enable }} +opcache.enable_cli={{ php_opcache_enable_cli }} +opcache.memory_consumption={{ php_opcache_memory_consumption }} +opcache.interned_strings_buffer={{ php_opcache_interned_strings_buffer }} +opcache.max_accelerated_files={{ php_opcache_max_accelerated_files }} +opcache.max_wasted_percentage={{ php_opcache_max_wasted_percentage }} +opcache.validate_timestamps={{ php_opcache_validate_timestamps }} +opcache.revalidate_path={{ php_opcache_revalidate_path }} +opcache.revalidate_freq={{ php_opcache_revalidate_freq }} +opcache.max_file_size={{ php_opcache_max_file_size }} +{% if php_opcache_blacklist_filename != '' %} +opcache.blacklist_filename={{ php_opcache_blacklist_filename }} +{% endif %} diff --git a/ansible/ansible-role-php/templates/php-fpm.conf.j2 b/ansible/ansible-role-php/templates/php-fpm.conf.j2 new file mode 100644 index 0000000000000000000000000000000000000000..12b277fbeef76747c8c70f9eae4791f28e71f290 --- /dev/null +++ b/ansible/ansible-role-php/templates/php-fpm.conf.j2 @@ -0,0 +1,12 @@ +;;;;;;;;;;;;;;;;;;;;; +; FPM Configuration ; +;;;;;;;;;;;;;;;;;;;;; + +include={{ php_fpm_conf_path }}/pool.d/*.conf + +;;;;;;;;;;;;;;;;;; +; Global Options ; +;;;;;;;;;;;;;;;;;; + +[global] +error_log = /var/log/php-fpm.log diff --git a/ansible/ansible-role-php/templates/php.ini.j2 b/ansible/ansible-role-php/templates/php.ini.j2 new file mode 100644 index 0000000000000000000000000000000000000000..14b7eeb3215111298272c7df62539b4806e3362a --- /dev/null +++ b/ansible/ansible-role-php/templates/php.ini.j2 @@ -0,0 +1,221 @@ +[PHP] + +;;;;;;;;;;;;;;;;;;;; +; Language Options ; +;;;;;;;;;;;;;;;;;;;; + +engine = On +short_open_tag = {{ php_short_open_tag }} +precision = {{ php_precision }} +output_buffering = {{ php_output_buffering }} + +zlib.output_compression = Off + +implicit_flush = Off +unserialize_callback_func = +serialize_precision = {{ php_serialize_precision }} +disable_functions = {{ php_disable_functions|join(",") }} +disable_classes = + +zend.enable_gc = On + +;;;;;;;;;;;;;;;;; +; Miscellaneous ; +;;;;;;;;;;;;;;;;; + +expose_php = {{ php_expose_php }} + +;;;;;;;;;;;;;;;;;;; +; Resource Limits ; +;;;;;;;;;;;;;;;;;;; + +max_execution_time = {{ php_max_execution_time }} +max_input_time = {{ php_max_input_time }} +max_input_vars = {{ php_max_input_vars }} +memory_limit = {{ php_memory_limit }} + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; Error handling and logging ; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +error_reporting = {{ php_error_reporting }} +display_errors = {{ php_display_errors }} +display_startup_errors = {{ php_display_startup_errors }} +log_errors = On +log_errors_max_len = 1024 +ignore_repeated_errors = Off +ignore_repeated_source = Off +report_memleaks = On +track_errors = Off +html_errors = On + +;;;;;;;;;;;;;;;;; +; Data Handling ; +;;;;;;;;;;;;;;;;; + +variables_order = "GPCS" +request_order = "GP" +register_argc_argv = Off +auto_globals_jit = On + +post_max_size = {{ php_post_max_size }} +auto_prepend_file = +auto_append_file = + +default_mimetype = "text/html" + +;;;;;;;;;;;;;;;;;;;;;;;;; +; Paths and Directories ; +;;;;;;;;;;;;;;;;;;;;;;;;; + +doc_root = +user_dir = + +enable_dl = Off + +realpath_cache_size = {{ php_realpath_cache_size }} + +;;;;;;;;;;;;;;;; +; File Uploads ; +;;;;;;;;;;;;;;;; + +file_uploads = {{ php_file_uploads }} +upload_max_filesize = {{ php_upload_max_filesize }} +max_file_uploads = {{ php_max_file_uploads }} + +;;;;;;;;;;;;;;;;;; +; Fopen wrappers ; +;;;;;;;;;;;;;;;;;; + +allow_url_fopen = {{ php_allow_url_fopen }} +allow_url_include = Off + +default_socket_timeout = 60 + +;;;;;;;;;;;;;;;;;;; +; Module Settings ; +;;;;;;;;;;;;;;;;;;; + +[CLI Server] +cli_server.color = On + +[Date] +date.timezone = {{ php_date_timezone }} + +[Pdo_mysql] +pdo_mysql.cache_size = 2000 +pdo_mysql.default_socket= + +[mail function] +; For Win32 only. +SMTP = localhost +smtp_port = 25 + +; For Unix only. You may supply arguments as well (default: "sendmail -t -i"). +sendmail_path = {{ php_sendmail_path }} + +mail.add_x_header = On + +[SQL] +sql.safe_mode = Off + +[ODBC] +odbc.allow_persistent = On +odbc.check_persistent = On +odbc.max_persistent = -1 +odbc.max_links = -1 +odbc.defaultlrl = 4096 +odbc.defaultbinmode = 1 + +[MySQL] +mysql.allow_local_infile = On +mysql.allow_persistent = On +mysql.cache_size = 2000 +mysql.max_persistent = -1 +mysql.max_links = -1 +mysql.default_port = +mysql.default_socket = +mysql.default_host = +mysql.default_user = +mysql.default_password = +mysql.connect_timeout = 60 +mysql.trace_mode = Off + +[MySQLi] +mysqli.max_persistent = -1 +mysqli.allow_persistent = On +mysqli.max_links = -1 +mysqli.cache_size = 2000 +mysqli.default_port = 3306 +mysqli.default_socket = +mysqli.default_host = +mysqli.default_user = +mysqli.default_pw = +mysqli.reconnect = Off + +[mysqlnd] +mysqlnd.collect_statistics = On +mysqlnd.collect_memory_statistics = Off + +[PostgreSQL] +pgsql.allow_persistent = On +pgsql.auto_reset_persistent = Off +pgsql.max_persistent = -1 +pgsql.max_links = -1 +pgsql.ignore_notice = 0 +pgsql.log_notice = 0 + +[bcmath] +bcmath.scale = 0 + +[Session] +session.save_handler = {{ php_session_save_handler }} +session.save_path = {{ php_session_save_path }} +session.use_cookies = 1 +session.use_only_cookies = 1 +session.name = PHPSESSID +session.auto_start = 0 + +session.cookie_lifetime = {{ php_session_cookie_lifetime }} +session.cookie_path = / +session.cookie_domain = +session.cookie_httponly = + +session.serialize_handler = php + +session.gc_probability = {{ php_session_gc_probability }} +session.gc_divisor = {{ php_session_gc_divisor }} +session.gc_maxlifetime = {{ php_session_gc_maxlifetime }} + +session.referer_check = + +session.cache_limiter = nocache +session.cache_expire = 180 + +session.use_trans_sid = 0 + +session.hash_function = 0 +session.hash_bits_per_character = 5 + +url_rewriter.tags = "a=href,area=href,frame=src,input=src,form=fakeentry" + +[MSSQL] +mssql.allow_persistent = On +mssql.max_persistent = -1 +mssql.max_links = -1 +mssql.min_error_severity = 10 +mssql.min_message_severity = 10 +mssql.compatability_mode = Off +mssql.secure_connection = Off + +[Tidy] +tidy.clean_output = Off + +[soap] +soap.wsdl_cache_enabled=1 +soap.wsdl_cache_dir="/tmp" +soap.wsdl_cache_ttl=86400 +soap.wsdl_cache_limit = 5 + +[ldap] +ldap.max_links = -1 diff --git a/ansible/ansible-role-php/templates/www.conf.j2 b/ansible/ansible-role-php/templates/www.conf.j2 new file mode 100644 index 0000000000000000000000000000000000000000..ae5d7237b088aed03eb7c8f49e6feb8fcd01b1e3 --- /dev/null +++ b/ansible/ansible-role-php/templates/www.conf.j2 @@ -0,0 +1,17 @@ +{{ ansible_managed | comment(decoration='; ') }} + +[{{ item.pool_name | mandatory }}] +listen = {{ item.pool_listen | mandatory }} +listen.allowed_clients = {{ item.pool_listen_allowed_clients | default('127.0.0.1', true) }} +user = {{ php_fpm_pool_user }} +group = {{ php_fpm_pool_group }} + +listen.owner = {{ php_fpm_pool_user }} +listen.group = {{ php_fpm_pool_group }} + +pm = {{ item.pool_pm | default('dynamic', true) }} +pm.max_children = {{ item.pool_pm_max_children | default(50, true) }} +pm.start_servers = {{ item.pool_pm_start_servers | default(5, true) }} +pm.min_spare_servers = {{ item.pool_pm_min_spare_servers | default(5, true) }} +pm.max_spare_servers = {{ item.pool_pm_max_spare_servers | default(5, true) }} +pm.max_requests = {{ item.pool_pm_max_requests | default(500, true) }} diff --git a/ansible/ansible-role-php/vars/Debian-10.yml b/ansible/ansible-role-php/vars/Debian-10.yml new file mode 100644 index 0000000000000000000000000000000000000000..ec895aec31765745cd52fd666d5377e8a890c8c2 --- /dev/null +++ b/ansible/ansible-role-php/vars/Debian-10.yml @@ -0,0 +1,2 @@ +--- +__php_default_version_debian: "7.3" diff --git a/ansible/ansible-role-php/vars/Debian-11.yml b/ansible/ansible-role-php/vars/Debian-11.yml new file mode 100644 index 0000000000000000000000000000000000000000..a16b99b155442b397dc0ca9c4c8c42ceb16ce814 --- /dev/null +++ b/ansible/ansible-role-php/vars/Debian-11.yml @@ -0,0 +1,2 @@ +--- +__php_default_version_debian: "7.4" diff --git a/ansible/ansible-role-php/vars/Debian-9.yml b/ansible/ansible-role-php/vars/Debian-9.yml new file mode 100644 index 0000000000000000000000000000000000000000..eb23ce3a0cc59fbe83261706e70920eddf76a8e9 --- /dev/null +++ b/ansible/ansible-role-php/vars/Debian-9.yml @@ -0,0 +1,2 @@ +--- +__php_default_version_debian: "7.0" diff --git a/ansible/ansible-role-php/vars/Debian.yml b/ansible/ansible-role-php/vars/Debian.yml new file mode 100644 index 0000000000000000000000000000000000000000..c487fd8a59f946d49c37a78b48cb5c2e91255ac0 --- /dev/null +++ b/ansible/ansible-role-php/vars/Debian.yml @@ -0,0 +1,39 @@ +--- +__php_default_version_debian: "7.0" + +__php_packages: + - php{{ php_default_version_debian }}-common + - php{{ php_default_version_debian }}-cli + - php{{ php_default_version_debian }}-dev + - php{{ php_default_version_debian }}-fpm + - libpcre3-dev + - php{{ php_default_version_debian }}-gd + - php{{ php_default_version_debian }}-curl + - php{{ php_default_version_debian }}-imap + - php{{ php_default_version_debian }}-json + - php{{ php_default_version_debian }}-opcache + - php{{ php_default_version_debian }}-xml + - php{{ php_default_version_debian }}-mbstring + - php-sqlite3 + - php-apcu +__php_webserver_daemon: "apache2" + +# Vendor-specific configuration paths on Debian/Ubuntu make my brain asplode. +__php_conf_paths: + - /etc/php/{{ php_default_version_debian }}/fpm + - /etc/php/{{ php_default_version_debian }}/apache2 + - /etc/php/{{ php_default_version_debian }}/cli + +__php_extension_conf_paths: + - /etc/php/{{ php_default_version_debian }}/fpm/conf.d + - /etc/php/{{ php_default_version_debian }}/apache2/conf.d + - /etc/php/{{ php_default_version_debian }}/cli/conf.d + +__php_apc_conf_filename: 20-apcu.ini +__php_opcache_conf_filename: 10-opcache.ini +__php_fpm_daemon: php{{ php_default_version_debian }}-fpm +__php_fpm_conf_path: "/etc/php/{{ php_default_version_debian }}/fpm" +__php_fpm_pool_conf_path: "{{ __php_fpm_conf_path }}/pool.d/www.conf" + +__php_fpm_pool_user: www-data +__php_fpm_pool_group: www-data diff --git a/ansible/ansible-role-php/vars/RedHat.yml b/ansible/ansible-role-php/vars/RedHat.yml new file mode 100644 index 0000000000000000000000000000000000000000..e1e4458d76ab2e534161030a10855e12dd47a2db --- /dev/null +++ b/ansible/ansible-role-php/vars/RedHat.yml @@ -0,0 +1,32 @@ +--- +__php_packages: + - php + - php-cli + - php-common + - php-devel + - php-fpm + - php-gd + - php-ldap + - php-mbstring + - php-opcache + - php-pdo + - php-pear + - php-pecl-apcu + - php-xml + - php-xmlrpc +__php_webserver_daemon: "httpd" + +__php_conf_paths: + - /etc + +__php_extension_conf_paths: + - /etc/php.d + +__php_apc_conf_filename: 50-apc.ini +__php_opcache_conf_filename: 10-opcache.ini +__php_fpm_daemon: php-fpm +__php_fpm_conf_path: "/etc/fpm" +__php_fpm_pool_conf_path: "/etc/php-fpm.d/www.conf" + +__php_fpm_pool_user: apache +__php_fpm_pool_group: apache diff --git a/ansible/ansible-role-php/vars/Ubuntu-16.yml b/ansible/ansible-role-php/vars/Ubuntu-16.yml new file mode 100644 index 0000000000000000000000000000000000000000..eb23ce3a0cc59fbe83261706e70920eddf76a8e9 --- /dev/null +++ b/ansible/ansible-role-php/vars/Ubuntu-16.yml @@ -0,0 +1,2 @@ +--- +__php_default_version_debian: "7.0" diff --git a/ansible/ansible-role-php/vars/Ubuntu-18.yml b/ansible/ansible-role-php/vars/Ubuntu-18.yml new file mode 100644 index 0000000000000000000000000000000000000000..82230bcd7950ba2dfd36ebcc904d8a447fee55ce --- /dev/null +++ b/ansible/ansible-role-php/vars/Ubuntu-18.yml @@ -0,0 +1,2 @@ +--- +__php_default_version_debian: "7.2" diff --git a/ansible/ansible-role-php/vars/Ubuntu-20.yml b/ansible/ansible-role-php/vars/Ubuntu-20.yml new file mode 100644 index 0000000000000000000000000000000000000000..a16b99b155442b397dc0ca9c4c8c42ceb16ce814 --- /dev/null +++ b/ansible/ansible-role-php/vars/Ubuntu-20.yml @@ -0,0 +1,2 @@ +--- +__php_default_version_debian: "7.4" diff --git a/ansible/ansible.cfg b/ansible/ansible.cfg new file mode 100644 index 0000000000000000000000000000000000000000..9592696ffe54c809d6c8526a06e4860e8f836885 --- /dev/null +++ b/ansible/ansible.cfg @@ -0,0 +1,56 @@ +# Fichier de configuration pour Ansible dans l'infrastructure de LQDN. + +# Pour voir toutes les options, lancez `ansible-config list` ou la +# documentation: https://docs.ansible.com/ansible/latest/reference_appendices/config.html. + +[defaults] + +inventory = inventory.yml +log_path = ansible-run-lqdn.log +interpreter_python = auto_silent +roles_path = roles/ + +# Rajoute cette ligne aux fichiers de configuration géré par Ansible. +ansible_managed = "⚠ Ce fichier est géré par Ansible, ne pas modifier à la main ! - Responsables : Équipe Technique de La Quadrature Du Net" + + +# Configuration de l'affichage des playbooks +stdout_callback = yaml + +# Ansible va nous prévenir si des commandes peuvent être remplacé +# par des modules ansible. +command_warnings = True + +# Meuuuh 🐮 +nocows = 0 + + +[inventory] + +# R.A.S + +[privilege_escalation] +become = False +become_method = sudo + +[colors] +highlight = white +verbose = blue +warn = bright purple +error = red +debug = dark gray +deprecate = purple +skip = cyan +unreachable = red +ok = green +changed = yellow +diff_add = green +diff_remove = red +diff_lines = cyan + + +[diff] +# Montre les différences, comme en utilisant -D/--diff +always = True +# Combien de lignes de contexte +context = 2 diff --git a/ansible/configuration.test.yml b/ansible/configuration.test.yml new file mode 100644 index 0000000000000000000000000000000000000000..21541894e45d3fe24df8330a884c949273322ffd --- /dev/null +++ b/ansible/configuration.test.yml @@ -0,0 +1,123 @@ +# Ce fichier contient les variables de configuration de l'environment de test +# du site de don. + +# Si certaines variables ne sont pas mentionnées ici, c'est qu'elles ont +# été assignées leurs valeurs par défaut, présentes dans le rôle don-lqdn sous +# defaults/main.yml ou vars/main.yml + +# Variables pour le site de don en test + +don_domaine: "don.test.lqdn.fr" + +don_checksum_needed: "55ce33d7678c5a611085589f1f3ddf8b3c52d662cd01d4ba75c0ee0459970c2200a51f492d557530c71c15d8dba01eae" +don_git_branch: "122-suppression-des-pi-plomes" +don_install_source_code: false + +## Don Config + +don_user_password: "test" + +# SQL +don_sql_database: "don" +don_sql_user: "don" +don_sql_password: "test" + +# Payements +don_base_domain: "{{ don_domaine }}" +don_payement_url: "http://localhost:5001/payment" +don_return_check_url: "http://localhost:5001/check" +don_site_id: "0" +don_certificate: "" +don_ctx_mode: "DEVELOPPEMENT" + +# Piplome +don_piplome_path: "" +don_piplome_url: "" + +# Logs + +don_logs: "/home/don/don/logs" + +# Campagne +don_campaign_start_date: "20220228" +don_campaign_budget: "200000" + +# SMTP +don_smtp_host: "localhost" +don_smtp_port: 25 +don_smtp_security: "none" # tls, ssl, or none +don_smtp_user: "" +don_smtp_pw: "" + +# Env debug +don_debug: 0 +don_env: "env" + +## PHP Config + +php_webserver_daemon: "nginx" +php_enable_php_fpm: true +php_memory_limit: "128M" +php_max_execution_time: "90" +php_upload_max_filesize: "256M" +php_fpm_pools: + - pool_name: don + pool_template: www.conf.j2 + pool_listen: "/var/run/php/don.sock" + pool_listen_allowed_clients: "127.0.0.1" + pool_pm: dynamic + pool_pm_max_children: 5 + pool_pm_start_servers: 2 + pool_pm_min_spare_servers: 1 + pool_pm_max_spare_servers: 3 + pool_pm_max_requests: 500 + + +## Nginx config +nginx_remove_default_vhost: true +nginx_vhosts: + - listen: "80" + server_name: "_" + access_log: "/var/log/nginx/{{ don_domaine }}_access.log" + error_log: "/var/log/nginx/{{ don_domaine }}_error.log" + state: "present" + root: "/home/don/don/www" + index: "index.php index.html" + template: "{{ nginx_vhost_template }}" + filename: "{{ don_domaine }}.http.conf" + extra_parameters: | + location ~* \.(js|css|png|jpg|jpeg|gif|ico)$ { + expires max; + log_not_found off; + } + + location ~ \.php$ { + #NOTE: You should have "cgi.fix_pathinfo = 0;" in php.ini + include /etc/nginx/fastcgi_params; + try_files $uri =404; + fastcgi_split_path_info ^(.+\.php)(/.+)$; + fastcgi_intercept_errors on; + fastcgi_index index.php; + fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; + fastcgi_read_timeout 300; + fastcgi_buffers 16 16k; + fastcgi_buffer_size 32k; + fastcgi_pass unix:/var/run/php/don.sock; + } + + location = /favicon.ico { + log_not_found off; + access_log off; + } + + location = /robots.txt { + allow all; + log_not_found off; + access_log off; + } + + location / { + # This is cool because no php is touched for static content. + # include the "?$args" part so non-default permalinks doesn't break when using query string + try_files $uri $uri/ /index.php?$args; + } diff --git a/ansible/don-lqdn b/ansible/don-lqdn new file mode 160000 index 0000000000000000000000000000000000000000..ab26059469a9b1f4ad32cbe70e13c903c01c87ea --- /dev/null +++ b/ansible/don-lqdn @@ -0,0 +1 @@ +Subproject commit ab26059469a9b1f4ad32cbe70e13c903c01c87ea diff --git a/ansible/playbook.yml b/ansible/playbook.yml new file mode 100644 index 0000000000000000000000000000000000000000..d7bcfeaf67f2ec605ffd2b26125b29777556c7c7 --- /dev/null +++ b/ansible/playbook.yml @@ -0,0 +1,38 @@ +# Example de playbook permettant d'installer le site de don. + +# Ce playbook peut à la fois être utilisé pour l'installation en production du +# site de don, mais aussi mettre en place le site de don dans un environment de +# test grâce à Vagrant. + +# - name: Collect facts about system services +# ansible.builtin.service_facts: +# register: services_state + +# - name: Debug +# debug: +# var: services_state + +# - block: +# - name: Remove Apache2 server +# hosts: don-debian64 +# become: yes +# remote_user: root +# tasks: +# - name: Stop Apache2 +# service: +# name: apache2 +# enabled: no +# state: stopped +# when: services_state.ansible_facts.services["apache2"] is defined + +- name: Installation du site de don dans l'environment de test + hosts: don-debian64 + become: yes + # become_user: root + remote_user: root + vars_files: + - configuration.test.yml + roles: + - ansible-role-nginx + - ansible-role-php + - don-lqdn diff --git a/app/Utils.php b/app/Utils.php index 5c7b36bbb00fbb3f7d730a0aad57b88e464e2ca9..84baffa75089cd04d43942cfcbe619ba245e19e5 100644 --- a/app/Utils.php +++ b/app/Utils.php @@ -37,15 +37,4 @@ Cette fonction définit un mot de passe de 12 caractères return addslashes($str); } - public static function sanitize_piplomes($str) - { - // - traduire $c[nom] en latin1 - $str = utf8_decode($str); - // - supprimer les \, {, }, ~, - $str = preg_replace('/[\\\{\}\~]/', '', $str); - // - proteger les caracteres foireux ( & => \&, _ => \_, $ => \$ ) - $str = preg_replace('/([&_\$])/', '\\\$1', $str); - - return $str=substr($str, 0, 100); - } }; diff --git a/app/config.php b/app/config.php index 705af37534e7a39e9e2946a2d30f2e6023dbc89e..f52c7c95bb80bb489318321c4212accdb9b7a006 100644 --- a/app/config.php +++ b/app/config.php @@ -50,11 +50,11 @@ define("DEBUG", getenv('DEBUG')); define("SENTRY", getenv('SENTRY')); -$sentry_client = new Raven_Client($SENTRY); -$error_handler = new Raven_ErrorHandler($sentry_client); -$error_handler->registerExceptionHandler(); -$error_handler->registerErrorHandler(); -$error_handler->registerShutdownFunction(); +// $sentry_client = new Raven_Client($SENTRY); +// $error_handler = new Raven_ErrorHandler($sentry_client); +// $error_handler->registerExceptionHandler(); +// $error_handler->registerErrorHandler(); +// $error_handler->registerShutdownFunction(); if ('prod' !== $env) { error_reporting(E_ALL|E_WARNING); diff --git a/app/controller/admin.php b/app/controller/admin.php index 22bf5fd58bba99dc82acce3f315287ee2ba62c42..32ea4acab7ea69a1c864f297beff4f92316298ce 100644 --- a/app/controller/admin.php +++ b/app/controller/admin.php @@ -81,7 +81,6 @@ class Admin extends Controller } }; - $f3->set('PIPLOME_URL', PIPLOME_URL); } public function afterRoute($f3, $args) @@ -152,7 +151,6 @@ class Admin extends Controller $f3->set('date1', substr($date1, 0, 10)); $f3->set('date2', substr($date2, 0, 10)); $f3->set('data', $results); - $f3->set('piplome_url', PIPLOME_URL); $f3->set('block_content', 'backend/dons.html'); } @@ -255,12 +253,12 @@ class Admin extends Controller $f3->reroute("/admin/users/".$result['user_id']); } - public function regenerate_pdf($f3, $args) - { - $f3->get('container')['command_handler']->handle(new DonationResetPdfCommand($f3->get('POST.id'))); - $f3->push('SESSION.message', 'Régénération effectuée avec succès.'); - $f3->reroute("/admin/"); - } + // public function regenerate_pdf($f3, $args) + // { + // $f3->get('container')['command_handler']->handle(new DonationResetPdfCommand($f3->get('POST.id'))); + // $f3->push('SESSION.message', 'Régénération effectuée avec succès.'); + // $f3->reroute("/admin/"); + // } public function support($f3, $args) { @@ -402,11 +400,12 @@ class Admin extends Controller $f3->set('block_content', 'backend/don.html'); } + // Affichage des contreparties et de leurs status public function counterparts_dashboard($f3, $args) { $db = $f3->get('DB'); $f3->set('counterparts_import', ''); - $total = array("hoodie" => 0, "pishirt" => 0, "pibag" => 0, "piplome" => 0); + $total = array("hoodie" => 0, "pishirt" => 0, "pibag" => 0); if ($f3->get('VERB') == 'POST') { $separator = ';'; @@ -455,9 +454,6 @@ class Admin extends Controller case 'pibag': $needed = 64; break; - case 'piplome': - $needed = 42; - break; } if ($user['cumul'] >= $needed) { // Assez de point, on crée @@ -489,6 +485,7 @@ class Admin extends Controller $f3->set($row['quoi'].'_s2', 0); } } + // Calcul des quantités $query = "SELECT quoi, status, @@ -525,7 +522,6 @@ class Admin extends Controller $export = false; $texte = ''; $pibag = ''; - $piplome = ''; $pishirt = ''; $hoodie = ''; $pseudo = ''; @@ -559,10 +555,9 @@ class Admin extends Controller } $texte = $f3->get('POST.texte'); $pibag = $f3->get('POST.pibag'); - $piplome = $f3->get('POST.piplome'); $pishirt = $f3->get('POST.pishirt'); $hoodie = $f3->get('POST.hoodie'); - $quoi = $quoi + $pibag + $piplome + $pishirt + $hoodie; + $quoi = $quoi + $pibag + $pishirt + $hoodie; $limite = $f3->exists('POST.limite') ? (int) $f3->get('POST.limite') : 50; $page = $f3->exists('POST.page') ? (int) $f3->get('POST.page') : 1; $status = $f3->get('POST.status'); @@ -605,9 +600,6 @@ class Admin extends Controller case 1: $query .= " AND c.quoi='".\Utils::asl('pibag')."' "; break; - case 2: - $query .= " AND c.quoi='".\Utils::asl('piplome')."' "; - break; case 4: $query .= " AND c.quoi='".\Utils::asl('pishirt')."' "; break; @@ -623,12 +615,11 @@ class Admin extends Controller HAVING SUM( CASE quoi WHEN 'pibag' THEN 1 - WHEN 'piplome' THEN 2 WHEN 'pishirt' THEN 4 WHEN 'hoodie' THEN 8 END )=$quoi) -"; + "; } if ($status) { $query .= " AND c.status IN (".\Utils::asl($status).") "; @@ -638,27 +629,10 @@ class Admin extends Controller $query .= " ORDER BY c.datec DESC LIMIT $first, $last;"; $result = $db->query($query); $data = array(); + if ($result) { $i = 0; foreach ($result->fetchAll(\PDO::FETCH_ASSOC) as $row) { - if ($row['quoi']=='piplome') { - $pdf = $db->query("SELECT d.id AS id, - a.nom AS pseudo, - d.pdf AS pdf - FROM dons d - JOIN adresses a ON a.id = d.adresse_id - WHERE d.id='".$row['taille']."'"); - if ($pdf) { - $pdf = $pdf->fetch(\PDO::FETCH_ASSOC); - } - $row['pdf_id'] = $pdf['id']; - $row['pdf_nom'] = $pdf['pseudo']; - $row['pdf_url'] = $pdf['pdf']; - } else { - $row['pdf_id'] = ''; - $row['pdf_nom'] = ''; - $row['pdf_url'] = ''; - } $data[] = $row; $i++; } @@ -670,7 +644,6 @@ class Admin extends Controller $f3->set('texte', $texte); $f3->set('quoi', $quoi); $f3->set('pibag', $pibag); - $f3->set('piplome', $piplome); $f3->set('pishirt', $pishirt); $f3->set('hoodie', $hoodie); $f3->set('limite', $limite); @@ -679,7 +652,6 @@ class Admin extends Controller $f3->set('query', $query); $f3->set('data', $data); $f3->set('pseudo', $pseudo); - $f3->set('PIPLOME_URL', PIPLOME_URL); if ($export) { $rows = array(); @@ -688,9 +660,6 @@ class Admin extends Controller // Affichage de la taille de manière courte $taille = ""; $atailles = $f3->get('TAILLES'); - if ($row['quoi']!="piplome" and $row['quoi']!="pibag") { - $row['taille'] = preg_replace('(Coupe |Taille |omme,|emme,)', '', $atailles[$row['taille']]); - } if ($row['quoi']=="pibag") { $row['taille'] = "N/A"; } @@ -741,120 +710,110 @@ class Admin extends Controller public function counterpart($f3, $args) { - $id = ''; - $user_id = ''; - $quoi = ''; - $taille = ''; - $nom = ''; - $adresse = ''; - $adresse2 = ''; - $codepostal = ''; - $ville = ''; - $pays = ''; - $msg = ''; - $comment = ''; - $db = $f3->get('DB'); + $id = ''; + $user_id = ''; + $quoi = ''; + $taille = ''; + $nom = ''; + $adresse = ''; + $adresse2 = ''; + $codepostal = ''; + $ville = ''; + $pays = ''; + $msg = ''; + $comment = ''; + $db = $f3->get('DB'); + + // If we are just showing the counterparts, if ($f3->get('VERB')=='GET') { if ($f3->exists('PARAMS.id')) { - $id = $f3->get('PARAMS.id'); + $id = $f3->get('PARAMS.id'); } + // If we are editing it } else { - $id = $f3->get('POST.id'); - $user_id = $f3->get('POST.user_id'); - $quoi = $f3->get('POST.quoi'); - $taille = $f3->get('POST.taille'); - $nom = $f3->get('POST.nom'); - $email = $f3->get('POST.email'); - $adresse = $f3->Get('POST.adresse'); - $adresse2 = $f3->Get('POST.adresse2'); - $codepostal = $f3->get('POST.codepostal'); - $ville = $f3->get('POST.ville'); - $pays = $f3->get('POST.pays'); - $status = $f3->get('POST.status'); - $comment = $f3->get('POST.commentaire'); - - // Mise à jour de la contrepartie - if ($id!='') { - // First, let's retrieve the adresse from the adresse_id if it exists - $result = $db->query("SELECT adresse_id - FROM contreparties - WHERE id = '".\Utils::asl($f3->get('POST.id'))."' - AND adresse_id IS NOT NULL"); - $result = $result->fetch(\PDO::FETCH_ASSOC); - $adresse_id = $result['adresse_id']; - - if (!$adresse_id or $adresse_id == 0) { - // We need to create an adresse_id - $db->query("INSERT INTO adresses - VALUES (nom='".\Utils::asl($nom)."', - adresse='".\Utils::asl($adresse)."', - adresse2='".\Utils::asl($adresse2)."', - codepostal='".\Utils::asl($codepostal)."', - ville='".\Utils::asl($ville)."', - pays='".\Utils::asl($pays)."')"); - $adresse_id = $db->lastInsertId(); - } else { - // Updating the adresses first - $db->query("UPDATE adresses - SET nom='".\Utils::asl($nom)."', - adresse='".\Utils::asl($adresse)."', - adresse2='".\Utils::asl($adresse2)."', - codepostal='".\Utils::asl($codepostal)."', - ville='".\Utils::asl($ville)."', - pays='".\Utils::asl($pays)."' - WHERE id = $adresse_id"); - }; - $db->query("UPDATE contreparties - SET quoi='".\Utils::asl($quoi)."', - taille='".\Utils::asl($taille)."', - status='".\Utils::asl($status)."' - WHERE id='".\Utils::asl($_POST['id'])."'"); - // We will update the comment - $db->query("UPDATE users SET commentaire='".\Utils::asl($comment)."' WHERE id='".\Utils::asl($user_id)."'"); - } + $id = $f3->get('POST.id'); + $user_id = $f3->get('POST.user_id'); + $quoi = $f3->get('POST.quoi'); + $taille = $f3->get('POST.taille'); + $nom = $f3->get('POST.nom'); + $email = $f3->get('POST.email'); + $adresse = $f3->Get('POST.adresse'); + $adresse2 = $f3->Get('POST.adresse2'); + $codepostal = $f3->get('POST.codepostal'); + $ville = $f3->get('POST.ville'); + $pays = $f3->get('POST.pays'); + $status = $f3->get('POST.status'); + $comment = $f3->get('POST.commentaire'); + + // Updating the counterpart + if ($id!='') { + // First, let's retrieve the adresse from the adresse_id if it exists + $result = $db->query("SELECT adresse_id + FROM contreparties + WHERE id = '".\Utils::asl($f3->get('POST.id'))."' + AND adresse_id IS NOT NULL"); + + $result = $result->fetch(\PDO::FETCH_ASSOC); + $adresse_id = $result['adresse_id']; + + // Is the counterpart linked to an adresse_id ? + if (!$adresse_id or $adresse_id == 0) { + // We need to create an adresse_id + $db->query("INSERT INTO adresses + VALUES (nom='".\Utils::asl($nom)."', + adresse='".\Utils::asl($adresse)."', + adresse2='".\Utils::asl($adresse2)."', + codepostal='".\Utils::asl($codepostal)."', + ville='".\Utils::asl($ville)."', + pays='".\Utils::asl($pays)."')"); + $adresse_id = $db->lastInsertId(); + } else { + // Updating the adresses first + $db->query("UPDATE adresses + SET nom='".\Utils::asl($nom)."', + adresse='".\Utils::asl($adresse)."', + adresse2='".\Utils::asl($adresse2)."', + codepostal='".\Utils::asl($codepostal)."', + ville='".\Utils::asl($ville)."', + pays='".\Utils::asl($pays)."' + WHERE id = $adresse_id"); + } + + $db->query("UPDATE contreparties + SET quoi='".\Utils::asl($quoi)."', + taille='".\Utils::asl($taille)."', + status='".\Utils::asl($status)."' + WHERE id='".\Utils::asl($_POST['id'])."'"); + + // We will update the comment + $db->query("UPDATE users SET commentaire='".\Utils::asl($comment)."' WHERE id='".\Utils::asl($user_id)."'"); + } } + if ($id!='') { - $contrepartie = $f3->get('container')['counterpart_finder']->findById((int) $id); - } else { - $contrepartie = array( - 'id'=>$id, - 'user_id'=>$user_id, - 'quoi'=>$quoi, - 'taille'=>$taille, - 'nom'=>$nom, - 'adresse'=>$adresse, - 'adresse2'=>$adresse2, - 'codepostal'=>$codepostal, - 'ville'=>$ville, - 'pays'=>$pays, - 'status'=>$status, - 'commentaire'=>$comment, - ); + $contrepartie = $f3->get('container')['counterpart_finder']->findById((int) $id); } - $pdfs = array(); - if ($contrepartie['quoi']=='piplome') { - $result = $db->query("SELECT d.id AS id, - d.pdf AS pdf, - a.nom AS nom - FROM dons d - INNER JOIN adresses a ON d.adresse_id = a.id - WHERE pdf<>'' - AND d.status IN (1,4,101) - AND d.user_id='".$contrepartie['user_id']."'"); - if ($result) { - foreach ($result->fetchAll(\PDO::FETCH_ASSOC) as $pdf) { - $pdfs[] = $pdf; - } - } + else { + $contrepartie = array( + 'id'=>$id, + 'user_id'=>$user_id, + 'quoi'=>$quoi, + 'taille'=>$taille, + 'nom'=>$nom, + 'adresse'=>$adresse, + 'adresse2'=>$adresse2, + 'codepostal'=>$codepostal, + 'ville'=>$ville, + 'pays'=>$pays, + 'status'=>$status, + 'commentaire'=>$comment, + ); } - $f3->set('pdfs', $pdfs); - - $f3->set('id', $id); - $f3->set('msg', $msg); - $f3->set('contrepartie', $contrepartie); - - $f3->set('block_content', 'backend/contrepartie.html'); + $f3->set('id', $id); + $f3->set('msg', $msg); + $f3->set('contrepartie', $contrepartie); + $f3->set('block_content', 'backend/contrepartie.html'); } public function adresse($f3, $args) diff --git a/app/controller/bank.php b/app/controller/bank.php index 5005462cffd191cdbc127d07b4f1ad306c43b1a8..f9124ffb678d88c6830a94df2d3f7ac6caeabbd3 100644 --- a/app/controller/bank.php +++ b/app/controller/bank.php @@ -198,7 +198,6 @@ Pour rester au courant de l'actualité sur ces questions, vous pouvez : * nous suivre sur Twitter : https://twitter.com/laquadrature * nous suivre sur Facebook : https://www.facebook.com/LaQuadrature * nous suivre sur Mastodon : https://mamot.fr/@LaQuadrature -* nous suivre sur Diaspora* : https://framasphere.org/u/la_quadrature_du_net * vous abonner à notre lettre d'actualité hebdomadaire : https://lists.laquadrature.net/cgi-bin/mailman/listinfo/discussion * vous abonner à notre newsletter mensuelle : https://lists.laquadrature.net/cgi-bin/mailman/listinfo/actu diff --git a/app/controller/campaign.php b/app/controller/campaign.php index e49afbeea7a5dc1df0e3d445f9de24a569f753f3..a1dab17643953d96f1007fee010c3870044bcd4e 100644 --- a/app/controller/campaign.php +++ b/app/controller/campaign.php @@ -13,49 +13,6 @@ class Campaign extends Controller */ public static function show($f3, $args) { - // Let's do some math first - // So, get the $db - $db = $f3->get('DB'); - // Number of month left for a one-year provisionning since CAMPAIGN_START_DATE - $now = new \DateTime('now'); - $start = new \DateTime(CAMPAIGN_START_DATE); - if ($start > $now) { - $months = 0; - } else { - $months = $now->diff($start)->m; - } - $total_confirmed = 0; - $total_provisional = 0; - // So now, let's get the amount of confirmed dons, which are all the 1, 4, 101 and 102 - // statuses since CAMPAIGN_START_DATE - $result = $db->query( - "SELECT SUM(somme) - AS total_confirmed - FROM dons - WHERE status IN (1, 4, 102) - AND datec > '".CAMPAIGN_START_DATE."'" - ); - $total_confirmed = intval($result->fetchColumn()); - $f3->set('total_confirmed', $total_confirmed); - // Now, provisional. All reccuring pledge who have a datec in the last month (still active) - // multiplied by the number of remaining month - $result = $db->query("SELECT - SUM(a.somme) AS total_provisional - FROM (SELECT sum(somme) as somme - FROM dons - WHERE datec >= (CURRENT_DATE() - INTERVAL 1 MONTH) - AND status IN (101, 102) - GROUP BY identifier - ) a"); - // How many month till the end of the year. Also, only 80% of them - $total_provisional = intval($result->fetchColumn()) * (12 - $months); - $f3->set('total_provisional', $total_provisional); - // Now, let's calculate the percentage of each of them - $campaign_goal = CAMPAIGN_BUDGET; - $percent_confirmed = number_format($total_confirmed * 100 / $campaign_goal); - $f3->set('percent_confirmed', $percent_confirmed); - $percent_provisional = number_format($total_provisional * 100 / $campaign_goal); - $f3->set('percent_provisional', $percent_provisional); $f3->set('block_content', 'campaign/home.html'); } diff --git a/app/controller/cron.php b/app/controller/cron.php index caecc3caaaec88ef9d468dd91c659e8078030886..f611c023a0d0fda180a75f40c22da5febdb85878 100644 --- a/app/controller/cron.php +++ b/app/controller/cron.php @@ -1,197 +1,20 @@ exists('SESSION.user')) { - $f3->reroute('/login'); - } - $logger = new \Log("/piplome.log"); - $ids = array(); - $db = $f3->get('DB'); - - if (array_key_exists('id', $args)) { - // Let's check if we can have a pdf - $result = $db->query("SELECT dons.id as id, decimale, users.pseudo as nom, lang FROM dons LEFT JOIN users ON dons.user_id = users.id WHERE dons.status IN (1, 4, 101) AND dons.id='".\Utils::asl($args['id'])."'"); - } else { - // We want to generate all piplomes which does not exists yet - $result = $db->query("SELECT dons.id as id, decimale, users.pseudo as nom, lang FROM dons LEFT JOIN users ON dons.user_id = users.id WHERE pdf='' AND dons.status IN (1, 4, 101) LIMIT 100;"); - } - - $pdfs = []; - foreach ($result->fetchAll(\PDO::FETCH_ASSOC) as $row) { - $pdfs[] = $row; - } - - // We do have our IDs - // We need to create a PDF - $lock = @fopen("../tmp/piplomes.lock", "ab"); - if ($lock) { - flock($lock, LOCK_EX); - foreach ($pdfs as $pdf) { - $logger->write("Generating piplome id:".$pdf['id'].""); - if (!$pdf['decimale'] or $pdf['decimale'] == 0) { - // We need to get a pi decimals - do { - $decimale = rand(10, 200000); - $logger->write("Trying if $decimale is free"); - $result = $db->query("SELECT id FROM dons WHERE decimale='".\Utils::asl($decimale)."';"); - $tmp = $result->fetchAll(\PDO::FETCH_COLUMN, 'id'); - } while ($tmp); - $logger->write("Found a decimal of pi: ".$decimale.""); - $pdf['decimale'] = $decimale; - } - - // We need a tmp unique filename - $pdf['hash'] = $pdf['id']."_".substr(md5("Enter the Darquenette".$pdf['id']), 10, 16); - $logger->write("Calculated hash: ".$pdf['hash'].""); - - // Let's trash the garbage - foreach (array('tex', 'aux', 'pdf', 'log') as $ext) { - @unlink(dirname(__FILE__)."/../../tmp/pplome.".$ext); - } - - // We now have only fr or en templates - if ($pdf['lang'] == 'fr') { - $pdf['lang'] = 'fr_FR'; - } - if ($pdf['lang'] != 'fr_FR') { - $pdf['lang'] = 'en_US'; - } - $logger->write("Language is ".$pdf['lang'].""); - - $template = file_get_contents(dirname(__FILE__)."/../../locales/".$pdf['lang']."/LC_MESSAGES/plome.tex"); - - // We will open the pi-decimals file - $pi = fopen(dirname(__FILE__)."/../../www/static/pi-billion/pi-billion.txt", "rb"); - - if (!$pi) { - $logger->write("FATAL: Can't open decimals"); - exit(); - } - - // Let's get the specific set of decimals we want - fseek($pi, 1000 * $pdf['decimale']); - $decimales = ""; - for ($i = 0; $i < 10; $i++) { - $dec = fgets($pi, 100); - $decimales .= "\x{".$dec."}\n"; - } - fclose($pi); - - $pdf['nom'] = \Utils::clean_encoding(\Utils::sanitize_piplomes($pdf['nom'])); - $logger->write("PDF File will be ". $pdf['hash']); - $logger->write("decimales: ".$decimales); - - // Let's replace the templates with values - file_put_contents( - dirname(__FILE__)."/../../tmp/pplome.tex", - str_replace( - "%%DECIMALES%%", - $decimales, - str_replace( - "%%NOM%%", - $pdf['nom'], - str_replace( - "%%MILLIER%%", - $pdf['decimale'], - $template - ) - ) - ) - ); - - // Let's create the pdf from the template - $logger->write("Building the pdf from the tex template"); - $command = 'TEXINPUTS='.dirname(__FILE__).'/../../tex/:$TEXINPUTS '; - - // We need to set an env variable first - putenv('TEXINPUTS='.dirname(__FILE__).'/../../tex:'.getenv('TEXINPUTS')); - $command .= '/usr/bin/pdflatex '; - $command .= '-output-directory='.dirname(__FILE__)."/../../tmp "; - $command .= dirname(__FILE__)."/../../tmp/pplome.tex"; - $logger->write($command); - exec($command, $output, $return); - foreach ($output as $line) { - $logger->write($line); - } - - if ($return != 0) { - $logger->write("Error"); - $db->query("UPDATE dons SET pdf='Error $return' WHERE id='".$pdf['id']."';"); - continue; - } - $logger->write("PDF created"); - - // Move the pdf to its position - @unlink(PIPLOME_PATH . $pdf['hash'] .".pdf"); - $logger->write("Moving pdf to ".PIPLOME_PATH.$pdf['hash'].".pdf"); - @rename(dirname(__FILE__)."/../../tmp/pplome.pdf", PIPLOME_PATH . $pdf['hash'] . ".pdf"); - - // Let's trash the garbage - foreach (array('tex', 'aux', 'pdf', 'log') as $ext) { - @unlink(dirname(__FILE__)."/../../tmp/pplome.".$ext); - } - - // Saving the pathin database - $db->query("UPDATE dons SET pdf='".$pdf['hash']."', decimale='".$pdf['decimale']."' WHERE id='".$pdf['id']."';"); - } - - // Generating all the pdf, freeing the locks - flock($lock, LOCK_UN); - fclose($lock); - @unlink("/tmp/generate.lock"); - } else { - //Error - $logger->write("Can't get access to lock."); - } - $logger->write("Generation finished"); - - if (array_key_exists('id', $args) && php_sapi_name() != 'cli') { - // We will send the PDF file to the browser - $result = $db->query("SELECT dons.id as id, - decimale, - users.pseudo as nom, - lang, - pdf - FROM dons - LEFT JOIN users ON dons.user_id = users.id - WHERE dons.status IN (1, 4, 101) - AND dons.id='".\Utils::asl($args['id'])."'"); - $pdf = $result->fetch(\PDO::FETCH_ASSOC); - $fp = fopen(PIPLOME_PATH . $pdf['pdf'] .".pdf", "rb"); - if ($fp) { - $fsize = filesize(PIPLOME_PATH . $pdf['pdf'] .".pdf"); - header("Content-Type: application/pdf"); - header("Content-Disposition: attachment; filename=\"".$pdf['pdf'].".pdf\""); - header("Content-Length: $fsize"); - while (!feof($fp)) { - $buffer = fread($fp, 2048); - echo $buffer; - } - fclose($fp); - } else { - $f3->reroute('/perso'); - } - } - } -} +// /* +// * This class is used to manage cronjobs. +// * We use the PHP_SAPI to be sure to refuse to run on a webserver. +// * The command should be called like this : +// * php index.php "/action" +// */ +// namespace Controller; + +// class Cron extends Controller +// { +// public function beforeRoute($f3, $args) +// { +// parent::beforeRoute($f3, $args); +// } + +// public function afterRoute($f3, $args) +// { +// } +// } \ No newline at end of file diff --git a/app/controller/perso.php b/app/controller/perso.php index 97e90a5b639779b20c7fb27c9ef8f50cfa1f52a5..861409e0a88783e2e265ee19c8fcd6aa2d361926 100644 --- a/app/controller/perso.php +++ b/app/controller/perso.php @@ -46,14 +46,15 @@ class Perso extends Controller $db = $f3->get('DB'); $user = $f3->get('container')['user_finder']->findById($f3->get('SESSION.id')); $f3->set('infos', $user); - $result = $db->query("SELECT id, pdf, decimale FROM dons WHERE user_id='".\Utils::asl($user['id'])."' and pdf!='' "); - $pdfs = array(); - foreach ($result->fetchAll(\PDO::FETCH_ASSOC) as $row) { - $pdfs[$row['pdf']] = $row; - } + // $result = $db->query("SELECT id, pdf, decimale FROM dons WHERE user_id='".\Utils::asl($user['id'])."' and pdf!='' "); + $result = $db->query("SELECT id FROM dons WHERE user_id=" . \Utils::asl($user['id'])); + // $pdfs = array(); + // foreach ($result->fetchAll(\PDO::FETCH_ASSOC) as $row) { + // $pdfs[$row['pdf']] = $row; + // } $addresse = $f3->get('container')['address_finder']->findByUserId((int) $user['id']); $f3->set('adresse', $addresse); - $f3->set('pdfs', $pdfs); + // $f3->set('pdfs', $pdfs); } public function get_contreparties($f3) @@ -116,13 +117,16 @@ class Perso extends Controller $email = \Utils::asl($f3->get('email')); $hash = hash('sha256', $f3->get('password')); $login = $auth->login($email, $hash); - + // As we're login with email, not for id, we need to get it if ($login) { // We want to retrieve the associated user $result = $db->query("SELECT id, email FROM users WHERE email='".$email."'"); - $id = $result->fetch(\PDO::FETCH_ASSOC)['id']; - $email = $result->fetch(\PDO::FETCH_ASSOC)['email']; + // You can only fetch ONCE, unfortunately + $res = $result->fetch(\PDO::FETCH_ASSOC); + $id = $res['id']; + $email = $res['email']; + $f3->set('SESSION.id', $id); $f3->set('SESSION.email', $email); $f3->set('SESSION.user', true); @@ -207,32 +211,86 @@ class Perso extends Controller } } + /** + * create_user + * + * @param mixed $f3 + * + * @return none + */ public function create_user($f3) { - if ($f3->get('email')!='') { - // On vérifie que l'adresse mail n'existe pas + /// + // Verify the information for the new account + /// + + $new_account_email = $f3->get("email"); + $new_account_password = $f3->get("password"); + + // error_log("New account email : ",3,"/home/don/don/log/error.log"); + // error_log(print_r($new_account_email, true) . "\n",3,"/home/don/don/log/error.log"); + // error_log("New account password : ",3,"/home/don/don/log/error.log"); + // error_log(print_r($new_account_password, true) . "\n",3,"/home/don/don/log/error.log"); + + // Did the user give an email ? + if (!$new_account_email || empty($new_account_email)){ + $f3->push('SESSION.error', _("Merci de renseigner une adresse email pour pouvoir créer un compte.")); + $f3->error('400'); + } + + // Did the user give a password ? + if (!$new_account_password || empty($new_account_password)){ + $f3->push('SESSION.error', _("Merci de renseigner un mot de passe pour pouvoir créer un compte.")); + $f3->error('400'); + } + + // Try to find an existing user account with an email matching the one given + $does_an_account_exist = $f3->get('container')['user_finder']->findByEmail($new_account_email); + // error_log("Does a user exists with the email address already ? : ",3,"/home/don/don/log/error.log"); + // error_log(print_r(!empty($does_an_account_exist), true) . "\n",3,"/home/don/don/log/error.log"); + + if ( !empty($does_an_account_exist)) { + $f3->push('SESSION.error', _("Désolé, un compte existe déjà avec cette adresse. Si vous avez perdu votre mot de passe, vous pouvez demander à le renouveller.")); + $f3->error('403'); + } + + /// + // Creating the new user account + /// + + $new_account_password_hash = hash('sha256', $new_account_password); + // error_log("Password hash for new user : ",3,"/home/don/don/log/error.log"); + // error_log(print_r($new_account_password_hash, true) . "\n",3,"/home/don/don/log/error.log"); + + // Cumulate all the donnations originating from this email address to update the new account's balance + try { $db = $f3->get('DB'); - $user = $f3->get('container')['user_finder']->findByEmail($f3->get('email')); - $total = 0; - $cumul = 0; - - if ($user['email']!=$f3->get('email')) { - $hash = hash('sha256', $f3->get('password')); - // On recherche le montant cumulé jusqu'à présent. On fait la somme depuis le - // premier janvier 2013 en se basant sur l'adresse mail - $res = $db->query("SELECT sum(dons.somme) as somme FROM dons INNER JOIN users WHERE dons.user_id = users.id AND users.email='".\Utils::asl($f3->get('email'))."' and dons.status in (1, 4, 102) and dons.datec>'2013-01-01';"); - $total = $res->fetch(\PDO::FETCH_ASSOC); - $total = (int) $total['somme']; - // Création de l'utilisateur - $f3->push('SESSION.message', _("Votre compte a bien été créé, merci.")); - $f3->get('container')['command_handler']->handle(new UserCreateCommand($f3->get('email'), $hash, '', $total, $total)); - $f3->reroute('/perso'); - } else { - $f3->push('SESSION.error', _("Vous avez déjà un compte associé à cette adresse mail, merci de demander un nouveau mot de passe.")); - } - } else { - $f3->push('SESSION.error', _("Merci de renseigner une adresse mail.")); + $res = $db->query("SELECT sum(dons.somme) as somme FROM dons INNER JOIN users WHERE dons.user_id = users.id AND users.email='".\Utils::asl($f3->get('email'))."' and dons.status in (1, 4, 102) and dons.datec>'2013-01-01';"); + $total = $res->fetch(\PDO::FETCH_ASSOC); + } catch (\Exception $th) { + // error_log("Error while getting balance : ",3,"/home/don/don/log/error.log"); + // error_log(print_r($th->getMessage(), true) . "\n",3,"/home/don/don/log/error.log"); + $f3->push('SESSION.error', _("Une erreur est survenue lors de la création de votre compte, merci de réessayer.")); + $f3->error('500'); + } + + $total = (int) $total['somme']; + // error_log("New account existing total balance : ",3,"/home/don/don/log/error.log"); + // error_log(print_r($total, true) . "\n",3,"/home/don/don/log/error.log"); + + // Inject the new user to the database + try { + $f3->get('container')['command_handler']->handle(new UserCreateCommand($new_account_email, $new_account_password_hash, '', $total, $total)); + } catch (\Exception $th) { + // error_log("Error while injecting the user ",3,"/home/don/don/log/error.log"); + // error_log(print_r($th, true) . "\n",3,"/home/don/don/log/error.log"); + $f3->push('SESSION.error', _("Une erreur est survenue lors de la création de votre compte,".$th->getMessage()." merci de réessayer.")); + $f3->error('500'); } + + $f3->push('SESSION.message', _("Votre compte a bien été créé, merci.")); + // error_log("New user created \n",3,"/home/don/don/log/error.log"); + $f3->reroute('/perso'); } public function infos($f3, $args) @@ -330,49 +388,56 @@ class Perso extends Controller $db = $f3->get('DB'); $user = $f3->get('container')['user_finder']->findById($f3->get('SESSION.id')); - // Récupération des valeurs du formulaire - $adresse_id = $f3->get('adresse_id'); + $adresse_id = $f3->get('container')['address_finder']->findByUserId($f3->get('SESSION.id'))["id"]; $quoi = $f3->get('quoi'); $commentaire = $f3->get('commentaire'); $valeur = 0; - $piplome_id = intval(substr($f3->get('piplome_id'), 0, strpos($f3->get('piplome_id'), '_'))); $taille = intval($f3->get('taille')); $taille_h = intval($f3->get('taille_h')); + + // Vérification des données avant l'ajout des contreparties + if (empty($adresse_id) || empty($quoi)) { + $f3->push('SESSION.error', _("Désolé, votre demande à été mal formulée, veulliez réessayer ou nous envoyer un email.")); + $f3->error('400'); + } + switch ($quoi) { - case 'piplome': - $valeur = 42; - break; - case 'pibag': - $valeur = 64; - break; - case 'pishirt': - $valeur = 128; - break; - case 'hoodie': - $valeur = 314; - break; + case 'pibag': + $valeur = 64; + break; + case 'pishirt': + $valeur = 128; + break; + case 'hoodie': + $valeur = 314; + break; + default: + $f3->push('SESSION.error', _("Désolé, mais vous avez demandé une contrepartie impossible...")); + $f3->error('400'); + break; } // Ajout d'une demande de contrepartie pour chaque contrepartie if ((int) $user['cumul'] >= $valeur) { + $parent = $f3->get('container')['counterpart_finder']->getNextInsertedId(); + switch ($quoi) { - case 'hoodie': - $f3->get('container')['command_handler']->handle(new CounterpartCreateCommand(\Utils::asl($adresse_id), $f3->get('SESSION.id'), 'hoodie', \Utils::asl($taille_h), 1, date("Y-m-d H:i:s"), \Utils::asl($commentaire), $parent)); - // no break - case 'pishirt': - $f3->get('container')['command_handler']->handle(new CounterpartCreateCommand(\Utils::asl($adresse_id), $f3->get('SESSION.id'), 'pishirt', \Utils::asl($taille), 1, date("Y-m-d H:i:s"), \Utils::asl($commentaire), $parent)); - // no break - case 'pibag': - $f3->get('container')['command_handler']->handle(new CounterpartCreateCommand(\Utils::asl($adresse_id), $f3->get('SESSION.id'), 'pibag', '', 1, date("Y-m-d H:i:s"), \Utils::asl($commentaire), $parent)); - // no break - case 'piplome': - $f3->get('container')['command_handler']->handle(new CounterpartCreateCommand(\Utils::asl($adresse_id), $f3->get('SESSION.id'), 'piplome', \Utils::asl($piplome_id), 1, date("Y-m-d H:i:s"), \Utils::asl($commentaire), $parent)); - break; + case 'hoodie': + $f3->get('container')['command_handler']->handle(new CounterpartCreateCommand(\Utils::asl($adresse_id), $f3->get('SESSION.id'), 'hoodie', \Utils::asl($taille_h), 1, date("Y-m-d H:i:s"), \Utils::asl($commentaire), $parent)); + // no break + case 'pishirt': + $f3->get('container')['command_handler']->handle(new CounterpartCreateCommand(\Utils::asl($adresse_id), $f3->get('SESSION.id'), 'pishirt', \Utils::asl($taille), 1, date("Y-m-d H:i:s"), \Utils::asl($commentaire), $parent)); + // no break + case 'pibag': + $f3->get('container')['command_handler']->handle(new CounterpartCreateCommand(\Utils::asl($adresse_id), $f3->get('SESSION.id'), 'pibag', 1, 1, date("Y-m-d H:i:s"), \Utils::asl($commentaire), $parent)); + break; } + // Puis diminution du cumul de la valeur des contreparties $f3->get('container')['command_handler']->handle(new UserUpdateCumulCommand($user['id'], $user['cumul'] - $valeur)); $f3->push('SESSION.message', _("Merci, vos contreparties seront envoyées dès que possible !".$valeur)); + } else { $f3->push('SESSION.error', _("Désolé, mais vous n'avez pas cumulé suffisament de dons pour avoir un ").$quoi); $f3->clear('SESSION.message'); diff --git a/app/view/backend/contrepartie.html b/app/view/backend/contrepartie.html index eed4b98d101e4264ca170b66daefe1f3ded8d24d..21e26605ebbad774ecdea8c1abddc274896b9b57 100644 --- a/app/view/backend/contrepartie.html +++ b/app/view/backend/contrepartie.html @@ -14,7 +14,6 @@ @@ -28,14 +27,6 @@ - - - -
@@ -96,22 +87,12 @@ document.forms['f'].nom.focus(); function select_span() { - if (document.forms['f'].quoi.value=='piplome') { - $('#quoi_pdf').show(); - $('#quoi_taille').hide(); - } else { - $('#quoi_pdf').hide(); - $('#quoi_taille').show(); - } + $('#quoi_taille').show(); select_taille(); } function select_taille() { - if (document.forms['f'].quoi.value=='piplome') { - document.forms['f'].taille.value = document.forms['f'].url.value; - } else { - document.forms['f'].taille.value = document.forms['f'].size.value; - } + document.forms['f'].taille.value = document.forms['f'].size.value; } window.onload = function() { diff --git a/app/view/backend/contreparties.html b/app/view/backend/contreparties.html index 84ace0e9c2afdfd09359af28b4d01e2650fa2665..aa358605ca4e8cc75881437bc31ed25a5973ba5a 100644 --- a/app/view/backend/contreparties.html +++ b/app/view/backend/contreparties.html @@ -8,14 +8,11 @@ -{{ @pibag }} / {{ @piplome }} / {{ @pishirt }} / {{ @hoodie }} / {{ @status }} +{{ @pibag }} / {{ @pishirt }} / {{ @hoodie }} / {{ @status }} - @@ -46,7 +43,7 @@ Email Date Quoi - Taille/Piplome + Taille Adresse Statut Commentaire @@ -61,20 +58,12 @@ {{ @row.datec }} {{ @row.quoi }} - + - {{ @row.pdf_url }} - ({{ @row.pdf_nom }}) +   - - -   - - - {{ @atailles[@row.taille] }} - - + {{ @atailles[@row.taille] }} @@ -105,10 +94,6 @@ - Annulé - - - - PDF - diff --git a/app/view/backend/contreparties_tableau.html b/app/view/backend/contreparties_tableau.html index a86a681a4b70cb6bc93bd4a5aae1e37f15e10ef2..64d7cde5e8b0b84e604303a08fc158ad7c60f45a 100644 --- a/app/view/backend/contreparties_tableau.html +++ b/app/view/backend/contreparties_tableau.html @@ -8,7 +8,7 @@ - +

Tableau de bord des contreparties

@@ -18,11 +18,6 @@ - - - - - diff --git a/app/view/backend/dons.html b/app/view/backend/dons.html index 9d4dd9bce501868d923777498e083afcc2426129..d859222754a78b5cb7481abc5706435ac8962203 100644 --- a/app/view/backend/dons.html +++ b/app/view/backend/dons.html @@ -58,7 +58,6 @@ - @@ -76,7 +75,6 @@ {{ @row.codepostal }} {{ @row.ville }}
{{ @row.pays }} - diff --git a/app/view/backend/fusion_user.html b/app/view/backend/fusion_user.html index 68c239dbbaa98b74bedab04df5fd95349298edf1..4ec48ebded77cbd0ba67e3ffa24e56e1d48cefbf 100644 --- a/app/view/backend/fusion_user.html +++ b/app/view/backend/fusion_user.html @@ -22,7 +22,7 @@ - + @@ -35,20 +35,12 @@ @@ -71,7 +63,6 @@ - @@ -80,7 +71,6 @@ - diff --git a/app/view/backend/user.html b/app/view/backend/user.html index 17908284eed3b89b123859ecad1e7c09a95ac027..d34069fd804d709b9b20634a01ce06563198c0c7 100644 --- a/app/view/backend/user.html +++ b/app/view/backend/user.html @@ -110,7 +110,7 @@ - + @@ -123,22 +123,14 @@ @@ -194,7 +182,6 @@ - @@ -204,16 +191,6 @@ - diff --git a/app/view/user/dons.html b/app/view/user/dons.html index 51088ec7410cc8b6e93628d7006e58219ce7cbf1..d208174dd7c9a97314ef590b724210972e5ea0a4 100644 --- a/app/view/user/dons.html +++ b/app/view/user/dons.html @@ -28,7 +28,6 @@ - @@ -43,13 +42,7 @@ - - - - - - - + diff --git a/app/view/user/infos.html b/app/view/user/infos.html index d5db158c805949858704adf693eb3ff2304c208d..21241f0a41e207e37bb9e711dd6b64e3ce103115 100644 --- a/app/view/user/infos.html +++ b/app/view/user/infos.html @@ -88,39 +88,29 @@ - - - @@ -165,16 +164,6 @@ -
Fait
Piplômes {{ @piplome_s1 }} {{ @piplome_s2 }}
Pishirts {{ @pishirt_s1 }}Email Don AdressePDF Statut Actions {{ @row.pdf }} {{ @DONS_STATUTS[@row.status] }} Editer @@ -87,8 +85,6 @@ Invalider - - - Regénérer le PDF Id du parent Date QuoiTaille/PiplomeTaille Statut Commentaire
{{ @row.datec }} {{ @row.quoi }} - + - {{ @row.pdf_url }} - ({{ @row.pdf_nom }}) +   - - -   - - - {{ @atailles[@row.taille] }} - - + {{ @atailles[@row.taille] }} Date Don AdressePDF Statut
{{ @row.id }} {{ @row.datec }} {{ @row.somme }}{{ @row.pdf }} {{ @row.status }}
Id du parent Date QuoiTaille/PiplomeTaille Adresse Statut Actions{{ @row.datec }} {{ @row.quoi }} - - - {{ @row.pdf_url }} - ({{ @row.pdf_nom }}) - - - - -   - - - {{ @TAILLES[@row.taille] }} - - - - + + +   + + + {{ @TAILLES[@row.taille] }} + + @@ -169,10 +161,6 @@ - Annulé - - - - PDF -
ID Date DonPDF Statut Actions {{ @row.id }} {{ @row.datec }} {{ @row.somme }} - - - PDF - - - PDF - - - {{ @DONS_STATUTS[@row.status] }} Editer @@ -243,22 +220,12 @@ document.forms['f'].nom.focus(); function select_span() { - if (document.forms['f'].quoi.value=='piplome') { - $('#quoi_pdf').show(); - $('#quoi_taille').hide(); - } else { - $('#quoi_pdf').hide(); - $('#quoi_taille').show(); - } + $('#quoi_taille').show(); select_taille(); } function select_taille() { - if (document.forms['f'].quoi.value=='piplome') { - document.forms['f'].taille.value = document.forms['f'].url.value; - } else { - document.forms['f'].taille.value = document.forms['f'].size.value; - } + document.forms['f'].taille.value = document.forms['f'].size.value; } window.onload = function() { diff --git a/app/view/campaign/donation.html b/app/view/campaign/donation.html index 48856f7a3f607a29589fc88c9f25dae931a87c14..97fa70c100cf70d366aa0b529700c0e8acb19aff 100644 --- a/app/view/campaign/donation.html +++ b/app/view/campaign/donation.html @@ -22,19 +22,11 @@

{{ _("En remerciement de votre don, vous obtiendrez :") }}

-
- -

{{ _("En 0 mois de dons.") }}

-
-
- -

{{ _("En 0 mois de dons.") }}

-

{{ _("En 0 mois de dons.") }}

@@ -48,11 +40,9 @@

{{ _("En 0 mois de dons.") }}


- - -

{{ _("Votre pi-plôme en tirage original et un pi-bag très pratique") }}

- - +

{{ _("Un pi-bag très pratique") }}

+ +
diff --git a/app/view/campaign/faq.html b/app/view/campaign/faq.html index 5cba55e7d2f09a657703c2cf037b8e7be1e0125b..517e0244078058868514cd44a82f803b7ec1bf6b 100644 --- a/app/view/campaign/faq.html +++ b/app/view/campaign/faq.html @@ -288,7 +288,7 @@
  • {{ _("Notre banque va également, dans le cadre du traitement des dons, être mise au courant du montant des dons, et de vos informations bancaires tel que fournis sur leur site. Pour en savoir plus sur la gestion des données par notre banque, vous pouvez consulter leur notice légale.") }}
  • - {{ _("Lors de la suppression de votre compte, nous supprimons toutes les données liées. Vous pouvez également demander à ce que vos informations vous soit transmises, rectifiées ou supprimées sur simple demande auprès de notre adresse de contact. Vous pouvez également vous renseigner sur vos droits auprès de la Commission Nationale Informatique et Liberté (CNIL).") }} + {{ _("Lors de la suppression de votre compte, nous supprimons toutes les données liées. Vous pouvez également demander à ce que vos informations vous soit transmises, rectifiées ou supprimées sur simple demande auprès de notre adresse de contact. Vous pouvez également vous renseigner sur vos droits auprès de la Commission Nationale Informatique et Liberté (CNIL).") }} ") }}

    diff --git a/app/view/campaign/home.html b/app/view/campaign/home.html index d12ae1983ffba7a11c873188469b643328eb8c99..9346310372b37a904bc1635705c669442122c848 100644 --- a/app/view/campaign/home.html +++ b/app/view/campaign/home.html @@ -91,6 +91,7 @@ {{ _("Détails personnels") }}
    -
    - -
    {{ _("Un πplome
    (cumul de 42€)") }}
    -
    {{ _("Un pibag
    (cumul de 64€)") }}
    diff --git a/app/view/user/contreparties.html b/app/view/user/contreparties.html index 5e3a6f065e8f56de4bfd7436a1511bd2456a0351..b20bd56636a8d52a9cd2f786db857ab851947152 100644 --- a/app/view/user/contreparties.html +++ b/app/view/user/contreparties.html @@ -12,19 +12,12 @@
    {{ @contrepartie.quoi }} - + - ({{ @contrepartie.taille }}) +   - - -   - - - ({{ @atailles[@contrepartie.taille] }}) - - + ({{ @atailles[@contrepartie.taille] }}) {{ _("Date") }} {{ _("Type") }} {{ _("Montant") }}{{ _("Pi-plôme") }} {{ _("Action") }} {{ @don.somme }}{{ _("Voir le pi-plôme") }}   {{ _("Imprimer un reçu pour ce don") }}
    {{ _("Date") }} {{ _("Dons") }} {{ _("Récurent") }}{{ _("Piplome") }}
    {{ _("Oui (en erreur)") }} {{ _("Non") }} - - - {{ _("Générer") }} - - - {{ @pdfs[@don.pdf].decimale }}.pdf - - -
    @@ -247,37 +236,6 @@
    - -
    -
    -
    -
    - disabled value="piplome"> - -
    -
    -

    - -

    -
    -
    -
    - -
    - - -
    -
    -
    -
    -

    42 €

    -
    -
    -
    -
    -
    @@ -295,7 +253,6 @@
    @@ -323,7 +280,7 @@
    @@ -360,7 +317,7 @@
    @@ -424,16 +381,6 @@

    {{ _("Récapitulatif :") }}