From d56c54518376e91635a2167ad954749bd4993a3c Mon Sep 17 00:00:00 2001 From: Ludovic Poujol Date: Mon, 19 Apr 2021 17:35:49 +0200 Subject: [PATCH 01/86] apache: new variable for mpm mode (+ updated default config accordingly) Also, itk package will only be installed if required --- CHANGELOG.md | 2 + apache/defaults/main.yml | 2 + apache/files/evolinux-defaults.conf | 58 ++++++++++++++++++----------- apache/tasks/main.yml | 26 ++++++++++++- 4 files changed, 65 insertions(+), 23 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 11b4a350..4f35ea6c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,8 @@ The **patch** part changes incrementally at each release. ### Added +* apache: new variable for mpm mode (+ updated default config accordingly) + ### Changed ### Fixed diff --git a/apache/defaults/main.yml b/apache/defaults/main.yml index e49dbc20..7b58ea3f 100644 --- a/apache/defaults/main.yml +++ b/apache/defaults/main.yml @@ -23,3 +23,5 @@ log2mail_alert_email: Null apache_logrotate_frequency: daily apache_logrotate_rotate: 365 + +apache_mpm: "itk" \ No newline at end of file diff --git a/apache/files/evolinux-defaults.conf b/apache/files/evolinux-defaults.conf index e5eadda8..06e28d9e 100644 --- a/apache/files/evolinux-defaults.conf +++ b/apache/files/evolinux-defaults.conf @@ -3,12 +3,43 @@ Timeout 10 KeepAliveTimeout 2 MaxKeepAliveRequests 10 #MaxClients 250 -MaxRequestWorkers 250 -ServerLimit 250 -StartServers 50 -MinSpareServers 20 -MaxSpareServers 30 -MaxRequestsPerChild 0 + + + MaxRequestWorkers 250 + ServerLimit 250 + StartServers 50 + MinSpareServers 20 + MaxSpareServers 30 + MaxRequestsPerChild 0 + + + + StartServers 3 + MinSpareThreads 25 + MaxSpareThreads 75 + ThreadLimit 64 + ThreadsPerChild 25 + MaxRequestWorkers 150 + MaxConnectionsPerChild 0 + + + + LimitUIDRange 0 6000 + LimitGIDRange 0 6000 + + + + SSLProtocol all -SSLv2 -SSLv3 + SSLCipherSuite HIGH:MEDIUM:!aNULL:!MD5:!RC4 + + + + ExtendedStatus On + + ProxyStatus On + + + AllowOverride None @@ -17,26 +48,11 @@ MaxRequestsPerChild 0 Deny from env=GoAway - - SSLProtocol all -SSLv2 -SSLv3 - SSLCipherSuite HIGH:MEDIUM:!aNULL:!MD5:!RC4 - Require all denied - - ExtendedStatus On - - ProxyStatus On - - - - - LimitUIDRange 0 6000 - LimitGIDRange 0 6000 - Require all denied diff --git a/apache/tasks/main.yml b/apache/tasks/main.yml index 3854c539..7be38e1f 100644 --- a/apache/tasks/main.yml +++ b/apache/tasks/main.yml @@ -4,7 +4,6 @@ apt: name: - apache2 - - libapache2-mpm-itk - libapache2-mod-evasive - apachetop - libwww-perl @@ -14,6 +13,18 @@ - packages when: ansible_distribution_major_version is version('9', '>=') +- name: itk package is installed if required (Debian 9 or later) + apt: + name: + - libapache2-mpm-itk + state: present + tags: + - apache + - packages + when: + - ansible_distribution_major_version is version('9', '>=') + - apache_mpm == "itk" + - name: packages are installed (jessie) apt: name: @@ -35,7 +46,6 @@ - rewrite - expires - headers - - cgi - ssl - include - negotiation @@ -44,6 +54,18 @@ tags: - apache +- name: basic modules are enabled + apache2_module: + name: '{{ item }}' + state: present + with_items: + - cgi + notify: reload apache + when: apache_mpm == "prefork" or apache_mpm == "itk" + tags: + - apache + + - name: Copy Apache defaults config file copy: src: evolinux-defaults.conf From 3457b14fed290e73c0bd4a1339c60824b1dd6e6a Mon Sep 17 00:00:00 2001 From: Ludovic Poujol Date: Wed, 21 Apr 2021 17:22:45 +0200 Subject: [PATCH 02/86] ntpd: Add leapfile configuration setting to ntpd on debian 10+ --- CHANGELOG.md | 2 ++ ntpd/templates/ntp.conf.j2 | 5 +++++ 2 files changed, 7 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4f35ea6c..2f0b17a2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,6 +16,8 @@ The **patch** part changes incrementally at each release. ### Changed +* ntpd: Add leapfile configuration setting to ntpd on debian 10+ + ### Fixed ### Removed diff --git a/ntpd/templates/ntp.conf.j2 b/ntpd/templates/ntp.conf.j2 index e57dad33..d89a83ee 100644 --- a/ntpd/templates/ntp.conf.j2 +++ b/ntpd/templates/ntp.conf.j2 @@ -2,6 +2,11 @@ driftfile /var/lib/ntp/ntp.drift +{% if ansible_distribution_major_version is version('10', '>=') %} +# Leap seconds definition provided by tzdata +leapfile /usr/share/zoneinfo/leap-seconds.list +{% endif %} + # Enable this if you want statistics to be logged. #statsdir /var/log/ntpstats/ From eab68545feb95d169e67ae5d18de13d2fe1a9396 Mon Sep 17 00:00:00 2001 From: Jeremy Lecour Date: Fri, 23 Apr 2021 11:41:27 +0200 Subject: [PATCH 03/86] evolinux-base: add default motd template --- CHANGELOG.md | 1 + evolinux-base/templates/motd/motd.default.j2 | 4 ++++ 2 files changed, 5 insertions(+) create mode 100644 evolinux-base/templates/motd/motd.default.j2 diff --git a/CHANGELOG.md b/CHANGELOG.md index 2f0b17a2..c628ec3c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,6 +13,7 @@ The **patch** part changes incrementally at each release. ### Added * apache: new variable for mpm mode (+ updated default config accordingly) +* evolinux-base: add default motd template ### Changed diff --git a/evolinux-base/templates/motd/motd.default.j2 b/evolinux-base/templates/motd/motd.default.j2 new file mode 100644 index 00000000..9f03958a --- /dev/null +++ b/evolinux-base/templates/motd/motd.default.j2 @@ -0,0 +1,4 @@ +This server has been installed with Evolix Ansible roles. +https://gitea.evolix.org/evolix/ansible-roles + +--- From 94a5d7daa27ce62f1d3a0e1d361dff53360bc6aa Mon Sep 17 00:00:00 2001 From: Jeremy Lecour Date: Fri, 23 Apr 2021 14:59:29 +0200 Subject: [PATCH 04/86] mysql: variable to disable myadd script overwrite (default: True) --- CHANGELOG.md | 1 + mysql/defaults/main.yml | 2 ++ mysql/tasks/utils.yml | 1 + 3 files changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index c628ec3c..30d91c83 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,6 +14,7 @@ The **patch** part changes incrementally at each release. * apache: new variable for mpm mode (+ updated default config accordingly) * evolinux-base: add default motd template +* mysql: variable to disable myadd script overwrite (default: True) ### Changed diff --git a/mysql/defaults/main.yml b/mysql/defaults/main.yml index 1e2f673d..2986a869 100644 --- a/mysql/defaults/main.yml +++ b/mysql/defaults/main.yml @@ -41,6 +41,8 @@ mysql_cron_mysqltuner_frequency: monthly mysql_force_new_nrpe_password: False +mysql_force_myadd_script: True + mysql_evolinux_defaults_file: z-evolinux-defaults.cnf mysql_evolinux_custom_file: zzz-evolinux-custom.cnf diff --git a/mysql/tasks/utils.yml b/mysql/tasks/utils.yml index 164507aa..fedda1ff 100644 --- a/mysql/tasks/utils.yml +++ b/mysql/tasks/utils.yml @@ -169,6 +169,7 @@ src: my-add.sh dest: "{{ mysql_scripts_dir or general_scripts_dir | mandatory }}/my-add.sh" mode: "0700" + force: "{{ mysql_force_myadd_script }}" tags: - mysql From 75675a96b118d445cbc88a345e2622b64c021e45 Mon Sep 17 00:00:00 2001 From: Gregory Colpart Date: Fri, 23 Apr 2021 16:24:52 +0200 Subject: [PATCH 05/86] add info for NFS and Apache-ITK --- apache/files/evolinux-custom.conf | 3 +++ 1 file changed, 3 insertions(+) diff --git a/apache/files/evolinux-custom.conf b/apache/files/evolinux-custom.conf index 64d8f97a..b5ed3a77 100644 --- a/apache/files/evolinux-custom.conf +++ b/apache/files/evolinux-custom.conf @@ -24,3 +24,6 @@ SetEnvIf User-Agent "ApacheBench" GoAway=1 # # Header set Access-Control-Allow-Origin "*" # + +# you need disable EnableCapabilities to use data on NFS mounts +#EnableCapabilities off From f260fedbae2ba2a1280558bfb27d40d10e7d81b5 Mon Sep 17 00:00:00 2001 From: Gregory Colpart Date: Mon, 26 Apr 2021 22:36:03 +0200 Subject: [PATCH 06/86] fix GPG key install for APT --- lxc-php/files/apt.gpg | Bin 0 -> 1769 bytes lxc-php/files/reg.asc | 920 ++++++++++++++++++++++++++++++++++++++++ lxc-php/tasks/php74.yml | 18 +- 3 files changed, 928 insertions(+), 10 deletions(-) create mode 100644 lxc-php/files/apt.gpg create mode 100644 lxc-php/files/reg.asc diff --git a/lxc-php/files/apt.gpg b/lxc-php/files/apt.gpg new file mode 100644 index 0000000000000000000000000000000000000000..384771a0f87beb284ea8cefe887b40c8d481c209 GIT binary patch literal 1769 zcmV&l~o1j)iwSqOsj~Ns;go1_KdQIW!;-!anC!95nCjR9ze)hwAN%IPRrMpm?4$c zV`lOPE{g|^hdysZz|Vb`XPDqc#(WCDQ3sf8F{qv%aX= zYdTej(&BnnRs1$cL(_dAU5T+JY-!wg>U~+hlA`*Wq$A~WxeI{!K?6V0^v=ZmZS#5A zq7oYw@5(_JcJ8O?&{ptOwO`G-!+AHNoOT3F6n%?VeHqo9dv4q4{F0^y+}%d8^=Hi)Fts&-GZO$20RRECF+@c|E>l%f zSuRgfM<79UbZ>28bZKKCQ)y>zX>MmAOJ#W=JY;2JKy!6+c`k2qXFiDm)C3a&3IIL= z8v_Lk2?z%Q1{Dek2nzxP76JnS0v-VZ7l0Na1Qi8^0H7mXm-W#AW3hPv&ZIDuEA^=)wc2V;IO2ObI)?Ca@jmsYvXHyEU1O1MaGcVJ$)v3TOYwB zei!yrx#(okSt1e0IC8nw)28Bvl6JCGh8KC;I`A$3r8?2!(n$_!-<}8@nupc!nD1&x z3x_VNlE2Vaesao4cko4Tn0Nu@kV5W@Mq=wQ_C1Q61P7aCV`j@3iBml&9Fxf(py*wE zNa*VVbWr4}Zec(2A5@QfeX@)hk6_^(ny{Ih|6c{|{k0 zo!p2BXWBr;8v1<)v1UNS$)H&I%4Oa0Ufw78OmY0MRo$5mz;ydB+0#4%?4qiKwtX{< z>OXkveST(^^*1jsRdu2yX%bE4dOOAaYkAKJ4>}C2*^rq|*PqAvMxzk6mbn3q1YD1A zp8*U2;Kv#>{I*>Lhm?>~VIK0Sn@3;y8S)Qlomi@nApj3Q7bq&|6Fb<}29~uRsBYNW ztI9>v4hpmYy65-^I@<@mXg4{@YdACHT;H)c%}b?rMpvmYlj7GpyqmQ6Rb}nPw(!hb zLltG=*o*5ZXNyxnc?yk{4*_;;-I^J#XT;_Ec;mYQ$2IMAh+* zTEBE`#wCHb=O}U?Bfk%|m^O6G7|c7yQ4hoJy#G{8pp7_*w3%-}*~K5GNk6y@DCQ8S z!-%DgFE#w4hBNyd!Olv@p|@FT0B^|}j@=a$Z}4EkH~+ZEK&GWTbTQjD6smBT zFfU*}6b2vReUk*K8C)CCGKEj55%l|a01*KI0f_;;1Q-Dd044$(3>F~-6$OO=pd($E z_0a%hv54ZfmAywp1p;6zg|P(*2|uus0162Zv54ZfmAywpc$^FX#zYn_s8dGTX}~Cd zR@$Qq7?lAy$3&v#DHV|mvzFj7^2hi1xjfju?{Xm?s}ivt$slx3yE}QFXrEbuPrk)f z|HrP_?Noapo44YM*8iF@@>_#)ck+;nf}^W2ty!rIcZUUTZuYit}YpfUF1@=$}CH%QrnVgXa1jvQ?2CoqEz9b0xZR2 z%C@h8%mk15=oRkef( zO-F1;f2vLizV}k;78QX6mRf=}C}Odj=k`>HEUVT+Or!75api0p=$aqe{Nem!(NURJ zUJv%O_YVwwK)Ngzu_ciJVP94VViH%HkJkcR)p^u6>^zCP@6%*87rR=&;6J<1OE;nE z7MV;lh*C8i9Behb2Sp5?ll17GD%bb0l8NyFgHrqj6kf--lo?`wV2|02{(?2Cl(&?K LP!%uJJN1-T?MXx$ literal 0 HcmV?d00001 diff --git a/lxc-php/files/reg.asc b/lxc-php/files/reg.asc new file mode 100644 index 00000000..3fadeb07 --- /dev/null +++ b/lxc-php/files/reg.asc @@ -0,0 +1,920 @@ +-----BEGIN PGP PUBLIC KEY BLOCK----- +Version: SKS 1.1.6 +Comment: Hostname: keyserver.ubuntu.com + +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 +BWcdiQ== +=iUyJ +-----END PGP PUBLIC KEY BLOCK----- diff --git a/lxc-php/tasks/php74.yml b/lxc-php/tasks/php74.yml index c32820f1..db25ee4e 100644 --- a/lxc-php/tasks/php74.yml +++ b/lxc-php/tasks/php74.yml @@ -16,19 +16,17 @@ - "deb https://packages.sury.org/php/ buster main" - "deb http://pub.evolix.net/ buster-php74/" -- name: Grab pub.evolix.net GPG Key - get_url: - url: https://keyserver.ubuntu.com/pks/lookup?op=get&search=0x0C016D3BD1195D30105837CC44975278B8612B5D +- name: copy pub.evolix.net GPG key + copy: + src: reg.asc dest: /var/lib/lxc/{{ lxc_php_version }}/rootfs/etc/apt/trusted.gpg.d/reg.asc - mode: 0644 - checksum: sha256:a2e0f56ba433aa0740aad6eeeb43bb67df9ab943d76324382b39948a4c7ce840 + mode: "0644" -- name: Grab packages.sury.org GPG Key - get_url: - url: https://packages.sury.org/php/apt.gpg +- name: copy packages.sury.org GPG Key + copy: + src: sury.gpg dest: /var/lib/lxc/{{ lxc_php_version }}/rootfs/etc/apt/trusted.gpg.d/sury.gpg - mode: 0644 - checksum: sha256:b3ea944563435e54bb64f181ee8bc26200985d09164cdc4c1702fc3ef051f19d + mode: "0644" - name: "{{ lxc_php_version }} - Update APT cache" lxc_container: From 5d79c31dc372a4b351ef87f076a3782df6c4cdbc Mon Sep 17 00:00:00 2001 From: Jeremy Lecour Date: Wed, 28 Apr 2021 15:53:36 +0200 Subject: [PATCH 07/86] kvm-host: add migrate-vm script --- CHANGELOG.md | 1 + kvm-host/files/migrate-vm.sh | 374 +++++++++++++++++++++++++++++++++++ kvm-host/tasks/main.yml | 2 + kvm-host/tasks/tools.yml | 13 ++ 4 files changed, 390 insertions(+) create mode 100644 kvm-host/files/migrate-vm.sh create mode 100644 kvm-host/tasks/tools.yml diff --git a/CHANGELOG.md b/CHANGELOG.md index 30d91c83..dc98a08d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,6 +14,7 @@ The **patch** part changes incrementally at each release. * apache: new variable for mpm mode (+ updated default config accordingly) * evolinux-base: add default motd template +* kvm-host: add migrate-vm script * mysql: variable to disable myadd script overwrite (default: True) ### Changed diff --git a/kvm-host/files/migrate-vm.sh b/kvm-host/files/migrate-vm.sh new file mode 100644 index 00000000..43264d71 --- /dev/null +++ b/kvm-host/files/migrate-vm.sh @@ -0,0 +1,374 @@ +#!/bin/sh + +# WARN: This script is a work in progress! +# The happy path works, but the rest is not finalized yet. + +# TODO: +# * exit with error if there is no DRBD +# * logging (stdout/stderr + syslog) +# * more checks, rollback if needed… +# * different return codes for different errors +# * migrate "from" +# * switch to Bash to use local and readonly variables + +VERSION="21.04" + +show_version() { + cat <, + Jérémy Lecour , + Victor Laborie + and others. + +migrate-vm comes with ABSOLUTELY NO WARRANTY. This is free software, +and you are welcome to redistribute it under certain conditions. +See the GNU General Public Licence for details. +END +} + +show_help() { + cat < + or migrate-vm --vm --resource + or migrate-vm --persistent + or migrate-vm --transient + +Options + --vm VM name (from libvirt point of view) + --resource DRBD resource name (default to VM name) + --transient Leave VM as defined on hosts + --persistent Undefine the VM on the source + and define it on the destination (default) + --help Print this message and exit + --version Print version and exit +END +} + +persistent() { + test "${persistent}" -eq 1 +} + +server_ips() { + ip addr show | grep 'inet '| awk '{print $2}' | cut -f1 -d'/' +} + +drbd_config_file() { + echo "/etc/drbd.d/${1:-}.res" +} + +is_drbd_resource() { + test -f "$(drbd_config_file "${1:-}")" +} + +drbd_peers() { + drbd_config_file=$(drbd_config_file "${1:-}") + + awk '$1 ~ /^on$/ { host = $2 } $1 ~ /^address/ { sub(";$", "", $NF); split($NF, a, ":"); ip = a[1]; printf "%s:%s\n", host, ip }' "${drbd_config_file}" +} + +is_vm_running_locally() { + vm=${1:-} + + virsh list --state-running --name | grep --fixed-strings --line-regexp --quiet "${vm}" +} + +execute_remotely() { + remote=${1:-} + shift + command=${*} + + # shellcheck disable=SC2029 + ssh "${remote}" "${command}" +} + +set_drbd_role() { + role=${1:-} + resource=${2:-} + remote=${3:-""} + + case "${role}" in + primary|secondary) + set_command="drbdadm ${role} ${resource}" + verify_command="drbdadm role ${resource} | grep --fixed-strings --ignore-case --quiet ${role}/" + ;; + *) + echo "Unknown DRBD role '${role}'" >&2 + exit 1 + ;; + esac + + if [ -z "${remote}" ]; then + retval=$(eval "${set_command}") + retcode=$? + if [ ${retcode} != 0 ]; then + echo "An error occured while setting ${resource} as ${role} : ${retval}" >&2 + exit 1 + fi + + retval=$(eval "${verify_command}") + retcode=$? + if [ ${retcode} != 0 ]; then + echo "Role has not been set to ${role} on ${resource}. Abort!" >&2 + exit 1 + fi + else + retval=$(execute_remotely "${remote}" "${set_command}") + retcode=$? + if [ ${retcode} != 0 ]; then + echo "An error occured while remotely setting ${resource} as ${role} : ${retval}" >&2 + exit 1 + fi + + retval=$(execute_remotely "${remote}" "${verify_command}") + retcode=$? + if [ ${retcode} != 0 ]; then + echo "Role has not been remotely set to ${role} on ${resource}. Abort!" >&2 + exit 1 + fi + fi +} + +define_vm() { + vm=${1:-} + remote=${2:-} + + if [ -z "${remote}" ]; then + # retval=$(virsh define "${vm}") + # retcode=$? + # if [ ${retcode} != 0 ]; then + # >&2 echo "An error occured while defining ${vm} : ${retval}" + # exit 1 + # fi + echo "Defining a VM locally is not supported yet. Let's skip this step." >&2 + else + retval=$(virsh dumpxml "${vm}" | ssh "${remote}" virsh define /dev/stdin) + retcode=$? + if [ ${retcode} != 0 ]; then + echo "An error occured while remotely defining ${vm} : ${retval}" >&2 + exit 1 + fi + fi +} + +undefine_vm() { + vm=${1:-} + remote=${2:-} + + command="virsh undefine ${vm}" + + if [ -z "${remote}" ]; then + retval=$(eval "${command}") + retcode=$? + if [ ${retcode} != 0 ]; then + echo "An error occured while undefining ${vm} : ${retval}" >&2 + exit 1 + fi + else + retval=$(execute_remotely "${remote}" "${command}") + retcode=$? + if [ ${retcode} != 0 ]; then + echo "An error occured while remotely undefining ${vm}: ${retval}" >&2 + exit 1 + fi + fi +} + +migrate_vm_from() { + vm=${1:-} + remote_ip=${2:-} + current_ip=${3:-} + + export VIRSH_DEFAULT_CONNECT_URI="qemu+ssh://${remote_ip}/system" + virsh migrate --live --unsafe --verbose "${vm}" "qemu:///system" "tcp://${current_ip}/" +} + +migrate_vm_to() { + vm=${1:-} + remote_ip=${2:-} + + export VIRSH_DEFAULT_CONNECT_URI="qemu:///system" + virsh migrate --live --unsafe --verbose "${vm}" "qemu+ssh://${remote_ip}/system" "tcp://${remote_ip}/" +} + +migrate_from() { + vm=${1:-} + resource=${2:-} + remote_ip=${3:-} + remote_host=${4:-} + current_ip=${5:-} + current_host=${6:-} + + echo "Start migration of ${vm} from ${remote_ip} (${remote_host})" + + set_drbd_role primary "${resource}" + migrate_vm_from "${vm}" "${remote_ip}" "${current_ip}" + set_drbd_role secondary "${resource}" "${remote_ip}" + if persistent; then + define_vm "${vm}" + undefine_vm "${vm}" "${remote_ip}" + fi +} + +migrate_to() { + vm=${1:-} + resource=${2:-} + remote_ip=${3:-} + remote_host=${4:-} + + echo "Start migration of ${vm} to ${remote_ip} (${remote_host})" + + set_drbd_role primary "${resource}" "${remote_ip}" + migrate_vm_to "${vm}" "${remote_ip}" + set_drbd_role secondary "${resource}" + if persistent; then + define_vm "${vm}" "${remote_ip}" + undefine_vm "${vm}" + fi +} + +main() { + vm=${1:-} + resource=${2:-} + server_ips=$(server_ips) + + if ! is_drbd_resource "${resource}"; then + echo "No DRBD resource found for '${resource}\`." >&2 + exit 1 + fi + + for peer in $(drbd_peers "${resource}"); do + host=$(echo "${peer}" | cut -d':' -f1) + ip=$(echo "${peer}" | cut -d':' -f2) + + # shellcheck disable=SC2086 + if echo ${server_ips} | grep --quiet "${ip}"; then + current_ip="${ip}" + current_host="${host}" + else + remote_ip="${ip}" + remote_host="${host}" + fi + done + + if is_vm_running_locally "${vm}"; then + migrate_to "${vm}" "${resource}" "${remote_ip}" "${remote_host}" + else + echo "Migrating \"from\" is not supported yet" >&2 + exit 1 + + migrate_from "${vm}" "${resource}" "${remote_ip}" "${remote_host}" "${current_ip}" "${current_host}" + fi +} + +if [ "$(id -u)" -ne "0" ] ; then + echo "This script must be run as root." >&2 + exit 1 +fi + +# Parse options +# based on https://gist.github.com/deshion/10d3cb5f88a21671e17a +while :; do + case $1 in + -h|-\?|--help) + show_help + exit 0 + ;; + -V|--version) + show_version + exit 0 + ;; + --transient) + transient=1 + persistent=0 + ;; + --persistent) + transient=0 + persistent=1 + ;; + --vm) + # with value separated by space + if [ -n "$2" ]; then + vm=$2 + shift + else + printf 'ERROR: "--vm" requires a non-empty option argument.\n' >&2 + exit 1 + fi + ;; + --vm=?*) + # with value speparated by = + vm=${1#*=} + ;; + --vm=) + # without value + printf 'ERROR: "--vm" requires a non-empty option argument.\n' >&2 + exit 1 + ;; + --resource) + # with value separated by space + if [ -n "$2" ]; then + resource=$2 + shift + else + printf 'ERROR: "--resource" requires a non-empty option argument.\n' >&2 + exit 1 + fi + ;; + --resource=?*) + # with value speparated by = + resource=${1#*=} + ;; + --resource=) + # without value + printf 'ERROR: "--resource" requires a non-empty option argument.\n' >&2 + exit 1 + ;; + --) + # End of all options. + shift + break + ;; + -?*|[[:alnum:]]*) + # ignore unknown options + printf 'ERROR: Unknown option : %s\n' "$1" >&2 + echo "" >&2 + show_usage >&2 + exit 1 + ;; + *) + # Default case: If no more options then break out of the loop. + break + ;; + esac + + shift +done + +# Initial values +vm=${vm:-} +resource=${resource:-${vm}} +transient=${transient:-0} +persistent=${persistent:-1} + +set -u +set -e + +if [ -z "${vm}" ]; then + echo "You must provide a VM name" >&2 + echo "" >&2 + show_usage >&2 + exit 1 +fi + +main "${vm}" "${resource}" + +exit 0 \ No newline at end of file diff --git a/kvm-host/tasks/main.yml b/kvm-host/tasks/main.yml index 71fcda41..5bb6bc9b 100644 --- a/kvm-host/tasks/main.yml +++ b/kvm-host/tasks/main.yml @@ -8,3 +8,5 @@ - include: munin.yml - include: images.yml + +- include: tools.yml diff --git a/kvm-host/tasks/tools.yml b/kvm-host/tasks/tools.yml new file mode 100644 index 00000000..b3a4be0f --- /dev/null +++ b/kvm-host/tasks/tools.yml @@ -0,0 +1,13 @@ +--- + +- include_role: + name: remount-usr + +- name: migrate-vm scripts is present + copy: + src: migrate-vm.sh + dest: /usr/share/scripts/migrate-vm + mode: "0755" + owner: root + group: root + force: yes \ No newline at end of file From 5b9d2a2776d382641fa70ce7efe2c11badb6698e Mon Sep 17 00:00:00 2001 From: Jeremy Lecour Date: Thu, 29 Apr 2021 09:56:39 +0200 Subject: [PATCH 08/86] migrate-vm: do not display drbd error --- kvm-host/files/migrate-vm.sh | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/kvm-host/files/migrate-vm.sh b/kvm-host/files/migrate-vm.sh index 43264d71..b2244607 100644 --- a/kvm-host/files/migrate-vm.sh +++ b/kvm-host/files/migrate-vm.sh @@ -11,7 +11,7 @@ # * migrate "from" # * switch to Bash to use local and readonly variables -VERSION="21.04" +VERSION="21.04.1" show_version() { cat </dev/null 2>&1 } drbd_peers() { From 23867332312c1a5d96838b6c256064740a5749bd Mon Sep 17 00:00:00 2001 From: Jeremy Lecour Date: Thu, 29 Apr 2021 10:22:21 +0200 Subject: [PATCH 09/86] =?UTF-8?q?bash=20syntax=20:=20``=20=E2=86=92=20$()?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apache/files/save_apache_status.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apache/files/save_apache_status.sh b/apache/files/save_apache_status.sh index 8ca29f15..12f8faed 100644 --- a/apache/files/save_apache_status.sh +++ b/apache/files/save_apache_status.sh @@ -4,7 +4,7 @@ set -e DIR="/var/log/apache-status" URL="http://127.0.0.1/server-status" -TS=`date +%Y%m%d%H%M%S` +TS=$(date +%Y%m%d%H%M%S) FILE="${DIR}/${TS}.html" if [ ! -d "${DIR}" ]; then From 66ea07ec29cbdfdc5b65b545320af907acf2ed5c Mon Sep 17 00:00:00 2001 From: Jeremy Lecour Date: Sat, 1 May 2021 16:50:38 +0200 Subject: [PATCH 10/86] evolinux-base: copy GPG key instead of using apt-key --- apt/tasks/evolix_public.yml | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/apt/tasks/evolix_public.yml b/apt/tasks/evolix_public.yml index 0edb2ec8..83dd7eaa 100644 --- a/apt/tasks/evolix_public.yml +++ b/apt/tasks/evolix_public.yml @@ -7,11 +7,10 @@ # tags: # - apt - - name: Add Evolix GPG key - apt_key: - #url: http://keyserver.ubuntu.com/pks/lookup?op=get&search=0x44975278B8612B5D - data: "{{ lookup('file', 'reg.gpg') }}" + copy: + src: reg.gpg + dest: /etc/apt/trusted.gpg.d/reg.gpg tags: - apt From 920cb7eaeb8307bb0c08a3d6f39cf4bd96e6cc90 Mon Sep 17 00:00:00 2001 From: Jeremy Lecour Date: Sat, 1 May 2021 16:51:20 +0200 Subject: [PATCH 11/86] update changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index dc98a08d..9a88ba44 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -19,6 +19,7 @@ The **patch** part changes incrementally at each release. ### Changed +* evolinux-base: copy GPG key instead of using apt-key * ntpd: Add leapfile configuration setting to ntpd on debian 10+ ### Fixed From 047605a2a21c002a896ee53ad3ebc346e08581ce Mon Sep 17 00:00:00 2001 From: Jeremy Lecour Date: Sat, 1 May 2021 17:20:06 +0200 Subject: [PATCH 12/86] evolinux-base: use a dearmored signature, stored in the correct location --- apt/files/reg.asc | 920 ++++++++++++++++++++++++++++ apt/files/reg.gpg | Bin 66796 -> 49306 bytes apt/tasks/evolix_public.yml | 11 +- apt/templates/evolix_public.list.j2 | 2 +- 4 files changed, 924 insertions(+), 9 deletions(-) create mode 100644 apt/files/reg.asc diff --git a/apt/files/reg.asc b/apt/files/reg.asc new file mode 100644 index 00000000..3fadeb07 --- /dev/null +++ b/apt/files/reg.asc @@ -0,0 +1,920 @@ +-----BEGIN PGP PUBLIC KEY BLOCK----- +Version: SKS 1.1.6 +Comment: Hostname: keyserver.ubuntu.com + +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 +BWcdiQ== +=iUyJ +-----END PGP PUBLIC KEY BLOCK----- diff --git a/apt/files/reg.gpg b/apt/files/reg.gpg index 3fadeb07fc33d7017d07a5f210e30bb7ec0922b7..48782d844514addfeecc92e00a2e0926e130298c 100644 GIT binary patch literal 49306 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 literal 66796 zcmZU5$Cj&FmTjM}$UdVAD@^rp5>~>y9w5AT!hHSP_uR}J^|GROMx2Np87~5?VZO|Nm>#by!ap=A`UkIn1nsZy{ukuu%UX}a|NO(zoPS{djr}(T31i>q z!}dS_kjHf!l0N^Rf3*3v=F2Z%{(DdNVcY*Z8+!=qE#=KiqZ~h4Ug89bLCxkG0yi^> zc=L-O(5c(vGLcb70nQ#qI!sR|n>Rkgjc@12J9SGU%s-&@z#T^~Fe&be)HO5Wl?Cqc zt-}U?S=!wgOM)4(<_-QwM0Ue(8#H#;+q3REK(PJD|m7)qnx7YQ|y?E}k*DIBIv)JPabf8Ka zR>Xt-7JORzBx31fQe*~0VgX4T`7p6tidr|e%hBOeO(RNuI=xCswO`8o#Ymz-?iX)D zXHoQgNjbFJMKpY!9PkIB z@$#OVL8b{KXBgqja^77?^7^XK-}Kk&dXt(C2uSH8a>j3W^tw|B=G)K*FA%80eXREL zZFz!JkX%RB*Rp@k$kAx;sTOY!OGJFMDz}X!>yedj4f;t0{wO{t-6L!KNVx9(+hU?| z$g3wGMeefalD_a+c2l+Xx$3(WGWe@L9)+NutP*e}%ilY$b_jh7K|SmkGl+gJ272Gl zZTzKaYjY<7xsS(6z#G#|*X(gmIDIo{ET=q4r_ZTU_NfnEqKVg)0loQvKaOXd(#wU@ zy?$Mx=6{~S62<27?cP-`HJ(YI=^Q`fFUsqh`f>k!J65oWi;Eng$XxBfq3ra= zHIJBL!NhzBfymayNe=a8*4&fRgb^Eebma*~+O2R1gloc*Chbmw{^tSEKTog**fal} zAd7cc+naYjZk$KCf$*@UM@pd`gN@5p0Z}3guM9siL{4SDU!PH~V>O`PpsB=TDN4-L zT~d2L|9Jw)_`j~8@r2y}IY3mxkRy0*7(ex=c`6O4+I zsh{GqOP`){`ARd!FI?%bXEdb-Y#H3k`hDz=QOto_)dG(evhw!<(7#V`ndR@d;C6I! zb59Z7+?(Y3BaxV!mlH2Yy#ilEU#x8B~tW% zp78GjZs+eSnEjJPISr9*JfBBys1f;B;s%+Mzopq9&|$jp_w!yk7Ww^kLWpH#q+?;N zqD45lDDGjz!sZP39|y$fRsFev%95~nkI*UFmHv#t36<(pg@fGo_@Zm~U6sdt>E~4;tp#IY^moKV2QZ zUly$&=)~@?9=kZQWa`5hUf)a!gxxOqu4=r&QwJB6aLD=&o=3^TkF_o2)2S@m(!Y1L z9$Ps|FDsa_UdG1B`PDITR>tvk>rinl46jMIemS*Qq@l9iGjyGw0x7qKGhRypqL?(i z$XsL{=^SIl$@~{R?T1)?H1Y5y;^#+rP~g`Fik51#3aD3$$a{>Bd>e-bQaLKF3q#= z5Y;d7H)p>KL40{YJ0`RDOX|zToxZ(WTdxe%qrckspL+Bi>G98778Htn1}xNlo}Mzb z2B#upT4QqBaf@AQ{aFi&A>zp3W({KK#HO=y5i{ujjz-ukq&UKacy`6L2wsLIF z1@&6>Qm0!g{H`Rb38$L0AsR_~^^MxqHNEf7;$yzrTyY{6?mI0*BlUEISQTg0KBDp# z^sW?MQ0>nN6=qDTj1Tg*F#81kx)~5k>YhK|aK5p*lZVAt+M>RyWscZqjCkl-B*`J& zXWD;bO+5V%6n?+REE3(Ds~NSVdTO>lEW(i)q7Mw(b&Ru7#!~2q`d}>jEuOlvaEC;E!|M&Jfy%MX8&R{4{(UOg%0pQIIk8Js48 zn2@hIVFZLtf}inud&4Nc8V8c8QdtLeK&O{Q-Y4RCFuyUz3w6wN`!Vs3ZO2&DA$>YN zGtr3MOHN{4O?rPswl{v^(LMSn{)T2oNyX}?_EIJYr9XC+ft6UaJ(=A=xSJ-ox85sE zxhi#tNDG6KkH+BM6YP!mNB@BdhkZ{z-$2R$N@Tb_;wKs9#+N6_EY|Ul%rv``PBCXb zxth>>f-N1RA#$(wlAlX0=%=MQftZataeu!p#US5%{5nL)@?Y|lP_c+D0>XuT(P#&*R+0{Eyt)misQ)%VP^`Lxvb z{8{oATXsX|k77rbW4>V815b9Pf!`gYdyead1*OqghY*0|Tj$n(qt6X(Rki#A5 z%=0_$kF}TI(ifeX@6C<|F9lh=*-`(}?s|A-{dsfCxA(8mCkv_dl9as*ohhmB>m1=X zbj+i?vEr8Rs^r;6(mEym{!9Fm7fUv*|#dSh;E`9dHu;* zXuclv#%>j4hwZ(MmzHshQ}=TAc`o`KaMlV!n=zH>ow(Yiewf`BqsDk;s`aCIMxK2< zuXQ2b6zQ9dLH>gxWXy~1C03}JzNYoyYU>`Iv-$a7vot+-eh+Jhj9O1WowX)<~%(_GwV3-zxqsIA~m94Yg|rP z=?N?heu&J3qk=cD^qm`iAkWYv*!$b8+@gH?Nn=SFOS(DE{_=$V_;BBqinzP?tc$ps zKVB3s&ig~^-R|>PO;P0z1IzHNRa2;to6V~$!as1HAlUc(gp(ovgsdTxpfzJz%6YvZ^7mS`iZ#hsDMCE(#km%TsRkkeCtee*ID_vNDEhD=I}WHu15f z$~=CVIR4Z62nte~bC#8TQ$D5fnPR2tVN326cog(PmKRA^Fj)kOkspun5N_}O&7Amn zi4z_c^-r{Rf5Y4a4>F1CH9vZHax@;(AkF7be>+YZ?jZz5V)&zx;h8)ax+d?1xgE-( z-*#PcU+FDuxUrCHH=^Blum@_lKs!H+6(>qY|Bwj7-U0kNwHIWXo|TSlK1pOHJ8Uz6vp>33O2D{)&+@II^j!8&AgNfW*aWDCqaoW1@7i;#XH z6JHDV;?o(K$;J&J>R02#9f17Op?#55R#;<@b@@uFyO=z~+#Sf*&$lS9Ufu+*kIjK4 zp!8>kUZ%E~S--8wJ}hNd8d*)#SZ9`V_DAw9^ffLY&1@v&LB4d!bfoVr?F^w$j)%G{ z%B#O8gixOANh?a;V&jAp_gc&<7{?xOPOs}Yb$)Pp3l|iHf8*)&_4795V9~paex_Jp z>Zz~<)vR<-3p;;`_y3OW_g(&pZj7u9`)sNPwbZ#pU|oB@3~XHZA^O2$ocmx7GZ$X< z+gyVN&M!k)o|KW@Bl<}#wh?;_FZbtcP*jU-=5Z|ky_AdYWE!17JL&Da{!j;kS>n@J#qT>+%2Qez zBc;EnG272~_p_nmgGk-@)eU`YMw>}b*N==M zxAPHs1PAh!Ca0*HYPsfzAw%fu@GgQyuOt1IyzSrpm@UC(scenoMnu@@sJ(OUxgy8O z>I8E?Xmt5}^L{J#@YVq0X}YYi6o^+A37xQ8me9{#ehW@P_F6S!;%mohxGqfX2fJjm zv^7U@+?Jw|IP&@1wd}1~W5;soAO`8wK{Kk-0zW?1n#7iH@)S^rnCJBsh!zJdbSrR4 zywbiWlzZSIk>(#1(-up+sytdMueqYABl;#R^qo|{Z~V7wKhhu_83c)CD|{BOEDJ_k z>7|(disY%e9mZpI)tAW^m1+JOzNk`vY=3>+={Hp*=qVh7(KP&HSja8+&|}6?nGq73 zpzMQSw9;NO_3JFEFD`uvbEIjm0g-T+MvTJGmPQ+gCj!SIrol6Gy8bh|yXO2mx+O-y z;$b9LU8oy?O#Jby{MtqCgKHVPp zlR7)IVi8n{9#O`+44?ON#^;k*HIE$N&?qOz`O!Wh?ge&C&T2n{)}?t^%G8Kz|s6x&H43Fb>xO z)+T9B$=Ab|68eCHvqbSFOp(zRlXTJ3@!Ncg5ubj853-zZw=h9O8PzO0tp2YhHl`kr zx94_Rdkzix1@ptxP>Y!7^LPFuFja4>YnD!Lr2I@zQRx>KP+QwHKV~c10rxle!NR44 z1^r=@03SWVR%PxqWHE7KyXlRyGN06IWzyhpqHsiWZU3TIG(b)tz;J)z|Qw7C@EYU z4V`M|U!y3-yqw@U3X?U1#<6 zIpktWX`)UjdJn$r!CbGLx7&EULK zz%!nj#Fkj=Cg>BgJlCBrgAP#v9s*fxy~BYI23jTH2pN; z@ZJ?QUT*?Yz6=!2u3^IillVf(vW(SJ{2ap00YYnf0D0`)GWuK4@FbD|^;QQM+9t1> zZ7G`bi^YFDCMNLRAe&rvv}o!`ieZ8pFQr0r+)2?uSai`s6U@=m~?(^ZA!B`=ypG02LoLM{`&q;5YWvS%wW8(85EpNKo`Y96_{an zYZpa?1QH5W>GZ1U-u=~A=FMM?HTvwJB%vhV6Ad+dS8{QA;!X(X8UsL`K9XNFL7VS4 zWK27jn)XEHPnASj@L;#SM&fY6J@M#VcfX3&nMUHFp%CnURk+`7rj$YX5&pAw;}2{6 zgG`o76XzkV7kP644nV>UmrZkL7gnFhm=+)pleRz-0j(R4b+m-ci*JgP4%InCTQ%T9 zS03N2yuHLjs5?A$QzAIV>AgHXr?T-&T5%V|tpYXJK>l*;JReOmxhb0x-ypCD}bv@)VU;Pja<2blxO4z4ex!*@yaEI*gmxhFDA zHq~x;q|a`{G^$^&HI273DMt81g}LI5_IuW9HorJ_|CY*EHg|)&rZsxbkb#*4?do4= zu!U={Ua0r%7GyXH-LnQqI(zGlyg}3 zRC(C|fk2qtcH-;shRVANaew&l`J(yHl6u-q;O=MMzsEK|Oz9e{v0zxFvQh6S1dOTp zcJBikG{#>y8(!%1{Dh9cg)3sAc1xe6HEx5xUN+aa#-_rtr(t#xl|Bi|$q zx2PW%=iVX(YxKJ)$(+RV6Vx?i2#{#pF!hb+!wZNC>$wa3t}vj5IX!(qM-FH>Q?D%`5mpSsjp>H z^CT&l&P0n5)!9s`r}-qnl&;CI9Omh}vf>X4S$yXfq1}OLXOEEv_8G&C=e6%Z8?E6= z>fCy4aMG~UIxKkhLD~DqfJ@S3f4Jp7Y+FPHGE5u@)*OMz^Co^pQm%46kM8!pt@f~8 z%XQ%TlM2qvxug=EA{cS>=V=tSVs;sK8V2g{wCr%t_~Ao?rOFwd^6h&%Fq)0#{9G07 z-_fo7n-O%4Khe$Dmf~_%CD~8r2DsbC`EJEe6Z)OwCbxP~rO<0t z2SKRA^ml#WPO$bOt$=@p0lLA(@hc?%lfv^mP--7sEhqP_wnGnx@Swo1EcK_5a&Y~OV0|LoY5r?G%V4q ztms@N{eEPOAs{A#fWMBM26k62?>OU8lMmvBzZ|4?u#~l>^66e4>E#OD$q(q(OY?i0 z8vhgCpVY3j68Uod?1=M2lA|&>2OzK!u258qxU{1P6Kf8>;Qr0ojc$^Xc=1mXX`u)0 z04ea=8rBW0(b`|!__gMDco^C{>%KSnv}0m1o{KlB4Y7;tiEo{Y5UJp67G`Cpb8DHD z&CorwTzoe&o%vE)PMQJ?HfonQ0Z%2bpA6L2C{9T!+CM1qDJ4)LSgp(}t1zp7&p04op~tX!UHQWMz^A3@aO z)8iGUiG8)zkwHyHcIKk2l0p(vW^R#)i0%`1OqbHUVz}tpx?ce$ra# z`)%&PrK(5Rn9itQ@BJ+kRJf%ck_ zyg&`AVWOPF`|{zVpNB3pl;v}+Rzt+3G?pHgT|H;N8lP=|DCR_e_r^MN)&I${rR(pO zCv9VX!L5yJJ4$-k^91d2%+TKg<&4BdU!&MJkBIFcCPhZy7I;Rg^P;{zlFG~U+^M&6 zjwhupHgo4kHoinlQ&_&U2Bu$>u|NYT3f|tnreL5??*~(VD#H9^4InXEkxtB!wGkH> zLwF_l(R7)lz2rpbX%CW`N{5-2K}Ipt62V|mHUVhMNhjC-I$cVcegXNVQ6JdJcz z%Y5^&91)mQ1rOo*ew{j->R*q(iZBIq&S3|afddF$Wy_A7dPXJfd-Pl~6P$7b$hZUv za4->4f@N`HOchQD)$E5z4oAL1FXtHv5ti=hmv*-(NFo1)2h3i$N8ZQ$89Zl34l@=s zn4ZvOA4jcodKBCkE!2mi!>F|COnC-$fp+SHtjk%Z=;PUZ3h4g0auH}~eJeR2*e2%e z8@fuLOBjAh3jROQZNLA<-QL5Nhws~QpD&9BwHu0Di_xAkJ+MY(Pbotbu3fa(l3&*4 ze$$L!t%J51w_Q(UPU~+S$AyAtihktEyzc!QPoHp|T96-|h&gGJvn2uMTgpRNPNa40 zo=-kqJ*8>!fjMGLCzh!u&FB;5{Q0y}z1dl-n#{7%=oMy34?RZTKN=;)2ZkMH0Ey?} zrFf33-`Yd58KD|eYMX$f+F0ChN-T8%Q-zp+E5SDknq_5YwCb9ZA=gV52gn?Ta;yZY z+hvUZ#%IWhGb~7$g)h96OvjRmPAge}-ePs7&vyrLFh0kZdb2;U`_%6YVi{cDW&ZRM z(&(}y*n-5eC^JB^he})OjoS5`Bswa_r*I&`g6D*x6t3{q(Az9Yj^&s4YPB|m+)Ql4*)Z;bvT za?*v;x}jqO{OWhC3uPns@8rQb#^n$l;^OuUCb9~dfbk@7@XB<%K60IHN^uwFP9zzo z&; ziU&L!wy)PDA`JmCDR79qKo)Pa9~`PaQX67|8DNk#_B-S=sr;Yl{wpB=Ad?(OHk2Nr zrB2?E2Esck({%M&Jnh)$v>Wav3>Lxd&ir`n96m1@t zWjD;q*2XW5c^DGp^wXGUd$dZY)Ubt>yc>BJKFdU8FlhHGVLBEuyX~-k2JdKrJF6=5 zp~mce_2#TyKvrUtxunqNV(rCUM)|d-zq?2yDRLOa9}~j_BvC_+SesJ6v3L8RtLWw7 z8IL-)v*)5|#M}V6BwE;l`4!M_Qe*VhfzINR>;38T)*YffR$rgJZvo9eP}J!n}cLzinlbhF2|@IQ}mrL;TPLJ2Z}hQu%8hnPxv3w{pnQxkAxUN72K)qA^R zF9R017?9(@zCu&W?U9j&I0Ejkf7vQHLLpZaz8?YU7G(9Z>42zK9%-Li!$%~9G-VNFv&1me8(<5Zg) zYs^C$`)V8BC(EN`fYGl<#tZ>=3C(Gq5oxiy5KTrDzIgnd4+#`qUokBUj@lD271|aY zx4|^X0Q(ENPV=aM(4+eSQ2uYN@?XfLcx!(v@u-iUA4TCHD>TLs7|B+eonciT>Aln9 zpC+~y{P92G;#7}ZdwKmnYox92=OXu8U?AAL{-0wlVZm9j8mq>#Qx@iaSYznfPmem!eD*};fq zsTB3A%?Nc>;7=ih}t66&7NMC9{5|VFw%wW(LI4j4e}34ZsA~ue8;8Be!aHkHuQ_wuo9O=V8RJ_4W9nn!AIH#REk>V`zXKrhsL9I(HUf4J!RnT`R|;bryhgg!}yf(_D5U zhxbs`?7UC!&h!pCvduA`pj3N!UIHj}089#Ifp)8wPu#S+6~_$=dXcQ*4KBU8o^1Rl zAoVj(mix!%gC;_U&&LJ<8=Cz#y{;Oio4mhj{l@2_Ga_{AS)<{nCrJVy!x}8oY2BGA_rw<9RynPtJB ziot-_MU>u-wwQj~Z}K@ctzji%rY5-HQD_2|Nd7`@YO7Qqxt`ni z&%c20rZ&dcpaKGDnvNHi6R=$)W5_|2a}rr_^k08@cgLI4mc)H_K=-du+p`{Tb=^*2 zJ~7|)X7sQr4G~MGrmM>Jb-%DN?eWi$fF}slbwX5rv+-2g?pwWYMEvGL@~U9WXA zLM+L$sFpY0_Ad(U6!_BF7zLi7CC z?{HQlBv0z$@X*0rQ1vg91HB2@ngm)z*zVL#?%^$zE{h(@=p5}3%_F9jF(rFQOC5UB z68;;RdJh8%w>uaBrUtVfe z1P`7CE|*S@fYYxwlX0` z=4?kntY0riTiT)^WbXiqG;l-Mwxzuv78V`TF^z?geZ`3Fh@$Vj_X%jFHz}O#&bv?; zVV{@#F=Sa7OFUOTN}Ca@OP(=uD_Qx}44iy)VFwrbFIAN<)5J~mJo4h5FJ1_yn(RF$ z-6%j`;OPd7Kp$lTzS}Ol^~#C6F#BAmhg+Da2pTE1YkZ*>71~3@kqE77ILdO)qfz3N z@_s(q8ZQsJP(0M0t9Th>ppfCF5E%Td;zw0Td z5v6}%^SJ%umYmm;41L|zt~f)*%X_&%G28s}8sSoEKms`KVdP z4Sxe&aQT9Ll|my1FbuCe#(qmRy3GMK(s9Y4pGp85&?Ce9#>HN;@?9pdfYHqQir+i) z)pW52E!^=D3zM-yN>)Sr&*-iRP`jbO!ut!@0}I5oAlMQEqWcr!D2f){t(?_-W;nrv zrIRo?j~L!$d_g_S1<>P&YiIo>@LOr#j~A4lgkfYZsa&ro;U}jS+p1{3GL7Ib)nVj8 z_&u19gx61Y^<12fRY@tzp_WULqiV45Vu`&0yjBqF`C}B#N>CJ(pTlHnMtPbP7vXWG zr|R-|X@{bc@M6s+;7Q)T>%ek=5~iz+q)xNV_kneflI4lQOnk0nkW%z@I8s~$hK$D~T zT)U{keC^lTChd1NmxpPSFJL}zfA>~1O>4fnUn5A0>`sAtv`P#+?*K{?1sEIC`0Kbv zL2QNJdMdMl!4)hR9V(l`ym?NwiGgki)So{6teUCiGUh0+56*iV62Ud9MFzBh} z$(8~ee70Q~+8#C5V@=kC9WNkboFz4=hC1eI(y3bp#E)wbj;{dPP8I2)Z*rw9cq0Uc z-~c#0A|pW8IbXg7GU|sb=gjL`c1A5S+rfIB-(54XyqB`!6+s8awf=y~Om=bh%`yjd zgIsHrmn>7xmofPR2CmYQTBiIZGrqs;g`6)u2v6f2ErWjgTwaKtu*i4dEpNGWy2t#& zNZEo(3M}WGd6_=K_sf9W9c%yv$VNvihk?PijB6&Z5{s_Ek5KMwXMUF8CgN=N^M6M7 z0Kn+q&}2npvkvAe@X8woCc)(syiLrXfzpWSQ;hdzW9UKv_+O#gfC51xw(Lor!Y&l= z8!s^T6TnM^$wro3A}rHEEQVpt&oAUMRTbFe3O+#3KqkKFh)vSKC|>-f`T%&|s{6EC zf1$W%C2Au?x|HPu?qN98l1=zu&U4{wSQi#ZSh@9HCsw(@tBVByIi(85U7tE7azTT{ z)Lwd0KW20P-Od}r^TNcQ9aV1qc$Nx!)w*~YodqrmBTXpKbC%>ZIY&=#t}CqKWU)VcNiiW$|;RpijcgqtFJFqW-)X3XK!FI;$_?`NN9f`@+EOF&+iC9Og8V=aT zth=Usq*1sWM_=a(Idf;1CABE@6F z67MyzD|HY0kVYN`2Yh5Qb-hqoKLrL_Uou6G-(3r0r3;Rx9Zz)f77mG9Nlfm+J3S3( zX=r{%TV|^4?qz+rK7Xf>qt54bB*4~~O3eyA+ZgHcj>q+Q0(BO_P=2;cg1b$rJ{d)0 zE88|6O{ih9C`I-wI*^R@N6Ree9AK^oesjRAUonu^=*Ua~PMgTf0RDbcKuCx8%9T?F zhP&#G)<^Kuhxy7(| z0+#Vkmkxms8f>#(j0aO(O+FdlJiir7-WeP}X8-%>?3gX0^?To2G-k}XeeOnufH=qr zBh^sZ_!}MZK>;?Ftv2;u5_8j%V28__G|{?=ks%3@Y7M*30C1yqC;XLfz)U%MxLiIU zk@DVjBrF#FaCxv(Y*aLge}8oq0;+KBy_Wy*z|yOYCvcJj${c_@{h%d%H{jI1V?cx! zd~{bdgp7|$dJ*praQZ10j%CrWFaZQ@6|4a5^aJ?BFS{$DP1f?2jaAHws{X zUpHI1Q;T*Eo<4^&hMp||}45q#@#pp zENu;i_vvEdsYNmi3{doiLVEfctr$m>T}Gm0{(PAD%MsRV`f2z}C?cLxfmWMZW4~H~ z(Ip^&v7>le9&bIs`}%k7hW;s5{)NPdN_36dI)7B z{rcqkz1v?Ekfk^yN?`TydMKJho2p+0`rHm6okS`CRdw`;x8&pLTbvX3XYHQ#NNP5B zG+HTrZU=lcK!zUAEe7kTh~7DF%VyBM{G~~%mcW%7u8))}+rXl*2#R!co7!1sKaawfNs1XM$jdJWfpDWmy{>{Zbxz@^FT zF8~&*Eut~eIy#<(4@7l+z>C`T5UMB;mwwOJJ2S~@jvgrtF`L#qyr~-K-b*$hhA8my z3t+_oW|jyhuU`W803>Bjc7*%#K(Iq3K7V1+)rcR9vu^+Uu^H0T3+R2_a6ad;g3(31 zjji3dC5fqcios9xm3kkrR-Vsy=W4_{1<_)bV*VhzT^^&p^yhAEXe|EGPbdqdg4S94 zn{o6y3qXex%QE}8w&<5|Zd19Sztnu=!TM^khG>#wsA~g;`?UiU4#X)pd%h09<3YcT zCM!62Dxuj96Q64xCTE%#y1IH==0gyd_=(83m*^4La7?rx*7!ZJkotHO|Mu9r>Yn`Z zWeNEh!fKdglwLr;?7(k z!GF7`{#wrY7bW8KtI;d{VecQjn&iECv z)E4>OK%hS=?hA>6rDiP&ZMT;?UqWiK+n^JHFpNyPvgpkIwXwhT0`$P@E6SyR5%^-e9!{x6s znyVDZe-TNf+UJg;0xfubeo73iyP%i0DC%VyjT>+Ps|>w-YuVdX@%iQAbmxBj%Vj4l zdbin}*n!iR_V=r@1MiAZf>=4LfZex{PrGr~YX9fBuPM90HlC)knYksuTF~vV#pvbL z)g-}PJ@CVSU*^=+ac^vkG8jDxJ-NymJz_X`DrH9HQ5qFViGaX(m{IHd@zs4uf5bUO z_u3pt6iImz8_Y|fl#IhLb-Sv?ZIML~^8EeA#AU|3`D-h93!RNapP}(lzijc+mtBRg zc;KGq;>&Ts5qEukke#ikg{R|YUR>;BVDB-7fN%JHyiTx6AQD`pa)3u+>6QE%FHZds z!Tl-$ce}@u0anG3pOO(nz_ktAtj|n5Rc3d6gW50LhDN2}4FU<*>56|nZtyPP(tk%4 z2DIu9=jusQOed=4tGdg^jA=IXV(O~Uiq`r)05;FjDt9{=;@8QTr)kg*v=95mE{6H_ z0{;H3Q|y6B-_k^C|BtLU=~h(Rx_0aS6$*glMMUyE5y2XHDxi}8`a2@_*>AhwIfbZ1 zYY{G8)5%DBe>%a3iv@s!=fr)Xk#{QWW5~W#i3)z7N9%h3HUDSM`R8=^PoJrQ%mQ5{ zP2c4mW?9;k4b?xD$*oiDkM7t!$y4A?KcD`eu?T3kz~n0>>P5`A&zpL^cSW5Yw?ke9 z8(M7p5KnNKeOK9j4KO=>9ZYUk0r`v(!8!=(F<0a>eJ^X-XRDy}{`WEtvmX{xyBqAM z?!fnaCi`csp^aua?)^K@`;nNKY~C43pUFq_gQ`sD!cQIPe<&P!0~#P#uXfNwns>Ip=WVZteNLO4LnPg>B-BJYH#Qa^UxVhwVDiXGJI+$k!u6Q4W4^HMYi=&fdxPCueAGH$kIZ~f!Lc{F;wlHS!|~qZWK3b-8j$H~r9G9<_09yt z!SKH{jmPDh+vishdIaOrN~Vyl|FJ`!T)o@X6LC@Leq#dnI%&((hx-+=4C?pVGAyKD zRqeOJ%=TsFckBl>q=fA01Duwz3$nbLxC_lI1!usB6D$xnHh_zWNYs=KYZ5ewYl8g4 z__&>U!j|04cbI{PKA^w}rGR3@CJf>fY+T@|=Npzu6-FXtvMQg-o+xwd4gYJ4s~!x} z6BpCbO0AAG&`W)$#nRa^8{)eBu5rP4xd%Ci(oI(;Wr6B?zC-?{OnuAT;r> zR7Yog_nOo^zbEye?RRw?*zj2w7wwea07poX+Du*SVD>`Ly&OEA)UgqUKF`KdjpZl% z${`Wb{afVP=SkK2bt{k;p9>?pMUUrVTqMnXvQIq*#KZlz?VhcXZ6#nvP!-;*j>Was zC-8H9XWw0p_ixSuEk~%f6UD3azmYY4q08pz}i_Ujb}KFUSQ zal~(yATSJ(AAa)na04#=X3>3(K+Dl3o5Y*AZf_mqU&=0q4iN)&6{$9y*GG0efo0%{ zp0AR4!ajb3Qx?W!Oxu-$BHxKMx|__@dBK<7&uqsN=uGiLyl9)_uSV$&GD8mqh{*4L zgQrb3+2*R;)q)S;KdU|F0gn34H#ac2uI|lFd`}tE*4^6j9y3pvjdZK{)@SqN z$>*>B`KURG`rbSW+LwDHEVNe{;rT(s7zKZxKk%u#ToJiZ1SE=ncKA}4eiz+)mxw(n z0SBG*>u1&qH*($$FsOaiitJkb``XW|Q&p*% z39@^^mXh#quY~?YP8eXYRcp`H)02^8h{B4lw)5!_{aUNA1rEZR&vboRE%xIs$cSNt zer~w`?2YzOBu!kav&5_*sACTO5-&w#^|2L?=KXC+_{4`3MTHq z3EfV@O%Wx!n~Zcyq?!pRoc+WO@{dy__g z@+$Zd&hN+)u5+C6g8vc1bD(W;&7DcHI(vJmzgzbEjjrIw(e#uge#$SluA*-W)|s3x zNFrubd7(RxDj!WK#YWfO7a8_C-*o(}_4Hlp^dSw4p-!>~0*8-Cbl&^geDJ6o$`*Wz zVH#bb8?Yj9cqKH3$9+O5a`O}U+eJ0x6(Ouq8x0J7g$NPL+Xa03#T03j;(5P_0>5P7D6JOQkHrNYfnE&M zz%O*8|J)&g{eiox7A`QTJ&X0{&bLqL3uU@Ya+maDaS0;o3oHeP=wp(!g`u7Ij5PkI z=w;t`AT`HQPYnK6$KmcWakktCr3+)muqIWG+)k*!D;`%jC=4uGkZvj~S27_`GH|qFp+&5pA|3xH zf&KS%_h0It(`_~$x?sYr&?)xk?oQ_5^VyuzeJ)cLjXau<)@6u>+v~183P=Q6#<9=1&t7)zEL5JC${#-vKn0A&YD2&4mCs6bAVtZNf>SNBop|OSlHq$Q; zPIMS9cq4=AZPlmH;Io)BU-U=a7^;9@6@Lq-#>{N)Ym`s8{BE@LuEkb3oSvyeyx`iX zWU-3_YXpLl`&X#3GKypXN0rg^Y&6 zdyheq^I$Gg%)F)VrXF01J}u)GX%BG6KyiA$W8g0dhUOwwuqSo3y!XT^unp)Q>bLt2 zvH{8$xGjw%4Tn{+FKnQ*I&Vr1Dkq)^)|ay&2W?`mg6w}|3QenP%lAH3i!dK( zzI|%kSp=ME+cTm3uNx3FpB+*BzNo}jJgd|4*HrKc3x5tpS@(~+O9b5U%m`$bjQH7( z;1Mw+>%wYD346wQ2qh_0bkF0X!j+E~4Jw4eo$SNq)vu zWsMzr)BTsgpjcw&#I2B=>4xvOO7EbbptbJabLej${&?JG=6WeykBAU>cuQ~iY^d*s z)K^yOoc$}=$UqMrJxOFlca-s43_uIBkf zm#t>b`2`+rttG>XjKFdNyO{g?p}$(5F4z~oFVPqV4Cr=u2eZ~nZSl4(ggZWD?hm+r z2R$Fd>y0AjiNescEWmm$1MFqUwwOy`0r+JTSoRID_G*g{b8Jhcm+rBD@s<36X!Ii* zdI|J1%lNLg*>2aus1V{Ia1*WZjrs@q0CzW3o88{P3__~5{>{h#%uY@VI#o-J?BWe` zbuj5rujyhZECC~{qx>T|W|Yo#f@S7^tb%maembTROLgSOy5X3=QNaV*lmuK;Xn0Va zUf$6a)4s=ts9&xUEgFchNv>8oUlG4^RcKbT&KH}&;o zHw|TO)*8QG`>lU|80T@pd_7HND+GT~Qi1dbrYFcdA3B(?t}2m?Zy37YjxY-&HHV#p ztbrPn2W#JsPNVK)MJ9lQXL*4>+s%<2+0l~(P9P=H*Y5hhfr2HxHyz%!r@^FA>4XH5 zf|Ky}E_?127n?barX{ti-vnK0r9Ir4DvuY zj@W#74(rwOg(>}jY$wQ*1k1C2L}zbBK|Sjq$YJkje!MCL>A%`tc|U1^JrjV8()OD} z_#}%AHOKeXo!;-xW{IFHxsSVoGxO1pS>MaMG7>efUGj3bEeUP6n0|r1arK_g^4kK@ zwLvUjz`Nz^uuLY~fZiMy_Al`$=+NN5j`bmJkj$p6bqG1ZUF3bf<-13ttnH@qD89dO z$t1FmR0%yERf{6ajGOdE#+?h2u^h2mtXb5HxF+z?gE9Kf0%Sw8le${qK8-!pm0%njhbJ zbA)7Wk9sf_K)^vu!;K6*#9QOrOccQ-!3&}wZzh<}ML{BgKG=;)V!L3*@6_97N*Bo; z0n+x9B%rte!}D*E?!l0-FzQ;z2}gm&W^*(FI4#YI5a4mBHcg>u!%cO4s@!j?kp7@| zzO<~ZJO_&px32NhIeNL*ioBDs4w7$+V_m@z(Jr#xGKui}087Let^_dM0#GcM5}{S5 zymg;vO!NIoPqLjugowejRe}3(isoGoYz_ z-=_SQJlRxeugl2?t^wo8#6;WTG95&Eic%&h53`eyqEk!moM`m{{5?S8bY1GcLk%8b zMWX}aCR&$;o*ww%eZDeE(UjnI+w(d0mx&D4zMI`j@n5tsf~opG#GZ&14IqPzoyW03 zT&lTgT&zqJD}?nNP9k|yoYIE<1o?)O z=F@lFlfHgCnVuT`M!w9Z_nNk8GLYhRsJHfMgSe+cTpYRnB%vK*+9U*JO?*e7S&=)T zSwx!maD@S33%eVRX7fwEvO_f9Zh6xy9LISI*2^nyohh##7p58$8G-8;ErC<_+Ukc} zzk|G#hDe+}_F-@+gXAmt>cbf9c`p@+x`>}p$Rz)mv;p%*+2A|uj#OY3zMlD-4PE6z z72M{?@wC2{QqC! zp`rc#FMI8_u{hbKp;=@{|K~N&CpN~pk;bicMZ(Sm(=7+T_2Rj}3j{|QU4-)kYfH}3 zB1|`b;xD|tw;OZ(=Pmq)$XEgG_#YzUA>o^~fdu!yIw!mU48g(F$67p4VtRMe`Qmf5 zGXF(j0wa`B&$}QLh$ax3m2tdq5$2O$khzr2|MLQYwC^yR{qq^smk_!Zee0@CzQI;X zh#bVD!qv0C-AdH6KwoM+edV7=00wXH?;6K0XSF{uGOiN5 zP^g-$9N?mz%2Wf9a@LjzWQ@%mjzng%bjuZk!RYX!_%d`AvMC?e$wxx$?Q31XIpv^?O@ibWMW>qpv{ z?2nPc18Bsbr^jFD+c$j?|6s8U7l%#k);poGyH$zCl;b9!TMi$#_~YE}eia+$ncQ*y z)ydnW3RCzF@s4MJ$EJb2zA}->M6eYH1EWfQKNa`Fg?mPR zq=vui2Bj{I@%zOfbR+P++x!E_S;M1X;VQLL@@7Y1{#=$owdnPMPk0qT zSyr5kcksrux~3Q*d68?y+rs_S7Pig-!u|`ugw$%TPjrtM6ys{C^~XdW*7{l>g$K*z z;D`4FE_BZJpv%air(JNE-=+UU0xq)R~n!)?# zDq%APBkZ7mUnxEA6wqkfX8ZzG@_K1{jA2XtsusyA?6ddq=r(ASokZ2=XGXxDn|*Lx z)JZ59bhz}jLc)^U$Vb3kvq#?nd!33}Fh6=DVv#9AN0r}fE_W-WL;gk?B^hn4SdW|{ zyNeP)q`&FzRRM+JIPzzXBr`;t#k5Y9{bqktP_Ll%A|WSu!l{{WoBk?A(LT zO}@ZR2waF?rK;;2_B?lfL3$t#0rA-me9RUA;$m74)Uy+4AV4+fOP|Dg?jk_!!`{1( z<^DTluu5LwM+L#-_KW!p%x^pkm;-w^U*r$4fkO>On)VSV(Mf1;!yI}Z@!#uK-dTvb(0Db3-zGWL`On5&Gk{GQSorbbIf3|9 zOsZqMEtB+gELBTyn3mW+@K-yjq|pa{X%{}7lbO_5q$h#x2G0uNQ7AXjvKY3H?-WLd z>H?3G{`YJiw_3rL;fx7_$8V#y9npwEa0RjD7p%H!svJ;1?L8G{XZHHL8N&7@WHG~^ zW8l-^5P>>hf^vBVaHy?twhOQTSS&av1Hv}FMZxFFT!_ak4{QI+G^c3#xv*U6DT0x( zV5z0#Wz0KpUcAE?SpMa_r`4ZErdw|yR;<76rF_l9Cm5xH$&ye~_jofz#(j~!y$h7} zS)NcwK|LZ9Y85)>+HLGFYYc)IIUbE_D{o!UFic~|FvD+K)5Wqy*o!nSsIs8steMnG zMo={&gvWx079Ml;^t_7gu2x*I@lL5p`ZL7*X9;?1`vsvOjTqm>&rQWSti2FVU$a7F z!jRr#h5N#`lCl?|6q7-XVhFzb!QQVx*R&dw6(+yJ$A1gC=J!~CkG&drB3Gd>?)#m1fgZ&<;?Hj=}=SIBs+2nave6u1@vC21S`do2>HZ958O&yTe zbE*)nkEb^YA!-kO(E|D~m)mE1lzqJ^*8 zHA`)vL?F*pxDKo4whK9v&m_XY05W!TdQqIuGA*)iCkYptaYqNI!`m`fpOD|<-&z}- zf!v9HW*N{&FFOmKQxU=Ap8Vu1q$xP>q`Z-3IA5-jkF54K0LH(9FRYFX0sutfV=EUO z6z3mVKpM2q*=-q`rJC(FBBNBlDklIL%|#folipFr+Ak9*5$zIhtLNfAzl%Ckq4+Rr zihkEsFNXMPa6}?Jc3WgRozIdVV}nt)Kt=bvJbNiUckM}sl?bq@Y*!-c_@C2#&&a>0 z+bYyR%wjU;#66E)-ZGW@?S?CU9!BE3E5p{To|JvLNfE?7brtF{OJ7{^(YG-90;?Xk{8Pt3&#Ovm5(<5^zRI8(V5ph zZFYuUT0e)oeIw@?s7}dQ$FY~ z#~G#x7FV>pvA3@s(YJCq3u6Oi7?{sch=uTZUB6~~y1reBr<87ywCnGYT|rR1INs&% z#mKq7%Wn(q5KBG=3DVj-X{^tv(0qE)0v9t6n{XVcc2|0BMmRsxeIL8Jah(MiMiNXJ_&UE0A z+ZX32{+H~;G2Zh_fa>43kYs>~fY0SENuQ{_n`m;@6L2>UNrtV%`Gr6s6i&R%h6kP| zz&_H{-@7sPjA`E6{3xmKWq~C@`S){!C896N_{q7ILiEk=+?(Kr8a6d}1 zzIgpsrw#dM)?RUNihwV8$JH@}jh_v=T|*3oHrW6BbiZO2hVzhKadUWpEzvN(-B?R> zd4uO3C5-6M*C)G9+JFpzm?wW_?L6wZ4<5US-(k9bN~HXLDEIg@`v(|DUQ0?DN&Qs= z$P=*DCV!VCw?P`yErYSCE<9T6e!V0HifQJ2n5OM12vMQo$tr6%8-zI6O|T&^kQ>TY zDtb0N2&qtgZkE?RP%#Dvqxj9fF2|YB5?yQxWUOwJ!t&watEVZ40pG}~1J>FVgt;7G zVaf_A>tuN9s(Q9q{;}Q)17NMC&w20Nsx zp)Tye9*t*xH#)(-B`AAh!m3d|4L?Shy8>h>?D7owX>Fdi8d<`N7YFYQK=JRxNq^6l z-rrRTu}W2hlOjTi&dw_Mc6dK;x;f$#u55y1RH_hXq!ProY`?Lgzw?&jBp)Aviw9?)eKPj{-9guOnp z{r;>?cZ8R?2H*fZdEsUk_*i)T&*}b^|J>cT?FRdE?SOT(mby@P+tv4}%$Y`T0aKM1 z_{fPKl=kn;B|*JRQcgLTOlu~ zeo_are1t1YjxM+{s&n(HV?SV%OtmdmzTO+ye$CQ%pW*@_B2u|^AF-|?`3+=}T1Zoi zMr<}(Z>zdO!LG(Ol`xxsHs}?%oJA&JlVVEY^*Es&xJvUHl{S?&PdO`LUJhY*adA5n zFpSLyDIxer=2g(1Uq%O94`Nk;Ja)F@@b&&FCk-n6xT@b?;*T=K-)Jp|(7-5s0iJcB zMID4nA`pRR6WV(1TpLmH?iYIn)s7$K;)SUVbFgXfp(qAAK6*PjM_3q$0j#rx% z%%iCl{kL!o4-60+e(f!-=i0iU>r1&|%)4KJ?AO+j5!&w4m)etnXH=PD#YqvxijL!w ztsNHy=x>FR&x8$?_c@+%kMk^yC@C8rwIKI6y%$|(B*1*_82jy}WkAPI6a!$h6P98C zDEl4k$_olMl|C?Y$vlFCWXGn`J~! zzs@E=F;4&XHUUto{qk3+faj2~ac`P%=qJ$6Z!N&sT#6T~R+^fXZn~r3arCfNBlocL z-homvkCfYEdi9w%uHcF4no5r#3xX-H0F?(KVrydtE-Cjq1_j2Y>lyp~RHK@Wp5z-F zvm2rQ_vy};2drA*?$+6+f+InGcIL#Pt0XqhOT>s7sOd7k9>XMNpt^l|E{NoSml$D8 za`T5^Q2?@8N1$QiOKqV_K&HnI9-X&Gh(7&&0n?j2OJnF8;#5Hdj~F3(WjthYWn$7& zIpD|VBqLbai;%`EUAy@5rRfYyev1L*WhI4{G>JE_vXifQ5D|bs@RYsm#0mOaCmC?O zy8%mSYWv$T_}MFj@96DXobX6aqV-sh4~qDpIE0)cUAO7aPOUPx=+}w?fPmJ4!P}<{ z2*y~N-D&|oXyL`y_==74ALlqW7<4r;tXqfh8DQQfyv*na*^9^gQcA!ui_=@bLwo`E zyqFRXNoRQl!r&!~G_!oY@Myyt>{@EB{^Ou7->_Ul>kuH2whNzOW34x7U>B+<>q-I% z2)NSj7}XgVF@gFIVh;_- zFv}OR!s2aEhxG!DKuX1Bg&w4;(egc}pLDf4P;5Mas#)M0ecL|X2EEfATRl?)pzS%T zo+XHE@|j(SgMF?-HQ>zT-I3tT^`x?4J`>9fIm3Q4UIhUu|l0EMuO%<4fUSTQH3&!OX9{>v@^tW8!-cAa8R7Mye9idKUO9IfcfQ#A{d_Qjx zgAAB`rNleTup|MK>(_U)k{RHQeo?BIBV(u<2BKf|CVf1Ew*k6dnjc%F9wc&N02L07 z1=db-{v~kn{o>xu(dk2ZW+xuQh--4^)3u-N#cyJ%YR7WRCKX93vjurR5wIWJIc;lz zwHI^yMl;p}7uKN6<8~w=g$qt9T1WjXG;^V5sNs3<^8GE(@#a8+5lD^DrlnK{7fYL5 z@33|S4z&K9+4rqI>{6ZXZ>8I<2d2c|w>|9VCz3x(07Zw&5|_2o?B&~nPGIH}ADC~zkns z%6q62`Wr#cQQgBfF1~JBTSBf}k;54WM{B?kGjwO;Q^T#uA(#gGnZZ`AFtr3XFZD~d z8Yp{p2_u`D1it$s>c)8q|5dv{r85n_qzZRYj3Mw6Vpsb;72TqGtM@W&%NH3RGx;$TBx!+%hmy@=}MdFwFYACNQyx+@N#668_s3C8vOGIUTv z0OiG#lKG+?o{26LOfcTUz8h4Jp^uNPRSZMT|DNuD^TZB_5~-H!MW#0_xaqE{6^ zs7&_!a`l}eehXAY+SB9yOF!;dFx=P*5Uqt=g%L8vSILqLEn#J!=YYq^@| zi&U;hkiM$k(@T4=|2Vkffc#)3HeIRr)6^t8`lRg7f_Xlm>+UD>$3Fb^Ued2YqyA{r zudsy*D1eW<+{KjY+|J8HX(ptoh7D|L;(@!V5ygHTrU*A^so~KGSsw1huaAZV(}I;d z^;ZFgV0QLBn9A?T`zJcL*RM4%<;hIi-az@OReXP+REWePUJ+%tQLNJ#oUqDAWTz|{QS0|&nh49(|ZF@;;;%;PmQSHd-#(unU&h<`~KA!g4O z|G|?P)T+OAUP9xVe(e>2VxcH9KRSO-ZjsRacxgeC^lU+qkTOq~jx6ajB|Wu+HiV8*~rW59JTWr`+-iL zsu!c~2mH6lt&Y&Ix71ss8jGNC5HVV>x19s+-oEQuu;Fq~)h~7cOQRfF9Uopkegqwx z!q%Y9;OBk2f-c>Jf_L&iOd5B?|D5iC{pWP6*_y$49;(z40rlMlI(%K06+Pr>!p{%8 zJNV=T1l;xDT6IIPy1d@$VsuekyY}=7KQNihE@%DBn?m{e2-_v2E=RC0W;UJd2RT&f zm5FscJ0Cta9ug9+G|qMi{w$o0)N3+<5J&kd|CC#^viD3+3w{&_q6%$qp&n3YL)3x# zdvY&`l{uzEis}$OO9DGR*0ggRCfRKR^y`cXkpZzWdAe1n(CM#H$ZZDlb6kb--jjx2 zf|y?_>|w?nU_No@T9%+*SQHo)u}QAULsLk@&-mKR5i9+g(D5}OnK$NcCVh(vnjz|z zq!d`xeP2_$TB>+>O*Ac;_-5jpkd6({uD76#?2)}+89o7L&Fi5^$T{4&%F~~ad)*0# z0JcBw7}<}eUZ}-?Q^wOyi2JWCh_*jVx5jRvk$$ca%ZPT>8>9V{1>cGhD-UovAUea4 zKigfdl`msb7qSp!nq5o|8c6khs^(-(A*aRm^Cg^N3Q<+B^L#B<M}!)VJx^=ZVXanpKym>rBDUqIJR2jBW+YHlJ6Hek$)Uec%uLN%!TG zB=i)xYK;H^JZMXQnuF^H6gEE@%D?xESzkSY0xP2sc-l39X7zVP5_0w@uQHYFH1 z!!->|m%pYwIg}{wvJ>cI*jacPzdpf)U_bVKvBo;K>DbhM%cqO2FZ19*qA%hTJ3z7_ z>A8LKe|7i&-QABM`FnRu_QRtDHlS!yft@ZhC@YqfNKE_X_@P9g-_~VW5It^jbv}(!@|n^ zN$kQIUv31Xm_HxI*g|+*e^|Q1!@8qupOGx!hE9j@*3P*5LF6U^+=h7+X&%hO2x93U z@qKT4a64166khHJ>b5h}z=yw*H0A^er`w-)a%rsI?E#IagD*rK zHD?bdlsrU)-vl*6toZU!chK1pZx9wxJuo5gA)XB&QQc&+rYJ@Lq5F@fRPBH6?!y}X zo^Ivi_yvUBS*n1%5)uIUMpJjMUfCqk#3q<3aq?);;7t>U-=jzisC&Wc7vY##Ak=$; zQ{3RVU*cu2K0&l_QIV_MGJuhvB`LbCrzJe@7J)@6;%Ya@y__md1l46w_iU}l%Q!RK zRxwi6{~#a>qFh9H)9Bnbmuus@e`X4n%1_xjfX^X9_b}0uQaei2^#&Dt@9vsY8>5M1 zq3Ub$2wM<2pIrH<11Ms+?k=p%MI;l%Swe>y4mbA&K$z50>~2PhFc9dy&pFVBC|iko zyp5qY%%mJTf%j{=F{zAt^y9jv6xBh+*6{t@kq?C8CdPt!ioa0CP(Z%H1mQ3&zJ>}x zfVM)lme-?xPtLeX7JPx}Uiyft;I2vIU;SV%F6b==9OkCpchLDh>gFavl;i^sZ1+36 zkJ4+$orJVXykcVz zfRf*JBRK65ke3@A+nwI=7(d{k8h31qq7{xu5K6>Ocv`gryKWr^U_@oi!+U-R9N6Wm zzZteJz+)T2BAEKPvnRyZH30Kz9*569_hsBV=U{F0qEoXG=;vtq|;CboI&@M znS;IFz9%fe&CP=C0q`@+AiPfxPCJ+kr#5M`i5L=)?BX~07zEygShi0K6NMm$^}r2i z4|oxFSE@)}icRFoH-j{lt8F^OOGfgNK)THZqfhmPDiz@#iv5Ji&3ptDhaKk#^f5_j zFCXQ#nUDE8#f1RB?{D9#*ZTd12pEV!3$s>afc~*%w270DowwHU#?LDR@hzW2ZKaoi zMyKqPMsfjn5>Yk=m8x ze1-7?I_R2u81C&-iU7z7(=tq=2e%qDZrCeKSw+SLnD5|;+bJAz4^b}TprVG3PoMOR zDrh^w4e^b{a5u7}F-Zc!H%g-dLup*R<1^CO3i(P6EWq%w-(S;$ zUv&sq<}1+DaA6j=>rAphRte_!-8D`YP2#I@DMrb7lLl#-kd8)yI&b?F18xR-*U_@N zBh18W3iTqI^9}sMc>3?t9T&i6g0AucsUC#mh|@hC?8B|#bZ0^)HnjY@frOy7pyRkU zM))w*`3cYAog=IyU9^UgrllUiXR1y03p^_qqNrh1M9vsmS!d^Uzf5?iXUl)l1e{_% z()g2VRf7J|kbJXkX2ytdQyB1QrDXMf#uPh^2BJ}ySJi#)pp$sbPpA?QyBMH|$}#{i zrMQ~N%ANPO7ek7RLYY^GXdLodGcM!z^$r^XIqXN{PWsO8!ah;L`}HufN3$$0x55&L z%7Bs^jE-qbcdJd?&*Gh_xWzx`UAzY}1UMnLUvzW&*!3i0{>-B*U6h%C4Nfn&$_;D+ z@d0jczIV^4d@{@D5f=k2Hs7GShU52n?cVI?aA8Id&r&PC zuNV1VP+LFep9023=p8*bfTETs8A_cf?B0ZZpTl4e@ZFhcWZ7eNs(`z18g1_8@p8Lq-(THtdS~~sb3doJRe;5%wfaM?K~8n2^zT&&HUf-e z$8vcq#X4g{`ss%g%!wR9y?#F}Pho%Ir8d%|Zl)AW!|Is(CJChh*=?HqAGQ z#_vauImrdWqUvwAnGm6Vjw=buMINBc7cJc}q{N+pCI*d@iPj|_GE>;W9S^-Ojs zt5;%JS-=cold2sMMt=yT?8Fl_JRf>Vl-O-N-tOD)z?_S23rG`L?B76}|`L2g!#|`1{Ra9B6?czI3Dgfh=TkD??pGz5 zr>wna5fyk5$-VCg%=EEzClP~~M^C1ogzcAoEdBBG?H7=*`L5t1^RmcgXDx5NTNj-!6lMpxb}| zNwBAd&kB~z=y1J(nl+#aUE;y?|7XoWu9*CqgLcv;1HZ?^BS$sb{_oR$iD%0B=X94c zf;la=RbXBCv#hjaP|J+T7mEpbabJkC#UFBJ{F)U~0pbn|h&UPV8SpoNFG#_~7QD19 zXT87?x}fP_Avt~pq=H-nBb1w~47ILC3*=V!L*H!oxq8qGQ27=IR)4_{49zV+2L0z! z`1c)5j;KUxGR@+3lUJsVW9xE$JOQ-h)@D7V7( zJtorZJd>Uov*AO%>*5%ev z0{nWj*}#3!%z#W!zkG;vf3+hB(4n!?(%+)*&+qr`^wAeB zKA!`V8Arx@>@JZogXXTauwO=sS7F^R%Q&#hKrcJTl!BId9ku7-rw9GvUTc{kUl5UZ z(WISasc$flU#?I#37-{ywUFzBm)FY=D_(@yNy(ebfMAoCtRpxN<~gIP#rpfoXwY+~ zv_HENVF99{A0#77nNLYVdWAZ}lRfR8<g@@J=tJrCWIGTKsB|3g<`156 zfSsCWr?m&0YDA#kMW!31x^WWR$p%XaxCP_-e-yBPW+oRHBAG9Y{HO3XEb!O$pD_el z=PWuXcE}l!_}s;Utjxtses|&wmzruBh}PalR1&~|Xu4{D<`?JLgSvqObmyICR@Jbx z&r1})Y6FS3^7fhBSbkJBryqj@XwqasNa9n#7jn&$MG{oa`2pd*6upbReXHE>0Bf8_ zJjOm{hFP%$50Ql)e#1MBDhl0SuY41D9VG3l;e^F|FVq7mah_M&>uC&kxjZhICgQC{ zZgAs&>-;(Y;^=7(kap?1A158cPXo^n>0WpVEIBccd>cUQ1t=0)%45zmV*d6FJU6UM z#7XG@Vq^Yk-bKf}ztEahavc(YaXQ+cOhb+ID-G9jh8Fh#g=SjM_5n8Nw9Eb8)FS2V zA*%2R&wkblAtTZSv%Igdv{l>fmt*tVUo#g1l>!t>@IRL(4~k%YIC}o6i0x3cKs(^v zZ8ABo2lNX0Ck*&&RG+fgC5k*KqI*-nU$CTvtKpmk<3Yz*y&F{yQF+?yz&7_f6R41Z zxAno;q(Z@4WkOrd`dbj zMtK=eR;cE#AOaa+RW}0k>q4tMEFgClhfIQxb8qaXi8aWsm10~RyEhHOR+qq(?O|hq z%Mn3t0oHBOa=sD!Ke17C_5%^K_PsQ%?I$gu14Vn$p@_u2r9lh_B4tRZOx!DfH#C18 zAo|yYFVvP@ErdMH)H45o2+Z@oJQN!d6EK=1JtfK>idnEQ>{5)p%aRpA9A>*Tsr-78b?okfux?0O31YQ%$gAq2HP?2sPffdA@s4E=Uv4L*Cl z0+S%9?W#lX?;PTz5OH_Qp0Tp)$al=vxAofq?STnR|0}zzmkjde?!VAyDf$stM56sM zMcpAK`*jsyiFNDEcdn%%WKSKHZNgrswMggjcLr5EUFNqjMR7g%5J&iQkYC z+&m?4;6ZFY68@=x!6}_%SKKy1-~rR=8QZjSBym*}vgp>XOU@OX*kHrHC+rzCbc_0$P+ zMWflJXOwdu5r5#t`gz{m%CnRZ^4bl0YL^jGoqe?!z?+v@?ua)4%HZxxG4RU&N7k8a zDX3=aw$H23pst!!B7%SvQuHVV1q7*i`nzIhp1fz|Y33feBX%g_&syI%rxi#J3%QIu zJCJ(359uj=K@dz|$GIrMlX(_OLVZ7a@s1wpK3$VqnM~_(Ctk0&&@K3S3%yTN712;` zWP;r&IsYQ9z4$rk8MTJ_6kp{EpV14Tau4|4ZJ=w*I-I{lr?qQo5&y;P>w1YH?U^xu z`O`+8At!!+{axLNB#F|0uI>ZK8ULKS_weViL3x8cEBklvhHYHQmy;ji#OA@kP7%7K zdK=iW4kGm;<3|JWe7FZ?M1}4r!8!`CHN8g2z%d+tn;X)xbq<(LU+sJbqQX={i)o@BD&9bO6#wy zCHCC*f=lhR8yoD590$TE%(PsP;e9(;XFOk!0QMa;d?}ln-9(6@ChekCvEx^vY-Gf)bwU~D@O`($5X7|&I-Ks zVW;5o&;nRJoZBfdg_oJNc7)bltjRD~-`U%DuG&&TA3zv4-4seQy{WZdxq}Qb1RJ~uY zx`r+K4wj7SGG7pp9B?tJnoD(A0!nIC?4wc4OH*E1TnW%=ye=`YU48SV-r=EOFGnZM zGth_MafZ0V!%6vv3cdpLJ_RSuU0&d|FP4S-9EuxN;3PP|4^HRkz=z%CN5|l>UFNPK ze!aMd_fYwgnFTZFK7L=eqe7DzxvNhK0{!rn&0V5bN8&JPxMbV{C&OpfEKz@f#-RJS z919B%BzdLhw^Qwj0Uke!C%yvlz2SkD^Ft&<0|GE)tsEjnfi1YR77ag;0OevK7H8dk zA`Y@sGN}P_LjczXGLF0t@GCM`5l+7kXt3mp0##pJ zWjEJU3(SZINOn4(FMN2$LzAPiFH!Vws<#RP~JZ`1f(L`0MVk#=+L5V zDKGqejpit)6>FTIy60?lBf8xTXNLvf7~O#Zt~+UVfq2BPguw~G5rK6yA-V&hA0C`v z)IsX=a4ChJ3@FSyVCV;1%2900H%L@q2BfFy_56*2Uap01U0#PCmQZl#W?#vz4m>qH zd<~-ceWKq!-;b}wI-m%qz3;GXrKPobxXI17xEfn2*oLs2pU+olLG7i&!iuJkK%V|q z^$+6vv1fT|qOJFh^&6^vN_5}uTnIo0GZG>OBOZm53-9E34pYrP&M}w=^bIk#0&2NZ zTm|jc5i9cGY3W(zz&yTxfL#jzu6p$mvt!-yLd>dom=#k<6Wm9aoO@!U8S>WfBERIiSl=#D8EX-(&}Rp z>2FOWOceongoBtV+-sK*y5_$ZQclnuHmr*QYQ;&}ob`3wo>XIIx6&9uNamO5ly_91 z#EnouVX0h*dt=;LPv3t~4m?|&<)gl+k%t9wnn8a5=idDiwZEszD2xAfbzkt~{dkQd z98^|ug8G6riNGJd{raV74AtFxE#M0UiQ7GNV6_9E9!#lVyL0&*1yp~d=ULe*m86;x zvaBOv3SX*K1LENDX$=sN)xX!$i9XIGa+Y@}h-|yA4g2~?70yfAxbYoYj%p!KtM~SL z@Yxt*f>0nK^+pydQM(;QII4ja{q6*lylm?|kZkq27 z5X#Ergyf#SNWv7i2nFZ|rs4ZXsWy0(H=KY~+<;Tt^9-eJP6Kg(2V{h;rYrlpIG1Jo ziAGw$;1e@3xX&>Uoi{iB{T&I0oIY{9of|a!tQZ;_uW5#;suDW$yI>}RhZreh-G+WN zZ>s>xfu2F*6l+j}0x{*o+#sH~15_WC(0ZRT$VEZTqkuA6$b}%BxQIFP85)ayb{lIW z5!2v1jdS@OF5anKfue8X>4Wfv4yxh9c<&!pBmkLI4m{U-ri9|h&W{!?D5KNU6zyg2 zTA)lrZbVEPHe}yBfx1)yNG}3dpgE`H^G;hWeouf1dH_&~+HyeE9f#?rhsXSQCwzbj zB}myC*Z@U9WI8*EZ%#K9zY#DO%sU4}*yd8tK$HQUg=Ru{FGkxvEi*K^Xiic%?mbFfjN(S9c4?hre^T@(E@i(!v~@d@vCruoie*1eM@( zSF{(^XE+`Cx=D8%Q#3_$z38HgUWe@-%#TWyifHo`m=9XdL=M9=gH2WGsVQK!GWnqo z@9ACnAj5rjk|f7SN<^1yv%{XGclmU&Fat~cKF3l-oS+W6j7fz>_Yqir z*t`wKFVo3q3UANbfqj>XObKT+Q9r)JfKUdgnQR6(6&Xc8*$so^__t3NSb(#7LTl&a z)YA(G#0Pup1ek%rHrc{#pz2;tq(147)^u|ZqMj<%pn7+~;$4CVBXykv;OHOxV~c*f zt?(76ULIWvL>foGjW1U)%y=ODX=ByP4S~CkqJc`XTtAYgzY-C45{7e3^{~{)+z2zf(mdtuH;&`v>V+QxG2T#N*2CC+$Eg@F=#R8wb6~9zgf6yyz41*xy8}EN0iqjG-4>tpq z)vu@)r$FIrMg@@cjP;{vFlOw;zw{h-r zMVluuNgEz~*_5|^CcaK6vdZiXb~9pEMWb3NZJkx@^%Shp-&KaI(x~Hy5VlarmjH%R z$w8eJz#Vgq{rAlQr7WakqWwedvNl{7bfZ* zfH<$9Q&fzXcD(FEc@$9OUW?NuDBY)AeF4}%0OCJVwRz-^Z^+*ddaMa7=Ny*+bR=@a zllg`!=Bvn{G`Gu|-ooU2D6$IHpVkA)*bY|Hp#WyD&w8^@9T-t0jS91zNP5FUEb!fe zlIn>p$>y*1k_%T0K!dPwC=WZ4FO`&Aet7Bk<*J|Yh>HOn*U%6M!Ki1pEr%W=aa;$7 zn;*ZEg{uYmJv8&2q!Ey?wsi;4dRN~c&-t}4`#X7Z3aIXg3JABEA!|RNOVMpY-ahS( zL`R(r?@bfZQUT)zMEiXQxl*FSH-UpLpV!-v2B4j^$NWc_c>?pe2tvGfV? zEoqSPEgnk7KKQw4?9v2LmV}+qJa|^gLIp>ma<2q)RqUWK?isx=60JQ9F)P7tgI8zTqA?Cp0`~R!>f1gY; z5yStvy05iQeux`v8~s^V9dvW+-z`6>jWdvgzrZqqLz@~R?^wGk?=dmk*jOU=bAwsy z-~-1&28h5D;1E&;2O@Ygn9uKEnPYz8+s`MOX>6hH|~nmHDY9VZ+=ot>LTmdANO#%qkB?4T$u$uSxlybZDwr zSpG1OE_`Q$Wp#kDurtqbZ70yYrvGmE@ae6qL}YUAvT<#>9$V?q%@RT?138{Fp-n3n zkSPw07ELj$llmWZ+zmDUf$6QNdG~p1uOTrk2e=s)kYfRj&i`s_E$YsbK~x@U8@WI_ zDU5z*)tomvCB!c>90;`tX7T!2G#m!@SGu>)1J*VpQQ6rDi+e_ozlgP% zC*^>Ty!{3e@KoE9ff(d1R5%T~pJ4m@E1hz0hu3$k^ zlgGuE0)W78*p8TeFfsTJbxFGCssOH;C+7kZf;(O!w?_{iB5Xa?{$5YZeNgl98}l|Y zHUTed$K(4szLg07`*C-!-ULqrQsZW}Nj_`1WMgJYq+eJ63xWB4WxR^Ig6AgDiMaXY ziIAFmB}%?rprm4y{&qz$Eq=d)^HqM0CArUF@Qr5GuKsGn%|8>tmw5j>cgHi1N|2gO zUYhvNRSwUDT;h9|6Ut^w06}l4!7Y4#P2&k{k?W(cB7p8&po|jM=#wLGoM1z*R-K(t17%7Yg}s!g$+EZWESuvDxZNpL;4$ zPc!0W4~1F4jKW6Xma`eu?YF>z3bXgagO~e!W{GGcGSHwZat4g!V^i&qP1BJ?{9bO; z9@-)lu2;Wy^YI0pB^bwG*MEoF)%H$XGCR=&;I40ie(=D`LiSrCusXhRP+WF8DF3_< zC&dV*CS?hrK1?gSvZDQ)e>O zl`j>D&8;Ak%M)6k_;Ui%-~;X!=X1J!RB-~V!YtE~LEGo@fto+T(>2T2%YpbN@h)zk zI8VOP1EatMpK$(-Nmhs=7Q?bWfS}z;5Vsc>cd?ebbCmc=V&m9d>{$8@K@9(6#o8$|qMO7gTzWmnpfiEN*Z{|2w3sUKI2V9eW@g>0o>)&aU-6ix}&1 zwicf^xrc9BJisyO(;EPGgULw*cE$p-Cn!3H6AwMpWTWv~qGa|9{Ukvy5*qyLGvF<} zVE=+=9!Mj0bK(P}&U8y$EPQuUq%_X}EE({$RS=jwB>+C2d-_raDdr2|cHLp!7@dmb z6u@4Ceb=3ZF6dwcWDAe~-mm7Wb#w?yL~2N>W8-pv*^`_-Tvi!~X}jqiJ_#?Uvgl5I zM&$<}>jk;G+AnKwu}Llb6UJ?@FYo1`y>t=>AsxSQ?HIt<4rS|$0#D*AkM3J3OqSGw>OPYjj!U9E%E$xy<2QNil>01f%~~0@mlJvJxM1!Z%_2z!M$f+(6zDnL>q^Jp**6Gx_rXLBd}h^Ba5bt`gzuXs(~3RtorRjD45(@bvZhTm{wM zkt*2xaVWOiD#F5)DjMjQmkkFdKwoOdhQ}+@4LX`4C?;@N@poM3p#MPwcmgHw=SmM} z-)%t^B1X-Gvs_>QD4rR0W8iCU&Hm&%{o`e*PZFq}1Efh`&h^#;39KzTVM?RdlJq(X z*dkSxRQTk?Fg^b4KaT&G4UWjiOma+B=XR3=1a94HmoUvAE_rx1NSE`)fsvjC+6f+R z?WZsS&}NJa+%p*;fd_#w{M$}K!&=I1hC8#P=WnBZnPk;590)TBT9k?`RQ!?dQTGl-@oABWXA6`FXMlH z!M!fPl&;FJC7s>RvCMnS$eFJj=HhyZd^l$*pJzvvLEYykbseYbFAJLu<0wgS(%|MeQ};L`lpUx3EZ z`yu}L;tDNj68?mgXtfwtk^8hcIoppe?*L*AwsXu&{94n97IPxsy7;bFZKYZE4lBN3 zvd;hg7yP|Oy>I->Ox06w+OglNrCl6gjh0q?KJ=&sq3H4(;1&5TU_4pF9Ot1_CxUfb zRgK^SoK(|p5oi6#4Nr6HG!g&)4e%cx|3S(@1pp*xxQ@uWZLCe_9QX+={F9EnL1D`J zFdHn3B^qFv+kuGR;`|F7_HPhPW4Csm-9!%16O<6wU47HH?+WlQ72t3Ge2e_eC=HS< zxPQJNWZVjWHGlI74>8A07mY{vgBgD4kwGU~er!sWvK;g6)}h@MBKZ*C0IVpvpVQ2S zAg|f)8|<;+S!IQI@()td+7IEKDw6sEc3c&8)(`+JgBk3(;2nM*>;xY|IFD+M_h{c> zdE^(oyHwGq0EWpOvg*YofSRQ;Gk}$QM-E?<&(53;+CzUeTx2(Vjb?H(ndgnVx@RvB zo#!xU^03=0=9K-_?4I~X7L44Ue)|hNl|X$%u6n{jTh0Hz;tu;PTeLk;e0+%a$&V>f z+f>-4-2ni-C_%3k0Wd3|sFh$Fv~*z^t?d3S6D+%C5QlRVSf|&Gi<`ebKw~z}&`sZ!d-*A%7$bf!& zb}4SKovAxMe`8;;2s#e_x)gyN96uI_!LUCk3S4#hZCmZUVQC~2*{EF5hBxP2yc*x_ zjn~BTJW9cf49HGb;M!2AHw&Yh4=hNG$lErxQtjZ{NqP~ZLHaXEah?%QAdWj!y%ht4 ziiw>CSgl?r=#1n0w7lp6lDb*1yqftdlS$uLh|AsLT@c7}p+>#rDrBU{B z*Z2FGpUZwJFR|8s07e3^Y0CPRvHS!(2^Z!sa{U23%!jv0&%}F3Kfx`CRyt@WrlS0r z$m8L!JTNwxU`79+Dqol|0Nv~k5pspMZ-i2~DO0H z#VwY=Pxgj{6E9F++YSl44}!1*m0_CD9Ry71q)7x46t?blpi zp6c_WN&({qDQFDGYI)s(H;Fy@Aq$zJ0kh!WXo(>$qiw*X_LIUkq%q>dci&@?KgkG= z-EA94III3{b?#dd(T6*&NUv`%n!wS}4i0j;4#L7h)+c{T*WP0^20U#1nOXQ(%K|_6 z&Vj-)ksiR?2Z2q}-V6@5ZB%&KHZ~)b&m8>ArvUe0%L1*JsNe1&|$5+_Cjj z+Ds*sDM^3itM~wl@V}|%Kh*1@_N(8PH==CfSI6{(Q?XXpXyD6Eo{4k3ev$0<^r8Xs(#7Q z4}tKah(2L%Siutw|2cqQDQN~wLg$|r!3=TbI32JRTCsHK{QbsOZ$ZUwDcz4`igc>$ zorHyy1;rDSsQ5K}HuQSHm&QE2d6XGm5Yw6FYyb$vHs_@IxJ>h1Ddo2`{gh@&lHW8? ze`ai>hnNEH*&gx+&l{{8R=G=sH{G>eK)Q$UxIs!n8V_ZwOUBKAE$@Ga)Zv)THWcc| z^ure|!5;Wtfi4ebkGBChz8TQ^_eHgpurb8?K>=$ce(@`Q+*b)Yv(=@WU!C{8m`-y?*>y4{lMUMt#Z$(kRquy??((9|5ZS7~e#cyt8e)-VH$e0Ozg3cR6h5 zVLV@<5KFnSjXxgufVfKDne7ct4nM5D1zEltO~VmqJ~>T&f(v8QfXM2`*-;m%`Yv9V zH%x^wpX?bGvcpVGJ*gGq_8H7P;Z;)U&-Ap^kBcz*iq*uDPuiL z^?gVmPFdv65)o*9%}n_>L$p@h3E4htK(a;}wCFvQ%n-=wAL$OM2fD|J>NN$J%wC*Q z8>{2@tD3h5V84f`P0h>II_{^#>FFKa$x0ioDb!R42+C9pO9o_pt|Y`vRceym`$-4s ze_!1|uy6jky2Y|ch9e!YqJRyxDngtiNp@j%K_-8Z5s=_4A67{uf{{?!zj-B`B*25< z0+)x^lDw(13n>DK^Md1cK4%6rL98RUU=F+Nkh%ZE{X;=}L6ZFQvW@L-@RZrU@%dVy z5+K4myGh0$SgV00May?Ud-#vUw8tGL?~yT7pB;h`6@N`{i~wy@LLRs}`yk%_bWe+tMdwRGK;R90DXG~d^09nXZ|N>%{SK~^ z@Jp0=d9m^`eZFrU*Tjt69IL_tc1M<1K#9(lu{m#}EOcPNqhrPYb???h(2)Pb`HvcP zzrweoZ;1aua^|jQOr;baU6Z{@IV@Kbqaygx-}QHb{i7M}Z10A${}FX;=q!I-HleHrIPRxeop{t`Kq ztGUk`262pIL_>BpNev~Kh)->)m1OUk;USE-a;tAMj4Ggz zw%(lQ1)|zgnJji%#{_(Mjey%10AwtMrLgUjhz{gUGX8->4==19EMPH4vj((Xr31&^ zRLIHdhKmG|a`)qwz-0&4z1{$2;RD(m=RF$1{VU|XEYAe;d)l~~#PB7iz^%O{oWmQl z$1)N3yIBtG`Cg37F5?H1m8K9XX^5uZ)k$y|`M(6Ja zE)S3=(Ue^*P(rhJvPl;xZOu$U-1u_4gu6h(7B;^2=IaXdUmOCUS|BE400{(`oNU!= zPg09#jbbBqhXv&7A{U?fH<>f{f+ytF8$MvJs-G}p1DRx7h8Oxie$TA}Jqgg*y%%D_ zCviA(_|Y34-CD~U$*IS*Z)dq{1U`|{gYS>YENn5}!M@sZspVdu8BcUjF;Q22*{_L8 zizSl3_i9>u+e&{q^A2^9Yc8)31yVu(S-#||E^y6tE8 z^W1!otkVDz^f3RBislO_=P1Rm`2{yn!#FB;tan^rB@aSGjElnimd_22CCMdJJoQ0T zL%lO2Qz=kKo=JNw4=^CZ@mMAnTiE+kg8WzapgSTM@NRP_XfEQn!vEwx`5+w2p64)# z=~U_S3kuX>`IkB&#}SOoH4YXaQ!0X90KISGQ-jj^gS|#N$ z1wuPlS392wAyJp=a+gLWN+7aPeHxL)ChHm^-~44ojS@ZY#c}NzYHz2l$e^&L_^j;Y z#d=<+!-Cr05Em>eUtYc>ZY&Pf_1_z^F|bJTuTuD$k@ez%dEOhz8XlzT89nX`9?IVY zLbr_{8}s&6Q6Bt9X*zCukXswEF*Wb|ml)4*>!_fgGF&5pM*QEBCVkrvR+zxG601} zuj|?KCijH+z)e62e*gR4on6s?UEMjL0+l2G@Zqu(3Pu9~WtpIeE&Ti%t&5sk0I7UgC^~+aQGU+_& zUPS75i=Qzruj{owu28lw?k&o$kgp>ao${^~4J$3pLdLU?0;c&dPH(<1E9yN307NdxG9d9T!a7o{P~fKD*u_$Jcen)||ERIPLu znp38IU^a3XE>(u0ZjAC^bF0+(;Cxl%(=>ey>BGzP1aCBj|q9sfJ0R@5fA*0lZnT`cXC$(CU+BDksu1pqq*P}w~_P!U^Qh%OI&p) zHi_neeP(?)v3X!*a2`0Ye~_K!a`#(ffJTPNp-NVU^ssF%HGDeaAwE+LYcom#&eUT7 zXKh~2-cdoTg@EVW$1J0Z)oQ2gZ^Jv z_cd$fe+)$Os(6`nUwF1rBQiOh=BX&P0r&p`%Aqx$5H9m^#R)Fc*^puKBm z|MoM32dEjf<;#Aw)7Yx*A9DE1=e09O;n~3Em=abZg|P+5YNQtpOW=!ZvZrk)1bIhW z)R&w0JEc_v?%Z<5QZu^qq$Y=aFb$pW14M=oeCC1xtqdIp8r*xO9!sv2Uq#J0s?&hV zY7Nlfduxp-#I#=&I0R$UH$wY0IP_eDppsTg8*_QP$@&>FzymctE?mm+bw=JyI5c)q zB;B4L&}G$z!US)lBOu0_{P~3ZEQF^Z!DRH}d#1`zqgnzC^am{?_r2YkmbyKGpg4hV z%cq#XGl}>5hJa9xwUEDKGL%B#XgtefE}rUs%L2jZ4f`p8emiRt{>I4(^4h;MQv!<; zBsIXXGQk8L8$YW{)CVeYMGJRV&N#tQdAm9?17pyAdQvwaMfn8RihxF+KIMA^$}l`% zb&a5~-qpA8dz`*Y*G#9&$X$phScCB^{#OZqP@q;iI+ek_g@Y08{X?L}8^~)ie(UbA z=Nl0Ew=UAmdNnlymqYP^M)+ia*_a*N$r|#XxAX`xJvzP@+c zfgm+v4>1czlikrdUA=-0L<8O~0k6hY0MutQitb7?20l=1FYcXoC0IC~#HI#OdCk#I}F()Vno;uyTN(|&%#PkcNKSwm2Otw54}qNvWXlftdAh#&-M8ohLs7{K@ri_(8KhkR z;^VeIdY_p^+dwTB_eXs*5X|$opC+ZsE^&4G`H-exLZzDE%lRVrUz~e7U!5O<89HK( z*&W`UObznB9N-Z{-^n`=cJ`}$B?Q#hG+u$fsb}fl;K_Qtd~Xi>QJl{S_94bf-9I9} z2w(&ID6UY8sV4mXsy(3Xv~uFIKj7}UI=^yYx&`!S* zv@Qioy>-3$o8LX*`uQF(<@_xmJ(M3;)tAr5&md#u0vVNCzukae{VO{k+!RmheHe*Z zmJ~tg=ufZyw$ggcho%i9T6Iz&YT=zWx!f06SeT#Mv4YOkgy6){rk6>S%R4OnPkvEcCwW&;is z5GT3msG%06R#nS$KxwZ(iZ#}u{-FUQ#rn_8K8Mq+;a4*z@&`v)#yg(~b#36c8hlZdF(#|dGw!% zCh-P2#KsL67xac+FIg}6_1zt6{vnB}8X!a}6+O>kjBpF+6b1yqz{TOdoI7u8@eaJX zpyhY;PMjxV#JptIw;g?L@~P7%NiHysTlwOo;L?UuwJQaIaXWHZIX4K5x;nbsLjE|@ z0K3}9=L%e6w*pXr-=*aiE6^!jrzb!^l??79c2_^$(;OeVM>0a`z8@unCOz2hPD3!_xIIF#6l zpZ?HtyLLw@yoV_yz~=b-$ySUNK9j84EA?jvOk*Hv37La3E5?38F98gg;-C$0njEQp zOr+v@V8VTHJ>YZBk@%l;_y1hoIQFlrTfQPDB~E@wx8uEnS+?-qFME=iH8eBz_W>CU z>s2-*{)KlI0OA%;xfQzR94(R~=?hrYe1`=#Ik=A;TXs^>CcrkMIJBSOLdJvz&}TRt zcs}ic9j?Pq<=&~kK~i!bb_a;n9>g0{ZdnGQ3sfjcq^Qt!Z7AF$XmWJHXp8 zYqJu%RV!)mDfnX>n}0DfEaxLWra7|)p^dY8wqvpB6cIVp^0~g5m5mGQB@u82Ij_%CqfX_SSK_H!b`)$ckuOLRUibxks68z z;KY7%9k`Z@%+jB}D`9$LuB`Xy{Q7KBK`6TpPdN;|d_tQ=2{P>ACP}g@EeT__bqu?Ad`d z?vk4Cmho9(vPH!782>hY;o!x+Q2@b^cisBHr|`}a9_Wd`-CR6!($RI<<$OmtZ<)QO z1@TZSADV@C;R?#BX0K~FJZ|jq$)TuDSwVUIM-mW{n_H@)KJ~!j%`g= zkUd5wEBSJN=HIakdgO+B&yg18JQYTz${EU(885j}zhBSAxq2@RjslcuHSjdQL8Tu` zbPbHoeia78?+fdOM~UOQu5m|_b{c{bA5&zinVa4=R(9zy05AyTym>UfzUl<%j?Qa@ z@>9jNc`>eVLeO10cpv?>$&B|m5>Yjs9gw*UJ^ANk|EH(TKI;oUjj zt^VRH`2Xnf_~G2Ou~ZnYMNl>6uSvwT`D5#Ss=O{I(s zy4;>sjz@QJyN~_4?1ne6PELU5(K!{7qyR|k@1GN}JTm@jJu%j6q~O?2Q9|v#PUkNk zGMh7s+pTQCu<-eMV68A9Bb-?syEFIHdDi*SckdQp(}3XM_a%8uGw8XS8F|7zTvsC0 zyFD)t*}&sr*>J1=L_0mX<40OPBAn@D_owWR6OQdmz-|pF3f_9}ad+&XTqPMdIQj(% zj3LRP0Emg`&FUUjA{C1f+rlaLH(c+_*9m4cHLSyCBgwqmS|@5>)(pTzWUm{X^>mKx zLlc2ox|d1Z{k)o&{JtLEX%eHSrY z?@^hgT!Sn%u)#~_%hdbV5{mPOL8xxD^k4&DcgxF!A+uUXdS~6AKl**YvlT?esfO_N z_c=lnN*?vgUHBlsTQOYWSRJVv+g5FrfO-{)~eD zOj)miZ#*9D^B0VTyM1sGxfIzI1G)>th+4Z>9=Kf|rxFIrDSq$gy~*l+{KgnH2>Sv= zqWf$ofX@J#Jt)b%l?#vyaAyb zL3jHWN1nObmU}+n2oH2eeT1$J4@&o617{})pDqM>Hn;^)MxK%QaXc>$z&O?0@0zz) ztE0WetFb(~v;h0c^u{aS;Kl$L)?-vn&jnkj8`|C>_z2yIkjj`h$pc;VEw1FBe>aT; zsMP0)US2U~1p=|5fS1c4?D#WG10qBLq#q<16xaHrVf1 z-+x5zhb=5)7~LY2n>61G(4Y)~etGi`P$aYG7H(yTG9}TROz+72y+` z_`=VmaCa7Y8kFdlQLw7&KoYrZ9P5+T0aVt%n@|5quie)I3-f#74|{-{lz2xvS1-lu z>((<76@Kope}rdk<0sJ16%ILtXq+wae2~gD$UVMz2JqcQ}*+1AX zLZfLD6OD9JR-?EQ_x+|#9;vQ*k*o}b`4#==iG zEu4CwNN(%^uqxnbPl%O;0*sm|q<|4gXxN5p7}P@~jH`Yi+5{**%DMe$TqjUEUAZ@8 z!n>p$4>26g9x?ZZ_(1Qqg;7+(xUbQi;>QOAYleu`Kb-i9IyM9LVZB_TAE8T!^?3dU z{*)k|;05)erAMAqBaWot`u3ym!4?;f2~Dy2jm#GhNw865A$*^T2`J8D@#H0OHL9#o zEb;A^(E}E(A2r_9ZnAGC6+Dn2HX*mg8()5K%JgEs@0DvMG1$85;V>VW0c=TF`kspj z#Y6w6TUzM}VpWa*uwMX#Odi6TTi;zd zpc~~oJ4}Q{;R%BaIQFhd`~sX|4tq**8^P~Wo1{cT_SobiH^6DgS{(!#Yb4!0*lnca zftJk(zj2ZO887sgc_j=`-rEE~E45aZ1hvL2!|Nqjj=U`@5SXBwqGap&hXFVOtjix= zria&!>}}x7{C!+BP6RcF@Qpaa0Xt&JP!xfi*gCpl+W>GKF#f2SBM>l#y_~)mk|jRQ zwI?9=HbYEMVsJ1`hr62;?jhEs0OhcU@tkQYqG0Km&X>{ol<>p^$JpW(S>O~u7cRYt zKvMNr9a4xd!4wwQY`_#dId|{7`WKE7+g&H-7qo9CJmuD zo?DOlPM&YM@e=(flA6j;clu8G4~RX#3^6$vS}WcM>G7A`ZZ4vGfkyfQw8S^HR%D^T z3PVS(?GN=+tRhRJGU`J%ea5Skt?UGwz`H@I9LzlXjQ%*r@dDW&Nzb5Mk4d6ipT;IO zkurbE($f*x?>^rs5OIrR2h|OK&a~_I?-RZj6%l&| z=#Kr!xn8_0`2*}cqAyMkaScYn-QjeH_=73^LHSGtC>Wp!UMVlpDqe z=#7H>{V=m#c%jdK-@B3j$k<_^XFvYAx~Y40LKe+$3M}{F>W&n$rm#47cCWICFh^zg zlg%4OK$Nk4DR#UM$Mh~{!{Xdk%G1g9K9 z7hq!KM7O$yJe%{Qm%gRa1~^S+9q&~MHRbSL}=`ONiG z?VS1-kfd;3VYD8X&Z7nbm(jp2%oUKca0nuy7oK^iL=Fan=-#rrdanT5hK<3u*CK|P zRBaVy!LG8Y{)*lzyomf;!&m~pi%$(te_$6fAgug>Pi89DPup8Sjk~HlxJ$@Vz5*2E z3JMKa@-K{;d@4f&%GEr+ z4a35%2?9E>NBlCrmXTfJ72x=Bn;p72r@(l=1puNF`o||Q_=Zd)5VDkb7{8=n^DSua zf(|bDBG#3M?XdW~PES8(yK%em8)b;- zHWRRF{Tl~OLI8aL%GdwIl{7@P5Sz_sk3IC+qR{+bfI}Ef2hdqBPiELH`x_e13=nHj z1^&p$ze0lleyr3A+x+L=EuZcOy`|$N0shfn&_oySr=UT3wJ`E}7oKByPFDklqMYdc zl4ZpaM)A(dxeD!mdq9IbRNUS)AtW<+pWj^>mvZ4UsA({f{&jN)Zu`bp(gDROCC(%L z?v{|c$NsZYgm|C_M1}oBR=V^iI==G&&6XHogTKGqXF%Ogs^%1{QB(Y{JM6Vo z;K{mV6Gf-H6Y#aI9=#`rihRq+i|%N7n>SP<yv3w%_d5P+H|plLu|UikX#`?5Ltr zINFR+z}x0Sc!k>LbsCRaMSEv~!|0QJ^HSRovC&~hy}dsX)NEg`k2iZ@Q@FQ2U;u=Q zy8(hkd5dE$CwM8XFS)}89P=#`NHE*4Vh{n06Z~U{s(u%TU!lQHNl4TK0<7b((Kokm zVZzS&V5NBi6;Hn5WyDaRpD8eZQ9M6it7Cxe%MH z{9n;Pf^SCnI_fGpsK97j*583J>a-oSN0swYMR;D9T4_*Q6_|^ z5<_WT-klbnDzCZ)7oA6+Cqd?ZsN_>?FIQCYOGymBtE22Z>&PvL!q~b)>i-^^Xb0B( zv#eA;J}rhg2?x|H_2H?KCLIvnR3v9zC&mSn4t6JHqtxgr=_J6XD*+yXEbR^4+BnYd zv#~hrw!nY#wATMto6>G z{r*rvr9#zW!Ek} z=U1FLQGp-`49)l@$Cl~;h2UM_TLcQ+^* zV?+!^oHBYxqBoA8O+5F?#Lj}_Rja(Jo>pIj-?c_KC3mDw$49xjbJlqIK~wVF8-T(l z@S8;Tul$Pia#+h-8CXYWYPq>VlRM)j;ZASxgoID89J@(#np37XgQ z*eaSgoKJ!VVhq*A{WYM`eLQK1<(3-oyGH%MP#nDVuf_X}VV`*rD?%qGp z2~DNl>7CFGmxm=De3eA!n#IXogOkK6_I4cd5xGB49EiqUyY7Jr)&rIIh=%EpMNCdE2~FR?KQDOTJm5iGz12D;Qiu7h z`#RfQF~L+0ULks_5fI-ouJg{(r0yg?cCXE+I)eOo$W#CZ=n*QYMg5JsfKG#?_w}Vt zw~Nj$>N)N{Um0}U8n zkX8ocj;@C7o09@5ndKYWz`FbKtMK-IxbB^it2qP5gm141a)SfS05X2-P19>QZYT9E zIjaZ-uc^)0TewDH#`Q)VxXmNotKSd~3!EL**%$pq&2504ds4s(4v)x{JfezF#uMI{ z(a7LY`b?i!1z-746z$QuCLG0qvXY}y5#>U8kqg;vz(-|8_6%9F)f?gOP28V@3X`bS zev&u)DT?)ljr_V3WjQ|mwsbDcj|jpxKfH-+b2@AL&F(YKyW&kNXOmsqvF2X!Canm2 z@|V8p?mD|kKmQe){8M*Fi9I6H{!eJ~ZI78@NK&1Ne1W@LX#KRA2J=Y;aflG|fH>6K ztndmyy_x_uCbo#G>bg{JjTpaCi;lI$L;M^E1)2~^fByx=Q6K*SFZKHb;;GgKL%IF5 z3gN$;<^-YHy-(;4^Z2=ozUr1g0gxH!Cs|DpSOT-?rq}UIuNPhq-o0^I=KV9eomgu_ zwNJXMQSGE{$L-Tvb zw_PEo?(fojT`3}53Ng8}Pz$vZpPx4gkxqTkzf2_2m=E%K*nJzGw3=Qc#no)1xqiQE zEpPVoQ6C_Ys`;%9jo85?;0eOQ54GM0d|l>~2N+UVF0(^p-!ONFmks?UePlfAnvsc{ zTN4cYj8rW1>(=OL6BFgb z5%5p`&@{mQXM=Pgonv4i_};<0;w5kQ zR+ZCrIo|JTYZ&srqP^5RKif0*wLX* zFYl5Q!@bFpV|J;=k!mmI4NE2F$wQS4<1#cFoMml;5e7^vbSv{JkyvNTA5a-C=aB^A zHz2KQSvHYJMbQjpsCrcWaFY?oPk`m2eH6?80%^)Hp0+y2;s_wo^pr$@U_4+lM1nrja!t zIg~Zd&*O!$zX-N}<)ocLZOIa1m6pEahuBy5>*KM#?;FULhRfx=iFSRMYjGR}$RGGN zh5U=o6(Zow_3UO^4J)PQKQgu{sOVgU^u%KkoE_oE-wg zefK~p!;dqC>7az^o#5#$803su9R1nskMBnAD1jCej9Ok-fM4$es&?wuzDDvYoPN;z zk?HL@=lJakO{=>cJ?C^heTaRxQx304{d&&FrHRwWwXTLrM{gYzm7czuX5AXM&a=-9K#n@8|YcZNS zq?|J{MA45|{1e*pn13rzAjea8-8-&)6qkX3?@1^};18vH&E#s^pKOZ#Z&&$$PB(X& z{}Fg|ntfhGha{WgU}2kM=k*JZwLcPbo!`OR8t>|%iQk;nJMT_NaA67W#6$IR-Si7g zYHW6tNW|@ZVfve{EI_QsIe#+eerKIOlqN?+!qqJkG7nEB$9!%xt*@QplMJit>n;`p z8;9?(nY(Ehc>q~2|Pc~|&sYeVahKja(4i#^Tq(iF$ez87{kJ)zx?t^9d>nt2nNPb zFsYN~#kCG%uX8D*&)%CpP$)JpF#vf=;5&S81+Nd@rOq7@I)xj))uF$g6#iA7RbAk= zSV9f)-_@}dsHNPUvdhK5`C{9L{R(2_FzUv(_q74(*~4?p(EDCg{(BqGM*4-bATm&W zrzK*P2+fh(Ry-=$5z+ZLm%MVK(n%T(%937V;->E>10wYg_L7@(?`6t1Yr~X78~@A8 z-c7bD4>je{B5I%I_U^6HA#_=PTR*hHo8Hy=?|+_dJ^t1IobJUkNZvneZlAl?<8 zyo5LJNzsOg-`S7EsOgnXDVi|(*0HVy8Rqf4xo#}4*xB##BM%*kf=o2%5FZ;RRpW-s zo~0e&+^}20{fZM2L>oxRyTd!5ka~0#uytO=KL{4NBX?N)bj9)7^hqSXp+L*k04(Rh zr|?-d73YmZl2&~kkKdJO$1|enW6Lq7R8mzf)1!;3Szu)3>3Zr?h3Tf^RAa1y) z1^UQyFy@^79n1mgN76g|`Q?>Ap6DeL366)s#iyzRMHeY8Hr9TMjOyH zLY2a7UME05R!Px9QjA!nbk%&L3^VXNLM%jQGR?Q;gZj$A2+!3WIN{3t!}) z-Z3fK9h$wd!<$(tuHh)pKE}o$6<+aM@Oo_R==OFG_t$CPNml;AylPB|u8jFZ@O1Vc zS;11{^A-mTU_dv&o<08mJKd8f{^xYd>{&!&?Dd{*ME8u-eIaJ}?X@)@(ayhw<8YmM zGTd$wgplCNbLX92Xvh`h^%X&z&o^={2cg_Jrr)fqa@*YL-&~A!S0)7SR>DL3&L1yX z+=JD+jJ!VtV)VYM5=O6NH)7Hs7E7h$Xa;*<&jPi3+8RimABubyrg=n8$JQs_K~)?m z+4AywbTEiv=c z7{FxnG}t{nX}gWoun`SSn*t!lkd%o>dYcOT`dG=_25;CkWKz_o`|pQFm`OjTgV9i# z_xeE%{g78YF2aK|s_p&9Ny8hjhO9cKm%)1I<>!?S)KQ=4$`fP^!!oLA7V!eFQGMG# zo_UWsKM7U+L}$Ffw8(S6uZ$UVp51HL7yu#`IFBh@Jne*+vC_VO{d;2_YcDLh+y*n|v)`4Nt8nS_- z@hm8c?+!=L;%06xP9DhEd1M_A$8l-xp8KiO1Ks*qC0hnnIY+swH+_F?v93tb-y2s4#;J~Z# zQq21w@}ZUX(%&ZDF1&lZSK_OT0Exfu^0*n9Gl9Jdw@a@F48HH4{mRu7!0?BnKRVpZ z9>?=j&VCe$ncKK6YTnbOEi5PmPQrFuH$UJDx5H{cOg;Ij0_S zlNt%Nv}$d0c_0U#(U2t|biEfieA}k+tt~E>P}+Zdhb_3UrsH)=LP6*9Q)GJtt0ZiX zgjY*c53zQv+Y02hM;5YQ!NA5?$cB5j34c!B9)EaD7*AvmO6A8hLgTH|ZLma2_q>)S zfOFwL7ySSSd*UF}=a*fBBF|=>lKKV_Nmj->QStrG@AWx9~k7@=oP2$PQjR zIHVZnX)l-oAYJH$1d?CHA=Bpj+UV5o8dIEkG$UsWs0Ym;?bO#5pHjgLFvnvsG}PZXI9V_VNVEv1XrQPMFHoVD{a&i0QYsRrf(QEsMAtrDBHI4DCg5KaIF; zm&JWy?(Ix|__vWaeXxQiNRE8-a>t1$f_u@j(%A<4(2%Bc1a6k8OlO4X9A!Wd|3oQj zOs}pt3F| zNRs#8qkawJ^AV8Lb>9^(9Q3_rViP1uEgo_f0O#2LY%5?S7gvW6ONd&lgks z`vP@2AXElBKe7()A|g#0V-53rd=4ht1A67%zMhs6 z^SV+h=I=MLUKKgv-t~@j?H{Qx;krAPP>1Q}g?9K6YaMSW@X$xuVZ9U_YV{YY!%hE! z*wkkUQJbV`uT3=M)%DZgq50_jI>OX;X(KDicZSja-Vwd(``;s20NADjQhX(L=_a&G;ue1to-60dykGFxDtrF~i$DXOy`ct|Dz2GcKgpoo2TDid`hkyeG(VUcmYHhaqKqKi9A zm3ES-N&I!1$fXe@%T)5!Hd-hN4@J$i1x403xxpz=TPJ16&j!=oh{yei6xBiSc3j&W z>Ahcp#8ZAFF!wwqqxEL8)eIk;G1%{61qXk<>ULO5$NX#!ytjXMK5O)KzpH=EQc#901D`M9Yk|0~^ z!FzT!A5!`hnv&q$U;DC-ODC;=*A<~}GC5pIV*?z*AcqR+#X_+_o$WTwk%Aj%zvfRd zY>2~xfDIOdsKut8=TCdCm&H80T>L52Ea=gyaTX>{yK7?AkGzxN@RQCxG&|yS#?yT| zkmp1WgC~Jy7exEGDh!Esv)zz~L5+2Ti1j&i#qdxccgK%6&S8@<`xEuE)m_dn*mm8& z?koa*=L1WNiiI#H|N3{CEB;x*{r$b*QU}`X|Gldtt;Ai8_uk-O+3!Anr9C<9LDI6L zop>Ujg%r`Bte5YflQx}hndu<5a6f9_BiYe}wUhVMN`1SL>>K)ksC2P;0e;}kZ$~MdSE0;j0ttPYDikML;w`ZV_HOQM_DTf|INJiY~Vc&u#>jPQLxJ`7f1uC8U)eORpHi zIm#3|4D*XB1OTjhU>?Wr6-3FK^+8k>h|tJ}fPKK%k+qcaB(<%>?E+#tCOR)EJ=bR^ zrJ`&_a7i6W^e|hm-7_E6H8$5WQ-?N0n7oxtj!Hgl0%b2QHY0?7{ez$ReK(W~QciL? z5JUXf=m@s7QDu-Izc%);RtU$I$y@B(U+orD;YrP}dvZ&!#DemKeVTCS6(Enl%kKu` zM*L%HQ~K@;yN^>)?_i)ufOq|{LS}m~u4}l}JP1|~jBo5D5L!=qK-_nr1ozn`Slixr z0RZ0iE-t($getrJ=`bax)pY*hXLP0X^Lk}-<}GmT4)vzQqH5ejiQZ}0))8`?V}J7R pe-r Date: Sun, 2 May 2021 00:34:19 +0200 Subject: [PATCH 13/86] apt: fix keyring permissions --- apt/tasks/evolix_public.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/apt/tasks/evolix_public.yml b/apt/tasks/evolix_public.yml index 09b6954d..1815f08e 100644 --- a/apt/tasks/evolix_public.yml +++ b/apt/tasks/evolix_public.yml @@ -6,6 +6,7 @@ src: reg.gpg dest: /usr/share/keyrings/reg.gpg force: yes + mode: "0644" tags: - apt From 43c726e86a5e0cac43e090850c30bad154c7eb0f Mon Sep 17 00:00:00 2001 From: Jeremy Lecour Date: Sun, 2 May 2021 01:22:57 +0200 Subject: [PATCH 14/86] spamassassin: change dependency on evomaintenance Fail with an error if evomaintenance config is missing instead of trying to install a package that doesn't exist anymore. --- CHANGELOG.md | 2 ++ spamassasin/tasks/main.yml | 12 +++++++++++- 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9a88ba44..79a38b83 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -21,6 +21,8 @@ The **patch** part changes incrementally at each release. * evolinux-base: copy GPG key instead of using apt-key * ntpd: Add leapfile configuration setting to ntpd on debian 10+ +* spamassassin: change dependency on evomaintenance +* squid: remove obsolete variable on Squid 4 ### Fixed diff --git a/spamassasin/tasks/main.yml b/spamassasin/tasks/main.yml index 53c6725b..5c46a65b 100644 --- a/spamassasin/tasks/main.yml +++ b/spamassasin/tasks/main.yml @@ -3,7 +3,6 @@ apt: name: - spamassassin - - evomaintenance state: present tags: - spamassassin @@ -47,6 +46,17 @@ tags: - spamassassin +- name: Check evomaintenance config + stat: + path: /etc/evomaintenance.cf + register: _evomaintenance_config + +- name: Verify sa-update dependency + assert: + that: + - _evomaintenance_config.stat.exists + msg: sa-update.sh needs /etc/evomaintenance.cf + - name: copy sa-update.sh script copy: src: sa-update.sh From 6eaeb90f6e6d50f6c336ba24246662054fa6c9ae Mon Sep 17 00:00:00 2001 From: Jeremy Lecour Date: Sun, 2 May 2021 23:28:09 +0200 Subject: [PATCH 15/86] ldap: fix edge cases where passwords were not set/get properly --- CHANGELOG.md | 2 + ldap/defaults/main.yml | 7 ++- ldap/tasks/init.yml | 32 ++++++++++++ ldap/tasks/ldapvirc.yml | 62 +++++++++++++++++++++++ ldap/tasks/main.yml | 100 ++++--------------------------------- ldap/tasks/nagios.yml | 74 +++++++++++++++++++++++++++ ldap/templates/ldapvirc.j2 | 2 +- 7 files changed, 186 insertions(+), 93 deletions(-) create mode 100644 ldap/tasks/init.yml create mode 100644 ldap/tasks/ldapvirc.yml create mode 100644 ldap/tasks/nagios.yml diff --git a/CHANGELOG.md b/CHANGELOG.md index 79a38b83..7aed1413 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -26,6 +26,8 @@ The **patch** part changes incrementally at each release. ### Fixed +* ldap: fix edge cases where passwords were not set/get properly + ### Removed ### Security diff --git a/ldap/defaults/main.yml b/ldap/defaults/main.yml index 450c7a6c..29c51244 100644 --- a/ldap/defaults/main.yml +++ b/ldap/defaults/main.yml @@ -1,5 +1,10 @@ --- -ldap_hostname: "{{ ansible_hostname }}" + ldap_listen: "ldap://127.0.0.1:389/" + +ldap_hostname: "{{ ansible_hostname }}" ldap_domain: "{{ ansible_domain }}" ldap_suffix: "dc={{ ldap_hostname }},dc={{ ldap_domain.split('.')[-2] }},dc={{ ldap_domain.split('.')[-1] }}" + +ldap_admin_password: "" +ldap_nagios_password: "" \ No newline at end of file diff --git a/ldap/tasks/init.yml b/ldap/tasks/init.yml new file mode 100644 index 00000000..16be0842 --- /dev/null +++ b/ldap/tasks/init.yml @@ -0,0 +1,32 @@ +--- + +- name: upload ldap initial config + template: + src: config_ldapvi.j2 + dest: /root/evolinux_ldap_config.ldapvi + mode: "0640" + +- name: upload ldap initial entries + template: + src: first-entries.ldif.j2 + dest: /root/evolinux_ldap_first-entries.ldif + mode: "0640" + +- name: inject config + command: ldapvi -Y EXTERNAL -h ldapi:// --ldapmodify /root/evolinux_ldap_config.ldapvi + environment: + TERM: xterm + +- name: inject first entries + command: slapadd -l /root/evolinux_ldap_first-entries.ldif + +- name: upload custom schema + copy: + src: "{{ ldap_schema }}" + dest: "/root/{{ ldap_schema }}" + mode: "0640" + when: ldap_schema is defined + +- name: inject custom schema + command: "ldapadd -Y EXTERNAL -H ldapi:/// -f /root/{{ ldap_schema }}" + when: ldap_schema is defined \ No newline at end of file diff --git a/ldap/tasks/ldapvirc.yml b/ldap/tasks/ldapvirc.yml new file mode 100644 index 00000000..06f9199d --- /dev/null +++ b/ldap/tasks/ldapvirc.yml @@ -0,0 +1,62 @@ +--- + +- name: "Is /root/.ldapvirc present ?" + stat: + path: /root/.ldapvirc + check_mode: no + register: root_ldapvirc_path + +- name: Warning when ldapvirc file is present and ldap_admin_password is given + debug: + msg: "WARNING: an LDAP admin password is given, but an ldapvirc file already exists. It will not be updated." + when: + - ldap_admin_password != "" + - root_ldapvirc_path.stat.exists + +# Generate ldap password if none is given and ldapvirc is absent +- name: apg package is installed + apt: + name: apg + state: present + when: not root_ldapvirc_path.stat.exists + +- name: create a password for cn=admin + command: "apg -n 1 -m 16 -M lcN" + register: new_ldap_admin_password + changed_when: False + when: + - ldap_admin_password == "" + - not root_ldapvirc_path.stat.exists + +# Use the generated password or the one found in the file +- name: overwrite ldap_admin_password + set_fact: + ldap_admin_password: "{{ new_ldap_admin_password.stdout }}" + when: + - ldap_admin_password == "" + - not root_ldapvirc_path.stat.exists + +- name: hash password for cn=admin + command: "slappasswd -s {{ ldap_admin_password }}" + register: ldap_admin_password_ssha + changed_when: False + when: not root_ldapvirc_path.stat.exists + +- name: create ldapvirc config + template: + src: ldapvirc.j2 + dest: /root/.ldapvirc + mode: "0640" + when: not root_ldapvirc_path.stat.exists + +# Read ldap password when none is given and ldapvirc is present +- name: read ldap admin password from ldapvirc file + shell: "grep -E '^password: .+$' /root/.ldapvirc | awk '{print $2}'" + changed_when: False + check_mode: no + register: new_ldap_admin_password + +# Use the password found in the file +- name: overwrite ldap_admin_password + set_fact: + ldap_admin_password: "{{ new_ldap_admin_password.stdout }}" diff --git a/ldap/tasks/main.yml b/ldap/tasks/main.yml index 8f6fbd67..9bfb6517 100644 --- a/ldap/tasks/main.yml +++ b/ldap/tasks/main.yml @@ -6,103 +6,21 @@ - ldapvi - shelldap state: present + update_cache: yes -- name: change sldap listen ip:port +- name: change slapd listen ip:port lineinfile: dest: /etc/default/slapd regexp: 'SLAPD_SERVICES=.*' line: "SLAPD_SERVICES=\"{{ ldap_listen }}\"" notify: restart slapd -- name: "Is /root/.ldapvirc present ?" - stat: - path: /root/.ldapvirc - check_mode: no - register: root_ldapvirc_path +- name: ldapvirc file + include: ldapvirc.yml -- name: apg package is installed - apt: - name: apg - state: present - when: not root_ldapvirc_path.stat.exists +- name: nagios config file for LDAP + include: nagios.yml -- name: create a password for cn=admin - command: "apg -n 1 -m 16 -M lcN" - register: ldap_admin_password - changed_when: False - when: not root_ldapvirc_path.stat.exists - -- name: create a password for cn=nagios - command: "apg -n 1 -m 16 -M lcN" - register: ldap_nagios_password - changed_when: False - when: not root_ldapvirc_path.stat.exists - -- name: hash password for cn=admin - command: "slappasswd -s {{ ldap_admin_password.stdout }}" - register: ldap_admin_password_ssha - changed_when: False - when: not root_ldapvirc_path.stat.exists - -- name: hash password for cn=nagios - command: "slappasswd -s {{ ldap_nagios_password.stdout }}" - register: ldap_nagios_password_ssha - changed_when: False - when: not root_ldapvirc_path.stat.exists - -- name: create ldapvirc config - template: - src: ldapvirc.j2 - dest: /root/.ldapvirc - mode: "0640" - when: not root_ldapvirc_path.stat.exists - -- name: set params for NRPE check - ini_file: - dest: /etc/nagios/monitoring-plugins.ini - owner: root - group: nagios - section: check_ldap - option: "{{ item.option }}" - value: "{{ item.value }}" - mode: 0640 - with_items: - - { option: 'hostname', value: '127.0.0.1' } - - { option: 'base', value: "{{ ldap_suffix }}" } - - { option: 'bind', value: "cn=nagios,ou=ldapusers,{{ ldap_suffix }}" } - - { option: 'pass', value: "{{ ldap_nagios_password.stdout }}" } - -- name: upload ldap initial config - template: - src: config_ldapvi.j2 - dest: /root/evolinux_ldap_config.ldapvi - mode: "0640" - when: not root_ldapvirc_path.stat.exists - -- name: upload ldap initial entries - template: - src: first-entries.ldif.j2 - dest: /root/evolinux_ldap_first-entries.ldif - mode: "0640" - when: not root_ldapvirc_path.stat.exists - -- name: inject config - command: ldapvi -Y EXTERNAL -h ldapi:// --ldapmodify /root/evolinux_ldap_config.ldapvi - environment: - TERM: xterm - when: not root_ldapvirc_path.stat.exists - -- name: inject first entries - command: slapadd -l /root/evolinux_ldap_first-entries.ldif - when: not root_ldapvirc_path.stat.exists - -- name: upload custom schema - copy: - src: "{{ ldap_schema }}" - dest: "/root/{{ ldap_schema }}" - mode: "0640" - when: not root_ldapvirc_path.stat.exists and ldap_schema is defined - -- name: inject custom schema - command: "ldapadd -Y EXTERNAL -H ldapi:/// -f /root/{{ ldap_schema }}" - when: not root_ldapvirc_path.stat.exists and ldap_schema is defined +- name: initialize database + include: init.yml + when: not root_ldapvirc_path.stat.exists \ No newline at end of file diff --git a/ldap/tasks/nagios.yml b/ldap/tasks/nagios.yml new file mode 100644 index 00000000..a9cb5751 --- /dev/null +++ b/ldap/tasks/nagios.yml @@ -0,0 +1,74 @@ +--- + +- name: "Is /etc/nagios/monitoring-plugins.ini present ?" + stat: + path: /etc/nagios/monitoring-plugins.ini + check_mode: no + register: nagios_monitoring_plugins_path + +- name: Warning when nagios config is present and ldap_nagios_password is given + debug: + msg: "WARNING: an LDAP nagios password is given, but a nagios config already exists. It will not be updated." + when: + - ldap_nagios_password != "" + - nagios_monitoring_plugins_path.stat.exists + +# Generate ldap password if none is given and nagios config is absent +- name: apg package is installed + apt: + name: apg + state: present + when: + - ldap_nagios_password == "" + - not nagios_monitoring_plugins_path.stat.exists + +- name: create a password for cn=admin + command: "apg -n 1 -m 16 -M lcN" + register: new_ldap_nagios_password + changed_when: False + when: + - ldap_nagios_password == "" + - not nagios_monitoring_plugins_path.stat.exists + +# Use the generated password or the one found in the file +- name: overwrite ldap_nagios_password (from apg) + set_fact: + ldap_nagios_password: "{{ new_ldap_nagios_password.stdout }}" + when: + - ldap_nagios_password == "" + - not nagios_monitoring_plugins_path.stat.exists + +- name: set params for NRPE check + ini_file: + dest: /etc/nagios/monitoring-plugins.ini + owner: root + group: nagios + section: check_ldap + option: "{{ item.option }}" + value: "{{ item.value }}" + mode: "0640" + with_items: + - { option: 'hostname', value: '127.0.0.1' } + - { option: 'base', value: "{{ ldap_suffix }}" } + - { option: 'bind', value: "cn=nagios,ou=ldapusers,{{ ldap_suffix }}" } + - { option: 'pass', value: "{{ ldap_nagios_password }}" } + when: not nagios_monitoring_plugins_path.stat.exists + +# Read ldap password when none is given and nagios config is present +# We can't parse a remote file, so we have to fetch it first +- name: Fetch /etc/nagios/monitoring-plugins.ini + fetch: + src: /etc/nagios/monitoring-plugins.ini + dest: /tmp/{{ inventory_hostname }}/ + flat: yes + +# Then web can parse it with the 'ini' lookup +# and set the variable +- name: overwrite ldap_nagios_password (from file) + set_fact: + ldap_nagios_password: "{{ lookup('ini', 'pass section=check_ldap file=/tmp/{{ inventory_hostname }}/etc/nagios/monitoring-plugins.ini') }}" + +- name: hash password for cn=nagios + command: "slappasswd -s {{ ldap_nagios_password }}" + register: ldap_nagios_password_ssha + changed_when: False \ No newline at end of file diff --git a/ldap/templates/ldapvirc.j2 b/ldap/templates/ldapvirc.j2 index e61a7524..53ece952 100644 --- a/ldap/templates/ldapvirc.j2 +++ b/ldap/templates/ldapvirc.j2 @@ -3,4 +3,4 @@ host: ldap://127.0.0.1 base: {{ ldap_suffix }} user: cn=admin,{{ ldap_suffix }} bind: simple -password: {{ ldap_admin_password.stdout }} +password: {{ ldap_admin_password }} From cc6acdbf34f3e2fab11d7fb0dba8d88a9ed9c038 Mon Sep 17 00:00:00 2001 From: Jeremy Lecour Date: Mon, 3 May 2021 11:25:24 +0200 Subject: [PATCH 16/86] certbot: sync_remote.sh is configurable --- CHANGELOG.md | 1 + certbot/files/hooks/sync_remote.sh | 34 ++++++++++++++++++++---------- 2 files changed, 24 insertions(+), 11 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7aed1413..d81eb470 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -21,6 +21,7 @@ The **patch** part changes incrementally at each release. * evolinux-base: copy GPG key instead of using apt-key * ntpd: Add leapfile configuration setting to ntpd on debian 10+ +* certbot: sync_remote.sh is configurable * spamassassin: change dependency on evomaintenance * squid: remove obsolete variable on Squid 4 diff --git a/certbot/files/hooks/sync_remote.sh b/certbot/files/hooks/sync_remote.sh index d041f895..a06c728c 100644 --- a/certbot/files/hooks/sync_remote.sh +++ b/certbot/files/hooks/sync_remote.sh @@ -29,20 +29,22 @@ main() { if found_renewed_lineage; then RENEWED_DOMAINS=${RENEWED_DOMAINS:-$(domain_from_cert)} - remore_lineage=${remote_dir}/renewed_lineage/$(basename ${RENEWED_LINEAGE}) + remote_lineage=${remote_dir}/renewed_lineage/$(basename "${RENEWED_LINEAGE}") for server in ${servers}; do remote_host="root@${server}" - ssh ${remote_host} "mkdir -p ${remote_dir}" \ + # shellcheck disable=SC2029 + ssh "${remote_host}" "mkdir -p ${remote_dir}" \ || error "Couldn't create ${remote_dir} directory ${server}" - rsync --archive --copy-links --delete ${RENEWED_LINEAGE}/ ${remote_host}:${remore_lineage}/ \ + rsync --archive --copy-links --delete "${RENEWED_LINEAGE}/" "${remote_host}:${remote_lineage}/" \ || error "Couldn't sync certificate on ${server}" - rsync --archive --copy-links --delete --exclude $0 --delete-excluded ${hooks_dir}/ ${remote_host}:${remote_dir}/hooks/ \ + rsync --archive --copy-links --delete --exclude $0 --delete-excluded "${hooks_dir}/" "${remote_host}:${remote_dir}/hooks/" \ || error "Couldn't sync hooks on ${server}" - ssh ${remote_host} "export RENEWED_LINEAGE=\"${remore_lineage}/\" RENEWED_DOMAINS=${RENEWED_DOMAINS}; find ${remote_dir}/hooks/ -mindepth 1 -maxdepth 1 -type f -executable -exec {} \;" \ + # shellcheck disable=SC2029 + ssh "${remote_host}" "export RENEWED_LINEAGE=\"${remote_lineage}/\" RENEWED_DOMAINS=${RENEWED_DOMAINS}; find ${remote_dir}/hooks/ -mindepth 1 -maxdepth 1 -type f -executable -exec {} \;" \ || error "Something went wrong on ${server} for deploy hooks" done else @@ -50,13 +52,23 @@ main() { fi } -readonly PROGNAME=$(basename "$0") -readonly VERBOSE=${VERBOSE:-"0"} -readonly QUIET=${QUIET:-"0"} +PROGNAME=$(basename "$0") +VERBOSE=${VERBOSE:-"0"} +QUIET=${QUIET:-"0"} -readonly hooks_dir="/etc/letsencrypt/renewal-hooks/deploy" -readonly remote_dir="/root/cert_sync" +hooks_dir="/etc/letsencrypt/renewal-hooks/deploy" +# The config file lust have the same name as the script, with a different extension (.cf instead of .sh) +config_file="${0%.*}.cf" +remote_dir="/root/cert_sync" -readonly servers="" +if [ -f "${config_file}" ]; then + . "${config_file}" +fi +servers=${servers:-""} + +if [ -z "${servers}" ]; then + echo "${PROGNAME}: No server provided. Skip." >&2 + exit 0 +fi main From 1caae2437a2f63bee55a89afa4517a90ca3b9f3a Mon Sep 17 00:00:00 2001 From: Jeremy Lecour Date: Mon, 3 May 2021 11:44:44 +0200 Subject: [PATCH 17/86] certbot: fix remote directory initialization --- certbot/files/hooks/sync_remote.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/certbot/files/hooks/sync_remote.sh b/certbot/files/hooks/sync_remote.sh index a06c728c..08006b38 100644 --- a/certbot/files/hooks/sync_remote.sh +++ b/certbot/files/hooks/sync_remote.sh @@ -34,7 +34,7 @@ main() { for server in ${servers}; do remote_host="root@${server}" # shellcheck disable=SC2029 - ssh "${remote_host}" "mkdir -p ${remote_dir}" \ + ssh "${remote_host}" "mkdir -p ${remote_lineage}" \ || error "Couldn't create ${remote_dir} directory ${server}" rsync --archive --copy-links --delete "${RENEWED_LINEAGE}/" "${remote_host}:${remote_lineage}/" \ From 92f28d85fec255fdfab55ba19153a07d09c8629b Mon Sep 17 00:00:00 2001 From: Jeremy Lecour Date: Mon, 3 May 2021 11:44:59 +0200 Subject: [PATCH 18/86] certbot: configure remote servers --- certbot/defaults/main.yml | 2 ++ certbot/tasks/main.yml | 7 +++++++ 2 files changed, 9 insertions(+) diff --git a/certbot/defaults/main.yml b/certbot/defaults/main.yml index 99f02e15..2d198b43 100644 --- a/certbot/defaults/main.yml +++ b/certbot/defaults/main.yml @@ -2,3 +2,5 @@ certbot_work_dir: /var/lib/letsencrypt certbot_custom_crontab: True + +certbot_hooks_sync_remote_servers: [] \ No newline at end of file diff --git a/certbot/tasks/main.yml b/certbot/tasks/main.yml index 54c1f803..0e65beda 100644 --- a/certbot/tasks/main.yml +++ b/certbot/tasks/main.yml @@ -29,6 +29,13 @@ owner: root group: root +- name: "sync_remote is configured with servers" + lineinfile: + dest: /etc/letsencrypt/renewal-hooks/deploy/sync_remote.cf + regexp: "^servers\b" + line: "servers=\"{{ certbot_hooks_sync_remote_servers | join(' ') }}\"" + create: yes + - name: Move commit-etc.sh to z-commit-etc.sh if present command: "mv /etc/letsencrypt/renewal-hooks/deploy/commit-etc.sh /etc/letsencrypt/renewal-hooks/deploy/z-commit-etc.sh" args: From a7971abb047cd8a2164bc8338aacd14c4ba840aa Mon Sep 17 00:00:00 2001 From: Jeremy Lecour Date: Mon, 3 May 2021 12:02:04 +0200 Subject: [PATCH 19/86] apt: store keys in /etc/apt/trusted.gpg.d in ascii format --- CHANGELOG.md | 1 + apt/tasks/evolix_public.yml | 4 ++-- apt/templates/evolix_public.list.j2 | 2 +- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d81eb470..2390187a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -19,6 +19,7 @@ The **patch** part changes incrementally at each release. ### Changed +* apt: store keys in /etc/apt/trusted.gpg.d in ascii format * evolinux-base: copy GPG key instead of using apt-key * ntpd: Add leapfile configuration setting to ntpd on debian 10+ * certbot: sync_remote.sh is configurable diff --git a/apt/tasks/evolix_public.yml b/apt/tasks/evolix_public.yml index 1815f08e..d6822f28 100644 --- a/apt/tasks/evolix_public.yml +++ b/apt/tasks/evolix_public.yml @@ -3,8 +3,8 @@ # https://wiki.debian.org/DebianRepository/UseThirdParty - name: Add Evolix GPG key copy: - src: reg.gpg - dest: /usr/share/keyrings/reg.gpg + src: reg.asc + dest: /etc/apt/trusted.gpg.d/reg.asc force: yes mode: "0644" tags: diff --git a/apt/templates/evolix_public.list.j2 b/apt/templates/evolix_public.list.j2 index 72127536..06de99c0 100644 --- a/apt/templates/evolix_public.list.j2 +++ b/apt/templates/evolix_public.list.j2 @@ -1,3 +1,3 @@ # {{ ansible_managed }} -deb [signed-by=/usr/share/keyrings/reg.gpg] http://pub.evolix.net/ {{ ansible_distribution_release }}/ +deb http://pub.evolix.net/ {{ ansible_distribution_release }}/ From 9cdddd50a83eba79e63953d037d75f86312b94c3 Mon Sep 17 00:00:00 2001 From: Jeremy Lecour Date: Mon, 3 May 2021 14:23:13 +0200 Subject: [PATCH 20/86] Move all trusted GPG keys to file repository --- apt/tasks/evolix_public.yml | 8 +- .../{docker-debian.gpg => docker-debian.asc} | 0 docker-host/tasks/main.yml | 8 +- .../files/{elasticsearch.key => elastic.asc} | 0 elasticsearch/tasks/packages.yml | 17 +- ...048_key1.pub => hpePublicKey2048_key1.asc} | 0 ...ert.net.gpg.key => hwraid.le-vert.net.asc} | 0 evolinux-base/tasks/hardware.yml | 27 +- filebeat/tasks/main.yml | 17 +- fluentd/files/{fluentd.gpg => fluentd.asc} | 0 fluentd/tasks/main.yml | 16 +- jenkins/files/{jenkins.key => jenkins.asc} | 0 jenkins/tasks/main.yml | 13 +- kibana/tasks/main.yml | 17 +- logstash/tasks/main.yml | 17 +- metricbeat/tasks/main.yml | 17 +- mongodb/tasks/main_buster.yml | 13 +- newrelic/files/{548C16BF.gpg => newrelic.asc} | 0 newrelic/tasks/sources.yml | 13 +- .../{nodesource.gpg.key => nodesource.asc} | 0 nodejs/files/{yarnpkg.gpg.key => yarnpkg.asc} | 486 +++++++++--------- nodejs/tasks/main.yml | 15 +- nodejs/tasks/yarn.yml | 16 +- percona/tasks/main.yml | 12 +- postgresql/files/{ACCC4CF8.asc => pgdg.asc} | 0 postgresql/tasks/pgdg-repo.yml | 13 +- 26 files changed, 429 insertions(+), 296 deletions(-) rename docker-host/files/{docker-debian.gpg => docker-debian.asc} (100%) rename elasticsearch/files/{elasticsearch.key => elastic.asc} (100%) rename evolinux-base/files/{hpePublicKey2048_key1.pub => hpePublicKey2048_key1.asc} (100%) rename evolinux-base/files/{hwraid.le-vert.net.gpg.key => hwraid.le-vert.net.asc} (100%) rename fluentd/files/{fluentd.gpg => fluentd.asc} (100%) rename jenkins/files/{jenkins.key => jenkins.asc} (100%) rename newrelic/files/{548C16BF.gpg => newrelic.asc} (100%) rename nodejs/files/{nodesource.gpg.key => nodesource.asc} (100%) rename nodejs/files/{yarnpkg.gpg.key => yarnpkg.asc} (98%) rename postgresql/files/{ACCC4CF8.asc => pgdg.asc} (100%) diff --git a/apt/tasks/evolix_public.yml b/apt/tasks/evolix_public.yml index d6822f28..be7baad8 100644 --- a/apt/tasks/evolix_public.yml +++ b/apt/tasks/evolix_public.yml @@ -1,6 +1,12 @@ --- -# https://wiki.debian.org/DebianRepository/UseThirdParty +- name: Evolix GPG embedded key is absent + apt_key: + id: "B8612B5D" + state: absent + tags: + - apt + - name: Add Evolix GPG key copy: src: reg.asc diff --git a/docker-host/files/docker-debian.gpg b/docker-host/files/docker-debian.asc similarity index 100% rename from docker-host/files/docker-debian.gpg rename to docker-host/files/docker-debian.asc diff --git a/docker-host/tasks/main.yml b/docker-host/tasks/main.yml index 9a66bb92..437de2a4 100644 --- a/docker-host/tasks/main.yml +++ b/docker-host/tasks/main.yml @@ -28,9 +28,11 @@ when: ansible_distribution_release == 'jessie' - name: Add Docker's official GPG key - apt_key: - #url: https://download.docker.com/linux/debian/gpg - data: "{{ lookup('file', 'docker-debian.gpg') }}" + copy: + src: docker-debian.asc + dest: /etc/apt/trusted.gpg.d/docker-debian.asc + force: yes + mode: "0644" - name: Install docker and python-docker apt: diff --git a/elasticsearch/files/elasticsearch.key b/elasticsearch/files/elastic.asc similarity index 100% rename from elasticsearch/files/elasticsearch.key rename to elasticsearch/files/elastic.asc diff --git a/elasticsearch/tasks/packages.yml b/elasticsearch/tasks/packages.yml index 1a0ad8dc..d5d91231 100644 --- a/elasticsearch/tasks/packages.yml +++ b/elasticsearch/tasks/packages.yml @@ -8,11 +8,20 @@ - elasticsearch - packages -- name: Elastic GPG key is installed +- name: Elastic GPG embedded key is absent apt_key: - # url: https://artifacts.elastic.co/GPG-KEY-elasticsearch - data: "{{ lookup('file', 'elasticsearch.key') }}" - state: present + id: "D88E42B4" + state: absent + tags: + - elasticsearch + - packages + +- name: Elastic GPG key is installed + copy: + src: elastic.asc + dest: /etc/apt/trusted.gpg.d/elastic.asc + force: yes + mode: "0644" tags: - elasticsearch - packages diff --git a/evolinux-base/files/hpePublicKey2048_key1.pub b/evolinux-base/files/hpePublicKey2048_key1.asc similarity index 100% rename from evolinux-base/files/hpePublicKey2048_key1.pub rename to evolinux-base/files/hpePublicKey2048_key1.asc diff --git a/evolinux-base/files/hwraid.le-vert.net.gpg.key b/evolinux-base/files/hwraid.le-vert.net.asc similarity index 100% rename from evolinux-base/files/hwraid.le-vert.net.gpg.key rename to evolinux-base/files/hwraid.le-vert.net.asc diff --git a/evolinux-base/tasks/hardware.yml b/evolinux-base/tasks/hardware.yml index c44c1248..832124bd 100644 --- a/evolinux-base/tasks/hardware.yml +++ b/evolinux-base/tasks/hardware.yml @@ -37,10 +37,17 @@ - name: HPE Smart Storage Administrator (ssacli) is present block: - - name: Add HPE GPG key + - name: HPE GPG is absent in embedded database apt_key: - #url: https://downloads.linux.hpe.com/SDR/hpePublicKey2048_key1.pub - data: "{{ lookup('file', 'hpePublicKey2048_key1.pub') }}" + id: "26C2B797" + state: absent + + - name: HPE GPG key is installed + copy: + src: hpePublicKey2048_key1.asc + dest: /etc/apt/trusted.gpg.d/hpePublicKey2048_key1.asc + force: yes + mode: "0644" - name: Add HPE repository apt_repository: @@ -93,10 +100,18 @@ - name: MegaRAID SAS package is present block: - - name: Add HW tool GPG key + - name: HWRaid GPG embedded key is absent apt_key: - # url: https://hwraid.le-vert.net/debian/hwraid.le-vert.net.gpg.key - data: "{{ lookup('file', 'hwraid.le-vert.net.gpg.key') }}" + id: "23B3D3B4" + state: absent + when: ansible_distribution_major_version is version('9', '>=') + + - name: HWRaid GPG key is installed + copy: + src: hwraid.le-vert.net.asc + dest: /etc/apt/trusted.gpg.d/hwraid.le-vert.net.asc + force: yes + mode: "0644" when: ansible_distribution_major_version is version('9', '>=') - name: Add HW tool repository diff --git a/filebeat/tasks/main.yml b/filebeat/tasks/main.yml index a19848e8..c86e0e63 100644 --- a/filebeat/tasks/main.yml +++ b/filebeat/tasks/main.yml @@ -8,11 +8,20 @@ - filebeat - packages -- name: Elastic GPG key is installed +- name: Elastic GPG embedded key is absent apt_key: - # url: https://artifacts.elastic.co/GPG-KEY-elasticsearch - data: "{{ lookup('file', 'elasticsearch.key') }}" - state: present + id: "D88E42B4" + state: absent + tags: + - filebeat + - packages + +- name: Elastic GPG key is installed + copy: + src: elastic.asc + dest: /etc/apt/trusted.gpg.d/elastic.asc + force: yes + mode: "0644" tags: - filebeat - packages diff --git a/fluentd/files/fluentd.gpg b/fluentd/files/fluentd.asc similarity index 100% rename from fluentd/files/fluentd.gpg rename to fluentd/files/fluentd.asc diff --git a/fluentd/tasks/main.yml b/fluentd/tasks/main.yml index 41c532d1..f66a072c 100644 --- a/fluentd/tasks/main.yml +++ b/fluentd/tasks/main.yml @@ -1,9 +1,19 @@ --- -- name: Fluentd GPG key is installed +- name: Fluentd GPG embedded key is absent apt_key: - # url: https://packages.treasuredata.com/GPG-KEY-td-agent - data: "{{ lookup('file', 'fluentd.gpg') }}" + id: "AB97ACBE" + state: absent + tags: + - packages + - fluentd + +- name: Add Fluentd GPG key + copy: + src: fluentd.asc + dest: /etc/apt/trusted.gpg.d/fluentd.asc + force: yes + mode: "0644" tags: - packages - fluentd diff --git a/jenkins/files/jenkins.key b/jenkins/files/jenkins.asc similarity index 100% rename from jenkins/files/jenkins.key rename to jenkins/files/jenkins.asc diff --git a/jenkins/tasks/main.yml b/jenkins/tasks/main.yml index a2e7c0aa..9221138e 100644 --- a/jenkins/tasks/main.yml +++ b/jenkins/tasks/main.yml @@ -5,10 +5,17 @@ # http://mirrors.jenkins.io/.* # http://jenkins.mirror.isppower.de/.* -- name: Add jenkins GPG key +- name: Jenkins GPG embedded key is absent apt_key: - # url: https://jenkins-ci.org/debian/jenkins-ci.org.key - data: "{{ lookup('file', 'jenkins.key') }}" + id: "D50582E6" + state: absent + +- name: Add Jenkins GPG key + copy: + src: jenkins.asc + dest: /etc/apt/trusted.gpg.d/jenkins.asc + force: yes + mode: "0644" - name: Add jenkins APT repository apt_repository: diff --git a/kibana/tasks/main.yml b/kibana/tasks/main.yml index 46fbe980..b32fea15 100644 --- a/kibana/tasks/main.yml +++ b/kibana/tasks/main.yml @@ -8,11 +8,20 @@ - kibana - packages -- name: Elastic GPG key is installed +- name: Elastic GPG embedded key is absent apt_key: - # url: https://artifacts.elastic.co/GPG-KEY-elasticsearch - data: "{{ lookup('file', 'elasticsearch.key') }}" - state: present + id: "D88E42B4" + state: absent + tags: + - kibana + - packages + +- name: Elastic GPG key is installed + copy: + src: elastic.asc + dest: /etc/apt/trusted.gpg.d/elastic.asc + force: yes + mode: "0644" tags: - kibana - packages diff --git a/logstash/tasks/main.yml b/logstash/tasks/main.yml index e6438abe..d0e26208 100644 --- a/logstash/tasks/main.yml +++ b/logstash/tasks/main.yml @@ -8,11 +8,20 @@ - logstash - packages -- name: Elastic GPG key is installed +- name: Elastic GPG embedded key is absent apt_key: - # url: https://artifacts.elastic.co/GPG-KEY-elasticsearch - data: "{{ lookup('file', 'elasticsearch.key') }}" - state: present + id: "D88E42B4" + state: absent + tags: + - logstash + - packages + +- name: Elastic GPG key is installed + copy: + src: elastic.asc + dest: /etc/apt/trusted.gpg.d/elastic.asc + force: yes + mode: "0644" tags: - logstash - packages diff --git a/metricbeat/tasks/main.yml b/metricbeat/tasks/main.yml index d148f1cd..cbb5e0e6 100644 --- a/metricbeat/tasks/main.yml +++ b/metricbeat/tasks/main.yml @@ -8,11 +8,20 @@ - metricbeat - packages -- name: Elastic GPG key is installed +- name: Elastic GPG embedded key is absent apt_key: - # url: https://artifacts.elastic.co/GPG-KEY-elasticsearch - data: "{{ lookup('file', 'elasticsearch.key') }}" - state: present + id: "D88E42B4" + state: absent + tags: + - metricbeat + - packages + +- name: Elastic GPG key is installed + copy: + src: elastic.asc + dest: /etc/apt/trusted.gpg.d/elastic.asc + force: yes + mode: "0644" tags: - metricbeat - packages diff --git a/mongodb/tasks/main_buster.yml b/mongodb/tasks/main_buster.yml index 5aae2ed3..53e75168 100644 --- a/mongodb/tasks/main_buster.yml +++ b/mongodb/tasks/main_buster.yml @@ -1,9 +1,16 @@ --- -- name: MongoDB public GPG Key +- name: MongoDB GPG embedded key is absent apt_key: - # url: https://www.mongodb.org/static/pgp/server-4.2.asc - data: "{{ lookup('file', 'server-4.2.asc') }}" + id: "B8612B5D" + state: absent + +- name: Add MongoDB GPG key + copy: + src: server-4.2.asc + dest: /etc/apt/trusted.gpg.d/mongodb-server-4.2.asc + force: yes + mode: "0644" - name: enable APT sources list apt_repository: diff --git a/newrelic/files/548C16BF.gpg b/newrelic/files/newrelic.asc similarity index 100% rename from newrelic/files/548C16BF.gpg rename to newrelic/files/newrelic.asc diff --git a/newrelic/tasks/sources.yml b/newrelic/tasks/sources.yml index b5b35fd0..1272b23b 100644 --- a/newrelic/tasks/sources.yml +++ b/newrelic/tasks/sources.yml @@ -1,9 +1,16 @@ --- -- name: Add dotdeb GPG key +- name: NewRelic GPG embedded key is absent apt_key: - # url: https://download.newrelic.com/548C16BF.gpg - data: "{{ lookup('file', '548C16BF.gpg') }}" + id: "548C16BF" + state: absent + +- name: Add NewRelic GPG key + copy: + src: newrelic.asc + dest: /etc/apt/trusted.gpg.d/newrelic.asc + force: yes + mode: "0644" - name: Install NewRelic repository apt_repository: diff --git a/nodejs/files/nodesource.gpg.key b/nodejs/files/nodesource.asc similarity index 100% rename from nodejs/files/nodesource.gpg.key rename to nodejs/files/nodesource.asc diff --git a/nodejs/files/yarnpkg.gpg.key b/nodejs/files/yarnpkg.asc similarity index 98% rename from nodejs/files/yarnpkg.gpg.key rename to nodejs/files/yarnpkg.asc index 530eb5e3..e8d9cabb 100644 --- a/nodejs/files/yarnpkg.gpg.key +++ b/nodejs/files/yarnpkg.asc @@ -1,243 +1,243 @@ ------BEGIN PGP PUBLIC KEY BLOCK----- - -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 -=IgpF ------END PGP PUBLIC KEY BLOCK----- +-----BEGIN PGP PUBLIC KEY BLOCK----- + +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 +=IgpF +-----END PGP PUBLIC KEY BLOCK----- diff --git a/nodejs/tasks/main.yml b/nodejs/tasks/main.yml index bad66d95..eb094938 100644 --- a/nodejs/tasks/main.yml +++ b/nodejs/tasks/main.yml @@ -8,10 +8,19 @@ - system - packages -- name: NodeJS GPG key is installed +- name: NodeJS GPG embedded key is absent apt_key: - # url: https://deb.nodesource.com/gpgkey/nodesource.gpg.key - data: "{{ lookup('file', 'nodesource.gpg.key') }}" + id: "68576280" + state: absent + tags: + - system + - packages + - nodejs + +- name: NodeJS GPG key is installed + copy: + src: nodesource.asc + dest: /etc/apt/trusted.gpg.d/nodesource.asc tags: - system - packages diff --git a/nodejs/tasks/yarn.yml b/nodejs/tasks/yarn.yml index 47af5c50..9ebdbce3 100644 --- a/nodejs/tasks/yarn.yml +++ b/nodejs/tasks/yarn.yml @@ -1,9 +1,19 @@ --- -- name: yarn GPG key is installed +- name: NodeJS GPG embedded key is absent apt_key: - # url: https://dl.yarnpkg.com/debian/pubkey.gpg - data: "{{ lookup('file', 'yarnpkg.gpg.key') }}" + id: "86E50310" + state: absent + tags: + - system + - packages + - nodejs + - yarn + +- name: NodeJS GPG key is installed + copy: + src: yarnpkg.asc + dest: /etc/apt/trusted.gpg.d/yarnpkg.asc tags: - system - packages diff --git a/percona/tasks/main.yml b/percona/tasks/main.yml index f0591b0e..35c32a80 100644 --- a/percona/tasks/main.yml +++ b/percona/tasks/main.yml @@ -3,9 +3,17 @@ - set_fact: percona__apt_config_package_file: "percona-release_latest.{{ ansible_distribution_release }}_all.deb" -- name: Add Percona's official GPG key +- name: Percona GPG embedded key is absent apt_key: - data: "{{ lookup('file', 'percona.asc') }}" + id: "8507EFA5" + state: absent + +- name: Add Percona GPG key + copy: + src: percona.asc + dest: /etc/apt/trusted.gpg.d/percona.asc + force: yes + mode: "0644" - name: Check if percona-release is installed command: "dpkg -l percona-release" diff --git a/postgresql/files/ACCC4CF8.asc b/postgresql/files/pgdg.asc similarity index 100% rename from postgresql/files/ACCC4CF8.asc rename to postgresql/files/pgdg.asc diff --git a/postgresql/tasks/pgdg-repo.yml b/postgresql/tasks/pgdg-repo.yml index 8d937b82..50a96ce0 100644 --- a/postgresql/tasks/pgdg-repo.yml +++ b/postgresql/tasks/pgdg-repo.yml @@ -13,10 +13,17 @@ repo: "deb http://apt.postgresql.org/pub/repos/apt/ {{ansible_distribution_release}}-pgdg main" update_cache: yes -- name: Add GPG key for PGDG repository +- name: PGDG GPG embedded key is absent apt_key: - #url: http://apt.postgresql.org/pub/repos/apt/ACCC4CF8.asc - data: "{{ lookup('file', 'ACCC4CF8.asc') }}" + id: "ACCC4CF8" + state: absent + +- name: Add PGDG GPG key + copy: + src: pgdg.asc + dest: /etc/apt/trusted.gpg.d/pgdg.asc + force: yes + mode: "0644" - name: Update and upgrade apt packages for PGDG repository apt: From eacdd2c7f2d711ace97fa7b3cbb6b0009cf35432 Mon Sep 17 00:00:00 2001 From: Jeremy Lecour Date: Mon, 3 May 2021 18:02:35 +0200 Subject: [PATCH 21/86] cerbot: fix regexp syntax for sync_remote --- certbot/tasks/main.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/certbot/tasks/main.yml b/certbot/tasks/main.yml index 0e65beda..1ab9c1c6 100644 --- a/certbot/tasks/main.yml +++ b/certbot/tasks/main.yml @@ -32,7 +32,7 @@ - name: "sync_remote is configured with servers" lineinfile: dest: /etc/letsencrypt/renewal-hooks/deploy/sync_remote.cf - regexp: "^servers\b" + regexp: "^servers=" line: "servers=\"{{ certbot_hooks_sync_remote_servers | join(' ') }}\"" create: yes From b3a62aa9d8651351bee6ce9e03daf16d0209a079 Mon Sep 17 00:00:00 2001 From: Jeremy Lecour Date: Mon, 3 May 2021 18:02:57 +0200 Subject: [PATCH 22/86] haproxy: use loop syntax instead of with_first_found --- haproxy/tasks/main.yml | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/haproxy/tasks/main.yml b/haproxy/tasks/main.yml index 972429c4..9e6936b5 100644 --- a/haproxy/tasks/main.yml +++ b/haproxy/tasks/main.yml @@ -100,9 +100,11 @@ dest: /etc/haproxy/haproxy.cfg force: "{{ haproxy_force_config }}" validate: "haproxy -c -f %s" - with_first_found: + loop: "{{ query('first_found', templates) }}" + vars: + templates: - "templates/haproxy/haproxy.{{ inventory_hostname }}.cfg.j2" - - "templates/haproxy/haproxy.{{ host_group }}.cfg.j2" + - "templates/haproxy/haproxy.{{ host_group | default('all') }}.cfg.j2" - "templates/haproxy/haproxy.default.cfg.j2" - "haproxy.default.cfg.j2" notify: reload haproxy From debc4a82caefda148aaa8f6e3e1bcaf0419a46c1 Mon Sep 17 00:00:00 2001 From: Jeremy Lecour Date: Tue, 4 May 2021 13:39:47 +0200 Subject: [PATCH 23/86] Use 'loop' syntax instead of 'with_first_found' --- CHANGELOG.md | 1 + evobackup-client/tasks/upload_scripts.yml | 12 ++++---- evolinux-base/tasks/motd.yml | 6 ++-- filebeat/tasks/main.yml | 6 ++-- haproxy/tasks/main.yml | 8 ++--- logstash/tasks/main.yml | 12 ++++---- metricbeat/tasks/main.yml | 6 ++-- minifirewall/tasks/tail.yml | 12 ++++---- varnish/tasks/main.yml | 20 +++++++------ webapps/evoadmin-web/tasks/config.yml | 18 +++++++----- webapps/evoadmin-web/tasks/user.yml | 12 ++++---- webapps/evoadmin-web/tasks/web.yml | 36 +++++++++++++---------- 12 files changed, 87 insertions(+), 62 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2390187a..a6bbfc1e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -19,6 +19,7 @@ The **patch** part changes incrementally at each release. ### Changed +* Use 'loop' syntax instead of 'with_first_found' * apt: store keys in /etc/apt/trusted.gpg.d in ascii format * evolinux-base: copy GPG key instead of using apt-key * ntpd: Add leapfile configuration setting to ntpd on debian 10+ diff --git a/evobackup-client/tasks/upload_scripts.yml b/evobackup-client/tasks/upload_scripts.yml index 8d698519..f3f7de25 100644 --- a/evobackup-client/tasks/upload_scripts.yml +++ b/evobackup-client/tasks/upload_scripts.yml @@ -6,11 +6,13 @@ dest: "{{ evobackup_client__cron_path }}" force: true mode: 0755 - with_first_found: - - "templates/evobackup-client/{{ evobackup_client__cron_template_name }}.{{ inventory_hostname }}.sh.j2" - - "templates/evobackup-client/{{ evobackup_client__cron_template_name }}.{{ host_group }}.sh.j2" - - "templates/evobackup-client/{{ evobackup_client__cron_template_name }}.sh.j2" - - "zzz_evobackup.default.sh.j2" + loop: "{{ query('first_found', templates) }}" + vars: + templates: + - "templates/evobackup-client/{{ evobackup_client__cron_template_name }}.{{ inventory_hostname }}.sh.j2" + - "templates/evobackup-client/{{ evobackup_client__cron_template_name }}.{{ host_group }}.sh.j2" + - "templates/evobackup-client/{{ evobackup_client__cron_template_name }}.sh.j2" + - "templates/zzz_evobackup.default.sh.j2" tags: - evobackup_client - evobackup_client_backup_scripts diff --git a/evolinux-base/tasks/motd.yml b/evolinux-base/tasks/motd.yml index d1171eb4..59076f8e 100644 --- a/evolinux-base/tasks/motd.yml +++ b/evolinux-base/tasks/motd.yml @@ -7,11 +7,11 @@ owner: root group: root mode: "0644" - with_first_found: - - files: + loop: "{{ query('first_found', templates, errors='ignore') }}" + vars: + templates: - "motd/motd.{{ inventory_hostname }}.j2" - "motd/motd.{{ host_group }}.j2" - "motd/motd.default.j2" - skip: True tags: - motd diff --git a/filebeat/tasks/main.yml b/filebeat/tasks/main.yml index c86e0e63..283ba1ce 100644 --- a/filebeat/tasks/main.yml +++ b/filebeat/tasks/main.yml @@ -145,11 +145,13 @@ src: "{{ item }}" dest: /etc/filebeat/filebeat.yml force: "{{ filebeat_force_config }}" - with_first_found: + loop: "{{ query('first_found', templates) }}" + vars: + templates: - "templates/filebeat/filebeat.{{ inventory_hostname }}.yml.j2" - "templates/filebeat/filebeat.{{ host_group }}.yml.j2" - "templates/filebeat/filebeat.default.yml.j2" - - "filebeat.default.yml.j2" + - "templates/filebeat.default.yml.j2" notify: restart filebeat when: filebeat_update_config when: filebeat_use_config_template diff --git a/haproxy/tasks/main.yml b/haproxy/tasks/main.yml index 9e6936b5..8b47127b 100644 --- a/haproxy/tasks/main.yml +++ b/haproxy/tasks/main.yml @@ -103,10 +103,10 @@ loop: "{{ query('first_found', templates) }}" vars: templates: - - "templates/haproxy/haproxy.{{ inventory_hostname }}.cfg.j2" - - "templates/haproxy/haproxy.{{ host_group | default('all') }}.cfg.j2" - - "templates/haproxy/haproxy.default.cfg.j2" - - "haproxy.default.cfg.j2" + - "templates/haproxy/haproxy.{{ inventory_hostname }}.cfg.j2" + - "templates/haproxy/haproxy.{{ host_group | default('all') }}.cfg.j2" + - "templates/haproxy/haproxy.default.cfg.j2" + - "templates/haproxy.default.cfg.j2" notify: reload haproxy when: haproxy_update_config tags: diff --git a/logstash/tasks/main.yml b/logstash/tasks/main.yml index d0e26208..1160711d 100644 --- a/logstash/tasks/main.yml +++ b/logstash/tasks/main.yml @@ -72,11 +72,13 @@ group: logstash mode: "0640" force: yes - with_first_found: - - "templates/logstash/logstash.{{ inventory_hostname }}.conf.j2" - - "templates/logstash/logstash.{{ host_group }}.conf.j2" - - "templates/logstash/logstash.default.conf.j2" - - "logstash.default.conf.j2" + loop: "{{ query('first_found', templates) }}" + vars: + templates: + - "templates/logstash/logstash.{{ inventory_hostname }}.conf.j2" + - "templates/logstash/logstash.{{ host_group }}.conf.j2" + - "templates/logstash/logstash.default.conf.j2" + - "templates/logstash.default.conf.j2" register: logstash_template - debug: diff --git a/metricbeat/tasks/main.yml b/metricbeat/tasks/main.yml index cbb5e0e6..a4706046 100644 --- a/metricbeat/tasks/main.yml +++ b/metricbeat/tasks/main.yml @@ -119,11 +119,13 @@ src: "{{ item }}" dest: /etc/metricbeat/metricbeat.yml force: "{{ metricbeat_force_config }}" - with_first_found: + loop: "{{ query('first_found', templates) }}" + vars: + templates: - "templates/metricbeat/metricbeat.{{ inventory_hostname }}.yml.j2" - "templates/metricbeat/metricbeat.{{ host_group }}.yml.j2" - "templates/metricbeat/metricbeat.default.yml.j2" - - "metricbeat.default.yml.j2" + - "templates/metricbeat.default.yml.j2" notify: restart metricbeat when: metricbeat_update_config when: metricbeat_use_config_template diff --git a/minifirewall/tasks/tail.yml b/minifirewall/tasks/tail.yml index 1f6b715d..629c2e59 100644 --- a/minifirewall/tasks/tail.yml +++ b/minifirewall/tasks/tail.yml @@ -4,11 +4,13 @@ src: "{{ item }}" dest: "{{ minifirewall_tail_file }}" force: "{{ minifirewall_tail_force | bool }}" - with_first_found: - - "templates/minifirewall-tail/minifirewall.{{ inventory_hostname }}.tail.j2" - - "templates/minifirewall-tail/minifirewall.{{ host_group }}.tail.j2" - - "templates/minifirewall-tail/minifirewall.default.tail.j2" - - "minifirewall.default.tail.j2" + loop: "{{ query('first_found', templates) }}" + vars: + templates: + - "templates/minifirewall-tail/minifirewall.{{ inventory_hostname }}.tail.j2" + - "templates/minifirewall-tail/minifirewall.{{ host_group }}.tail.j2" + - "templates/minifirewall-tail/minifirewall.default.tail.j2" + - "templates/minifirewall.default.tail.j2" register: minifirewall_tail_template - debug: diff --git a/varnish/tasks/main.yml b/varnish/tasks/main.yml index 035ae4a4..a8f9fa80 100644 --- a/varnish/tasks/main.yml +++ b/varnish/tasks/main.yml @@ -84,15 +84,17 @@ dest: "{{ varnish_config_file }}" mode: "0644" force: yes - with_first_found: - - "templates/varnish/varnish.{{ inventory_hostname }}.vcl.j2" - - "templates/varnish/default.{{ inventory_hostname }}.vcl.j2" - - "templates/varnish/varnish.{{ host_group }}.vcl.j2" - - "templates/varnish/default.{{ host_group }}.vcl.j2" - - "templates/varnish/varnish.default.vcl.j2" - - "templates/varnish/default.default.vcl.j2" - - "varnish.vcl.j2" - - "default.vcl.j2" + loop: "{{ query('first_found', templates) }}" + vars: + templates: + - "templates/varnish/varnish.{{ inventory_hostname }}.vcl.j2" + - "templates/varnish/default.{{ inventory_hostname }}.vcl.j2" + - "templates/varnish/varnish.{{ host_group }}.vcl.j2" + - "templates/varnish/default.{{ host_group }}.vcl.j2" + - "templates/varnish/varnish.default.vcl.j2" + - "templates/varnish/default.default.vcl.j2" + - "templates/varnish.vcl.j2" + - "templates/default.vcl.j2" notify: reload varnish tags: - varnish diff --git a/webapps/evoadmin-web/tasks/config.yml b/webapps/evoadmin-web/tasks/config.yml index 689a217e..9f16a2d6 100644 --- a/webapps/evoadmin-web/tasks/config.yml +++ b/webapps/evoadmin-web/tasks/config.yml @@ -11,11 +11,13 @@ src: "{{ item }}" dest: /etc/evolinux/web-add.conf force: "{{ evoadmin_add_conf_force }}" - with_first_found: + loop: "{{ query('first_found', templates) }}" + vars: + templates: - "templates/evoadmin-web/web-add.{{ inventory_hostname }}.conf.j2" - "templates/evoadmin-web/web-add.{{ host_group }}.conf.j2" - "templates/evoadmin-web/web-add.conf.j2" - - "web-add.conf.j2" + - "templates/web-add.conf.j2" register: evoadmin_add_conf_template - name: Configure web-add template file for mail @@ -23,9 +25,11 @@ src: "{{ item }}" dest: "{{ evoadmin_scripts_dir }}/web-mail.tpl" force: "{{ evoadmin_mail_tpl_force }}" - with_first_found: - - "templates/evoadmin-web/web-mail.{{ inventory_hostname }}.tpl.j2" - - "templates/evoadmin-web/web-mail.{{ host_group }}.tpl.j2" - - "templates/evoadmin-web/web-mail.tpl.j2" - - "web-mail.tpl.j2" + loop: "{{ query('first_found', templates) }}" + vars: + templates: + - "templates/evoadmin-web/web-mail.{{ inventory_hostname }}.tpl.j2" + - "templates/evoadmin-web/web-mail.{{ host_group }}.tpl.j2" + - "templates/evoadmin-web/web-mail.tpl.j2" + - "templates/web-mail.tpl.j2" register: evoadmin_mail_tpl_template diff --git a/webapps/evoadmin-web/tasks/user.yml b/webapps/evoadmin-web/tasks/user.yml index 7b58270c..9c774f0d 100644 --- a/webapps/evoadmin-web/tasks/user.yml +++ b/webapps/evoadmin-web/tasks/user.yml @@ -112,9 +112,11 @@ mode: "0600" force: "{{ evoadmin_sudoers_conf_force }}" validate: "visudo -cf %s" - with_first_found: - - "templates/evoadmin-web/sudoers.{{ inventory_hostname }}.j2" - - "templates/evoadmin-web/sudoers.{{ host_group }}.j2" - - "templates/evoadmin-web/sudoers.j2" - - "sudoers.j2" + loop: "{{ query('first_found', templates) }}" + vars: + templates: + - "templates/evoadmin-web/sudoers.{{ inventory_hostname }}.j2" + - "templates/evoadmin-web/sudoers.{{ host_group }}.j2" + - "templates/evoadmin-web/sudoers.j2" + - "templates/sudoers.j2" register: evoadmin_sudoers_conf diff --git a/webapps/evoadmin-web/tasks/web.yml b/webapps/evoadmin-web/tasks/web.yml index cafccc72..251af4ea 100644 --- a/webapps/evoadmin-web/tasks/web.yml +++ b/webapps/evoadmin-web/tasks/web.yml @@ -32,11 +32,13 @@ src: "{{ item }}" dest: /etc/apache2/sites-available/evoadmin.conf force: "{{ evoadmin_force_vhost }}" - with_first_found: - - "templates/evoadmin-web/evoadmin.{{ inventory_hostname }}.conf.j2" - - "templates/evoadmin-web/evoadmin.{{ host_group }}.conf.j2" - - "templates/evoadmin-web/evoadmin.conf.j2" - - "evoadmin.conf.j2" + loop: "{{ query('first_found', templates) }}" + vars: + templates: + - "templates/evoadmin-web/evoadmin.{{ inventory_hostname }}.conf.j2" + - "templates/evoadmin-web/evoadmin.{{ host_group }}.conf.j2" + - "templates/evoadmin-web/evoadmin.conf.j2" + - "templates/evoadmin.conf.j2" register: evoadmin_vhost_template notify: reload apache2 @@ -62,11 +64,13 @@ owner: root group: www-data force: "{{ evoadmin_htpasswd_force }}" - with_first_found: - - "templates/evoadmin-web/htpasswd.{{ inventory_hostname }}.j2" - - "templates/evoadmin-web/htpasswd.{{ host_group }}.j2" - - "templates/evoadmin-web/htpasswd.j2" - - "htpasswd.j2" + loop: "{{ query('first_found', templates) }}" + vars: + templates: + - "templates/evoadmin-web/htpasswd.{{ inventory_hostname }}.j2" + - "templates/evoadmin-web/htpasswd.{{ host_group }}.j2" + - "templates/evoadmin-web/htpasswd.j2" + - "templates/htpasswd.j2" register: evoadmin_htpasswd_template when: evoadmin_htpasswd @@ -78,9 +82,11 @@ owner: evoadmin group: evoadmin force: "{{ evoadmin_config_local_php_force }}" - with_first_found: - - "templates/evoadmin-web/config.local.{{ inventory_hostname }}.php.j2" - - "templates/evoadmin-web/config.local.{{ host_group }}.php.j2" - - "templates/evoadmin-web/config.local.php.j2" - - "config.local.php.j2" + loop: "{{ query('first_found', templates) }}" + vars: + templates: + - "templates/evoadmin-web/config.local.{{ inventory_hostname }}.php.j2" + - "templates/evoadmin-web/config.local.{{ host_group }}.php.j2" + - "templates/evoadmin-web/config.local.php.j2" + - "templates/config.local.php.j2" register: evoadmin_config_local_php_template From 5138065059263e0eb0c7fe39df2c311fa2f6d7c9 Mon Sep 17 00:00:00 2001 From: Jeremy Lecour Date: Tue, 4 May 2021 14:18:40 +0200 Subject: [PATCH 24/86] Use 'loop' syntax instead of 'with_items' --- CHANGELOG.md | 2 +- amazon-ec2/tasks/create-instance.yml | 6 +++--- apache/tasks/auth.yml | 4 ++-- apache/tasks/ip_whitelist.yml | 4 ++-- apache/tasks/main.yml | 6 +++--- apache/tasks/munin.yml | 2 +- apt/tasks/basics.yml | 2 +- apt/tasks/config.yml | 4 ++-- bind/tasks/munin.yml | 4 ++-- clamav/tasks/main.yml | 4 ++-- docker-host/tasks/main.yml | 2 +- dovecot/tasks/main.yml | 2 +- etc-git/tasks/repository.yml | 2 +- evoacme/tasks/conf.yml | 4 ++-- evoacme/tasks/scripts.yml | 2 +- evobackup-client/tasks/open_ssh_ports.yml | 2 +- evolinux-base/tasks/kernel.yml | 6 +++--- evolinux-base/tasks/packages.yml | 2 +- evolinux-base/tasks/postfix.yml | 4 ++-- evolinux-base/tasks/provider_orange_fce.yml | 2 +- evolinux-base/tasks/root.yml | 4 ++-- evolinux-base/tasks/system.yml | 4 ++-- evolinux-users/tasks/user.yml | 4 ++-- evomaintenance/tasks/install_vendor_debian.yml | 2 +- evomaintenance/tasks/install_vendor_openbsd.yml | 2 +- evomaintenance/tasks/minifirewall.yml | 2 +- fail2ban/tasks/main.yml | 4 ++-- filebeat/tasks/main.yml | 2 +- java/tasks/oracle.yml | 2 +- kibana/tasks/main.yml | 2 +- kvm-host/tasks/munin.yml | 2 +- kvm-host/tasks/ssh.yml | 4 ++-- ldap/tasks/nagios.yml | 4 ++-- lxc-php/tasks/php56.yml | 2 +- lxc-php/tasks/php70.yml | 2 +- lxc-php/tasks/php73.yml | 2 +- lxc-php/tasks/php74.yml | 4 ++-- lxc-solr/tasks/main.yml | 4 ++-- memcached/tasks/munin.yml | 2 +- metricbeat/tasks/main.yml | 2 +- minifirewall/tasks/config.yml | 2 +- mongodb/tasks/main_buster.yml | 4 ++-- munin/tasks/main.yml | 4 ++-- mysql-oracle/tasks/munin.yml | 4 ++-- mysql-oracle/tasks/nrpe.yml | 2 +- mysql-oracle/tasks/users.yml | 2 +- mysql/tasks/munin.yml | 4 ++-- mysql/tasks/nrpe.yml | 2 +- mysql/tasks/users_jessie.yml | 2 +- mysql/tasks/users_stretch.yml | 2 +- nameserver/tasks/main.yml | 4 ++-- newrelic/tasks/php.yml | 4 ++-- nginx/tasks/ip_whitelist.yml | 4 ++-- nginx/tasks/main.yml | 4 ++-- nginx/tasks/munin_graphs.yml | 2 +- opendkim/tasks/main.yml | 2 +- packweb-apache/tasks/apache.yml | 4 ++-- packweb-apache/tasks/fhs_retrictions.yml | 8 ++++---- packweb-apache/tasks/main.yml | 7 +++---- php/tasks/config_apache.yml | 4 ++-- php/tasks/config_cli.yml | 4 ++-- php/tasks/config_fpm.yml | 6 +++--- php/tasks/main_buster.yml | 2 +- php/tasks/main_stretch.yml | 2 +- php/tasks/sury_post.yml | 6 +++--- postfix/tasks/common.yml | 2 +- postfix/tasks/packmail.yml | 6 +++--- postfix/tasks/slow_transport.yml | 2 +- postgresql/tasks/locales.yml | 2 +- postgresql/tasks/munin.yml | 2 +- postgresql/tasks/packages_jessie.yml | 2 +- postgresql/tests/test.yml | 2 +- proftpd/tasks/accounts.yml | 12 ++++++------ rbenv/tasks/main.yml | 4 ++-- redis/tasks/default-munin.yml | 2 +- redis/tasks/instance-munin.yml | 2 +- redis/tasks/instance-server.yml | 8 ++++---- redmine/tasks/config.yml | 4 ++-- redmine/tasks/mysql.yml | 2 +- redmine/tasks/source.yml | 12 ++++++------ redmine/tasks/user.yml | 2 +- squid/tasks/main.yml | 4 ++-- squid/tasks/minifirewall.yml | 2 +- tomcat-instance/tasks/bootstrap.yml | 2 +- varnish/tasks/main.yml | 2 +- varnish/tasks/munin.yml | 2 +- vrrpd/tasks/main.yml | 2 +- webapps/evoadmin-web/tasks/packages.yml | 2 +- webapps/evoadmin-web/tasks/user.yml | 2 +- webapps/nextcloud/tasks/mysql.yml | 2 +- webapps/nextcloud/tasks/user.yml | 2 +- webapps/roundcube/tasks/main.yml | 2 +- webapps/wordpress/tasks/main.yml | 6 +++--- 93 files changed, 154 insertions(+), 155 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a6bbfc1e..8d8b9417 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -19,7 +19,7 @@ The **patch** part changes incrementally at each release. ### Changed -* Use 'loop' syntax instead of 'with_first_found' +* Use 'loop' syntax instead of 'with_first_found/with_items' * apt: store keys in /etc/apt/trusted.gpg.d in ascii format * evolinux-base: copy GPG key instead of using apt-key * ntpd: Add leapfile configuration setting to ntpd on debian 10+ diff --git a/amazon-ec2/tasks/create-instance.yml b/amazon-ec2/tasks/create-instance.yml index 470cac72..a3f84b1a 100644 --- a/amazon-ec2/tasks/create-instance.yml +++ b/amazon-ec2/tasks/create-instance.yml @@ -21,11 +21,11 @@ groupname: launched-instances ansible_user: admin ansible_ssh_common_args: "-o StrictHostKeyChecking=no" - with_items: "{{ec2.instances}}" + loop: "{{ec2.instances}}" - debug: msg: "Your newly created instance is reachable at: {{item.public_dns_name}}" - with_items: "{{ec2.instances}}" + loop: "{{ec2.instances}}" - name: Wait for SSH to come up on all instances (give up after 2m) wait_for: @@ -33,4 +33,4 @@ host: "{{item.public_dns_name}}" port: 22 timeout: 120 - with_items: "{{ec2.instances}}" + loop: "{{ec2.instances}}" diff --git a/apache/tasks/auth.yml b/apache/tasks/auth.yml index b785c704..b66fbe98 100644 --- a/apache/tasks/auth.yml +++ b/apache/tasks/auth.yml @@ -40,7 +40,7 @@ dest: /etc/apache2/private_htpasswd line: "{{ item }}" state: present - with_items: "{{ apache_private_htpasswd_present }}" + loop: "{{ apache_private_htpasswd_present }}" notify: reload apache tags: - apache @@ -50,7 +50,7 @@ dest: /etc/apache2/private_htpasswd line: "{{ item }}" state: absent - with_items: "{{ apache_private_htpasswd_absent }}" + loop: "{{ apache_private_htpasswd_absent }}" notify: reload apache tags: - apache diff --git a/apache/tasks/ip_whitelist.yml b/apache/tasks/ip_whitelist.yml index ac2b6f87..18f4a681 100644 --- a/apache/tasks/ip_whitelist.yml +++ b/apache/tasks/ip_whitelist.yml @@ -5,7 +5,7 @@ dest: /etc/apache2/ipaddr_whitelist.conf line: "Require ip {{ item }}" state: present - with_items: "{{ apache_ipaddr_whitelist_present }}" + loop: "{{ apache_ipaddr_whitelist_present }}" notify: reload apache tags: - apache @@ -16,7 +16,7 @@ dest: /etc/apache2/ipaddr_whitelist.conf line: "Require ip {{ item }}" state: absent - with_items: "{{ apache_ipaddr_whitelist_absent }}" + loop: "{{ apache_ipaddr_whitelist_absent }}" notify: reload apache tags: - apache diff --git a/apache/tasks/main.yml b/apache/tasks/main.yml index 7be38e1f..a52bd886 100644 --- a/apache/tasks/main.yml +++ b/apache/tasks/main.yml @@ -42,7 +42,7 @@ apache2_module: name: '{{ item }}' state: present - with_items: + loop: - rewrite - expires - headers @@ -58,7 +58,7 @@ apache2_module: name: '{{ item }}' state: present - with_items: + loop: - cgi notify: reload apache when: apache_mpm == "prefork" or apache_mpm == "itk" @@ -102,7 +102,7 @@ command: "a2enconf {{ item }}" register: command_result changed_when: "'Enabling' in command_result.stderr" - with_items: + loop: - z-evolinux-defaults.conf - zzz-evolinux-custom.conf notify: reload apache diff --git a/apache/tasks/munin.yml b/apache/tasks/munin.yml index 144ae0f8..fe07a5cf 100644 --- a/apache/tasks/munin.yml +++ b/apache/tasks/munin.yml @@ -15,7 +15,7 @@ src: "/usr/share/munin/plugins/{{ item }}" dest: "/etc/munin/plugins/{{ item }}" state: link - with_items: + loop: - apache_accesses - apache_processes - apache_volume diff --git a/apt/tasks/basics.yml b/apt/tasks/basics.yml index 3b9aadd6..83d3e7dc 100644 --- a/apt/tasks/basics.yml +++ b/apt/tasks/basics.yml @@ -14,7 +14,7 @@ file: path: '{{ item }}' state: absent - with_items: + loop: - /etc/apt/sources.list.d/debian-security.list - /etc/apt/sources.list.d/debian-jessie.list - /etc/apt/sources.list.d/debian-stretch.list diff --git a/apt/tasks/config.yml b/apt/tasks/config.yml index 48892b9e..e854d4c6 100644 --- a/apt/tasks/config.yml +++ b/apt/tasks/config.yml @@ -8,7 +8,7 @@ create: yes state: present mode: "0640" - with_items: + loop: - { line: "APT::Install-Recommends \"false\";", regexp: 'APT::Install-Recommends' } - { line: "APT::Install-Suggests \"false\";", regexp: 'APT::Install-Suggests' } - { line: "APT::Periodic::Enable \"0\";", regexp: 'APT::Periodic::Enable' } @@ -23,7 +23,7 @@ create: yes state: present mode: "0640" - with_items: + loop: - "DPkg::Pre-Invoke { \"df /tmp | grep -q /tmp && mount -oremount,exec /tmp || true\"; };" - "DPkg::Pre-Invoke { \"df /usr | grep -q /usr && mount -oremount,rw /usr || true\"; };" - "DPkg::Post-Invoke { \"df /tmp | grep -q /tmp && mount -oremount /tmp || true\"; };" diff --git a/bind/tasks/munin.yml b/bind/tasks/munin.yml index 5f9da280..f97ddf85 100644 --- a/bind/tasks/munin.yml +++ b/bind/tasks/munin.yml @@ -14,7 +14,7 @@ src: "/usr/share/munin/plugins/{{ item }}" dest: "/etc/munin/plugins/{{ item }}" state: link - with_items: + loop: - bind9 - bind9_rndc notify: restart munin-node @@ -30,7 +30,7 @@ src: "/usr/share/munin/plugins/{{ item }}" dest: "/etc/munin/plugins/{{ item }}" state: link - with_items: + loop: - bind9 - bind9_rndc notify: restart munin-node diff --git a/clamav/tasks/main.yml b/clamav/tasks/main.yml index 27d30cbc..be9e5b00 100644 --- a/clamav/tasks/main.yml +++ b/clamav/tasks/main.yml @@ -5,7 +5,7 @@ question: "{{ item.key }}" value: "{{ item.value }}" vtype: "{{ item.type }}" - with_items: + loop: - { key: 'clamav-daemon/debconf', type: 'boolean', value: 'true' } - { key: 'clamav-daemon/MaxHTMLNormalize', type: 'string', value: '10M' } - { key: 'clamav-daemon/StatsPEDisabled', type: 'boolean', value: 'true' } @@ -57,7 +57,7 @@ question: "{{ item.key }}" value: "{{ item.value }}" vtype: "{{ item.type }}" - with_items: + loop: - { key: 'clamav-freshclam/autoupdate_freshclam', type: 'select', value: 'daemon' } - { key: 'clamav-freshclam/proxy_user', type: 'string', value: '' } - { key: 'clamav-freshclam/NotifyClamd', type: 'boolean', value: 'true' } diff --git a/docker-host/tasks/main.yml b/docker-host/tasks/main.yml index 437de2a4..c32701bb 100644 --- a/docker-host/tasks/main.yml +++ b/docker-host/tasks/main.yml @@ -80,7 +80,7 @@ src: "{{ item }}.j2" dest: "{{ docker_tls_path }}/{{ item }}" mode: "0744" - with_items: + loop: - shellpki.sh - openssl.cnf when: docker_tls_enabled diff --git a/dovecot/tasks/main.yml b/dovecot/tasks/main.yml index 1a7e4280..aa817086 100644 --- a/dovecot/tasks/main.yml +++ b/dovecot/tasks/main.yml @@ -24,7 +24,7 @@ line: "{{ item.key }} = {{ item.value }}" regexp: "^#*{{ item.key }}" state: present - with_items: + loop: - { key: 'hosts', value: '127.0.0.1' } - { key: 'auth_bind', value: 'yes' } - { key: 'ldap_version', value: 3 } diff --git a/etc-git/tasks/repository.yml b/etc-git/tasks/repository.yml index 1430c5bd..9be0a436 100644 --- a/etc-git/tasks/repository.yml +++ b/etc-git/tasks/repository.yml @@ -46,7 +46,7 @@ lineinfile: dest: "{{ repository_path }}/.gitignore" line: "{{ item }}" - with_items: "{{ gitignore_items | default([]) }}" + loop: "{{ gitignore_items | default([]) }}" tags: - etc-git diff --git a/evoacme/tasks/conf.yml b/evoacme/tasks/conf.yml index 4d9f6704..402fbdcf 100644 --- a/evoacme/tasks/conf.yml +++ b/evoacme/tasks/conf.yml @@ -4,7 +4,7 @@ section: 'req' option: "{{ item.name }}" value: "{{ item.var }}" - with_items: + loop: - { name: 'default_bits', var: "{{ evoacme_ssl_key_size }}" } - { name: 'encrypt_key', var: 'yes' } - { name: 'distinguished_name', var: 'req_dn' } @@ -16,7 +16,7 @@ section: 'req_dn' option: "{{ item.name }}" value: "{{ item.var }}" - with_items: + loop: - { name: 'C', var: "{{ evoacme_ssl_ct }}" } - { name: 'ST', var: "{{ evoacme_ssl_state }}" } - { name: 'L', var: "{{ evoacme_ssl_loc }}" } diff --git a/evoacme/tasks/scripts.yml b/evoacme/tasks/scripts.yml index 50d95890..89aacff8 100644 --- a/evoacme/tasks/scripts.yml +++ b/evoacme/tasks/scripts.yml @@ -39,6 +39,6 @@ file: path: "/usr/local/bin/{{ item }}" state: absent - with_items: + loop: - 'make-csr' - 'evoacme' diff --git a/evobackup-client/tasks/open_ssh_ports.yml b/evobackup-client/tasks/open_ssh_ports.yml index be96c161..3d1701ef 100644 --- a/evobackup-client/tasks/open_ssh_ports.yml +++ b/evobackup-client/tasks/open_ssh_ports.yml @@ -14,7 +14,7 @@ marker: "# {mark} {{ item.name }}" block: | /sbin/iptables -A INPUT -p tcp --sport {{ item.port }} --dport 1024:65535 -s {{ item.ip }} -m state --state ESTABLISHED,RELATED -j ACCEPT - with_items: "{{ evobackup_client__hosts }}" + loop: "{{ evobackup_client__hosts }}" notify: restart minifirewall when: evobackup_client__minifirewall.stat.exists tags: diff --git a/evolinux-base/tasks/kernel.yml b/evolinux-base/tasks/kernel.yml index 95912855..e19ab0e6 100644 --- a/evolinux-base/tasks/kernel.yml +++ b/evolinux-base/tasks/kernel.yml @@ -7,7 +7,7 @@ sysctl_file: "{{ evolinux_kernel_sysctl_path }}" state: present reload: yes - with_items: + loop: - { name: kernel.panic_on_oops, value: 1 } - { name: kernel.panic, value: 60 } when: evolinux_kernel_reboot_after_panic @@ -18,7 +18,7 @@ sysctl_file: "{{ evolinux_kernel_sysctl_path }}" state: absent reload: yes - with_items: + loop: - kernel.panic_on_oops - kernel.panic when: not evolinux_kernel_reboot_after_panic @@ -57,7 +57,7 @@ sysctl_file: "{{ evolinux_kernel_sysctl_path }}" state: present reload: yes - with_items: + loop: - { name: "net.ipv4.ipfrag_low_thresh", value: 196608 } - { name: "net.ipv6.ip6frag_low_thresh", value: 196608 } - { name: "net.ipv4.ipfrag_high_thresh", value: 262144 } diff --git a/evolinux-base/tasks/packages.yml b/evolinux-base/tasks/packages.yml index ed2b1cd2..afedf1a4 100644 --- a/evolinux-base/tasks/packages.yml +++ b/evolinux-base/tasks/packages.yml @@ -128,7 +128,7 @@ dest: /etc/apt/listchanges.conf regexp: '^{{ item.option }}\s*=' line: "{{ item.option }}={{ item.value }}" - with_items: + loop: - { option: "confirm", value: "1" } - { option: "which", value: "both" } when: diff --git a/evolinux-base/tasks/postfix.yml b/evolinux-base/tasks/postfix.yml index aa60e737..e83a190b 100644 --- a/evolinux-base/tasks/postfix.yml +++ b/evolinux-base/tasks/postfix.yml @@ -45,7 +45,7 @@ dest: /etc/aliases regexp: "^{{ item }}:.*" line: "{{ item }}: root" - with_items: "{{ non_root_users_list.stdout_lines }}" + loop: "{{ non_root_users_list.stdout_lines }}" notify: newaliases when: evolinux_postfix_users_alias_root tags: @@ -56,7 +56,7 @@ dest: /etc/aliases regexp: "^{{ item }}:.*" line: "{{ item }}: root" - with_items: + loop: - postmaster - abuse - mailer-daemon diff --git a/evolinux-base/tasks/provider_orange_fce.yml b/evolinux-base/tasks/provider_orange_fce.yml index 6cef30fb..4b9a26c7 100644 --- a/evolinux-base/tasks/provider_orange_fce.yml +++ b/evolinux-base/tasks/provider_orange_fce.yml @@ -5,7 +5,7 @@ sysctl_file: /etc/sysctl.d/evolinux_fce.conf state: present reload: yes - with_items: + loop: - { name: net.ipv4.tcp_keepalive_time, value: 250 } - { name: net.ipv4.tcp_keepalive_intvl, value: 60 } - { name: net.ipv6.conf.all.disable_ipv6, value: 1 } diff --git a/evolinux-base/tasks/root.yml b/evolinux-base/tasks/root.yml index 23f3cd9c..ce57d4fd 100644 --- a/evolinux-base/tasks/root.yml +++ b/evolinux-base/tasks/root.yml @@ -13,7 +13,7 @@ line: "{{ item }}" create: yes state: present - with_items: + loop: - "export HISTCONTROL=$HISTCONTROL${HISTCONTROL+,}ignoreboth,erasedups" - "export HISTSIZE=65535" - "export HISTTIMEFORMAT=\"%c : \"" @@ -79,7 +79,7 @@ line: "{{ item }}" create: yes state: present - with_items: + loop: - "syntax on" - "set background=dark" - "set expandtab" diff --git a/evolinux-base/tasks/system.yml b/evolinux-base/tasks/system.yml index 55820890..06661ada 100644 --- a/evolinux-base/tasks/system.yml +++ b/evolinux-base/tasks/system.yml @@ -13,7 +13,7 @@ line: "{{ item }}" create: yes state: present - with_items: + loop: - "en_US.UTF-8 UTF-8" - "fr_FR ISO-8859-1" - "fr_FR.UTF-8 UTF-8" @@ -112,7 +112,7 @@ dest: /etc/crontab regexp: "{{ item.regexp }}" replace: "{{ item.replace }}" - with_items: + loop: - { regexp: '^17((\s*\*){4})', replace: '{{ 59|random(start=1) }}\1' } - { regexp: '^25\s*6((\s*\*){3})', replace: '{{ 59|random(start=1) }} {{ [0,1,3,4,5,6,7]|random }}\1' } - { regexp: '^47\s*6((\s*\*){2}\s*7)', replace: '{{ 59|random(start=1) }} {{ [0,1,3,4,5,6,7]|random }}\1' } diff --git a/evolinux-users/tasks/user.yml b/evolinux-users/tasks/user.yml index b8dda1d2..0d2105bd 100644 --- a/evolinux-users/tasks/user.yml +++ b/evolinux-users/tasks/user.yml @@ -120,7 +120,7 @@ - name: "Secondary Unix groups are present" group: name: "{{ group }}" - with_items: "{{ user.groups }}" + loop: "{{ user.groups }}" loop_control: loop_var: group when: @@ -184,7 +184,7 @@ user: "{{ user.name }}" key: "{{ ssk_key }}" state: present - with_items: "{{ user.ssh_keys }}" + loop: "{{ user.ssh_keys }}" loop_control: loop_var: ssk_key when: user.ssh_keys is defined diff --git a/evomaintenance/tasks/install_vendor_debian.yml b/evomaintenance/tasks/install_vendor_debian.yml index a3d29b95..96bbee86 100644 --- a/evomaintenance/tasks/install_vendor_debian.yml +++ b/evomaintenance/tasks/install_vendor_debian.yml @@ -42,7 +42,7 @@ mode: "{{ item.mode }}" force: yes backup: yes - with_items: + loop: - { src: 'evomaintenance.sh', dest: '/usr/share/scripts/', mode: '0700' } - { src: 'evomaintenance.tpl', dest: '/usr/share/scripts/', mode: '0600' } tags: diff --git a/evomaintenance/tasks/install_vendor_openbsd.yml b/evomaintenance/tasks/install_vendor_openbsd.yml index 37307cfb..e82a9a39 100644 --- a/evomaintenance/tasks/install_vendor_openbsd.yml +++ b/evomaintenance/tasks/install_vendor_openbsd.yml @@ -28,7 +28,7 @@ mode: "{{ item.mode }}" force: yes backup: yes - with_items: + loop: - { src: 'evomaintenance.sh', dest: '/usr/share/scripts/', mode: '0700' } - { src: 'evomaintenance.tpl', dest: '/usr/share/scripts/', mode: '0600' } tags: diff --git a/evomaintenance/tasks/minifirewall.yml b/evomaintenance/tasks/minifirewall.yml index fc6ed0a5..c99bd34f 100644 --- a/evomaintenance/tasks/minifirewall.yml +++ b/evomaintenance/tasks/minifirewall.yml @@ -12,7 +12,7 @@ dest: /etc/default/minifirewall line: "/sbin/iptables -A INPUT -p tcp --sport 5432 --dport 1024:65535 -s {{ item }} -m state --state ESTABLISHED,RELATED -j ACCEPT" insertafter: "^# EvoMaintenance" - with_items: "{{ evomaintenance_hosts }}" + loop: "{{ evomaintenance_hosts }}" notify: "{{ minifirewall_restart_handler_name }}" when: minifirewall_default_file.stat.exists tags: diff --git a/fail2ban/tasks/main.yml b/fail2ban/tasks/main.yml index e496c07e..5e4909d6 100644 --- a/fail2ban/tasks/main.yml +++ b/fail2ban/tasks/main.yml @@ -9,7 +9,7 @@ owner: root group: root mode: "0755" - with_items: + loop: - "/etc/fail2ban" - "/etc/fail2ban/filter.d" tags: @@ -52,7 +52,7 @@ src: "{{ item }}" dest: /etc/fail2ban/filter.d/ mode: "0644" - with_items: + loop: - dovecot-evolix.conf - sasl-evolix.conf - wordpress-soft.conf diff --git a/filebeat/tasks/main.yml b/filebeat/tasks/main.yml index 283ba1ce..d5c61322 100644 --- a/filebeat/tasks/main.yml +++ b/filebeat/tasks/main.yml @@ -120,7 +120,7 @@ regexp: '{{ item.regexp }}' line: '{{ item.line }}' insertafter: "output.elasticsearch:" - with_items: + loop: - { regexp: '^ #?username: .*', line: ' username: "{{ filebeat_elasticsearch_auth_username }}"' } - { regexp: '^ #?password: .*', line: ' password: "{{ filebeat_elasticsearch_auth_password }}"' } notify: restart filebeat diff --git a/java/tasks/oracle.yml b/java/tasks/oracle.yml index a2268b7b..bbdd86f4 100644 --- a/java/tasks/oracle.yml +++ b/java/tasks/oracle.yml @@ -13,7 +13,7 @@ path: "{{ item }}" state: directory mode: "0777" - with_items: + loop: - /srv/java-package - /srv/java-package/src - /srv/java-package/tmp diff --git a/kibana/tasks/main.yml b/kibana/tasks/main.yml index b32fea15..832cdee3 100644 --- a/kibana/tasks/main.yml +++ b/kibana/tasks/main.yml @@ -107,7 +107,7 @@ # args: # creates: "/var/lib/kibana/{{ item }}" # notify: restart kibana -# with_items: +# loop: # - optimize # - data diff --git a/kvm-host/tasks/munin.yml b/kvm-host/tasks/munin.yml index fe5c0217..dc130238 100644 --- a/kvm-host/tasks/munin.yml +++ b/kvm-host/tasks/munin.yml @@ -5,7 +5,7 @@ url: "https://raw.githubusercontent.com/munin-monitoring/contrib/master/plugins/libvirt/{{ item }}" dest: "/etc/munin/plugins/" mode: "0755" - with_items: + loop: - kvm_cpu - kvm_io - kvm_mem diff --git a/kvm-host/tasks/ssh.yml b/kvm-host/tasks/ssh.yml index bdfac0d0..7e42238b 100644 --- a/kvm-host/tasks/ssh.yml +++ b/kvm-host/tasks/ssh.yml @@ -33,7 +33,7 @@ special_time: "hourly" user: root job: "rsync -a --delete /etc/libvirt/qemu/ {{ hostvars[item]['ansible_hostname'] }}:/root/libvirt-{{ inventory_hostname }}/" - with_items: + loop: - "{{ groups['hypervisors'] }}" when: item != inventory_hostname @@ -44,6 +44,6 @@ special_time: "daily" user: root job: "virsh list | ssh {{ hostvars[item]['ansible_hostname'] }} 'cat >/root/libvirt-{{ inventory_hostname }}/virsh-list.txt'" - with_items: + loop: - "{{ groups['hypervisors'] }}" when: item != inventory_hostname diff --git a/ldap/tasks/nagios.yml b/ldap/tasks/nagios.yml index a9cb5751..97db7dba 100644 --- a/ldap/tasks/nagios.yml +++ b/ldap/tasks/nagios.yml @@ -47,7 +47,7 @@ option: "{{ item.option }}" value: "{{ item.value }}" mode: "0640" - with_items: + loop: - { option: 'hostname', value: '127.0.0.1' } - { option: 'base', value: "{{ ldap_suffix }}" } - { option: 'bind', value: "cn=nagios,ou=ldapusers,{{ ldap_suffix }}" } @@ -66,7 +66,7 @@ # and set the variable - name: overwrite ldap_nagios_password (from file) set_fact: - ldap_nagios_password: "{{ lookup('ini', 'pass section=check_ldap file=/tmp/{{ inventory_hostname }}/etc/nagios/monitoring-plugins.ini') }}" + ldap_nagios_password: "{{ lookup('ini', 'pass section=check_ldap file=/tmp/{{ inventory_hostname }}/monitoring-plugins.ini') }}" - name: hash password for cn=nagios command: "slappasswd -s {{ ldap_nagios_password }}" diff --git a/lxc-php/tasks/php56.yml b/lxc-php/tasks/php56.yml index b10bb772..ece7dc8d 100644 --- a/lxc-php/tasks/php56.yml +++ b/lxc-php/tasks/php56.yml @@ -11,7 +11,7 @@ dest: "{{ line_item }}" mode: "0644" notify: "Reload {{ lxc_php_version }}-fpm" - with_items: + loop: - "/var/lib/lxc/{{ lxc_php_version }}/rootfs/etc/php5/fpm/conf.d/z-evolinux-defaults.ini" - "/var/lib/lxc/{{ lxc_php_version }}/rootfs/etc/php5/cli/conf.d/z-evolinux-defaults.ini" loop_control: diff --git a/lxc-php/tasks/php70.yml b/lxc-php/tasks/php70.yml index 8cbb0125..2291b386 100644 --- a/lxc-php/tasks/php70.yml +++ b/lxc-php/tasks/php70.yml @@ -11,7 +11,7 @@ dest: "{{ line_item }}" mode: "0644" notify: "Reload {{ lxc_php_version }}-fpm" - with_items: + loop: - "/var/lib/lxc/{{ lxc_php_version }}/rootfs/etc/php/7.0/fpm/conf.d/z-evolinux-defaults.ini" - "/var/lib/lxc/{{ lxc_php_version }}/rootfs/etc/php/7.0/cli/conf.d/z-evolinux-defaults.ini" loop_control: diff --git a/lxc-php/tasks/php73.yml b/lxc-php/tasks/php73.yml index eae17e4e..d7fd7937 100644 --- a/lxc-php/tasks/php73.yml +++ b/lxc-php/tasks/php73.yml @@ -11,7 +11,7 @@ dest: "{{ line_item }}" mode: "0644" notify: "Reload {{ lxc_php_version }}-fpm" - with_items: + loop: - "/var/lib/lxc/{{ lxc_php_version }}/rootfs/etc/php/7.3/fpm/conf.d/z-evolinux-defaults.ini" - "/var/lib/lxc/{{ lxc_php_version }}/rootfs/etc/php/7.3/cli/conf.d/z-evolinux-defaults.ini" loop_control: diff --git a/lxc-php/tasks/php74.yml b/lxc-php/tasks/php74.yml index db25ee4e..1f3bc516 100644 --- a/lxc-php/tasks/php74.yml +++ b/lxc-php/tasks/php74.yml @@ -12,7 +12,7 @@ state: present create: yes mode: "0644" - with_items: + loop: - "deb https://packages.sury.org/php/ buster main" - "deb http://pub.evolix.net/ buster-php74/" @@ -44,7 +44,7 @@ dest: "{{ line_item }}" mode: "0644" notify: "Reload {{ lxc_php_version }}-fpm" - with_items: + loop: - "/var/lib/lxc/{{ lxc_php_version }}/rootfs/etc/php/7.4/fpm/conf.d/z-evolinux-defaults.ini" - "/var/lib/lxc/{{ lxc_php_version }}/rootfs/etc/php/7.4/cli/conf.d/z-evolinux-defaults.ini" loop_control: diff --git a/lxc-solr/tasks/main.yml b/lxc-solr/tasks/main.yml index a18c46dc..3fad863f 100644 --- a/lxc-solr/tasks/main.yml +++ b/lxc-solr/tasks/main.yml @@ -8,9 +8,9 @@ path: "/var/lib/lxc/{{ item.name }}/rootfs" state: directory mode: '0755' - with_items: + loop: - "{{ lxc_containers }}" - include: "solr.yml name={{item.name}} solr_version={{item.solr_version}} solr_port={{item.solr_port}}" - with_items: + loop: - "{{ lxc_containers }}" diff --git a/memcached/tasks/munin.yml b/memcached/tasks/munin.yml index c7ea3da9..cd75fa64 100644 --- a/memcached/tasks/munin.yml +++ b/memcached/tasks/munin.yml @@ -26,7 +26,7 @@ src: '/usr/share/munin/plugins/memcached_' dest: /etc/munin/plugins/{{ multi }}{{ item }} state: link - with_items: + loop: - memcached_bytes - memcached_counters - memcached_rates diff --git a/metricbeat/tasks/main.yml b/metricbeat/tasks/main.yml index a4706046..5d8ee2c9 100644 --- a/metricbeat/tasks/main.yml +++ b/metricbeat/tasks/main.yml @@ -78,7 +78,7 @@ regexp: '{{ item.regexp }}' line: '{{ item.line }}' insertafter: "output.elasticsearch:" - with_items: + loop: - { regexp: '^ #?username: .*', line: ' username: "{{ metricbeat_elasticsearch_auth_username }}"' } - { regexp: '^ #?password: .*', line: ' password: "{{ metricbeat_elasticsearch_auth_password }}"' } notify: restart metricbeat diff --git a/minifirewall/tasks/config.yml b/minifirewall/tasks/config.yml index 4c852d6b..1b556674 100644 --- a/minifirewall/tasks/config.yml +++ b/minifirewall/tasks/config.yml @@ -184,7 +184,7 @@ dest: "{{ minifirewall_main_file }}" line: "/sbin/iptables -A INPUT -p tcp --sport 5432 --dport 1024:65535 -s {{ item }} -m state --state ESTABLISHED,RELATED -j ACCEPT" insertafter: "^# EvoMaintenance" - with_items: "{{ evomaintenance_hosts }}" + loop: "{{ evomaintenance_hosts }}" - name: remove minifirewall example rule for the evomaintenance lineinfile: diff --git a/mongodb/tasks/main_buster.yml b/mongodb/tasks/main_buster.yml index 53e75168..15e7fdc3 100644 --- a/mongodb/tasks/main_buster.yml +++ b/mongodb/tasks/main_buster.yml @@ -57,7 +57,7 @@ src: "munin/{{ item }}" dest: '/usr/local/share/munin/plugins/{{ item }}' force: yes - with_items: + loop: - mongo_btree - mongo_collections - mongo_conn @@ -73,7 +73,7 @@ src: '/usr/local/share/munin/plugins/{{ item }}' dest: /etc/munin/plugins/{{ item }} state: link - with_items: + loop: - mongo_btree - mongo_collections - mongo_conn diff --git a/munin/tasks/main.yml b/munin/tasks/main.yml index 344962f8..aab79f62 100644 --- a/munin/tasks/main.yml +++ b/munin/tasks/main.yml @@ -35,7 +35,7 @@ file: path: '/etc/munin/plugins/{{ item }}' state: absent - with_items: + loop: - http_loadtime - exim_mailqueue - exim_mailstats @@ -52,7 +52,7 @@ src: "/usr/share/munin/plugins/{{ item }}" dest: "/etc/munin/plugins/{{ item }}" state: link - with_items: + loop: - meminfo - netstat_multi - tcp diff --git a/mysql-oracle/tasks/munin.yml b/mysql-oracle/tasks/munin.yml index 70e871e1..b9e633b0 100644 --- a/mysql-oracle/tasks/munin.yml +++ b/mysql-oracle/tasks/munin.yml @@ -22,7 +22,7 @@ src: '/usr/share/munin/plugins/{{ item }}' dest: /etc/munin/plugins/{{ item }} state: link - with_items: + loop: - mysql_bytes - mysql_queries - mysql_slowqueries @@ -34,7 +34,7 @@ src: /usr/share/munin/plugins/mysql_ dest: '/etc/munin/plugins/mysql_{{ item }}' state: link - with_items: + loop: - commands - connections - files_tables diff --git a/mysql-oracle/tasks/nrpe.yml b/mysql-oracle/tasks/nrpe.yml index c02fc007..58820786 100644 --- a/mysql-oracle/tasks/nrpe.yml +++ b/mysql-oracle/tasks/nrpe.yml @@ -44,7 +44,7 @@ section: client option: '{{ item.option }}' value: '{{ item.value }}' - with_items: + loop: - { option: 'user', value: 'nrpe' } - { option: 'password', value: '{{ mysql_nrpe_password.stdout }}' } when: create_nrpe_user.changed diff --git a/mysql-oracle/tasks/users.yml b/mysql-oracle/tasks/users.yml index 50e0fb58..508ab4cc 100644 --- a/mysql-oracle/tasks/users.yml +++ b/mysql-oracle/tasks/users.yml @@ -36,7 +36,7 @@ option: '{{ item.option }}' value: '{{ item.value }}' create: yes - with_items: + loop: - { option: 'user', value: 'mysqladmin' } - { option: 'password', value: '{{ mysql_admin_password.stdout }}' } when: create_mysqladmin_user is changed diff --git a/mysql/tasks/munin.yml b/mysql/tasks/munin.yml index c7017aa2..f2a333e7 100644 --- a/mysql/tasks/munin.yml +++ b/mysql/tasks/munin.yml @@ -22,7 +22,7 @@ src: '/usr/share/munin/plugins/{{ item }}' dest: /etc/munin/plugins/{{ item }} state: link - with_items: + loop: - mysql_bytes - mysql_queries - mysql_slowqueries @@ -34,7 +34,7 @@ src: /usr/share/munin/plugins/mysql_ dest: '/etc/munin/plugins/mysql_{{ item }}' state: link - with_items: + loop: - commands - connections - files_tables diff --git a/mysql/tasks/nrpe.yml b/mysql/tasks/nrpe.yml index c02fc007..58820786 100644 --- a/mysql/tasks/nrpe.yml +++ b/mysql/tasks/nrpe.yml @@ -44,7 +44,7 @@ section: client option: '{{ item.option }}' value: '{{ item.value }}' - with_items: + loop: - { option: 'user', value: 'nrpe' } - { option: 'password', value: '{{ mysql_nrpe_password.stdout }}' } when: create_nrpe_user.changed diff --git a/mysql/tasks/users_jessie.yml b/mysql/tasks/users_jessie.yml index f11e41af..027d0bd8 100644 --- a/mysql/tasks/users_jessie.yml +++ b/mysql/tasks/users_jessie.yml @@ -42,7 +42,7 @@ option: '{{ item.option }}' value: '{{ item.value }}' create: yes - with_items: + loop: - { option: 'user', value: 'mysqladmin' } - { option: 'password', value: '{{ mysql_admin_password.stdout }}' } when: create_mysqladmin_user.changed diff --git a/mysql/tasks/users_stretch.yml b/mysql/tasks/users_stretch.yml index 70ae9933..0613de19 100644 --- a/mysql/tasks/users_stretch.yml +++ b/mysql/tasks/users_stretch.yml @@ -37,7 +37,7 @@ option: '{{ item.option }}' value: '{{ item.value }}' create: yes - with_items: + loop: - { option: 'user', value: 'mysqladmin' } - { option: 'password', value: '{{ mysql_admin_password.stdout }}' } when: create_mysqladmin_user.changed diff --git a/nameserver/tasks/main.yml b/nameserver/tasks/main.yml index 4623fffc..420e65af 100644 --- a/nameserver/tasks/main.yml +++ b/nameserver/tasks/main.yml @@ -12,7 +12,7 @@ dest: /etc/resolv.conf line: "nameserver {{ item }}" state: present - with_items: "{{ nameservers }}" + loop: "{{ nameservers }}" tags: - nameserver @@ -21,7 +21,7 @@ dest: /etc/resolv.conf line: "nameserver {{ item }}" state: absent - with_items: "{{ grep_nameserver.stdout_lines }}" + loop: "{{ grep_nameserver.stdout_lines }}" when: item not in nameservers tags: - nameserver diff --git a/newrelic/tasks/php.yml b/newrelic/tasks/php.yml index 7d1177dc..5d44e8e5 100644 --- a/newrelic/tasks/php.yml +++ b/newrelic/tasks/php.yml @@ -27,14 +27,14 @@ dest: "{{ item }}" regexp: '^;?newrelic.daemon.utilization.detect_aws' line: 'newrelic.daemon.utilization.detect_aws = false' - with_items: "{{ find_newrelic_ini.stdout_lines }}" + loop: "{{ find_newrelic_ini.stdout_lines }}" - name: Disable Docker detection lineinfile: dest: "{{ item }}" regexp: '^;?newrelic.daemon.utilization.detect_docker' line: 'newrelic.daemon.utilization.detect_docker = false' - with_items: "{{ find_newrelic_ini.stdout_lines }}" + loop: "{{ find_newrelic_ini.stdout_lines }}" - name: Install package for PHP apt: diff --git a/nginx/tasks/ip_whitelist.yml b/nginx/tasks/ip_whitelist.yml index 10cdcc37..2667d1d3 100644 --- a/nginx/tasks/ip_whitelist.yml +++ b/nginx/tasks/ip_whitelist.yml @@ -5,7 +5,7 @@ dest: /etc/nginx/snippets/ipaddr_whitelist line: "allow {{ item }};" state: present - with_items: "{{ nginx_ipaddr_whitelist_present }}" + loop: "{{ nginx_ipaddr_whitelist_present }}" notify: reload nginx tags: - nginx @@ -16,7 +16,7 @@ dest: /etc/nginx/snippets/ipaddr_whitelist line: "allow {{ item }};" state: absent - with_items: "{{ nginx_ipaddr_whitelist_absent }}" + loop: "{{ nginx_ipaddr_whitelist_absent }}" notify: reload nginx tags: - nginx diff --git a/nginx/tasks/main.yml b/nginx/tasks/main.yml index 6fe9a94e..58b9f95b 100644 --- a/nginx/tasks/main.yml +++ b/nginx/tasks/main.yml @@ -80,7 +80,7 @@ dest: /etc/nginx/snippets/private_htpasswd line: "{{ item }}" state: present - with_items: "{{ nginx_private_htpasswd_present }}" + loop: "{{ nginx_private_htpasswd_present }}" notify: reload nginx tags: - nginx @@ -90,7 +90,7 @@ dest: /etc/nginx/snippets/private_htpasswd line: "{{ item }}" state: absent - with_items: "{{ nginx_private_htpasswd_absent }}" + loop: "{{ nginx_private_htpasswd_absent }}" notify: reload nginx tags: - nginx diff --git a/nginx/tasks/munin_graphs.yml b/nginx/tasks/munin_graphs.yml index 470f8fd6..ae0bb9ac 100644 --- a/nginx/tasks/munin_graphs.yml +++ b/nginx/tasks/munin_graphs.yml @@ -12,7 +12,7 @@ src: '/usr/share/munin/plugins/{{ item }}' dest: '/etc/munin/plugins/{{ item }}' state: link - with_items: + loop: - nginx_request - nginx_status notify: restart munin diff --git a/opendkim/tasks/main.yml b/opendkim/tasks/main.yml index 901d03f2..1db961e2 100644 --- a/opendkim/tasks/main.yml +++ b/opendkim/tasks/main.yml @@ -38,7 +38,7 @@ owner: opendkim group: opendkim mode: "0640" - with_items: + loop: - 'KeyTable' - 'SigningTable' changed_when: False diff --git a/packweb-apache/tasks/apache.yml b/packweb-apache/tasks/apache.yml index 61d37341..57b360ce 100644 --- a/packweb-apache/tasks/apache.yml +++ b/packweb-apache/tasks/apache.yml @@ -28,7 +28,7 @@ apache2_module: name: '{{ item }}' state: present - with_items: + loop: - ssl - include - negotiation @@ -56,6 +56,6 @@ command: "a2enconf {{ item }}" register: command_result changed_when: "'Enabling' in command_result.stderr" - with_items: + loop: - evolinux-evasive - evolinux-modsec diff --git a/packweb-apache/tasks/fhs_retrictions.yml b/packweb-apache/tasks/fhs_retrictions.yml index 1d370038..7fa41478 100644 --- a/packweb-apache/tasks/fhs_retrictions.yml +++ b/packweb-apache/tasks/fhs_retrictions.yml @@ -5,7 +5,7 @@ register: command_result changed_when: "'changed' in command_result.stdout" failed_when: False - with_items: + loop: - / - /etc - /usr @@ -29,7 +29,7 @@ register: command_result changed_when: "'changed' in command_result.stdout" failed_when: False - with_items: + loop: - /var/log/apt - /var/lib/dpkg - /var/log/munin @@ -51,7 +51,7 @@ register: command_result changed_when: "'changed' in command_result.stdout" failed_when: False - with_items: + loop: - /bin/ping - /bin/ping6 - /usr/bin/fping @@ -63,6 +63,6 @@ register: command_result changed_when: "'changed' in command_result.stdout" failed_when: False - with_items: + loop: - /var/log/evolix.log - /etc/warnquota.conf diff --git a/packweb-apache/tasks/main.yml b/packweb-apache/tasks/main.yml index 922dcea8..6122c4a2 100644 --- a/packweb-apache/tasks/main.yml +++ b/packweb-apache/tasks/main.yml @@ -41,7 +41,7 @@ path: "/etc/skel/{{ item.path }}" state: "{{ item.state }}" mode: "{{ item.mode }}" - with_items: + loop: - { path: log, mode: "0750", state: directory } - { path: awstats, mode: "0750", state: directory } - { path: www, mode: "0750", state: directory } @@ -50,7 +50,7 @@ command: "touch /etc/skel/log/{{ item }}" args: creates: "/etc/skel/log/{{ item }}" - with_items: + loop: - access.log - error.log @@ -58,7 +58,7 @@ file: dest: "/etc/skel/log/{{ item }}" mode: "0644" - with_items: + loop: - access.log - error.log @@ -85,7 +85,6 @@ - include: apache.yml - include: phpmyadmin.yml - when: ansible_distribution_release != "buster" - include: awstats.yml diff --git a/php/tasks/config_apache.yml b/php/tasks/config_apache.yml index 1ce74733..3ae9738c 100644 --- a/php/tasks/config_apache.yml +++ b/php/tasks/config_apache.yml @@ -8,7 +8,7 @@ value: "{{ item.value }}" mode: "0644" create: yes - with_items: + loop: - { option: "short_open_tag", value: "Off" } - { option: "expose_php", value: "Off" } - { option: "display_errors", value: "Off" } @@ -42,6 +42,6 @@ option: "{{ item.option }}" value: "{{ item.value }}" mode: "0644" - with_items: + loop: - { option: "date.timezone", value: "Europe/Paris" } when: php_symfony_requirements diff --git a/php/tasks/config_cli.yml b/php/tasks/config_cli.yml index 23ed695c..c4678cd5 100644 --- a/php/tasks/config_cli.yml +++ b/php/tasks/config_cli.yml @@ -7,7 +7,7 @@ value: "{{ item.value }}" mode: "0644" create: yes - with_items: + loop: - { option: "display_errors", value: "On" } - { option: "allow_url_fopen", value: "On" } - { option: "disable_functions", value: "" } @@ -33,6 +33,6 @@ option: "{{ item.option }}" value: "{{ item.value }}" mode: "0644" - with_items: + loop: - { option: "date.timezone", value: "Europe/Paris" } when: php_symfony_requirements diff --git a/php/tasks/config_fpm.yml b/php/tasks/config_fpm.yml index 1644fd6a..57680ea9 100644 --- a/php/tasks/config_fpm.yml +++ b/php/tasks/config_fpm.yml @@ -8,7 +8,7 @@ value: "{{ item.value }}" mode: "0644" create: yes - with_items: + loop: - { option: "short_open_tag", value: "Off" } - { option: "expose_php", value: "Off" } - { option: "display_errors", value: "Off" } @@ -43,7 +43,7 @@ value: "{{ item.value }}" mode: "0644" create: yes - with_items: + loop: - { option: "user", value: "www-data" } - { option: "group", value: "www-data" } - { option: "listen", value: "{{ php_fpm_default_pool_socket }}" } @@ -76,7 +76,7 @@ option: "{{ item.option }}" value: "{{ item.value }}" mode: "0644" - with_items: + loop: - { option: "date.timezone", value: "Europe/Paris" } notify: "restart {{ php_fpm_service_name }}" when: php_symfony_requirements diff --git a/php/tasks/main_buster.yml b/php/tasks/main_buster.yml index 16eed389..c757d539 100644 --- a/php/tasks/main_buster.yml +++ b/php/tasks/main_buster.yml @@ -65,7 +65,7 @@ file: dest: "{{ item }}" mode: "0755" - with_items: + loop: - /etc/php - /etc/php/7.3 diff --git a/php/tasks/main_stretch.yml b/php/tasks/main_stretch.yml index 136fa346..004aec02 100644 --- a/php/tasks/main_stretch.yml +++ b/php/tasks/main_stretch.yml @@ -65,7 +65,7 @@ file: dest: "{{ item }}" mode: "0755" - with_items: + loop: - /etc/php - /etc/php/7.0 diff --git a/php/tasks/sury_post.yml b/php/tasks/sury_post.yml index ecfb13dc..3f82d23d 100644 --- a/php/tasks/sury_post.yml +++ b/php/tasks/sury_post.yml @@ -6,7 +6,7 @@ dest: "{{ item.dest }}" force: yes state: link - with_items: + loop: - { src: "{{ php_cli_defaults_ini_file }}", dest: "/etc/php/7.4/cli/conf.d/z-evolinux-defaults.ini" } - { src: "{{ php_cli_custom_ini_file }}", dest: "/etc/php/7.4/cli/conf.d/zzz-evolinux-custom.ini" } @@ -21,7 +21,7 @@ dest: "{{ item.dest }}" force: yes state: link - with_items: + loop: - { src: "{{ php_apache_defaults_ini_file }}", dest: "/etc/php/7.4/apache2/conf.d/z-evolinux-defaults.ini" } - { src: "{{ php_apache_custom_ini_file }}", dest: "/etc/php/7.4/apache2/conf.d/zzz-evolinux-custom.ini" } when: php_apache_enable @@ -38,7 +38,7 @@ dest: "{{ item.dest }}" force: yes state: link - with_items: + loop: - { src: "{{ php_fpm_defaults_ini_file }}", dest: "/etc/php/7.4/fpm/conf.d/z-evolinux-defaults.ini" } - { src: "{{ php_fpm_custom_ini_file }}", dest: "/etc/php/7.4/fpm/conf.d/zzz-evolinux-custom.ini" } - { src: "{{ php_fpm_defaults_conf_file }}", dest: "/etc/php/7.4/fpm/pool.d/z-evolinux-defaults.conf" } diff --git a/postfix/tasks/common.yml b/postfix/tasks/common.yml index 08ee6a56..bcd5ed79 100644 --- a/postfix/tasks/common.yml +++ b/postfix/tasks/common.yml @@ -14,7 +14,7 @@ line: '{{ item }}' state: present create: no - with_items: + loop: - "postfix/sa-blacklist.access" - "postfix/*.db" tags: diff --git a/postfix/tasks/packmail.yml b/postfix/tasks/packmail.yml index f6900639..cf4482ed 100644 --- a/postfix/tasks/packmail.yml +++ b/postfix/tasks/packmail.yml @@ -37,7 +37,7 @@ src: filter dest: "/etc/postfix/{{ item }}" force: no - with_items: + loop: - virtual - client.access - client.access_local @@ -55,7 +55,7 @@ - name: postmap filter files command: "postmap /etc/postfix/{{ item }}" - with_items: + loop: - virtual - client.access - client.access_local @@ -76,7 +76,7 @@ src: "{{ item }}.j2" dest: "/etc/postfix/{{ item }}" mode: "0644" - with_items: + loop: - virtual_aliases.cf - virtual_domains.cf - virtual_mailboxes.cf diff --git a/postfix/tasks/slow_transport.yml b/postfix/tasks/slow_transport.yml index 2f4cab1e..2f1867ae 100644 --- a/postfix/tasks/slow_transport.yml +++ b/postfix/tasks/slow_transport.yml @@ -13,7 +13,7 @@ dest: /etc/postfix/transport line: "{{ item }}" create: yes - with_items: + loop: - "orange.fr slow:" - "wanadoo.fr slow:" - "voila.fr slow:" diff --git a/postgresql/tasks/locales.yml b/postgresql/tasks/locales.yml index 89687a7c..8cf70989 100644 --- a/postgresql/tasks/locales.yml +++ b/postgresql/tasks/locales.yml @@ -6,7 +6,7 @@ locale_gen: name: "{{ item }}" state: present - with_items: + loop: - "fr_FR.UTF-8" become: yes notify: reconfigure locales diff --git a/postgresql/tasks/munin.yml b/postgresql/tasks/munin.yml index e576b4cd..5292b017 100644 --- a/postgresql/tasks/munin.yml +++ b/postgresql/tasks/munin.yml @@ -14,7 +14,7 @@ state: link src: '/usr/share/munin/plugins/{{item}}' dest: '/etc/munin/plugins/{{item}}' - with_items: + loop: - postgres_bgwriter - postgres_checkpoints - postgres_connections_db diff --git a/postgresql/tasks/packages_jessie.yml b/postgresql/tasks/packages_jessie.yml index 3e21bc0e..ba21632e 100644 --- a/postgresql/tasks/packages_jessie.yml +++ b/postgresql/tasks/packages_jessie.yml @@ -11,7 +11,7 @@ - name: Install postgresql package apt: name: '{{item}}' - with_items: + loop: - "postgresql-{{postgresql_version}}" - ptop - libdbd-pg-perl diff --git a/postgresql/tests/test.yml b/postgresql/tests/test.yml index d8386b29..06bd32ac 100644 --- a/postgresql/tests/test.yml +++ b/postgresql/tests/test.yml @@ -15,7 +15,7 @@ create: yes state: present changed_when: false - with_items: + loop: - "en_US.UTF-8 UTF-8" - "fr_FR ISO-8859-1" - "fr_FR.UTF-8 UTF-8" diff --git a/proftpd/tasks/accounts.yml b/proftpd/tasks/accounts.yml index 95098df2..20b1d3d2 100644 --- a/proftpd/tasks/accounts.yml +++ b/proftpd/tasks/accounts.yml @@ -1,14 +1,14 @@ --- - include: accounts_password.yml when: item.password is undefined - with_items: "{{ proftpd_accounts }}" + loop: "{{ proftpd_accounts }}" tags: - proftpd - set_fact: proftpd_accounts_final: "{{ proftpd_accounts_final + [ item ] }}" when: item.password is defined - with_items: "{{ proftpd_accounts }}" + loop: "{{ proftpd_accounts }}" tags: - proftpd @@ -20,7 +20,7 @@ mode: "0440" line: "{{ item.name | mandatory }}:{{ item.password }}:{{ item.uid }}:{{ item.gid }}::{{ item.home | mandatory }}:/bin/false" regexp: "^{{ item.name }}:.*" - with_items: "{{ proftpd_accounts_final }}" + loop: "{{ proftpd_accounts_final }}" notify: restart proftpd tags: - proftpd @@ -31,7 +31,7 @@ state: present line: "\tAllowUser {{ item.name }}" insertbefore: "DenyAll" - with_items: "{{ proftpd_accounts_final }}" + loop: "{{ proftpd_accounts_final }}" notify: restart proftpd when: proftpd_ftp_enable tags: @@ -43,7 +43,7 @@ state: present line: "\tAllowUser {{ item.name }}" insertbefore: "DenyAll" - with_items: "{{ proftpd_accounts_final }}" + loop: "{{ proftpd_accounts_final }}" notify: restart proftpd when: proftpd_ftps_enable tags: @@ -55,7 +55,7 @@ state: present line: "\tAllowUser {{ item.name }}" insertbefore: "DenyAll" - with_items: "{{ proftpd_accounts_final }}" + loop: "{{ proftpd_accounts_final }}" notify: restart proftpd when: proftpd_sftp_enable tags: diff --git a/rbenv/tasks/main.yml b/rbenv/tasks/main.yml index 28f25481..08f8242e 100644 --- a/rbenv/tasks/main.yml +++ b/rbenv/tasks/main.yml @@ -46,7 +46,7 @@ owner: '{{ username }}' group: '{{ username }}' create: yes - with_items: '{{ rbenv_default_gems }}' + loop: '{{ rbenv_default_gems }}' become_user: "{{ username }}" become: yes tags: @@ -68,7 +68,7 @@ version: '{{ item.version }}' accept_hostkey: yes force: yes - with_items: + loop: - "{{ rbenv_plugins }}" become_user: "{{ username }}" become: yes diff --git a/redis/tasks/default-munin.yml b/redis/tasks/default-munin.yml index b7edce3a..c94f171a 100644 --- a/redis/tasks/default-munin.yml +++ b/redis/tasks/default-munin.yml @@ -41,7 +41,7 @@ src: /usr/local/share/munin/plugins/redis_ dest: "/etc/munin/plugins/redis_{{item}}" state: link - with_items: + loop: - connected_clients - key_ratio - keys_per_sec diff --git a/redis/tasks/instance-munin.yml b/redis/tasks/instance-munin.yml index 8d0e207c..80c67c6f 100644 --- a/redis/tasks/instance-munin.yml +++ b/redis/tasks/instance-munin.yml @@ -41,7 +41,7 @@ src: /usr/local/share/munin/plugins/redis_ dest: "/etc/munin/plugins/{{ redis_instance_name }}_redis_{{item}}" state: link - with_items: + loop: - connected_clients - key_ratio - keys_per_sec diff --git a/redis/tasks/instance-server.yml b/redis/tasks/instance-server.yml index 1b491d9a..d5f7e8e8 100644 --- a/redis/tasks/instance-server.yml +++ b/redis/tasks/instance-server.yml @@ -44,7 +44,7 @@ group: "root" follow: yes state: directory - with_items: + loop: - "{{ redis_conf_dir }}/redis-server.pre-up.d" - "{{ redis_conf_dir }}/redis-server.post-up.d" - "{{ redis_conf_dir }}/redis-server.pre-down.d" @@ -59,7 +59,7 @@ command: "cp -a /etc/redis/{{ item }}/00_example {{ redis_conf_dir }}/{{ item }}" args: creates: "{{ redis_conf_dir }}/{{ item }}/00_example" - with_items: + loop: - "redis-server.pre-up.d" - "redis-server.post-up.d" - "redis-server.pre-down.d" @@ -78,7 +78,7 @@ group: "redis-{{ redis_instance_name }}" follow: yes state: directory - with_items: + loop: - "{{ redis_pid_dir }}" - "{{ redis_socket_dir }}" tags: @@ -92,7 +92,7 @@ group: "redis-{{ redis_instance_name }}" follow: yes state: directory - with_items: + loop: - "{{ redis_data_dir }}" - "{{ redis_log_dir }}" tags: diff --git a/redmine/tasks/config.yml b/redmine/tasks/config.yml index a08ba1c6..d65f8172 100644 --- a/redmine/tasks/config.yml +++ b/redmine/tasks/config.yml @@ -6,7 +6,7 @@ mode: "0750" owner: "{{ redmine_user }}" group: "{{ redmine_user }}" - with_items: + loop: - ".config" - ".config/systemd" - ".config/systemd/user" @@ -50,7 +50,7 @@ owner: "{{ redmine_user }}" group: "{{ redmine_user }}" mode: "0640" - with_items: + loop: - 'configuration.yml' - 'database.yml' - 'additional_environment.rb' diff --git a/redmine/tasks/mysql.yml b/redmine/tasks/mysql.yml index 414da319..64e42683 100644 --- a/redmine/tasks/mysql.yml +++ b/redmine/tasks/mysql.yml @@ -42,7 +42,7 @@ section: client option: '{{ item.option }}' value: '{{ item.value }}' - with_items: + loop: - { option: 'host', value: "{{ redmine_db_host }}" } - { option: 'user', value: "{{ redmine_db_username }}" } - { option: 'database', value: "{{ redmine_db_name }}" } diff --git a/redmine/tasks/source.yml b/redmine/tasks/source.yml index 51427acf..7893a5ad 100644 --- a/redmine/tasks/source.yml +++ b/redmine/tasks/source.yml @@ -6,7 +6,7 @@ owner: "{{ redmine_user }}" group: "{{ redmine_user }}" mode: "0750" - with_items: + loop: - "releases" - "releases/{{ redmine_version }}" tags: @@ -30,7 +30,7 @@ dest: "/home/{{ redmine_user }}/releases/{{ redmine_version }}/config/{{ item }}" owner: "{{ redmine_user }}" group: "{{ redmine_user }}" - with_items: + loop: - 'configuration.yml' - 'database.yml' - 'additional_environment.rb' @@ -46,7 +46,7 @@ group: "{{ redmine_user }}" mode: "0750" when: item.zip is defined - with_items: "{{ redmine_plugins }}" + loop: "{{ redmine_plugins }}" tags: - redmine @@ -58,7 +58,7 @@ umask: "027" become_user: "{{ redmine_user }}" when: item.git is defined - with_items: "{{ redmine_plugins }}" + loop: "{{ redmine_plugins }}" tags: - redmine @@ -71,7 +71,7 @@ group: "{{ redmine_user }}" mode: "0750" when: item.zip is defined - with_items: "{{ redmine_themes }}" + loop: "{{ redmine_themes }}" tags: - redmine @@ -83,7 +83,7 @@ umask: "027" become_user: "{{ redmine_user }}" when: item.git is defined - with_items: "{{ redmine_themes }}" + loop: "{{ redmine_themes }}" tags: - redmine diff --git a/redmine/tasks/user.yml b/redmine/tasks/user.yml index ecc5b6d5..932e049c 100644 --- a/redmine/tasks/user.yml +++ b/redmine/tasks/user.yml @@ -33,7 +33,7 @@ owner: "{{ redmine_user }}" group: "{{ redmine_user }}" mode: "0750" - with_items: + loop: - "/home/{{ redmine_user }}" - "/home/{{ redmine_user }}/files" tags: diff --git a/squid/tasks/main.yml b/squid/tasks/main.yml index 68f721f8..bca2db5a 100644 --- a/squid/tasks/main.yml +++ b/squid/tasks/main.yml @@ -119,7 +119,7 @@ dest: /etc/squid3/whitelist.conf line: "{{ item }}" state: present - with_items: '{{ squid_whitelist_items }}' + loop: '{{ squid_whitelist_items }}' notify: "reload squid3" when: ansible_distribution_major_version == '8' @@ -129,7 +129,7 @@ dest: /etc/squid/evolinux-whitelist-custom.conf line: "{{ item }}" state: present - with_items: '{{ squid_whitelist_items }}' + loop: '{{ squid_whitelist_items }}' notify: "reload squid" when: ansible_distribution_major_version is version('9', '>=') diff --git a/squid/tasks/minifirewall.yml b/squid/tasks/minifirewall.yml index 44c7ada6..e878b0a8 100644 --- a/squid/tasks/minifirewall.yml +++ b/squid/tasks/minifirewall.yml @@ -27,7 +27,7 @@ regexp: "^#? *{{ item }}" line: "{{ item }}" insertafter: "^# Proxy" - with_items: + loop: - "/sbin/iptables -t nat -A OUTPUT -p tcp --dport 80 -m owner --uid-owner proxy -j ACCEPT" - "/sbin/iptables -t nat -A OUTPUT -p tcp --dport 80 -d {{ squid_address }} -j ACCEPT" - "/sbin/iptables -t nat -A OUTPUT -p tcp --dport 80 -d 127.0.0.0/8 -j ACCEPT" diff --git a/tomcat-instance/tasks/bootstrap.yml b/tomcat-instance/tasks/bootstrap.yml index c177aea9..001088b1 100644 --- a/tomcat-instance/tasks/bootstrap.yml +++ b/tomcat-instance/tasks/bootstrap.yml @@ -6,7 +6,7 @@ mode: "u=rwx,g=rwxs,o=" owner: "{{ tomcat_instance_name }}" group: "{{ tomcat_instance_name }}" - with_items: + loop: - 'conf' - 'logs' - 'webapps' diff --git a/varnish/tasks/main.yml b/varnish/tasks/main.yml index a8f9fa80..14515698 100644 --- a/varnish/tasks/main.yml +++ b/varnish/tasks/main.yml @@ -10,7 +10,7 @@ file: path: "{{ item }}" state: absent - with_items: + loop: - /etc/default/varnish - /etc/default/varnishncsa - /etc/default/varnishlog diff --git a/varnish/tasks/munin.yml b/varnish/tasks/munin.yml index 6e307c49..1d58aee6 100644 --- a/varnish/tasks/munin.yml +++ b/varnish/tasks/munin.yml @@ -35,7 +35,7 @@ src: /usr/local/share/munin/plugins/varnish4_ dest: "/etc/munin/plugins/varnish4_{{item}}" state: link - with_items: + loop: - backend_traffic - bad - expunge diff --git a/vrrpd/tasks/main.yml b/vrrpd/tasks/main.yml index b6f4e7f5..84d4f4ee 100644 --- a/vrrpd/tasks/main.yml +++ b/vrrpd/tasks/main.yml @@ -18,7 +18,7 @@ value: "{{ item.value }}" sysctl_set: yes state: present - with_items: + loop: - { name: 'net.ipv4.conf.default.rp_filter', value: 0 } - { name: 'net.ipv4.conf.eth0.rp_filter', value: 0 } - { name: 'net.ipv4.conf.all.rp_filter', value: 0 } diff --git a/webapps/evoadmin-web/tasks/packages.yml b/webapps/evoadmin-web/tasks/packages.yml index 7d3f6051..7044bd43 100644 --- a/webapps/evoadmin-web/tasks/packages.yml +++ b/webapps/evoadmin-web/tasks/packages.yml @@ -19,7 +19,7 @@ apt: deb: '{{ item }}' state: present - with_items: + loop: - 'http://mirror.evolix.org/debian/pool/main/p/php-log/php-log_1.12.9-2_all.deb' when: ansible_distribution_major_version is version('10', '>=') diff --git a/webapps/evoadmin-web/tasks/user.yml b/webapps/evoadmin-web/tasks/user.yml index 9c774f0d..4593dcf3 100644 --- a/webapps/evoadmin-web/tasks/user.yml +++ b/webapps/evoadmin-web/tasks/user.yml @@ -37,7 +37,7 @@ line: "{{ item.line }}" regexp: "{{ item.regexp }}" state: present - with_items: + loop: - line: 'evoadmin: root' regexp: '^evoadmin:' - line: 'www-evoadmin: root' diff --git a/webapps/nextcloud/tasks/mysql.yml b/webapps/nextcloud/tasks/mysql.yml index f2fcee32..a12a80f4 100644 --- a/webapps/nextcloud/tasks/mysql.yml +++ b/webapps/nextcloud/tasks/mysql.yml @@ -54,7 +54,7 @@ section: client option: "{{ item.option }}" value: "{{ item.value }}" - with_items: + loop: - { option: "user", value: "{{ nextcloud_db_user }}" } - { option: "database", value: "{{ nextcloud_db_name }}" } - { option: "password", value: "{{ nextcloud_db_pass }}" } diff --git a/webapps/nextcloud/tasks/user.yml b/webapps/nextcloud/tasks/user.yml index 07d5a31a..dd1d7cc5 100644 --- a/webapps/nextcloud/tasks/user.yml +++ b/webapps/nextcloud/tasks/user.yml @@ -30,7 +30,7 @@ mode: "0770" owner: "{{ nextcloud_user }}" group: "{{ nextcloud_user }}" - with_items: + loop: - "{{ nextcloud_home }}/log" - "{{ nextcloud_home }}/tmp" - "{{ nextcloud_home }}/data" diff --git a/webapps/roundcube/tasks/main.yml b/webapps/roundcube/tasks/main.yml index 2efd1823..46eaa022 100644 --- a/webapps/roundcube/tasks/main.yml +++ b/webapps/roundcube/tasks/main.yml @@ -5,7 +5,7 @@ question: "{{ item.key }}" value: "{{ item.value }}" vtype: "{{ item.type }}" - with_items: + loop: - { key: 'roundcube/database-type', type: 'select', value: 'sqlite3' } - { key: 'roundcube/db/basepath', type: 'string', value: '/var/lib/roundcube/' } tags: diff --git a/webapps/wordpress/tasks/main.yml b/webapps/wordpress/tasks/main.yml index 6b6a67e2..db94b9f4 100644 --- a/webapps/wordpress/tasks/main.yml +++ b/webapps/wordpress/tasks/main.yml @@ -66,17 +66,17 @@ - name: Install default plugin shell: '{{ wordpress_wpcli }} plugin is-installed {{ item }} || {{ wordpress_wpcli }} plugin install {{ item }}' changed_when: false - with_items: "{{ wordpress_plugins }}" + loop: "{{ wordpress_plugins }}" - name: Update default plugins shell: '{{ wordpress_wpcli }} plugin is-installed {{ item }} && {{ wordpress_wpcli }} plugin update {{ item }}' changed_when: false - with_items: "{{ wordpress_plugins }}" + loop: "{{ wordpress_plugins }}" - name: Activate default plugins shell: '{{ wordpress_wpcli }} plugin is-installed {{ item }} && {{ wordpress_wpcli }} plugin activate {{ item }}' changed_when: false - with_items: "{{ wordpress_plugins }}" + loop: "{{ wordpress_plugins }}" - name: Send a summary mail mail: From 07fd6451e125c8218e8aae499c4dd645d74794dc Mon Sep 17 00:00:00 2001 From: Jeremy Lecour Date: Tue, 4 May 2021 14:20:53 +0200 Subject: [PATCH 25/86] Use 'loop' syntax instead of 'with_dict' --- CHANGELOG.md | 2 +- evolinux-users/tasks/main.yml | 4 ++-- evolinux-users/tasks/ssh.yml | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8d8b9417..f994d98f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -19,7 +19,7 @@ The **patch** part changes incrementally at each release. ### Changed -* Use 'loop' syntax instead of 'with_first_found/with_items' +* Use 'loop' syntax instead of 'with_first_found/with_items/with_dict' * apt: store keys in /etc/apt/trusted.gpg.d in ascii format * evolinux-base: copy GPG key instead of using apt-key * ntpd: Add leapfile configuration setting to ntpd on debian 10+ diff --git a/evolinux-users/tasks/main.yml b/evolinux-users/tasks/main.yml index b3be0c8d..20cdf040 100644 --- a/evolinux-users/tasks/main.yml +++ b/evolinux-users/tasks/main.yml @@ -15,14 +15,14 @@ include: user.yml vars: user: "{{ item.value }}" - with_dict: "{{ evolinux_users }}" + loop: "{{ evolinux_users | dict2items }}" when: evolinux_users != {} - name: Configure sudo include: sudo.yml vars: user: "{{ item.value }}" - with_dict: "{{ evolinux_users }}" + loop: "{{ evolinux_users | dict2items }}" when: evolinux_users != {} - name: Configure SSH diff --git a/evolinux-users/tasks/ssh.yml b/evolinux-users/tasks/ssh.yml index e21f0978..06a05b89 100644 --- a/evolinux-users/tasks/ssh.yml +++ b/evolinux-users/tasks/ssh.yml @@ -48,7 +48,7 @@ - include: ssh_allowusers.yml vars: user: "{{ item.value }}" - with_dict: "{{ evolinux_users }}" + loop: "{{ evolinux_users | dict2items }}" when: - ssh_allowusers - not ssh_allowgroups From 485ec396747214a7bd15ea8625551ba0fedbbd7b Mon Sep 17 00:00:00 2001 From: Jeremy Lecour Date: Tue, 4 May 2021 14:29:50 +0200 Subject: [PATCH 26/86] Use 'loop' syntax instead of 'with_nested' --- CHANGELOG.md | 2 +- kvm-host/tasks/ssh.yml | 7 ++++--- mysql-oracle/tasks/users.yml | 11 ++++++----- mysql/tasks/users_stretch.yml | 17 +++++++++-------- postgresql/tasks/munin.yml | 7 ++++--- 5 files changed, 24 insertions(+), 20 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f994d98f..46475fb4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -19,7 +19,7 @@ The **patch** part changes incrementally at each release. ### Changed -* Use 'loop' syntax instead of 'with_first_found/with_items/with_dict' +* Use 'loop' syntax instead of 'with_first_found/with_items/with_dict/with_nested' * apt: store keys in /etc/apt/trusted.gpg.d in ascii format * evolinux-base: copy GPG key instead of using apt-key * ntpd: Add leapfile configuration setting to ntpd on debian 10+ diff --git a/kvm-host/tasks/ssh.yml b/kvm-host/tasks/ssh.yml index 7e42238b..1b0f7915 100644 --- a/kvm-host/tasks/ssh.yml +++ b/kvm-host/tasks/ssh.yml @@ -21,9 +21,10 @@ state: present key: "{{ item[0] }}" delegate_to: "{{ item[1] }}" - with_nested: - - "{{ ssh_keys.stdout }}" - - "{{ groups['hypervisors'] }}" + loop: "{{ _keys | product(_servers) | list }}" + vars: + _keys: ssh_keys.stdout + _servers: groups['hypervisors'] when: item[1] != inventory_hostname - name: Crontab for sync libvirt xml file diff --git a/mysql-oracle/tasks/users.yml b/mysql-oracle/tasks/users.yml index 508ab4cc..da1ca05f 100644 --- a/mysql-oracle/tasks/users.yml +++ b/mysql-oracle/tasks/users.yml @@ -71,11 +71,12 @@ option: '{{ item[1].option }}' value: '{{ item[1].value }}' create: yes - with_nested: - - [ "client", "mysql_upgrade" ] - - [ { option: 'user', value: 'debian-sys-maint' }, - { option: 'password', value: '{{ mysql_debian_password.stdout }}' } - ] + loop: "{{ _sections | product(_credentials) | list }}" + vars: + _sections: [ 'client', 'mysql_upgrade' ] + _credentials: + - { option: 'user', value: 'debian-sys-maint' } + - { option: 'password', value: '{{ mysql_debian_password.stdout }}' } when: create_debian_user is changed tags: - mysql diff --git a/mysql/tasks/users_stretch.yml b/mysql/tasks/users_stretch.yml index 0613de19..bca16bc6 100644 --- a/mysql/tasks/users_stretch.yml +++ b/mysql/tasks/users_stretch.yml @@ -63,7 +63,7 @@ config_file: "/root/.my.cnf" register: create_debian_user tags: - - mysql + - mysql - name: store debian-sys-maint user credentials ini_file: @@ -73,14 +73,15 @@ option: '{{ item[1].option }}' value: '{{ item[1].value }}' create: yes - with_nested: - - [ "client", "mysql_upgrade" ] - - [ { option: 'user', value: 'debian-sys-maint' }, - { option: 'password', value: '{{ mysql_debian_password.stdout }}' } - ] + loop: "{{ _sections | product(_credentials) | list }}" + vars: + _sections: [ 'client', 'mysql_upgrade' ] + _credentials: + - { option: 'user', value: 'debian-sys-maint' } + - { option: 'password', value: '{{ mysql_debian_password.stdout }}' } when: create_debian_user.changed tags: - - mysql + - mysql - name: remove root user mysql_user: @@ -89,4 +90,4 @@ config_file: "/root/.my.cnf" state: absent tags: - - mysql + - mysql diff --git a/postgresql/tasks/munin.yml b/postgresql/tasks/munin.yml index 5292b017..4e62ddf6 100644 --- a/postgresql/tasks/munin.yml +++ b/postgresql/tasks/munin.yml @@ -28,8 +28,9 @@ state: link src: '/usr/share/munin/plugins/{{item[0]}}' dest: '/etc/munin/plugins/{{item[0]}}{{item[1]}}' - with_nested: - - ['postgres_cache_', 'postgres_connections_', 'postgres_locks_', 'postgres_querylength_', 'postgres_scans_', 'postgres_size_', 'postgres_transactions_', 'postgres_tuples_'] - - '{{postgresql_databases}}' + loop: "{{ _plugins | product(_databases) | list }}" + vars: + _plugins: ['postgres_cache_', 'postgres_connections_', 'postgres_locks_', 'postgres_querylength_', 'postgres_scans_', 'postgres_size_', 'postgres_transactions_', 'postgres_tuples_'] + _databases: postgresql_databases notify: restart munin-node when: etc_munin_plugins.stat.exists and usr_share_munin_plugins.stat.exists From e7ddf9d46c047b5eea19bf2aa24b7ed95d6f57fc Mon Sep 17 00:00:00 2001 From: Jeremy Lecour Date: Tue, 4 May 2021 14:31:22 +0200 Subject: [PATCH 27/86] Use 'loop' syntax instead of 'with_list' --- CHANGELOG.md | 2 +- evobackup-client/tasks/verify_ssh.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 46475fb4..7e1e6c00 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -19,7 +19,7 @@ The **patch** part changes incrementally at each release. ### Changed -* Use 'loop' syntax instead of 'with_first_found/with_items/with_dict/with_nested' +* Use 'loop' syntax instead of 'with_first_found/with_items/with_dict/with_nested/with_list' * apt: store keys in /etc/apt/trusted.gpg.d in ascii format * evolinux-base: copy GPG key instead of using apt-key * ntpd: Add leapfile configuration setting to ntpd on debian 10+ diff --git a/evobackup-client/tasks/verify_ssh.yml b/evobackup-client/tasks/verify_ssh.yml index 4e968197..d48fb455 100644 --- a/evobackup-client/tasks/verify_ssh.yml +++ b/evobackup-client/tasks/verify_ssh.yml @@ -5,7 +5,7 @@ path: /root/.ssh/known_hosts name: "[{{ item.name }}]:{{ item.port }}" key: "[{{ item.name }}]:{{ item.port }} {{ item.fingerprint }}" - with_list: "{{ evobackup_client__hosts }}" + loop: "{{ evobackup_client__hosts }}" tags: - evobackup_client - evobackup_client_backup_hosts From e5e4dc95fa32887350bfb7b2da5ab7c09053ac47 Mon Sep 17 00:00:00 2001 From: Jeremy Lecour Date: Tue, 4 May 2021 14:57:18 +0200 Subject: [PATCH 28/86] packweb-apache: install phpMyAdmin from buster-backports --- CHANGELOG.md | 3 ++- packweb-apache/tasks/phpmyadmin.yml | 29 +++++++++++++++++------------ 2 files changed, 19 insertions(+), 13 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7e1e6c00..31f38bf3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -21,9 +21,10 @@ The **patch** part changes incrementally at each release. * Use 'loop' syntax instead of 'with_first_found/with_items/with_dict/with_nested/with_list' * apt: store keys in /etc/apt/trusted.gpg.d in ascii format +* certbot: sync_remote.sh is configurable * evolinux-base: copy GPG key instead of using apt-key * ntpd: Add leapfile configuration setting to ntpd on debian 10+ -* certbot: sync_remote.sh is configurable +* packweb-apache: install phpMyAdmin from buster-backports * spamassassin: change dependency on evomaintenance * squid: remove obsolete variable on Squid 4 diff --git a/packweb-apache/tasks/phpmyadmin.yml b/packweb-apache/tasks/phpmyadmin.yml index fc3e6d32..30c38aa7 100644 --- a/packweb-apache/tasks/phpmyadmin.yml +++ b/packweb-apache/tasks/phpmyadmin.yml @@ -4,20 +4,25 @@ apt: name: apg -- name: Install phpmyadmin (Debian <=9) +# On Debian 10, we need to install the package from buster-backports +- name: Enable backports (Debian 10) + include_role: + name: evolix/apt + tasks_from: backports.yml + when: ansible_distribution_major_version is version('10', '=') + +- name: Prefer phpMyAdmin package from backports (Debian 10) + template: + src: phpmyadmin_apt_preferences.j2 + dest: /etc/apt/preferences.d/999-phpmyadmin + force: yes + mode: "0640" + when: ansible_distribution_major_version is version('10', '=') + +- name: Install phpmyadmin apt: name: phpmyadmin - when: ansible_distribution_major_version is version('9', '<=') - -- include_role: - name: evolix/remount-usr - -# /!\ Warning: this is a temporary hack as phpmyadmin for Buster is not yet -# available -- name: Install phpmyadmin using sid package (Debian >=10) - apt: - deb: http://mirror.evolix.org/debian/pool/main/p/phpmyadmin/phpmyadmin_4.6.6-4_all.deb - when: ansible_distribution_major_version is version('10', '>=') + update_cache: yes - name: Check if phpmyadmin default configuration is present stat: From 9f2125e28797b155986537a7494d83fd07a4289a Mon Sep 17 00:00:00 2001 From: Jeremy Lecour Date: Tue, 4 May 2021 16:43:48 +0200 Subject: [PATCH 29/86] packweb-apache: fix backports for phpmyadmin --- packweb-apache/tasks/phpmyadmin.yml | 2 +- packweb-apache/templates/phpmyadmin_apt_preferences.j2 | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) create mode 100644 packweb-apache/templates/phpmyadmin_apt_preferences.j2 diff --git a/packweb-apache/tasks/phpmyadmin.yml b/packweb-apache/tasks/phpmyadmin.yml index 30c38aa7..39fd1163 100644 --- a/packweb-apache/tasks/phpmyadmin.yml +++ b/packweb-apache/tasks/phpmyadmin.yml @@ -16,7 +16,7 @@ src: phpmyadmin_apt_preferences.j2 dest: /etc/apt/preferences.d/999-phpmyadmin force: yes - mode: "0640" + mode: "0644" when: ansible_distribution_major_version is version('10', '=') - name: Install phpmyadmin diff --git a/packweb-apache/templates/phpmyadmin_apt_preferences.j2 b/packweb-apache/templates/phpmyadmin_apt_preferences.j2 new file mode 100644 index 00000000..02578c0d --- /dev/null +++ b/packweb-apache/templates/phpmyadmin_apt_preferences.j2 @@ -0,0 +1,3 @@ +Package: phpmyadmin php-twig +Pin: release a=buster-backports +Pin-Priority: 999 \ No newline at end of file From 83705a48b8b411f696466124f98ddb015d07b3ef Mon Sep 17 00:00:00 2001 From: Jeremy Lecour Date: Thu, 6 May 2021 10:42:12 +0200 Subject: [PATCH 30/86] remove key from trusted.gpg only if file is present --- apt/tasks/evolix_public.yml | 8 +++++++ elasticsearch/tasks/packages.yml | 29 +++++++++++++++--------- evolinux-base/tasks/hardware.yml | 15 ++++++++++++- filebeat/tasks/main.yml | 25 ++++++++++++++------- fluentd/tasks/main.yml | 9 ++++++++ jenkins/tasks/main.yml | 6 +++++ kibana/tasks/main.yml | 38 +++++++++++++++++++++++++------- logstash/tasks/main.yml | 33 ++++++++++++++++++++------- metricbeat/tasks/main.yml | 25 ++++++++++++++------- mongodb/tasks/main_buster.yml | 6 +++++ newrelic/tasks/sources.yml | 6 +++++ nodejs/tasks/main.yml | 11 +++++++++ nodejs/tasks/yarn.yml | 13 ++++++++++- percona/tasks/main.yml | 6 +++++ postgresql/tasks/pgdg-repo.yml | 6 +++++ 15 files changed, 192 insertions(+), 44 deletions(-) diff --git a/apt/tasks/evolix_public.yml b/apt/tasks/evolix_public.yml index be7baad8..e5e56f0f 100644 --- a/apt/tasks/evolix_public.yml +++ b/apt/tasks/evolix_public.yml @@ -1,9 +1,17 @@ --- +- name: Look for /etc/apt/trusted.gpg + stat: + path: /etc/apt/trusted.gpg + register: apt_trusted_gpg + tags: + - apt + - name: Evolix GPG embedded key is absent apt_key: id: "B8612B5D" state: absent + when: apt_trusted_gpg.stat.exists tags: - apt diff --git a/elasticsearch/tasks/packages.yml b/elasticsearch/tasks/packages.yml index d5d91231..09f45b30 100644 --- a/elasticsearch/tasks/packages.yml +++ b/elasticsearch/tasks/packages.yml @@ -5,16 +5,25 @@ name: apt-transport-https state: present tags: - - elasticsearch - - packages + - elasticsearch + - packages + +- name: Look for /etc/apt/trusted.gpg + stat: + path: /etc/apt/trusted.gpg + register: apt_trusted_gpg + tags: + - elasticsearch + - packages - name: Elastic GPG embedded key is absent apt_key: id: "D88E42B4" state: absent + when: apt_trusted_gpg.stat.exists tags: - - elasticsearch - - packages + - elasticsearch + - packages - name: Elastic GPG key is installed copy: @@ -23,8 +32,8 @@ force: yes mode: "0644" tags: - - elasticsearch - - packages + - elasticsearch + - packages - name: Elastic sources list is available apt_repository: @@ -33,16 +42,16 @@ state: present update_cache: yes tags: - - elasticsearch - - packages + - elasticsearch + - packages - name: Elasticsearch is installed apt: name: elasticsearch state: present tags: - - elasticsearch - - packages + - elasticsearch + - packages - name: Elasticsearch service is enabled service: diff --git a/evolinux-base/tasks/hardware.yml b/evolinux-base/tasks/hardware.yml index 832124bd..d9c4a230 100644 --- a/evolinux-base/tasks/hardware.yml +++ b/evolinux-base/tasks/hardware.yml @@ -37,10 +37,16 @@ - name: HPE Smart Storage Administrator (ssacli) is present block: + - name: Look for /etc/apt/trusted.gpg + stat: + path: /etc/apt/trusted.gpg + register: apt_trusted_gpg + - name: HPE GPG is absent in embedded database apt_key: id: "26C2B797" state: absent + when: apt_trusted_gpg.stat.exists - name: HPE GPG key is installed copy: @@ -100,11 +106,18 @@ - name: MegaRAID SAS package is present block: + - name: Look for /etc/apt/trusted.gpg + stat: + path: /etc/apt/trusted.gpg + register: apt_trusted_gpg + - name: HWRaid GPG embedded key is absent apt_key: id: "23B3D3B4" state: absent - when: ansible_distribution_major_version is version('9', '>=') + when: + - apt_trusted_gpg.stat.exists + - ansible_distribution_major_version is version('9', '>=') - name: HWRaid GPG key is installed copy: diff --git a/filebeat/tasks/main.yml b/filebeat/tasks/main.yml index d5c61322..f0893d10 100644 --- a/filebeat/tasks/main.yml +++ b/filebeat/tasks/main.yml @@ -5,16 +5,25 @@ name: apt-transport-https state: present tags: - - filebeat - - packages + - filebeat + - packages + +- name: Look for /etc/apt/trusted.gpg + stat: + path: /etc/apt/trusted.gpg + register: apt_trusted_gpg + tags: + - filebeat + - packages - name: Elastic GPG embedded key is absent apt_key: id: "D88E42B4" state: absent + when: apt_trusted_gpg.stat.exists tags: - - filebeat - - packages + - filebeat + - packages - name: Elastic GPG key is installed copy: @@ -23,8 +32,8 @@ force: yes mode: "0644" tags: - - filebeat - - packages + - filebeat + - packages - name: Elastic sources list is available apt_repository: @@ -33,8 +42,8 @@ state: present update_cache: yes tags: - - filebeat - - packages + - filebeat + - packages - name: Filebeat is installed apt: diff --git a/fluentd/tasks/main.yml b/fluentd/tasks/main.yml index f66a072c..25dcc3ea 100644 --- a/fluentd/tasks/main.yml +++ b/fluentd/tasks/main.yml @@ -1,9 +1,18 @@ --- +- name: Look for /etc/apt/trusted.gpg + stat: + path: /etc/apt/trusted.gpg + register: apt_trusted_gpg + tags: + - packages + - fluentd + - name: Fluentd GPG embedded key is absent apt_key: id: "AB97ACBE" state: absent + when: apt_trusted_gpg.stat.exists tags: - packages - fluentd diff --git a/jenkins/tasks/main.yml b/jenkins/tasks/main.yml index 9221138e..1c61145d 100644 --- a/jenkins/tasks/main.yml +++ b/jenkins/tasks/main.yml @@ -5,10 +5,16 @@ # http://mirrors.jenkins.io/.* # http://jenkins.mirror.isppower.de/.* +- name: Look for /etc/apt/trusted.gpg + stat: + path: /etc/apt/trusted.gpg + register: apt_trusted_gpg + - name: Jenkins GPG embedded key is absent apt_key: id: "D50582E6" state: absent + when: apt_trusted_gpg.stat.exists - name: Add Jenkins GPG key copy: diff --git a/kibana/tasks/main.yml b/kibana/tasks/main.yml index 832cdee3..86aedb3a 100644 --- a/kibana/tasks/main.yml +++ b/kibana/tasks/main.yml @@ -5,16 +5,25 @@ name: apt-transport-https state: present tags: - - kibana - - packages + - kibana + - packages + +- name: Look for /etc/apt/trusted.gpg + stat: + path: /etc/apt/trusted.gpg + register: apt_trusted_gpg + tags: + - kibana + - packages - name: Elastic GPG embedded key is absent apt_key: id: "D88E42B4" state: absent + when: apt_trusted_gpg.stat.exists tags: - - kibana - - packages + - kibana + - packages - name: Elastic GPG key is installed copy: @@ -23,8 +32,8 @@ force: yes mode: "0644" tags: - - kibana - - packages + - kibana + - packages - name: Elastic sources list is available apt_repository: @@ -33,14 +42,15 @@ state: present update_cache: yes tags: - - kibana - - packages + - kibana + - packages - name: Kibana is installed apt: name: kibana state: present tags: + - kibana - packages - name: kibana server host configuration @@ -50,6 +60,8 @@ regexp: '^server.host:' insertafter: '^#server.host:' notify: restart kibana + tags: + - kibana - name: kibana server basepath configuration lineinfile: @@ -58,6 +70,8 @@ regexp: '^server.basePath:' insertafter: '^#server.basePath:' notify: restart kibana + tags: + - kibana - name: kibana log destination is present file: @@ -66,6 +80,8 @@ group: kibana mode: "0750" state: directory + tags: + - kibana - name: kibana log messages go to custom file lineinfile: @@ -74,12 +90,16 @@ regexp: '^logging.dest:' insertafter: '^#logging.dest:' notify: restart kibana + tags: + - kibana - name: Kibana service is enabled and started systemd: name: kibana enabled: yes state: started + tags: + - kibana - name: Logrotate configuration is enabled copy: @@ -88,6 +108,8 @@ mode: "0644" owner: root group: root + tags: + - kibana # - name: Get mount options for /usr partition # shell: "mount | grep 'on /usr type'" diff --git a/logstash/tasks/main.yml b/logstash/tasks/main.yml index 1160711d..9889bf7d 100644 --- a/logstash/tasks/main.yml +++ b/logstash/tasks/main.yml @@ -5,16 +5,25 @@ name: apt-transport-https state: present tags: - - logstash - - packages + - logstash + - packages + +- name: Look for /etc/apt/trusted.gpg + stat: + path: /etc/apt/trusted.gpg + register: apt_trusted_gpg + tags: + - logstash + - packages - name: Elastic GPG embedded key is absent apt_key: id: "D88E42B4" state: absent + when: apt_trusted_gpg.stat.exists tags: - - logstash - - packages + - logstash + - packages - name: Elastic GPG key is installed copy: @@ -23,8 +32,8 @@ force: yes mode: "0644" tags: - - logstash - - packages + - logstash + - packages - name: Elastic sources list is available apt_repository: @@ -33,20 +42,23 @@ state: present update_cache: yes tags: - - logstash - - packages + - logstash + - packages - name: Logstash is installed apt: name: logstash state: present tags: + - logstash - packages - name: Logstash service is enabled systemd: name: logstash enabled: yes + tags: + - logstash - name: JVM Heap size (min) is set lineinfile: @@ -54,6 +66,7 @@ regexp: "^-Xms" line: "-Xms{{ logstash_jvm_xms }}" tags: + - logstash - config - name: JVM Heap size (max) is set @@ -62,6 +75,7 @@ regexp: "^-Xmx" line: "-Xmx{{ logstash_jvm_xmx }}" tags: + - logstash - config - name: Add a configuration @@ -80,6 +94,9 @@ - "templates/logstash/logstash.default.conf.j2" - "templates/logstash.default.conf.j2" register: logstash_template + tags: + - logstash + - config - debug: var: logstash_template diff --git a/metricbeat/tasks/main.yml b/metricbeat/tasks/main.yml index 5d8ee2c9..f1e8f614 100644 --- a/metricbeat/tasks/main.yml +++ b/metricbeat/tasks/main.yml @@ -5,16 +5,25 @@ name: apt-transport-https state: present tags: - - metricbeat - - packages + - metricbeat + - packages + +- name: Look for /etc/apt/trusted.gpg + stat: + path: /etc/apt/trusted.gpg + register: apt_trusted_gpg + tags: + - metricbeat + - packages - name: Elastic GPG embedded key is absent apt_key: id: "D88E42B4" state: absent + when: apt_trusted_gpg.stat.exists tags: - - metricbeat - - packages + - metricbeat + - packages - name: Elastic GPG key is installed copy: @@ -23,8 +32,8 @@ force: yes mode: "0644" tags: - - metricbeat - - packages + - metricbeat + - packages - name: Elastic sources list is available apt_repository: @@ -33,8 +42,8 @@ state: present update_cache: yes tags: - - metricbeat - - packages + - metricbeat + - packages - name: Metricbeat is installed apt: diff --git a/mongodb/tasks/main_buster.yml b/mongodb/tasks/main_buster.yml index 15e7fdc3..89d2c069 100644 --- a/mongodb/tasks/main_buster.yml +++ b/mongodb/tasks/main_buster.yml @@ -1,9 +1,15 @@ --- +- name: Look for /etc/apt/trusted.gpg + stat: + path: /etc/apt/trusted.gpg + register: apt_trusted_gpg + - name: MongoDB GPG embedded key is absent apt_key: id: "B8612B5D" state: absent + when: apt_trusted_gpg.stat.exists - name: Add MongoDB GPG key copy: diff --git a/newrelic/tasks/sources.yml b/newrelic/tasks/sources.yml index 1272b23b..768f9979 100644 --- a/newrelic/tasks/sources.yml +++ b/newrelic/tasks/sources.yml @@ -1,9 +1,15 @@ --- +- name: Look for /etc/apt/trusted.gpg + stat: + path: /etc/apt/trusted.gpg + register: apt_trusted_gpg + - name: NewRelic GPG embedded key is absent apt_key: id: "548C16BF" state: absent + when: apt_trusted_gpg.stat.exists - name: Add NewRelic GPG key copy: diff --git a/nodejs/tasks/main.yml b/nodejs/tasks/main.yml index eb094938..c1696ee0 100644 --- a/nodejs/tasks/main.yml +++ b/nodejs/tasks/main.yml @@ -7,11 +7,22 @@ tags: - system - packages + - nodejs + +- name: Look for /etc/apt/trusted.gpg + stat: + path: /etc/apt/trusted.gpg + register: apt_trusted_gpg + tags: + - system + - packages + - nodejs - name: NodeJS GPG embedded key is absent apt_key: id: "68576280" state: absent + when: apt_trusted_gpg.stat.exists tags: - system - packages diff --git a/nodejs/tasks/yarn.yml b/nodejs/tasks/yarn.yml index 9ebdbce3..8eca7dec 100644 --- a/nodejs/tasks/yarn.yml +++ b/nodejs/tasks/yarn.yml @@ -1,9 +1,20 @@ --- -- name: NodeJS GPG embedded key is absent +- name: Look for /etc/apt/trusted.gpg + stat: + path: /etc/apt/trusted.gpg + register: apt_trusted_gpg + tags: + - system + - packages + - nodejs + - yarn + +- name: NodeJS GPG embedded key is absent apt_key: id: "86E50310" state: absent + when: apt_trusted_gpg.stat.exists tags: - system - packages diff --git a/percona/tasks/main.yml b/percona/tasks/main.yml index 35c32a80..91706e31 100644 --- a/percona/tasks/main.yml +++ b/percona/tasks/main.yml @@ -3,10 +3,16 @@ - set_fact: percona__apt_config_package_file: "percona-release_latest.{{ ansible_distribution_release }}_all.deb" +- name: Look for /etc/apt/trusted.gpg + stat: + path: /etc/apt/trusted.gpg + register: apt_trusted_gpg + - name: Percona GPG embedded key is absent apt_key: id: "8507EFA5" state: absent + when: apt_trusted_gpg.stat.exists - name: Add Percona GPG key copy: diff --git a/postgresql/tasks/pgdg-repo.yml b/postgresql/tasks/pgdg-repo.yml index 50a96ce0..6d6c9720 100644 --- a/postgresql/tasks/pgdg-repo.yml +++ b/postgresql/tasks/pgdg-repo.yml @@ -13,10 +13,16 @@ repo: "deb http://apt.postgresql.org/pub/repos/apt/ {{ansible_distribution_release}}-pgdg main" update_cache: yes +- name: Look for /etc/apt/trusted.gpg + stat: + path: /etc/apt/trusted.gpg + register: apt_trusted_gpg + - name: PGDG GPG embedded key is absent apt_key: id: "ACCC4CF8" state: absent + when: apt_trusted_gpg.stat.exists - name: Add PGDG GPG key copy: From b049ad79d69a770c83520a4618d590fb31676d79 Mon Sep 17 00:00:00 2001 From: Jeremy Lecour Date: Thu, 6 May 2021 10:50:57 +0200 Subject: [PATCH 31/86] fix indentation --- filebeat/tasks/main.yml | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/filebeat/tasks/main.yml b/filebeat/tasks/main.yml index f0893d10..d4716445 100644 --- a/filebeat/tasks/main.yml +++ b/filebeat/tasks/main.yml @@ -154,13 +154,13 @@ src: "{{ item }}" dest: /etc/filebeat/filebeat.yml force: "{{ filebeat_force_config }}" - loop: "{{ query('first_found', templates) }}" - vars: - templates: - - "templates/filebeat/filebeat.{{ inventory_hostname }}.yml.j2" - - "templates/filebeat/filebeat.{{ host_group }}.yml.j2" - - "templates/filebeat/filebeat.default.yml.j2" - - "templates/filebeat.default.yml.j2" + loop: "{{ query('first_found', templates) }}" + vars: + templates: + - "templates/filebeat/filebeat.{{ inventory_hostname }}.yml.j2" + - "templates/filebeat/filebeat.{{ host_group }}.yml.j2" + - "templates/filebeat/filebeat.default.yml.j2" + - "templates/filebeat.default.yml.j2" notify: restart filebeat when: filebeat_update_config when: filebeat_use_config_template From b41a2fd04f2cb33b4b776064e50cb6a87986a73d Mon Sep 17 00:00:00 2001 From: Jeremy Lecour Date: Thu, 6 May 2021 11:31:42 +0200 Subject: [PATCH 32/86] fix indentation --- apt/tasks/evolix_public.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apt/tasks/evolix_public.yml b/apt/tasks/evolix_public.yml index e5e56f0f..abeffd1f 100644 --- a/apt/tasks/evolix_public.yml +++ b/apt/tasks/evolix_public.yml @@ -3,7 +3,7 @@ - name: Look for /etc/apt/trusted.gpg stat: path: /etc/apt/trusted.gpg - register: apt_trusted_gpg + register: apt_trusted_gpg tags: - apt From 7d08b0a30ab79f4369c48ca14f476159e4772b9e Mon Sep 17 00:00:00 2001 From: Jeremy Lecour Date: Thu, 6 May 2021 11:33:19 +0200 Subject: [PATCH 33/86] rename the tasks for embedded GPG keys --- apt/tasks/evolix_public.yml | 2 +- elasticsearch/tasks/packages.yml | 2 +- evolinux-base/tasks/hardware.yml | 2 +- filebeat/tasks/main.yml | 2 +- fluentd/tasks/main.yml | 2 +- jenkins/tasks/main.yml | 2 +- kibana/tasks/main.yml | 2 +- logstash/tasks/main.yml | 2 +- metricbeat/tasks/main.yml | 2 +- mongodb/tasks/main_buster.yml | 2 +- newrelic/tasks/sources.yml | 2 +- nodejs/tasks/main.yml | 2 +- nodejs/tasks/yarn.yml | 2 +- percona/tasks/main.yml | 2 +- postgresql/tasks/pgdg-repo.yml | 2 +- 15 files changed, 15 insertions(+), 15 deletions(-) diff --git a/apt/tasks/evolix_public.yml b/apt/tasks/evolix_public.yml index abeffd1f..06219740 100644 --- a/apt/tasks/evolix_public.yml +++ b/apt/tasks/evolix_public.yml @@ -7,7 +7,7 @@ tags: - apt -- name: Evolix GPG embedded key is absent +- name: Evolix embedded GPG key is absent apt_key: id: "B8612B5D" state: absent diff --git a/elasticsearch/tasks/packages.yml b/elasticsearch/tasks/packages.yml index 09f45b30..56ef347c 100644 --- a/elasticsearch/tasks/packages.yml +++ b/elasticsearch/tasks/packages.yml @@ -16,7 +16,7 @@ - elasticsearch - packages -- name: Elastic GPG embedded key is absent +- name: Elastic embedded GPG key is absent apt_key: id: "D88E42B4" state: absent diff --git a/evolinux-base/tasks/hardware.yml b/evolinux-base/tasks/hardware.yml index d9c4a230..f1892a43 100644 --- a/evolinux-base/tasks/hardware.yml +++ b/evolinux-base/tasks/hardware.yml @@ -111,7 +111,7 @@ path: /etc/apt/trusted.gpg register: apt_trusted_gpg - - name: HWRaid GPG embedded key is absent + - name: HWRaid embedded GPG key is absent apt_key: id: "23B3D3B4" state: absent diff --git a/filebeat/tasks/main.yml b/filebeat/tasks/main.yml index d4716445..7972bcd8 100644 --- a/filebeat/tasks/main.yml +++ b/filebeat/tasks/main.yml @@ -16,7 +16,7 @@ - filebeat - packages -- name: Elastic GPG embedded key is absent +- name: Elastic embedded GPG key is absent apt_key: id: "D88E42B4" state: absent diff --git a/fluentd/tasks/main.yml b/fluentd/tasks/main.yml index 25dcc3ea..172a1fc3 100644 --- a/fluentd/tasks/main.yml +++ b/fluentd/tasks/main.yml @@ -8,7 +8,7 @@ - packages - fluentd -- name: Fluentd GPG embedded key is absent +- name: Fluentd embedded GPG key is absent apt_key: id: "AB97ACBE" state: absent diff --git a/jenkins/tasks/main.yml b/jenkins/tasks/main.yml index 1c61145d..5584f03d 100644 --- a/jenkins/tasks/main.yml +++ b/jenkins/tasks/main.yml @@ -10,7 +10,7 @@ path: /etc/apt/trusted.gpg register: apt_trusted_gpg -- name: Jenkins GPG embedded key is absent +- name: Jenkins embedded GPG key is absent apt_key: id: "D50582E6" state: absent diff --git a/kibana/tasks/main.yml b/kibana/tasks/main.yml index 86aedb3a..717500ca 100644 --- a/kibana/tasks/main.yml +++ b/kibana/tasks/main.yml @@ -16,7 +16,7 @@ - kibana - packages -- name: Elastic GPG embedded key is absent +- name: Elastic embedded GPG key is absent apt_key: id: "D88E42B4" state: absent diff --git a/logstash/tasks/main.yml b/logstash/tasks/main.yml index 9889bf7d..e390a797 100644 --- a/logstash/tasks/main.yml +++ b/logstash/tasks/main.yml @@ -16,7 +16,7 @@ - logstash - packages -- name: Elastic GPG embedded key is absent +- name: Elastic embedded GPG key is absent apt_key: id: "D88E42B4" state: absent diff --git a/metricbeat/tasks/main.yml b/metricbeat/tasks/main.yml index f1e8f614..4b277833 100644 --- a/metricbeat/tasks/main.yml +++ b/metricbeat/tasks/main.yml @@ -16,7 +16,7 @@ - metricbeat - packages -- name: Elastic GPG embedded key is absent +- name: Elastic embedded GPG key is absent apt_key: id: "D88E42B4" state: absent diff --git a/mongodb/tasks/main_buster.yml b/mongodb/tasks/main_buster.yml index 89d2c069..5e955b11 100644 --- a/mongodb/tasks/main_buster.yml +++ b/mongodb/tasks/main_buster.yml @@ -5,7 +5,7 @@ path: /etc/apt/trusted.gpg register: apt_trusted_gpg -- name: MongoDB GPG embedded key is absent +- name: MongoDB embedded GPG key is absent apt_key: id: "B8612B5D" state: absent diff --git a/newrelic/tasks/sources.yml b/newrelic/tasks/sources.yml index 768f9979..c526d253 100644 --- a/newrelic/tasks/sources.yml +++ b/newrelic/tasks/sources.yml @@ -5,7 +5,7 @@ path: /etc/apt/trusted.gpg register: apt_trusted_gpg -- name: NewRelic GPG embedded key is absent +- name: NewRelic embedded GPG key is absent apt_key: id: "548C16BF" state: absent diff --git a/nodejs/tasks/main.yml b/nodejs/tasks/main.yml index c1696ee0..2baa68a5 100644 --- a/nodejs/tasks/main.yml +++ b/nodejs/tasks/main.yml @@ -18,7 +18,7 @@ - packages - nodejs -- name: NodeJS GPG embedded key is absent +- name: NodeJS embedded GPG key is absent apt_key: id: "68576280" state: absent diff --git a/nodejs/tasks/yarn.yml b/nodejs/tasks/yarn.yml index 8eca7dec..f4fb9d3f 100644 --- a/nodejs/tasks/yarn.yml +++ b/nodejs/tasks/yarn.yml @@ -10,7 +10,7 @@ - nodejs - yarn -- name: NodeJS GPG embedded key is absent +- name: NodeJS embedded GPG key is absent apt_key: id: "86E50310" state: absent diff --git a/percona/tasks/main.yml b/percona/tasks/main.yml index 91706e31..59b70d53 100644 --- a/percona/tasks/main.yml +++ b/percona/tasks/main.yml @@ -8,7 +8,7 @@ path: /etc/apt/trusted.gpg register: apt_trusted_gpg -- name: Percona GPG embedded key is absent +- name: Percona embedded GPG key is absent apt_key: id: "8507EFA5" state: absent diff --git a/postgresql/tasks/pgdg-repo.yml b/postgresql/tasks/pgdg-repo.yml index 6d6c9720..fb83e67d 100644 --- a/postgresql/tasks/pgdg-repo.yml +++ b/postgresql/tasks/pgdg-repo.yml @@ -18,7 +18,7 @@ path: /etc/apt/trusted.gpg register: apt_trusted_gpg -- name: PGDG GPG embedded key is absent +- name: PGDG embedded GPG key is absent apt_key: id: "ACCC4CF8" state: absent From 403ea45eeb888d4e8a672cba274792f7d9a0a38e Mon Sep 17 00:00:00 2001 From: Jeremy Lecour Date: Thu, 6 May 2021 13:03:12 +0200 Subject: [PATCH 34/86] Add forgotten tag --- varnish/tasks/main.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/varnish/tasks/main.yml b/varnish/tasks/main.yml index 14515698..3d2a134d 100644 --- a/varnish/tasks/main.yml +++ b/varnish/tasks/main.yml @@ -109,6 +109,7 @@ tags: - varnish - config + - update-config - name: Copy included Varnish config template: From 58bf79218f61716365c7e83e0851b2530eea4c23 Mon Sep 17 00:00:00 2001 From: Jeremy Lecour Date: Thu, 6 May 2021 13:43:59 +0200 Subject: [PATCH 35/86] remove apt keys specifically from embedded database --- apt/tasks/evolix_public.yml | 9 +-------- elasticsearch/tasks/packages.yml | 10 +--------- evolinux-base/tasks/hardware.yml | 19 ++++--------------- filebeat/tasks/main.yml | 10 +--------- fluentd/tasks/main.yml | 10 +--------- jenkins/tasks/main.yml | 7 +------ kibana/tasks/main.yml | 10 +--------- logstash/tasks/main.yml | 10 +--------- metricbeat/tasks/main.yml | 10 +--------- mongodb/tasks/main_buster.yml | 7 +------ newrelic/tasks/sources.yml | 7 +------ nodejs/tasks/main.yml | 11 +---------- nodejs/tasks/yarn.yml | 12 +----------- percona/tasks/main.yml | 7 +------ postgresql/tasks/pgdg-repo.yml | 7 +------ 15 files changed, 18 insertions(+), 128 deletions(-) diff --git a/apt/tasks/evolix_public.yml b/apt/tasks/evolix_public.yml index 06219740..eefd008e 100644 --- a/apt/tasks/evolix_public.yml +++ b/apt/tasks/evolix_public.yml @@ -1,17 +1,10 @@ --- -- name: Look for /etc/apt/trusted.gpg - stat: - path: /etc/apt/trusted.gpg - register: apt_trusted_gpg - tags: - - apt - - name: Evolix embedded GPG key is absent apt_key: id: "B8612B5D" + keyring: /etc/apt/trusted.gpg state: absent - when: apt_trusted_gpg.stat.exists tags: - apt diff --git a/elasticsearch/tasks/packages.yml b/elasticsearch/tasks/packages.yml index 56ef347c..57beb0cc 100644 --- a/elasticsearch/tasks/packages.yml +++ b/elasticsearch/tasks/packages.yml @@ -8,19 +8,11 @@ - elasticsearch - packages -- name: Look for /etc/apt/trusted.gpg - stat: - path: /etc/apt/trusted.gpg - register: apt_trusted_gpg - tags: - - elasticsearch - - packages - - name: Elastic embedded GPG key is absent apt_key: id: "D88E42B4" + keyring: /etc/apt/trusted.gpg state: absent - when: apt_trusted_gpg.stat.exists tags: - elasticsearch - packages diff --git a/evolinux-base/tasks/hardware.yml b/evolinux-base/tasks/hardware.yml index f1892a43..08f7dd33 100644 --- a/evolinux-base/tasks/hardware.yml +++ b/evolinux-base/tasks/hardware.yml @@ -37,16 +37,11 @@ - name: HPE Smart Storage Administrator (ssacli) is present block: - - name: Look for /etc/apt/trusted.gpg - stat: - path: /etc/apt/trusted.gpg - register: apt_trusted_gpg - - - name: HPE GPG is absent in embedded database + - name: HPE GPG embedded key is absent apt_key: id: "26C2B797" + keyring: /etc/apt/trusted.gpg state: absent - when: apt_trusted_gpg.stat.exists - name: HPE GPG key is installed copy: @@ -106,18 +101,12 @@ - name: MegaRAID SAS package is present block: - - name: Look for /etc/apt/trusted.gpg - stat: - path: /etc/apt/trusted.gpg - register: apt_trusted_gpg - - name: HWRaid embedded GPG key is absent apt_key: id: "23B3D3B4" + keyring: /etc/apt/trusted.gpg state: absent - when: - - apt_trusted_gpg.stat.exists - - ansible_distribution_major_version is version('9', '>=') + when: ansible_distribution_major_version is version('9', '>=') - name: HWRaid GPG key is installed copy: diff --git a/filebeat/tasks/main.yml b/filebeat/tasks/main.yml index 7972bcd8..0f5511eb 100644 --- a/filebeat/tasks/main.yml +++ b/filebeat/tasks/main.yml @@ -8,19 +8,11 @@ - filebeat - packages -- name: Look for /etc/apt/trusted.gpg - stat: - path: /etc/apt/trusted.gpg - register: apt_trusted_gpg - tags: - - filebeat - - packages - - name: Elastic embedded GPG key is absent apt_key: id: "D88E42B4" + keyring: /etc/apt/trusted.gpg state: absent - when: apt_trusted_gpg.stat.exists tags: - filebeat - packages diff --git a/fluentd/tasks/main.yml b/fluentd/tasks/main.yml index 172a1fc3..4e165e2b 100644 --- a/fluentd/tasks/main.yml +++ b/fluentd/tasks/main.yml @@ -1,18 +1,10 @@ --- -- name: Look for /etc/apt/trusted.gpg - stat: - path: /etc/apt/trusted.gpg - register: apt_trusted_gpg - tags: - - packages - - fluentd - - name: Fluentd embedded GPG key is absent apt_key: id: "AB97ACBE" + keyring: /etc/apt/trusted.gpg state: absent - when: apt_trusted_gpg.stat.exists tags: - packages - fluentd diff --git a/jenkins/tasks/main.yml b/jenkins/tasks/main.yml index 5584f03d..e6533e9d 100644 --- a/jenkins/tasks/main.yml +++ b/jenkins/tasks/main.yml @@ -5,16 +5,11 @@ # http://mirrors.jenkins.io/.* # http://jenkins.mirror.isppower.de/.* -- name: Look for /etc/apt/trusted.gpg - stat: - path: /etc/apt/trusted.gpg - register: apt_trusted_gpg - - name: Jenkins embedded GPG key is absent apt_key: id: "D50582E6" + keyring: /etc/apt/trusted.gpg state: absent - when: apt_trusted_gpg.stat.exists - name: Add Jenkins GPG key copy: diff --git a/kibana/tasks/main.yml b/kibana/tasks/main.yml index 717500ca..f4334879 100644 --- a/kibana/tasks/main.yml +++ b/kibana/tasks/main.yml @@ -8,19 +8,11 @@ - kibana - packages -- name: Look for /etc/apt/trusted.gpg - stat: - path: /etc/apt/trusted.gpg - register: apt_trusted_gpg - tags: - - kibana - - packages - - name: Elastic embedded GPG key is absent apt_key: id: "D88E42B4" + keyring: /etc/apt/trusted.gpg state: absent - when: apt_trusted_gpg.stat.exists tags: - kibana - packages diff --git a/logstash/tasks/main.yml b/logstash/tasks/main.yml index e390a797..b4c71b3d 100644 --- a/logstash/tasks/main.yml +++ b/logstash/tasks/main.yml @@ -8,19 +8,11 @@ - logstash - packages -- name: Look for /etc/apt/trusted.gpg - stat: - path: /etc/apt/trusted.gpg - register: apt_trusted_gpg - tags: - - logstash - - packages - - name: Elastic embedded GPG key is absent apt_key: id: "D88E42B4" + keyring: /etc/apt/trusted.gpg state: absent - when: apt_trusted_gpg.stat.exists tags: - logstash - packages diff --git a/metricbeat/tasks/main.yml b/metricbeat/tasks/main.yml index 4b277833..29b88fb6 100644 --- a/metricbeat/tasks/main.yml +++ b/metricbeat/tasks/main.yml @@ -8,19 +8,11 @@ - metricbeat - packages -- name: Look for /etc/apt/trusted.gpg - stat: - path: /etc/apt/trusted.gpg - register: apt_trusted_gpg - tags: - - metricbeat - - packages - - name: Elastic embedded GPG key is absent apt_key: id: "D88E42B4" + keyring: /etc/apt/trusted.gpg state: absent - when: apt_trusted_gpg.stat.exists tags: - metricbeat - packages diff --git a/mongodb/tasks/main_buster.yml b/mongodb/tasks/main_buster.yml index 5e955b11..8bad2bee 100644 --- a/mongodb/tasks/main_buster.yml +++ b/mongodb/tasks/main_buster.yml @@ -1,15 +1,10 @@ --- -- name: Look for /etc/apt/trusted.gpg - stat: - path: /etc/apt/trusted.gpg - register: apt_trusted_gpg - - name: MongoDB embedded GPG key is absent apt_key: id: "B8612B5D" + keyring: /etc/apt/trusted.gpg state: absent - when: apt_trusted_gpg.stat.exists - name: Add MongoDB GPG key copy: diff --git a/newrelic/tasks/sources.yml b/newrelic/tasks/sources.yml index c526d253..330f1ecf 100644 --- a/newrelic/tasks/sources.yml +++ b/newrelic/tasks/sources.yml @@ -1,15 +1,10 @@ --- -- name: Look for /etc/apt/trusted.gpg - stat: - path: /etc/apt/trusted.gpg - register: apt_trusted_gpg - - name: NewRelic embedded GPG key is absent apt_key: id: "548C16BF" + keyring: /etc/apt/trusted.gpg state: absent - when: apt_trusted_gpg.stat.exists - name: Add NewRelic GPG key copy: diff --git a/nodejs/tasks/main.yml b/nodejs/tasks/main.yml index 2baa68a5..af15112b 100644 --- a/nodejs/tasks/main.yml +++ b/nodejs/tasks/main.yml @@ -9,20 +9,11 @@ - packages - nodejs -- name: Look for /etc/apt/trusted.gpg - stat: - path: /etc/apt/trusted.gpg - register: apt_trusted_gpg - tags: - - system - - packages - - nodejs - - name: NodeJS embedded GPG key is absent apt_key: id: "68576280" + keyring: /etc/apt/trusted.gpg state: absent - when: apt_trusted_gpg.stat.exists tags: - system - packages diff --git a/nodejs/tasks/yarn.yml b/nodejs/tasks/yarn.yml index f4fb9d3f..05438e64 100644 --- a/nodejs/tasks/yarn.yml +++ b/nodejs/tasks/yarn.yml @@ -1,20 +1,10 @@ --- -- name: Look for /etc/apt/trusted.gpg - stat: - path: /etc/apt/trusted.gpg - register: apt_trusted_gpg - tags: - - system - - packages - - nodejs - - yarn - - name: NodeJS embedded GPG key is absent apt_key: id: "86E50310" + keyring: /etc/apt/trusted.gpg state: absent - when: apt_trusted_gpg.stat.exists tags: - system - packages diff --git a/percona/tasks/main.yml b/percona/tasks/main.yml index 59b70d53..ede6f394 100644 --- a/percona/tasks/main.yml +++ b/percona/tasks/main.yml @@ -3,16 +3,11 @@ - set_fact: percona__apt_config_package_file: "percona-release_latest.{{ ansible_distribution_release }}_all.deb" -- name: Look for /etc/apt/trusted.gpg - stat: - path: /etc/apt/trusted.gpg - register: apt_trusted_gpg - - name: Percona embedded GPG key is absent apt_key: id: "8507EFA5" + keyring: /etc/apt/trusted.gpg state: absent - when: apt_trusted_gpg.stat.exists - name: Add Percona GPG key copy: diff --git a/postgresql/tasks/pgdg-repo.yml b/postgresql/tasks/pgdg-repo.yml index fb83e67d..11d7893b 100644 --- a/postgresql/tasks/pgdg-repo.yml +++ b/postgresql/tasks/pgdg-repo.yml @@ -13,16 +13,11 @@ repo: "deb http://apt.postgresql.org/pub/repos/apt/ {{ansible_distribution_release}}-pgdg main" update_cache: yes -- name: Look for /etc/apt/trusted.gpg - stat: - path: /etc/apt/trusted.gpg - register: apt_trusted_gpg - - name: PGDG embedded GPG key is absent apt_key: id: "ACCC4CF8" + keyring: /etc/apt/trusted.gpg state: absent - when: apt_trusted_gpg.stat.exists - name: Add PGDG GPG key copy: From 3dde4ee6d368d960d84cd718ad4ed8908bfbd424 Mon Sep 17 00:00:00 2001 From: Jeremy Lecour Date: Thu, 6 May 2021 13:44:22 +0200 Subject: [PATCH 36/86] Rename Sury GPG key --- lxc-php/files/{apt.gpg => sury.gpg} | Bin 1 file changed, 0 insertions(+), 0 deletions(-) rename lxc-php/files/{apt.gpg => sury.gpg} (100%) diff --git a/lxc-php/files/apt.gpg b/lxc-php/files/sury.gpg similarity index 100% rename from lxc-php/files/apt.gpg rename to lxc-php/files/sury.gpg From 2ed77c60f06728c4b47e088511c30645d023db7d Mon Sep 17 00:00:00 2001 From: Jeremy Lecour Date: Sun, 9 May 2021 23:06:42 +0200 Subject: [PATCH 37/86] Improve Ansible syntax MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit replace « x | changed » by « x is changed » add explicit « bool » filter use « length » filter instead of string comparison --- apache/tasks/main.yml | 4 +- apache/tasks/server_status.yml | 2 +- apt/tasks/basics.yml | 2 +- apt/tasks/config.yml | 8 +-- apt/tasks/hold_packages.yml | 4 +- apt/tasks/main.yml | 10 ++-- bind/tasks/main.yml | 22 ++++---- certbot/tasks/install-legacy.yml | 2 +- docker-host/tasks/main.yml | 8 +-- elasticsearch/tasks/configuration.yml | 16 +++--- elasticsearch/tasks/datadir.yml | 8 +-- elasticsearch/tasks/main.yml | 4 +- elasticsearch/tasks/tmpdir.yml | 15 ++++-- etc-git/tasks/do_commit.yml | 2 +- etc-git/tasks/repository.yml | 2 +- evoacme/tasks/evoacme_hook.yml | 2 +- evoacme/tasks/main.yml | 2 +- evobackup-client/handlers/main.yml | 2 +- evocheck/tasks/exec.yml | 2 +- evocheck/tasks/main.yml | 2 +- evolinux-base/tasks/default_www.yml | 8 +-- evolinux-base/tasks/fstab.yml | 12 ++--- evolinux-base/tasks/hostname.yml | 10 ++-- evolinux-base/tasks/kernel.yml | 10 ++-- evolinux-base/tasks/logs.yml | 10 ++-- evolinux-base/tasks/main.yml | 50 +++++++++---------- evolinux-base/tasks/packages.yml | 26 +++++----- evolinux-base/tasks/postfix.yml | 10 ++-- evolinux-base/tasks/root.yml | 18 +++---- evolinux-base/tasks/system.yml | 48 ++++++++++-------- evolinux-todo/tasks/cat.yml | 2 +- evolinux-users/tasks/main.yml | 8 +-- evolinux-users/tasks/ssh.yml | 2 +- evolinux-users/tasks/sudo.yml | 4 +- evolinux-users/tasks/sudo_jessie.yml | 2 +- evolinux-users/tasks/user.yml | 20 +++++--- .../tasks/install_vendor_debian.yml | 2 +- evomaintenance/tasks/main.yml | 8 +-- evomaintenance/tasks/minifirewall.yml | 2 +- fail2ban/tasks/main.yml | 4 +- filebeat/tasks/main.yml | 27 +++++----- haproxy/tasks/main.yml | 4 +- java/tasks/main.yml | 4 +- java/tasks/openjdk.yml | 2 +- java/tasks/oracle.yml | 2 +- keepalived/tasks/main.yml | 2 + kibana/tasks/main.yml | 2 +- kvm-host/tasks/images.yml | 4 +- ldap/tasks/ldapvirc.yml | 6 +-- ldap/tasks/nagios.yml | 8 +-- logstash/tasks/tmpdir.yml | 11 ++-- lxc-php/tasks/misc.yml | 5 +- lxc/tasks/create-container.yml | 2 +- lxc/tasks/main.yml | 6 +-- memcached/tasks/main.yml | 14 +++--- memcached/tasks/munin.yml | 2 +- metricbeat/tasks/main.yml | 19 ++++--- minifirewall/tasks/activate.yml | 4 +- minifirewall/tasks/config.yml | 9 ++-- minifirewall/tasks/main.yml | 6 +-- minifirewall/tasks/tail.yml | 4 +- mongodb/tasks/main_buster.yml | 2 +- mysql-oracle/tasks/datadir.yml | 4 +- mysql-oracle/tasks/nrpe.yml | 6 ++- mysql-oracle/tasks/packages.yml | 2 +- mysql-oracle/tasks/tmpdir.yml | 2 +- mysql-oracle/tasks/utils.yml | 21 ++++---- mysql/tasks/config_stretch.yml | 2 +- mysql/tasks/datadir.yml | 4 +- mysql/tasks/logdir.yml | 4 +- mysql/tasks/main.yml | 2 +- mysql/tasks/nrpe.yml | 6 ++- mysql/tasks/packages_jessie.yml | 2 +- mysql/tasks/packages_stretch.yml | 2 +- mysql/tasks/tmpdir.yml | 2 +- mysql/tasks/users_jessie.yml | 2 +- mysql/tasks/users_stretch.yml | 4 +- mysql/tasks/utils.yml | 31 ++++++------ nagios-nrpe/tasks/main.yml | 2 +- networkd-to-ifconfig/tasks/main.yml | 8 +-- .../tasks/set_facts_from_ansible.yml | 4 +- newrelic/tasks/main.yml | 4 +- newrelic/tasks/php.yml | 4 +- newrelic/tasks/sysmond.yml | 2 +- nginx/tasks/main.yml | 4 +- nginx/tasks/packages.yml | 4 +- nginx/tasks/server_status_read.yml | 2 +- nodejs/tasks/main.yml | 2 +- packweb-apache/tasks/main.yml | 2 +- packweb-apache/tasks/phpmyadmin.yml | 2 +- percona/tasks/main.yml | 6 +-- php/tasks/config_apache.yml | 2 +- php/tasks/config_cli.yml | 2 +- php/tasks/config_fpm.yml | 6 +-- php/tasks/main.yml | 3 +- php/tasks/main_buster.yml | 16 +++--- php/tasks/main_jessie.yml | 12 ++--- php/tasks/main_stretch.yml | 16 +++--- php/tasks/sury_post.yml | 8 +-- postfix/tasks/main.yml | 6 +-- postfix/tasks/minimal.yml | 2 +- postfix/tasks/packmail.yml | 4 +- postgresql/tasks/main.yml | 2 +- postgresql/tasks/nrpe.yml | 2 +- postgresql/tasks/packages_buster.yml | 2 +- postgresql/tasks/packages_jessie.yml | 2 +- postgresql/tasks/packages_stretch.yml | 2 +- postgresql/tests/test.yml | 2 +- proftpd/tasks/accounts.yml | 6 +-- proftpd/tasks/main.yml | 8 +-- redis/tasks/default-munin.yml | 8 +-- redis/tasks/instance-server.yml | 6 +-- redis/tasks/main.yml | 6 +-- redmine/tasks/mysql.yml | 2 +- redmine/tasks/release.yml | 2 +- squid/tasks/main.yml | 24 ++++++--- squid/tasks/systemd.yml | 2 +- supervisord/tasks/main.yml | 2 +- tomcat-instance/tasks/check.yml | 4 +- tomcat-instance/tasks/user.yml | 2 +- webapps/evoadmin-mail/tasks/apache.yml | 4 +- webapps/evoadmin-mail/tasks/nginx.yml | 4 +- webapps/evoadmin-web/tasks/main.yml | 2 +- webapps/evoadmin-web/tasks/web.yml | 6 +-- webapps/nextcloud/tasks/config.yml | 2 +- webapps/wordpress/tasks/main.yml | 4 +- 126 files changed, 450 insertions(+), 395 deletions(-) diff --git a/apache/tasks/main.yml b/apache/tasks/main.yml index a52bd886..c55fc900 100644 --- a/apache/tasks/main.yml +++ b/apache/tasks/main.yml @@ -21,9 +21,9 @@ tags: - apache - packages - when: + when: - ansible_distribution_major_version is version('9', '>=') - - apache_mpm == "itk" + - apache_mpm == "itk" - name: packages are installed (jessie) apt: diff --git a/apache/tasks/server_status.yml b/apache/tasks/server_status.yml index 1d6cd8df..2ca77951 100644 --- a/apache/tasks/server_status.yml +++ b/apache/tasks/server_status.yml @@ -14,7 +14,7 @@ # The last character "\u000A" is a line feed (LF), it's better to keep it content: "{{ apache_serverstatus_suffix }}\u000A" force: yes - when: apache_serverstatus_suffix != "" + when: apache_serverstatus_suffix | length > 0 - name: generate random string for server-status suffix shell: "apg -a 1 -M N -n 1 > {{ apache_serverstatus_suffix_file }}" diff --git a/apt/tasks/basics.yml b/apt/tasks/basics.yml index 83d3e7dc..fee1430a 100644 --- a/apt/tasks/basics.yml +++ b/apt/tasks/basics.yml @@ -20,7 +20,7 @@ - /etc/apt/sources.list.d/debian-stretch.list - /etc/apt/sources.list.d/debian-buster.list - /etc/apt/sources.list.d/debian-update.list - when: apt_clean_gandi_sourceslist + when: apt_clean_gandi_sourceslist | bool tags: - apt diff --git a/apt/tasks/config.yml b/apt/tasks/config.yml index e854d4c6..4d7372fc 100644 --- a/apt/tasks/config.yml +++ b/apt/tasks/config.yml @@ -12,7 +12,7 @@ - { line: "APT::Install-Recommends \"false\";", regexp: 'APT::Install-Recommends' } - { line: "APT::Install-Suggests \"false\";", regexp: 'APT::Install-Suggests' } - { line: "APT::Periodic::Enable \"0\";", regexp: 'APT::Periodic::Enable' } - when: apt_evolinux_config + when: apt_evolinux_config | bool tags: - apt @@ -28,7 +28,7 @@ - "DPkg::Pre-Invoke { \"df /usr | grep -q /usr && mount -oremount,rw /usr || true\"; };" - "DPkg::Post-Invoke { \"df /tmp | grep -q /tmp && mount -oremount /tmp || true\"; };" - "DPkg::Post-Invoke { \"df /usr | grep -q /usr && mount -oremount /usr || true\"; };" - when: apt_hooks + when: apt_hooks | bool tags: - apt @@ -36,7 +36,7 @@ apt: name: aptitude state: absent - when: apt_remove_aptitude + when: apt_remove_aptitude | bool tags: - apt @@ -50,6 +50,6 @@ - name: Upgrading system apt: upgrade: dist - when: apt_upgrade + when: apt_upgrade | bool tags: - apt diff --git a/apt/tasks/hold_packages.yml b/apt/tasks/hold_packages.yml index f93c34a7..63643409 100644 --- a/apt/tasks/hold_packages.yml +++ b/apt/tasks/hold_packages.yml @@ -4,7 +4,9 @@ shell: "(dpkg -l {{ item }} 2>/dev/null | grep -q -E '^(i|h)i') && ((apt-mark showhold | grep --quiet {{ item }}) || apt-mark hold {{ item }})" register: apt_mark changed_when: "item + ' set on hold.' in apt_mark.stdout" - failed_when: apt_mark.rc != 0 and not apt_mark.stdout == '' + failed_when: + - apt_mark.rc != 0 + - apt_mark.stdout | length > 0 loop: "{{ apt_hold_packages }}" tags: - apt diff --git a/apt/tasks/main.yml b/apt/tasks/main.yml index 92f06856..118f8ef9 100644 --- a/apt/tasks/main.yml +++ b/apt/tasks/main.yml @@ -10,30 +10,30 @@ - name: Custom configuration include: config.yml - when: apt_config + when: apt_config | bool tags: - apt - name: Install basics repositories include: basics.yml - when: apt_install_basics + when: apt_install_basics | bool tags: - apt - name: Install APT Backports repository include: backports.yml - when: apt_install_backports + when: apt_install_backports | bool tags: - apt - name: Install Evolix Public APT repository include: evolix_public.yml - when: apt_install_evolix_public + when: apt_install_evolix_public | bool tags: - apt - name: Install check for packages marked hold include: hold_packages.yml - when: apt_install_hold_packages + when: apt_install_hold_packages | bool tags: - apt diff --git a/bind/tasks/main.yml b/bind/tasks/main.yml index c5b9110c..67f8662f 100644 --- a/bind/tasks/main.yml +++ b/bind/tasks/main.yml @@ -6,7 +6,7 @@ bind_cache_dir: /var/cache/bind bind_statistics_file: /var/run/named.stats bind_chroot_path: /var/chroot-bind - when: bind_chroot_set + when: bind_chroot_set | bool - name: configure apparmor template: @@ -34,7 +34,7 @@ mode: "0644" force: yes notify: restart bind - when: bind_recursive_server + when: bind_recursive_server | bool - name: enable zones.rfc1918 for recursive server lineinfile: @@ -42,7 +42,7 @@ line: 'include "/etc/bind/zones.rfc1918";' regexp: "zones.rfc1918" notify: restart bind - when: bind_recursive_server + when: bind_recursive_server | bool - name: Set bind configuration for authoritative server template: @@ -53,7 +53,7 @@ mode: "0644" force: yes notify: restart bind - when: bind_authoritative_server + when: bind_authoritative_server | bool - name: Create systemd service template: @@ -75,7 +75,7 @@ group: adm mode: "0640" state: touch - when: not bind_chroot_set + when: not (bind_chroot_set | bool) - name: "touch {{ bind_query_file }} if non chroot" file: @@ -84,7 +84,7 @@ group: adm mode: "0640" state: touch - when: not bind_chroot_set + when: not (bind_chroot_set | bool) - name: send chroot-bind.sh in /root copy: @@ -94,17 +94,19 @@ owner: root force: yes backup: yes - when: bind_chroot_set + when: bind_chroot_set | bool - name: exec chroot-bind.sh command: "/root/chroot-bind.sh" register: chrootbind_run changed_when: False - when: bind_chroot_set + when: bind_chroot_set | bool - debug: var: chrootbind_run.stdout_lines - when: bind_chroot_set and chrootbind_run.stdout != "" + when: + - bind_chroot_set | bool + - chrootbind_run.stdout | length > 0 - name: Modify OPTIONS in /etc/default/bind9 for chroot replace: @@ -112,7 +114,7 @@ regexp: '^OPTIONS=.*' replace: 'OPTIONS="-u bind -t {{ bind_chroot_path }}"' notify: restart bind - when: bind_chroot_set + when: bind_chroot_set | bool - name: logrotate for bind template: diff --git a/certbot/tasks/install-legacy.yml b/certbot/tasks/install-legacy.yml index fe0cb8e2..e186c80d 100644 --- a/certbot/tasks/install-legacy.yml +++ b/certbot/tasks/install-legacy.yml @@ -48,7 +48,7 @@ src: cron_jessie dest: /etc/cron.d/certbot force: yes - when: certbot_custom_crontab + when: certbot_custom_crontab | bool - name: disable self-upgrade ini_file: diff --git a/docker-host/tasks/main.yml b/docker-host/tasks/main.yml index c32701bb..c31405b8 100644 --- a/docker-host/tasks/main.yml +++ b/docker-host/tasks/main.yml @@ -73,7 +73,7 @@ state: directory mode: "0644" owner: root - when: docker_tls_enabled + when: docker_tls_enabled | bool - name: Copy shellpki utility to Docker TLS directory template: @@ -83,7 +83,7 @@ loop: - shellpki.sh - openssl.cnf - when: docker_tls_enabled + when: docker_tls_enabled | bool - name: Check if certs are already created stat: @@ -92,4 +92,6 @@ - name: Creating a CA, server key command: "{{ docker_tls_path }}/shellpki.sh init" - when: docker_tls_enabled and not tls_certs_stat.stat.isdir is defined + when: + - docker_tls_enabled | bool + - not tls_certs_stat.stat.isdir diff --git a/elasticsearch/tasks/configuration.yml b/elasticsearch/tasks/configuration.yml index e8362fa3..72d36bb3 100644 --- a/elasticsearch/tasks/configuration.yml +++ b/elasticsearch/tasks/configuration.yml @@ -6,7 +6,7 @@ line: "cluster.name: {{ elasticsearch_cluster_name }}" regexp: "^cluster.name:" insertafter: "^# *cluster.name:" - when: elasticsearch_cluster_name|default("", True) + when: elasticsearch_cluster_name | default("", True) | length > 0 tags: - config @@ -25,7 +25,7 @@ line: "network.host: {{ elasticsearch_network_host }}" regexp: "^network.host:" insertafter: "^# *network.host:" - when: elasticsearch_network_host|default("", True) + when: elasticsearch_network_host | default("", True) | length > 0 tags: - config @@ -35,7 +35,7 @@ line: "network.publish_host: {{ elasticsearch_network_publish_host }}" regexp: "^network.publish_host:" insertafter: "^network.host:" - when: elasticsearch_network_publish_host|default("", True) + when: elasticsearch_network_publish_host | default("", True) | length > 0 tags: - config @@ -45,7 +45,7 @@ line: "http.publish_host: {{ elasticsearch_http_publish_host }}" regexp: "^http.publish_host:" insertafter: "^http.port:" - when: elasticsearch_http_publish_host|default("", True) + when: elasticsearch_http_publish_host | default("", True) | length > 0 tags: - config @@ -54,7 +54,7 @@ dest: /etc/elasticsearch/elasticsearch.yml line: "discovery.seed_hosts: {{ elasticsearch_discovery_seed_hosts | to_yaml }}" regexp: "^discovery.seed_hosts:" - when: elasticsearch_discovery_seed_hosts + when: elasticsearch_discovery_seed_hosts | length > 0 tags: - config @@ -63,7 +63,7 @@ dest: /etc/elasticsearch/elasticsearch.yml line: "cluster.initial_master_nodes: {{ elasticsearch_cluster_initial_master_nodes | to_yaml }}" regexp: "^cluster.initial_master_nodes:" - when: elasticsearch_cluster_initial_master_nodes + when: elasticsearch_cluster_initial_master_nodes | length > 0 tags: - config @@ -98,7 +98,7 @@ line: "discovery.zen.ping.unicast.hosts: {{ elasticsearch_cluster_members }}" regexp: "^discovery.zen.ping.unicast.hosts:" insertafter: "^#discovery.zen.ping.unicast.hosts" - when: elasticsearch_cluster_members|default("", True) + when: elasticsearch_cluster_members | default("", True) | length > 0 tags: - config @@ -108,6 +108,6 @@ line: "discovery.zen.minimum_master_nodes: {{ elasticsearch_minimum_master_nodes }}" regexp: "^discovery.zen.minimum_master_nodes:" insertafter: "^#discovery.zen.minimum_master_nodes" - when: elasticsearch_minimum_master_nodes|default("", True) + when: elasticsearch_minimum_master_nodes | default("", True) | length > 0 tags: - config diff --git a/elasticsearch/tasks/datadir.yml b/elasticsearch/tasks/datadir.yml index 66ec48a1..c0c20f05 100644 --- a/elasticsearch/tasks/datadir.yml +++ b/elasticsearch/tasks/datadir.yml @@ -16,8 +16,8 @@ tags: - elasticsearch when: - - elasticsearch_custom_datadir != '' - - elasticsearch_custom_datadir != None + - elasticsearch_custom_datadir is not none + - elasticsearch_custom_datadir | length > 0 - name: Datadir is moved to custom path block: @@ -44,7 +44,7 @@ tags: - elasticsearch when: - - elasticsearch_custom_datadir != '' - - elasticsearch_custom_datadir != None + - elasticsearch_custom_datadir is not none + - elasticsearch_custom_datadir | length > 0 - elasticsearch_custom_datadir != elasticsearch_current_real_datadir_test.stdout - not elasticsearch_custom_datadir_test.stat.exists diff --git a/elasticsearch/tasks/main.yml b/elasticsearch/tasks/main.yml index 126170a1..6f5ccc8c 100644 --- a/elasticsearch/tasks/main.yml +++ b/elasticsearch/tasks/main.yml @@ -15,7 +15,7 @@ - include: additional_scripts.yml - include: plugin_head.yml - when: elasticsearch_plugin_head + when: elasticsearch_plugin_head | bool - include: curator.yml - when: elasticsearch_curator + when: elasticsearch_curator | bool diff --git a/elasticsearch/tasks/tmpdir.yml b/elasticsearch/tasks/tmpdir.yml index 086870fe..920300d7 100644 --- a/elasticsearch/tasks/tmpdir.yml +++ b/elasticsearch/tasks/tmpdir.yml @@ -9,9 +9,14 @@ - name: Tmpdir is moved to custom path block: - - name: "Create {{ elasticsearch_custom_tmpdir or elasticsearch_default_tmpdir | mandatory }}" + - set_fact: + _elasticsearch_custom_tmpdir: "{{ elasticsearch_custom_tmpdir | default(elasticsearch_default_tmpdir, True) | mandatory }}" + tags: + - elasticsearch + + - name: "Create {{ _elasticsearch_custom_tmpdir }}" file: - path: "{{ elasticsearch_custom_tmpdir or elasticsearch_default_tmpdir | mandatory }}" + path: "{{ _elasticsearch_custom_tmpdir }}" owner: elasticsearch group: elasticsearch mode: "0755" @@ -22,7 +27,7 @@ - name: change JVM tmpdir (< 6.x) lineinfile: dest: /etc/elasticsearch/jvm.options - line: "-Djava.io.tmpdir={{ elasticsearch_custom_tmpdir or elasticsearch_default_tmpdir | mandatory }}" + line: "-Djava.io.tmpdir={{ _elasticsearch_custom_tmpdir }}" regexp: "^-Djava.io.tmpdir=" insertafter: "## JVM configuration" notify: @@ -34,7 +39,7 @@ - name: check if ES_TMPDIR is available (>= 6.x) lineinfile: dest: /etc/default/elasticsearch - line: "ES_TMPDIR={{ elasticsearch_custom_tmpdir or elasticsearch_default_tmpdir | mandatory }}" + line: "ES_TMPDIR={{ _elasticsearch_custom_tmpdir }}" regexp: "^ES_TMPDIR=" insertafter: "JAVA_HOME" notify: @@ -54,4 +59,4 @@ tags: - elasticsearch when: elastic_stack_version is version('6', '>=') - when: (elasticsearch_custom_tmpdir != '' and elasticsearch_custom_tmpdir != None) or fstab_tmp_noexec.rc == 0 + when: (elasticsearch_custom_tmpdir is not none and elasticsearch_custom_tmpdir | length > 0) or fstab_tmp_noexec.rc == 0 diff --git a/etc-git/tasks/do_commit.yml b/etc-git/tasks/do_commit.yml index f13c7e50..806aefd2 100644 --- a/etc-git/tasks/do_commit.yml +++ b/etc-git/tasks/do_commit.yml @@ -50,7 +50,7 @@ register: commit_end_run when: - not ansible_check_mode - - git_status.stdout + - git_status.stdout | length > 0 ignore_errors: yes tags: - etc-git diff --git a/etc-git/tasks/repository.yml b/etc-git/tasks/repository.yml index 9be0a436..e8599c1e 100644 --- a/etc-git/tasks/repository.yml +++ b/etc-git/tasks/repository.yml @@ -68,6 +68,6 @@ chdir: "{{ repository_path }}" warn: no register: git_commit - when: git_log.rc != 0 or (git_init is defined and git_init.changed) + when: git_log.rc != 0 or (git_init is defined and git_init is changed) tags: - etc-git diff --git a/evoacme/tasks/evoacme_hook.yml b/evoacme/tasks/evoacme_hook.yml index 51dbb21c..2951fa00 100644 --- a/evoacme/tasks/evoacme_hook.yml +++ b/evoacme/tasks/evoacme_hook.yml @@ -16,4 +16,4 @@ src: "hooks/{{ hook_name }}" dest: "{{ evoacme_hooks_dir }}/{{ hook_name }}" mode: "0750" - when: _find_hook.stdout == "" + when: _find_hook.stdout | length == 0 diff --git a/evoacme/tasks/main.yml b/evoacme/tasks/main.yml index 4c71d90e..1cc84c5d 100644 --- a/evoacme/tasks/main.yml +++ b/evoacme/tasks/main.yml @@ -6,7 +6,7 @@ - ansible_distribution == "Debian" - ansible_distribution_major_version is version('9', '>=') msg: only compatible with Debian >= 9 - when: not evoacme_disable_debian_check + when: not (evoacme_disable_debian_check | bool) - include: certbot.yml diff --git a/evobackup-client/handlers/main.yml b/evobackup-client/handlers/main.yml index 17df304a..fc1b7739 100644 --- a/evobackup-client/handlers/main.yml +++ b/evobackup-client/handlers/main.yml @@ -13,4 +13,4 @@ command: "bkctld restart {{ evolinux_hostname }}" # - "bkctld sync {{ evolinux_hostname }}" delegate_to: "{{ evobackup_client__hosts[0].ip }}" - when: evobackup_client__hosts|length > 1 + when: evobackup_client__hosts | length > 1 diff --git a/evocheck/tasks/exec.yml b/evocheck/tasks/exec.yml index 244d0347..306cf019 100644 --- a/evocheck/tasks/exec.yml +++ b/evocheck/tasks/exec.yml @@ -10,6 +10,6 @@ - debug: var: evocheck_run.stdout_lines - when: evocheck_run.stdout != "" + when: evocheck_run.stdout | length > 0 tags: - evocheck-exec diff --git a/evocheck/tasks/main.yml b/evocheck/tasks/main.yml index 0e374b92..87e2d636 100644 --- a/evocheck/tasks/main.yml +++ b/evocheck/tasks/main.yml @@ -7,4 +7,4 @@ when: evocheck_force_install == "package" - include: cron.yml - when: evocheck_update_crontab + when: evocheck_update_crontab | bool diff --git a/evolinux-base/tasks/default_www.yml b/evolinux-base/tasks/default_www.yml index 8956d824..84580b54 100644 --- a/evolinux-base/tasks/default_www.yml +++ b/evolinux-base/tasks/default_www.yml @@ -4,7 +4,7 @@ path: /var/www state: directory mode: "0755" - when: evolinux_default_www_files + when: evolinux_default_www_files | bool - name: images are copied copy: @@ -13,7 +13,7 @@ mode: "0644" directory_mode: "0755" follow: yes - when: evolinux_default_www_files + when: evolinux_default_www_files | bool - name: index is copied template: @@ -21,7 +21,7 @@ dest: /var/www/index.html mode: "0644" force: no - when: evolinux_default_www_files + when: evolinux_default_www_files | bool # SSL cert @@ -43,6 +43,6 @@ command: openssl x509 -req -days 3650 -sha256 -in /etc/ssl/{{ ansible_fqdn }}.csr -signkey /etc/ssl/private/{{ ansible_fqdn }}.key -out /etc/ssl/certs/{{ ansible_fqdn }}.crt args: creates: "/etc/ssl/certs/{{ ansible_fqdn }}.crt" - when: evolinux_default_www_ssl_cert + when: evolinux_default_www_ssl_cert | bool - meta: flush_handlers diff --git a/evolinux-base/tasks/fstab.yml b/evolinux-base/tasks/fstab.yml index bb70fde8..e10f483e 100644 --- a/evolinux-base/tasks/fstab.yml +++ b/evolinux-base/tasks/fstab.yml @@ -17,7 +17,7 @@ notify: remount /home when: - fstab_content.stdout | regex_search('\s/home\s') - - evolinux_fstab_home + - evolinux_fstab_home | bool - name: /tmp partition is customized replace: @@ -26,7 +26,7 @@ replace: '\1{{ evolinux_fstab_tmp_options | mandatory }}\3' when: - fstab_content.stdout | regex_search('\s/tmp\s') - - evolinux_fstab_tmp + - evolinux_fstab_tmp | bool - name: /usr partition is customized replace: @@ -35,7 +35,7 @@ replace: '\1{{ evolinux_fstab_usr_options | mandatory }}\3' when: - fstab_content.stdout | regex_search('\s/usr\s') - - evolinux_fstab_usr + - evolinux_fstab_usr | bool - name: /var partition is customized replace: @@ -45,7 +45,7 @@ notify: remount /var when: - fstab_content.stdout | regex_search('\s/var\s') - - evolinux_fstab_var + - evolinux_fstab_var | bool - name: /var/tmp is created mount: @@ -55,7 +55,7 @@ opts: "{{ evolinux_fstab_var_tmp_options | mandatory }}" state: mounted when: - - evolinux_fstab_var_tmp + - evolinux_fstab_var_tmp | bool - name: /dev/shm is created (Debian 10 and later) mount: @@ -65,7 +65,7 @@ opts: "{{ evolinux_fstab_dev_shm_options | mandatory }}" state: mounted when: - - evolinux_fstab_dev_shm + - evolinux_fstab_dev_shm | bool - ansible_distribution_major_version is version('10', '>=') - meta: flush_handlers diff --git a/evolinux-base/tasks/hostname.yml b/evolinux-base/tasks/hostname.yml index b73c11c7..2b9cfa93 100644 --- a/evolinux-base/tasks/hostname.yml +++ b/evolinux-base/tasks/hostname.yml @@ -7,14 +7,14 @@ - name: Set hostname "{{ evolinux_hostname }}" hostname: name: "{{ evolinux_hostname }}" - when: evolinux_hostname_hosts + when: evolinux_hostname_hosts | bool - name: Set right localhost line in /etc/hosts replace: dest: /etc/hosts regexp: '^127.0.0.1(\s+)localhost.*$' replace: '127.0.0.1\1localhost.localdomain localhost' - when: evolinux_hostname_hosts + when: evolinux_hostname_hosts | bool - name: Set ip+fqdn+hostname in /etc/hosts lineinfile: @@ -22,21 +22,21 @@ regexp: '^{{ ansible_default_ipv4.address }}\s+' line: "{{ ansible_default_ipv4.address }} {{ [evolinux_fqdn, evolinux_internal_fqdn] | unique | join(' ') }} {{ [evolinux_hostname, evolinux_internal_hostname] | unique | join(' ') }}" insertafter: '127.0.0.1\s+localhost.localdomain' - when: evolinux_hostname_hosts + when: evolinux_hostname_hosts | bool - name: 127.0.1.1 is removed lineinfile: dest: /etc/hosts regexp: '^127.0.1.1\s+' state: absent - when: evolinux_hostname_hosts + when: evolinux_hostname_hosts | bool - name: /etc/mailname is up-to-date copy: dest: /etc/mailname content: "{{ evolinux_fqdn }}\n" force: yes - when: evolinux_hostname_mailname + when: evolinux_hostname_mailname | bool # Override facts diff --git a/evolinux-base/tasks/kernel.yml b/evolinux-base/tasks/kernel.yml index e19ab0e6..282e10eb 100644 --- a/evolinux-base/tasks/kernel.yml +++ b/evolinux-base/tasks/kernel.yml @@ -10,7 +10,7 @@ loop: - { name: kernel.panic_on_oops, value: 1 } - { name: kernel.panic, value: 60 } - when: evolinux_kernel_reboot_after_panic + when: evolinux_kernel_reboot_after_panic | bool - name: Don't reboot after panic sysctl: @@ -21,7 +21,7 @@ loop: - kernel.panic_on_oops - kernel.panic - when: not evolinux_kernel_reboot_after_panic + when: not evolinux_kernel_reboot_after_panic | bool - name: Disable net.ipv4.tcp_timestamps sysctl: @@ -30,7 +30,7 @@ sysctl_file: "{{ evolinux_kernel_sysctl_path }}" state: present reload: yes - when: evolinux_kernel_disable_tcp_timestamps + when: evolinux_kernel_disable_tcp_timestamps | bool - name: Customize the swappiness sysctl: @@ -39,7 +39,7 @@ sysctl_file: "{{ evolinux_kernel_sysctl_path }}" state: present reload: yes - when: evolinux_kernel_customize_swappiness + when: evolinux_kernel_customize_swappiness | bool - name: Patch for TCP stack vulnerability CVE-2016-5696 sysctl: @@ -48,7 +48,7 @@ sysctl_file: "{{ evolinux_kernel_sysctl_path }}" state: present reload: yes - when: evolinux_kernel_cve20165696 + when: evolinux_kernel_cve20165696 | bool - name: Patch for TCP stack vulnerability CVE-2018-5391 (FragmentSmack) sysctl: diff --git a/evolinux-base/tasks/logs.yml b/evolinux-base/tasks/logs.yml index 9c1f45e4..2bf28b98 100644 --- a/evolinux-base/tasks/logs.yml +++ b/evolinux-base/tasks/logs.yml @@ -8,7 +8,7 @@ dest: /etc/rsyslog.conf mode: "0644" notify: restart rsyslog - when: evolinux_logs_rsyslog_conf + when: evolinux_logs_rsyslog_conf | bool - name: Disable logrotate default conf command: mv /etc/logrotate.d/rsyslog /etc/logrotate.d/rsyslog.disabled @@ -16,25 +16,25 @@ removes: /etc/logrotate.d/rsyslog creates: /etc/logrotate.d/rsyslog.disabled notify: restart rsyslog - when: evolinux_logs_disable_logrotate_rsyslog + when: evolinux_logs_disable_logrotate_rsyslog | bool - name: Copy many logrotate files copy: src: logs/logrotate.d/ dest: /etc/logrotate.d/ - when: evolinux_logs_logrotate_confs + when: evolinux_logs_logrotate_confs | bool - name: Copy rsyslog logrotate file template: src: logs/zsyslog.j2 dest: /etc/logrotate.d/zsyslog - when: evolinux_logs_logrotate_confs + when: evolinux_logs_logrotate_confs | bool - name: Configure logrotate.conf replace: dest: /etc/logrotate.conf regexp: "rotate [0-9]+" replace: "rotate 12" - when: evolinux_logs_default_rotate + when: evolinux_logs_default_rotate | bool - meta: flush_handlers diff --git a/evolinux-base/tasks/main.yml b/evolinux-base/tasks/main.yml index 0b2fdf89..68a6d424 100644 --- a/evolinux-base/tasks/main.yml +++ b/evolinux-base/tasks/main.yml @@ -13,51 +13,51 @@ vars: apt_install_basics: "{{ evolinux_apt_replace_default_sources }}" apt_install_evolix_public: "{{ evolinux_apt_public_sources }}" - when: evolinux_apt_include + when: evolinux_apt_include | bool - name: /etc versioning with Git include_role: name: evolix/etc-git - when: evolinux_etcgit_include + when: evolinux_etcgit_include | bool - name: /etc/evolinux base include: etc-evolinux.yml - when: evolinux_etcevolinux_include + when: evolinux_etcevolinux_include | bool - name: Hostname include: hostname.yml - when: evolinux_hostname_include + when: evolinux_hostname_include | bool - name: Kernel tuning include: kernel.yml - when: evolinux_kernel_include + when: evolinux_kernel_include | bool - name: Fstab configuration include: fstab.yml - when: evolinux_fstab_include + when: evolinux_fstab_include | bool - name: Packages include: packages.yml - when: evolinux_packages_include + when: evolinux_packages_include | bool - name: System settings include: system.yml - when: evolinux_system_include + when: evolinux_system_include | bool - name: Minifirewall include_role: name: evolix/minifirewall - when: evolinux_minifirewall_include + when: evolinux_minifirewall_include | bool - name: Evomaintenance include_role: name: evolix/evomaintenance - when: evolinux_evomaintenance_include + when: evolinux_evomaintenance_include | bool - name: SSH configuration include: ssh.yml when: evolinux_ssh_include - + ### disabled because of a memory leak # - name: Create evolinux users # include_role: @@ -66,66 +66,66 @@ - name: Root user configuration include: root.yml - when: evolinux_root_include + when: evolinux_root_include | bool - name: Postfix include: postfix.yml - when: evolinux_postfix_include + when: evolinux_postfix_include | bool - name: Logs management include: logs.yml - when: evolinux_logs_include + when: evolinux_logs_include | bool - name: Default index page include: default_www.yml - when: evolinux_default_www_include + when: evolinux_default_www_include | bool - name: Hardware drivers and tools include: hardware.yml - when: evolinux_hardware_include + when: evolinux_hardware_include | bool - name: Customize for Online.net include: provider_online.yml - when: evolinux_provider_online_include + when: evolinux_provider_online_include | bool - name: Customize for Orange FCE include: provider_orange_fce.yml - when: evolinux_provider_orange_fce_include + when: evolinux_provider_orange_fce_include | bool - name: Override Log2mail service include: log2mail.yml - when: evolinux_log2mail_include + when: evolinux_log2mail_include | bool - include: motd.yml - name: Munin include_role: name: evolix/munin - when: evolinux_munin_include + when: evolinux_munin_include | bool - name: Nagios/NRPE include_role: name: evolix/nagios-nrpe - when: evolinux_nagios_nrpe_include + when: evolinux_nagios_nrpe_include | bool - name: fail2ban include_role: name: evolix/fail2ban - when: evolinux_fail2ban_include + when: evolinux_fail2ban_include | bool - name: Evocheck include_role: name: evolix/evocheck vars: evocheck_force_install: "{{ evolinux_evocheck_force_install }}" - when: evolinux_evocheck_include + when: evolinux_evocheck_include | bool - name: Listupgrade include_role: name: evolix/listupgrade - when: evolinux_listupgrade_include + when: evolinux_listupgrade_include | bool - name: Generate ldif script include_role: name: evolix/generate-ldif - when: evolinux_generateldif_include + when: evolinux_generateldif_include | bool diff --git a/evolinux-base/tasks/packages.yml b/evolinux-base/tasks/packages.yml index afedf1a4..8df64abd 100644 --- a/evolinux-base/tasks/packages.yml +++ b/evolinux-base/tasks/packages.yml @@ -16,7 +16,7 @@ - ssl-cert - ca-certificates - rename - when: evolinux_packages_system + when: evolinux_packages_system | bool - name: Install/Update diagnostic tools apt: @@ -34,7 +34,7 @@ - telnet - traceroute - man - when: evolinux_packages_diagnostic + when: evolinux_packages_diagnostic | bool - name: Install/Update hardware tools apt: @@ -42,7 +42,7 @@ - hdparm - smartmontools - lm-sensors - when: evolinux_packages_hardware + when: evolinux_packages_hardware | bool - name: Install/Update common tools apt: @@ -58,21 +58,21 @@ - bc - pinentry-curses - ncurses-term - when: evolinux_packages_common + when: evolinux_packages_common | bool - name: Be sure that openntpd package is absent/purged apt: name: openntpd state: absent purge: True - when: evolinux_packages_purge_openntpd + when: evolinux_packages_purge_openntpd | bool - name: the chrony package is absent apt: name: chrony purge: True state: absent - when: evolinux_packages_purge_chrony + when: evolinux_packages_purge_chrony | bool - name: Be sure locate/mlocate is absent/purged apt: @@ -81,19 +81,19 @@ - mlocate state: absent purge: yes - when: evolinux_packages_purge_locate + when: evolinux_packages_purge_locate | bool - name: Install/Update serveur-base meta-package apt: name: serveur-base allow_unauthenticated: yes - when: evolinux_packages_serveur_base + when: evolinux_packages_serveur_base | bool - name: Install/Update packages for Stretch and later apt: name: net-tools when: - - evolinux_packages_stretch + - evolinux_packages_stretch | bool - ansible_distribution_major_version is version('9', '>=') - name: Install/Update packages for Buster and later @@ -102,7 +102,7 @@ - spectre-meltdown-checker - binutils when: - - evolinux_packages_buster + - evolinux_packages_buster | bool - ansible_distribution_major_version is version('10', '>=') - name: Customize logcheck recipient @@ -110,7 +110,7 @@ dest: /etc/logcheck/logcheck.conf regexp: '^SENDMAILTO=".*"$' line: 'SENDMAILTO="{{ logcheck_alert_email or general_alert_email | mandatory }}"' - when: evolinux_packages_logcheck_recipient + when: evolinux_packages_logcheck_recipient | bool - name: Deleting rpcbind and nfs-common apt: @@ -118,7 +118,7 @@ - rpcbind - nfs-common state: absent - when: evolinux_packages_delete_nfs + when: evolinux_packages_delete_nfs | bool # TODO: use ini_file when Ansible > 2.1 (no_extra_spaces: yes) @@ -132,7 +132,7 @@ - { option: "confirm", value: "1" } - { option: "which", value: "both" } when: - - evolinux_packages_listchanges + - evolinux_packages_listchanges | bool - ansible_distribution == "Debian" - ansible_distribution_release == "jessie" diff --git a/evolinux-base/tasks/postfix.yml b/evolinux-base/tasks/postfix.yml index e83a190b..5ae33aa7 100644 --- a/evolinux-base/tasks/postfix.yml +++ b/evolinux-base/tasks/postfix.yml @@ -6,7 +6,7 @@ - postfix - mailgraph state: present - when: evolinux_postfix_packages + when: evolinux_postfix_packages | bool tags: - packages - postfix @@ -47,7 +47,7 @@ line: "{{ item }}: root" loop: "{{ non_root_users_list.stdout_lines }}" notify: newaliases - when: evolinux_postfix_users_alias_root + when: evolinux_postfix_users_alias_root | bool tags: - postfix @@ -64,7 +64,7 @@ - error - bounce notify: newaliases - when: evolinux_postfix_mailer_alias_root + when: evolinux_postfix_mailer_alias_root | bool tags: - postfix @@ -74,7 +74,7 @@ regexp: "^root:" line: "root: {{ postfix_alias_email or general_alert_email | mandatory }}" notify: newaliases - when: evolinux_postfix_root_alias + when: evolinux_postfix_root_alias | bool tags: - postfix @@ -89,7 +89,7 @@ - exim4-daemon-light purge: yes state: absent - when: evolinux_postfix_purge_exim + when: evolinux_postfix_purge_exim | bool tags: - packages - postfix diff --git a/evolinux-base/tasks/root.yml b/evolinux-base/tasks/root.yml index ce57d4fd..df50d977 100644 --- a/evolinux-base/tasks/root.yml +++ b/evolinux-base/tasks/root.yml @@ -5,7 +5,7 @@ path: /root state: directory mode: "0700" - when: evolinux_root_chmod + when: evolinux_root_chmod | bool - name: "Customize root's bashrc..." lineinfile: @@ -19,7 +19,7 @@ - "export HISTTIMEFORMAT=\"%c : \"" - "shopt -s histappend" - "PROMPT_COMMAND=\"history -a;${PROMPT_COMMAND}\"" - when: evolinux_root_bashrc + when: evolinux_root_bashrc | bool ## .bash_history should be append-only @@ -28,14 +28,14 @@ content: "" dest: "/root/.bash_history" force: no - when: evolinux_root_bash_history + when: evolinux_root_bash_history | bool - name: Set umask in /root/.profile lineinfile: dest: "/root/.profile" line: "umask 0077" regexp: "umask [0-9]+" - when: evolinux_root_umask + when: evolinux_root_umask | bool - name: "/usr/share/scripts is present in root's PATH" lineinfile: @@ -48,7 +48,7 @@ src: root/gitconfig dest: "/root/.gitconfig" force: no - when: evolinux_root_gitconfig + when: evolinux_root_gitconfig | bool - name: Is .bash_history append-only shell: lsattr /root/.bash_history | grep -E "^.*a.* " @@ -61,7 +61,7 @@ - name: Set .bash_history append-only command: chattr +a /root/.bash_history when: - - evolinux_root_bash_history_appendonly + - evolinux_root_bash_history_appendonly | bool - bash_history_append_only.rc != 0 - "'Inappropriate ioctl' not in bash_history_append_only.stderr" @@ -71,7 +71,7 @@ regexp: '^SELECTED_EDITOR=' line: "SELECTED_EDITOR=\"/usr/bin/vim.basic\"" create: yes - when: evolinux_root_vim_default + when: evolinux_root_vim_default | bool - name: Setting vim root configuration lineinfile: @@ -86,7 +86,7 @@ - "set tabstop=4" - "set softtabstop=4" - "set shiftwidth=4" - when: evolinux_root_vim_conf + when: evolinux_root_vim_conf | bool - name: disable SSH access for root replace: @@ -95,7 +95,7 @@ replace: "PermitRootLogin no" validate: '/usr/sbin/sshd -t -f %s' notify: reload sshd - when: evolinux_root_disable_ssh + when: evolinux_root_disable_ssh | bool ### Disabled : it seems useless and too dangerous for now # - name: remove root from AllowUsers directive diff --git a/evolinux-base/tasks/system.yml b/evolinux-base/tasks/system.yml index 06661ada..6504655b 100644 --- a/evolinux-base/tasks/system.yml +++ b/evolinux-base/tasks/system.yml @@ -5,7 +5,7 @@ path: /tmp state: directory mode: "u=rwx,g=rwx,o=rwxt" - when: evolinux_system_chmod_tmp + when: evolinux_system_chmod_tmp | bool - name: Setting default locales lineinfile: @@ -18,7 +18,7 @@ - "fr_FR ISO-8859-1" - "fr_FR.UTF-8 UTF-8" register: default_locales - when: evolinux_system_locales + when: evolinux_system_locales | bool - name: Reconfigure locales command: /usr/sbin/locale-gen @@ -28,7 +28,7 @@ timezone: name: "{{ evolinux_system_timezone | mandatory }}" notify: restart cron - when: evolinux_system_set_timezone + when: evolinux_system_set_timezone | bool # TODO : find a way to force the console-data configuration # non-interactively (like tzdata ↑) @@ -41,13 +41,13 @@ dest: /etc/vim/vimrc regexp: 'let g:skip_defaults_vim =' line: 'let g:skip_defaults_vim = 1' - when: evolinux_system_vim_skip_defaults + when: evolinux_system_vim_skip_defaults | bool - name: Setting vim as default editor alternatives: name: editor path: /usr/bin/vim.basic - when: evolinux_system_vim_default_editor + when: evolinux_system_vim_default_editor | bool - name: Add "umask 027" to /etc/profile.d/evolinux.sh lineinfile: @@ -55,14 +55,14 @@ line: "umask 027" create: yes state: present - when: evolinux_system_profile + when: evolinux_system_profile | bool - name: Set /etc/adduser.conf DIR_MODE to 0700 replace: dest: /etc/adduser.conf regexp: "^DIR_MODE=0755$" replace: "DIR_MODE=0700" - when: evolinux_system_dirmode_adduser + when: evolinux_system_dirmode_adduser | bool # TODO: trouver comment ne pas faire ça sur Xen Dom-U @@ -72,7 +72,7 @@ line: "tty2" create: yes state: present - when: evolinux_system_restrict_securetty + when: evolinux_system_restrict_securetty | bool - name: Setting TMOUT to disconnect inactive users lineinfile: @@ -80,7 +80,7 @@ line: "export TMOUT=36000" create: yes state: present - when: evolinux_system_set_timeout + when: evolinux_system_set_timeout | bool #- name: Customizing /etc/fstab @@ -97,7 +97,9 @@ line: "EXTRA_OPTS='-L 15'" create: yes state: present - when: is_cron_installed.rc == 0 and evolinux_system_cron_verboselog + when: + - is_cron_installed.rc == 0 + - evolinux_system_cron_verboselog | bool - name: Modify default umask for cron deamon lineinfile: @@ -105,7 +107,9 @@ line: "umask 022" create: yes state: present - when: is_cron_installed.rc == 0 and evolinux_system_cron_umask + when: + - is_cron_installed.rc == 0 + - evolinux_system_cron_umask | bool - name: Randomize periodic crontabs replace: @@ -117,7 +121,9 @@ - { regexp: '^25\s*6((\s*\*){3})', replace: '{{ 59|random(start=1) }} {{ [0,1,3,4,5,6,7]|random }}\1' } - { regexp: '^47\s*6((\s*\*){2}\s*7)', replace: '{{ 59|random(start=1) }} {{ [0,1,3,4,5,6,7]|random }}\1' } - { regexp: '^52\s*6(\s*1(\s*\*){2})', replace: '{{ 59|random(start=1) }} {{ [0,1,3,4,5,6,7]|random }}\1' } - when: is_cron_installed.rc == 0 and evolinux_system_cron_random + when: + - is_cron_installed.rc == 0 + - evolinux_system_cron_random | bool - include_role: name: evolix/ntpd @@ -131,7 +137,7 @@ force: no mode: "0755" when: - - evolinux_system_alert5_init + - evolinux_system_alert5_init | bool - ansible_distribution_release == "jessie" or ansible_distribution_release == "stretch" - name: Enable alert5 init script (jessie/stretch) @@ -139,8 +145,8 @@ name: alert5 enabled: yes when: - - evolinux_system_alert5_init - - evolinux_system_alert5_enable + - evolinux_system_alert5_init | bool + - evolinux_system_alert5_enable | bool - ansible_distribution_release == "jessie" or ansible_distribution_release == "stretch" @@ -152,7 +158,7 @@ force: no mode: "0755" when: - - evolinux_system_alert5_init + - evolinux_system_alert5_init | bool - ansible_distribution_major_version is version('10', '>=') - name: Install alert5 service (buster) @@ -162,7 +168,7 @@ force: yes mode: "0644" when: - - evolinux_system_alert5_init + - evolinux_system_alert5_init | bool - ansible_distribution_major_version is version('10', '>=') - name: Enable alert5 init script (buster) @@ -171,8 +177,8 @@ daemon_reload: yes enabled: yes when: - - evolinux_system_alert5_init - - evolinux_system_alert5_enable + - evolinux_system_alert5_init | bool + - evolinux_system_alert5_enable | bool - ansible_distribution_major_version is version('10', '>=') ## network interfaces @@ -189,7 +195,9 @@ dest: /etc/network/interfaces regexp: "allow-hotplug" replace: "auto" - when: evolinux_system_eni_auto and grep_hotplug_eni.rc == 0 + when: + - evolinux_system_eni_auto | bool + - grep_hotplug_eni.rc == 0 ## /sbin/deny diff --git a/evolinux-todo/tasks/cat.yml b/evolinux-todo/tasks/cat.yml index 9cebeca5..58e3ba4c 100644 --- a/evolinux-todo/tasks/cat.yml +++ b/evolinux-todo/tasks/cat.yml @@ -10,4 +10,4 @@ - name: "Content of /etc/evolinux/todo.txt" debug: var: evolinux_todo.stdout_lines - when: evolinux_todo.stdout != "" + when: evolinux_todo.stdout | length > 0 diff --git a/evolinux-users/tasks/main.yml b/evolinux-users/tasks/main.yml index 20cdf040..8f12ba1b 100644 --- a/evolinux-users/tasks/main.yml +++ b/evolinux-users/tasks/main.yml @@ -9,22 +9,22 @@ - debug: msg: "Warning: empty 'evolinux_users' variable, tasks will be skipped!" - when: evolinux_users == {} + when: evolinux_users | length == 0 - name: Create user accounts include: user.yml vars: user: "{{ item.value }}" loop: "{{ evolinux_users | dict2items }}" - when: evolinux_users != {} + when: evolinux_users | length > 0 - name: Configure sudo include: sudo.yml vars: user: "{{ item.value }}" loop: "{{ evolinux_users | dict2items }}" - when: evolinux_users != {} + when: evolinux_users | length > 0 - name: Configure SSH include: ssh.yml - when: evolinux_users != {} + when: evolinux_users | length > 0 diff --git a/evolinux-users/tasks/ssh.yml b/evolinux-users/tasks/ssh.yml index 06a05b89..ac2fdf12 100644 --- a/evolinux-users/tasks/ssh.yml +++ b/evolinux-users/tasks/ssh.yml @@ -59,6 +59,6 @@ regexp: '^PermitRootLogin (yes|without-password|prohibit-password)' replace: "PermitRootLogin no" notify: reload sshd - when: evolinux_root_disable_ssh + when: evolinux_root_disable_ssh | bool - meta: flush_handlers diff --git a/evolinux-users/tasks/sudo.yml b/evolinux-users/tasks/sudo.yml index 6f127da8..c27f5a29 100644 --- a/evolinux-users/tasks/sudo.yml +++ b/evolinux-users/tasks/sudo.yml @@ -4,6 +4,8 @@ when: ansible_distribution_release == "jessie" - include: sudo_stretch.yml - when: ansible_distribution_major_version is defined and ansible_distribution_major_version is version('9', '>=') + when: + - ansible_distribution_major_version is defined + - ansible_distribution_major_version is version('9', '>=') - meta: flush_handlers diff --git a/evolinux-users/tasks/sudo_jessie.yml b/evolinux-users/tasks/sudo_jessie.yml index f675954e..d3f70198 100644 --- a/evolinux-users/tasks/sudo_jessie.yml +++ b/evolinux-users/tasks/sudo_jessie.yml @@ -15,4 +15,4 @@ regexp: '^(User_Alias\s+ADMINS\s+=((?!{{ user.name }}).)*)$' replace: '\1,{{ user.name }}' validate: '/usr/sbin/visudo -cf %s' - when: not copy_sudoers_evolinux.changed + when: copy_sudoers_evolinux is not changed diff --git a/evolinux-users/tasks/user.yml b/evolinux-users/tasks/user.yml index 0d2105bd..4939f533 100644 --- a/evolinux-users/tasks/user.yml +++ b/evolinux-users/tasks/user.yml @@ -4,11 +4,11 @@ - fail: msg: "You must provide a value for the 'user.name ' variable." - when: user.name is not defined or user.name == '' + when: user.name is not defined or user.name | length == 0 - fail: msg: "You must provide a value for the 'user.uid ' variable." - when: user.uid is not defined or user.uid == '' + when: user.uid is not defined or user.uid | length == 0 - name: "Test if '{{ user.name }}' exists" command: 'id -u "{{ user.name }}"' @@ -102,7 +102,7 @@ state: present when: - evolinux_internal_group is defined - - evolinux_internal_group != "" + - evolinux_internal_group | length > 0 - ansible_distribution_major_version is version('9', '>=') - name: "Unix user '{{ user.name }}' belongs to group '{{ evolinux_internal_group }}' (Debian 9 or later)" @@ -112,7 +112,7 @@ append: yes when: - evolinux_internal_group is defined - - evolinux_internal_group != "" + - evolinux_internal_group | length > 0 - ansible_distribution_major_version is version('9', '>=') ## Optional secondary groups, defined per user @@ -125,7 +125,7 @@ loop_var: group when: - user.groups is defined - - user.groups != [] + - user.groups | length > 0 - name: "Unix user '{{ user.name }}' belongs to secondary groups" user: @@ -134,7 +134,7 @@ append: yes when: - user.groups is defined - - user.groups != [] + - user.groups | length > 0 # Permissions on home directory @@ -177,7 +177,9 @@ user: "{{ user.name }}" key: "{{ user.ssh_key }}" state: present - when: user.ssh_key is defined + when: + - user.ssh_key is defined + - user.ssh_key | length > 0 - name: "SSH public keys for '{{ user.name }}' are present" authorized_key: @@ -187,6 +189,8 @@ loop: "{{ user.ssh_keys }}" loop_control: loop_var: ssk_key - when: user.ssh_keys is defined + when: + - user.ssh_keys is defined + - user.ssh_keys | length > 0 - meta: flush_handlers diff --git a/evomaintenance/tasks/install_vendor_debian.yml b/evomaintenance/tasks/install_vendor_debian.yml index 96bbee86..2faaac79 100644 --- a/evomaintenance/tasks/install_vendor_debian.yml +++ b/evomaintenance/tasks/install_vendor_debian.yml @@ -14,7 +14,7 @@ name: - postgresql-client state: present - when: evomaintenance_hook_db + when: evomaintenance_hook_db | bool tags: - evomaintenance diff --git a/evomaintenance/tasks/main.yml b/evomaintenance/tasks/main.yml index d56a124a..642b2954 100644 --- a/evomaintenance/tasks/main.yml +++ b/evomaintenance/tasks/main.yml @@ -1,7 +1,7 @@ --- - set_fact: - minifirewall_restart_handler_name: "{{ minifirewall_restart_if_needed | ternary('restart minifirewall', 'restart minifirewall (noop)') }}" + minifirewall_restart_handler_name: "{{ minifirewall_restart_if_needed | bool | ternary('restart minifirewall', 'restart minifirewall (noop)') }}" - assert: that: @@ -11,12 +11,12 @@ - include: install_package_debian.yml when: - - not evomaintenance_install_vendor + - not (evomaintenance_install_vendor | bool) - ansible_distribution == "Debian" - include: install_vendor_debian.yml when: - - evomaintenance_install_vendor + - evomaintenance_install_vendor | bool - ansible_distribution == "Debian" - include: install_vendor_openbsd.yml @@ -25,5 +25,5 @@ - include: minifirewall.yml when: - - evomaintenance_hook_db + - evomaintenance_hook_db | bool - ansible_distribution == "Debian" diff --git a/evomaintenance/tasks/minifirewall.yml b/evomaintenance/tasks/minifirewall.yml index c99bd34f..ad48e856 100644 --- a/evomaintenance/tasks/minifirewall.yml +++ b/evomaintenance/tasks/minifirewall.yml @@ -31,6 +31,6 @@ - name: Force restart minifirewall command: /bin/true notify: restart minifirewall - when: minifirewall_restart_force + when: minifirewall_restart_force | bool tags: - evomaintenance diff --git a/fail2ban/tasks/main.yml b/fail2ban/tasks/main.yml index 5e4909d6..30c795c9 100644 --- a/fail2ban/tasks/main.yml +++ b/fail2ban/tasks/main.yml @@ -32,7 +32,7 @@ - name: Include ignoredips update task include: ip_whitelist.yml - when: fail2ban_force_update_ignore_ips + when: fail2ban_force_update_ignore_ips | bool tags: - fail2ban @@ -43,7 +43,7 @@ option: enabled value: false notify: restart fail2ban - when: fail2ban_disable_ssh + when: fail2ban_disable_ssh | bool tags: - fail2ban diff --git a/filebeat/tasks/main.yml b/filebeat/tasks/main.yml index 0f5511eb..06f7d564 100644 --- a/filebeat/tasks/main.yml +++ b/filebeat/tasks/main.yml @@ -64,7 +64,9 @@ register: logstash_plugin_installed failed_when: false changed_when: false - when: filebeat_logstash_plugin and logstash_plugin.stat.exists + when: + - filebeat_logstash_plugin | bool + - logstash_plugin.stat.exists - name: Logstash plugin is installed block: @@ -74,9 +76,9 @@ - name: logstash-plugin install logstash-input-beats command: /usr/share/logstash/bin/logstash-plugin install logstash-input-beats when: - - filebeat_logstash_plugin + - filebeat_logstash_plugin | bool - logstash_plugin.stat.exists - - not logstash_plugin_installed | success + - not (logstash_plugin_installed | success) # When we don't use a config template (default) - block: @@ -86,7 +88,7 @@ regexp: '^(\s+)(- add_cloud_metadata:)' replace: '\1# \2' notify: restart filebeat - when: not filebeat_processors_cloud_metadata + when: not (filebeat_processors_cloud_metadata | bool) - name: cloud_metadata processor is disabled lineinfile: @@ -94,7 +96,7 @@ line: " - add_cloud_metadata: ~" insert_after: '^processors:' notify: restart filebeat - when: filebeat_processors_cloud_metadata + when: filebeat_processors_cloud_metadata | bool - name: Filebeat knows where to find Elasticsearch lineinfile: @@ -103,8 +105,7 @@ line: " hosts: [\"{{ filebeat_elasticsearch_hosts | join('\", \"') }}\"]" insertafter: "output.elasticsearch:" notify: restart filebeat - when: - - filebeat_elasticsearch_hosts + when: filebeat_elasticsearch_hosts | length > 0 - name: Filebeat protocol for Elasticsearch lineinfile: @@ -126,9 +127,9 @@ - { regexp: '^ #?password: .*', line: ' password: "{{ filebeat_elasticsearch_auth_password }}"' } notify: restart filebeat when: - - filebeat_elasticsearch_auth_username - - filebeat_elasticsearch_auth_password - when: not filebeat_use_config_template + - filebeat_elasticsearch_auth_username | length > 0 + - filebeat_elasticsearch_auth_password | length > 0 + when: not (filebeat_use_config_template | bool) - name: Filebeat api_key for Elasticsearch are configured lineinfile: @@ -137,7 +138,7 @@ line: ' api_key: "{{ filebeat_elasticsearch_auth_api_key }}"' insertafter: "output.elasticsearch:" notify: restart filebeat - when: filebeat_elasticsearch_auth_api_key + when: filebeat_elasticsearch_auth_api_key | length > 0 # When we use a config template - block: @@ -154,5 +155,5 @@ - "templates/filebeat/filebeat.default.yml.j2" - "templates/filebeat.default.yml.j2" notify: restart filebeat - when: filebeat_update_config - when: filebeat_use_config_template + when: filebeat_update_config | bool + when: filebeat_use_config_template | bool diff --git a/haproxy/tasks/main.yml b/haproxy/tasks/main.yml index 8b47127b..d29e3cbc 100644 --- a/haproxy/tasks/main.yml +++ b/haproxy/tasks/main.yml @@ -84,7 +84,7 @@ - update-config - include: packages_backports.yml - when: haproxy_backports + when: haproxy_backports | bool - name: Install HAProxy package apt: @@ -108,7 +108,7 @@ - "templates/haproxy/haproxy.default.cfg.j2" - "templates/haproxy.default.cfg.j2" notify: reload haproxy - when: haproxy_update_config + when: haproxy_update_config | bool tags: - haproxy - config diff --git a/java/tasks/main.yml b/java/tasks/main.yml index f6de0b43..f899bf1c 100644 --- a/java/tasks/main.yml +++ b/java/tasks/main.yml @@ -4,7 +4,7 @@ # when: java_version != 8 - include: openjdk.yml - when: "{{ java_alternative == 'openjdk' }}" + when: java_alternative == 'openjdk' - include: oracle.yml - when: "{{ java_alternative == 'oracle' }}" + when: java_alternative == 'oracle' diff --git a/java/tasks/openjdk.yml b/java/tasks/openjdk.yml index 8e187d1b..b41db0a7 100644 --- a/java/tasks/openjdk.yml +++ b/java/tasks/openjdk.yml @@ -26,6 +26,6 @@ alternatives: name: java path: "{{ java_bin_path[java_version] }}" - when: java_default_alternative + when: java_default_alternative | bool tags: - java diff --git a/java/tasks/oracle.yml b/java/tasks/oracle.yml index bbdd86f4..c2ab5ebf 100644 --- a/java/tasks/oracle.yml +++ b/java/tasks/oracle.yml @@ -52,6 +52,6 @@ alternatives: name: java path: "/usr/lib/jvm/oracle-java{{ java_version }}-server-jre-amd64/bin/java" - when: java_default_alternative + when: java_default_alternative | bool tags: - java diff --git a/keepalived/tasks/main.yml b/keepalived/tasks/main.yml index dee97bca..807713a8 100644 --- a/keepalived/tasks/main.yml +++ b/keepalived/tasks/main.yml @@ -1,3 +1,5 @@ +--- + - name: install Keepalived service apt: pkg: keepalived diff --git a/kibana/tasks/main.yml b/kibana/tasks/main.yml index f4334879..44bed1a6 100644 --- a/kibana/tasks/main.yml +++ b/kibana/tasks/main.yml @@ -126,4 +126,4 @@ # - data - include: proxy_nginx.yml - when: kibana_proxy_nginx + when: kibana_proxy_nginx | bool diff --git a/kvm-host/tasks/images.yml b/kvm-host/tasks/images.yml index 420e83ec..b9ec57a8 100644 --- a/kvm-host/tasks/images.yml +++ b/kvm-host/tasks/images.yml @@ -13,7 +13,7 @@ changed_when: False check_mode: no register: kvm_libvirt_images_current_real_path_test - when: kvm_custom_libvirt_images_path != '' + when: kvm_custom_libvirt_images_path | length > 0 - name: Images directory is moved to custom path block: @@ -35,6 +35,6 @@ dest: '/var/lib/libvirt/images' state: link when: - - kvm_custom_libvirt_images_path != '' + - kvm_custom_libvirt_images_path | length > 0 - kvm_custom_libvirt_images_path != kvm_libvirt_images_current_real_path_test.stdout - not kvm_custom_libvirt_images_path_test.stat.exists diff --git a/ldap/tasks/ldapvirc.yml b/ldap/tasks/ldapvirc.yml index 06f9199d..9b015249 100644 --- a/ldap/tasks/ldapvirc.yml +++ b/ldap/tasks/ldapvirc.yml @@ -10,7 +10,7 @@ debug: msg: "WARNING: an LDAP admin password is given, but an ldapvirc file already exists. It will not be updated." when: - - ldap_admin_password != "" + - ldap_admin_password | length > 0 - root_ldapvirc_path.stat.exists # Generate ldap password if none is given and ldapvirc is absent @@ -25,7 +25,7 @@ register: new_ldap_admin_password changed_when: False when: - - ldap_admin_password == "" + - ldap_admin_password | length == 0 - not root_ldapvirc_path.stat.exists # Use the generated password or the one found in the file @@ -33,7 +33,7 @@ set_fact: ldap_admin_password: "{{ new_ldap_admin_password.stdout }}" when: - - ldap_admin_password == "" + - ldap_admin_password | length == 0 - not root_ldapvirc_path.stat.exists - name: hash password for cn=admin diff --git a/ldap/tasks/nagios.yml b/ldap/tasks/nagios.yml index 97db7dba..90921bf2 100644 --- a/ldap/tasks/nagios.yml +++ b/ldap/tasks/nagios.yml @@ -10,7 +10,7 @@ debug: msg: "WARNING: an LDAP nagios password is given, but a nagios config already exists. It will not be updated." when: - - ldap_nagios_password != "" + - ldap_nagios_password | length > 0 - nagios_monitoring_plugins_path.stat.exists # Generate ldap password if none is given and nagios config is absent @@ -19,7 +19,7 @@ name: apg state: present when: - - ldap_nagios_password == "" + - ldap_nagios_password | length == 0 - not nagios_monitoring_plugins_path.stat.exists - name: create a password for cn=admin @@ -27,7 +27,7 @@ register: new_ldap_nagios_password changed_when: False when: - - ldap_nagios_password == "" + - ldap_nagios_password | length == 0 - not nagios_monitoring_plugins_path.stat.exists # Use the generated password or the one found in the file @@ -35,7 +35,7 @@ set_fact: ldap_nagios_password: "{{ new_ldap_nagios_password.stdout }}" when: - - ldap_nagios_password == "" + - ldap_nagios_password | length == 0 - not nagios_monitoring_plugins_path.stat.exists - name: set params for NRPE check diff --git a/logstash/tasks/tmpdir.yml b/logstash/tasks/tmpdir.yml index 4149f5af..e41b1205 100644 --- a/logstash/tasks/tmpdir.yml +++ b/logstash/tasks/tmpdir.yml @@ -8,9 +8,12 @@ check_mode: no - block: - - name: "Create {{ logstash_custom_tmpdir or logstash_default_tmpdir | mandatory }}" + - set_fact: + _logstash_custom_tmpdir: "{{ logstash_custom_tmpdir | default(logstash_default_tmpdir, True) | mandatory }}" + + - name: "Create {{ _logstash_custom_tmpdir }}" file: - path: "{{ logstash_custom_tmpdir or logstash_default_tmpdir | mandatory }}" + path: "{{ _logstash_custom_tmpdir }}" owner: logstash group: logstash mode: "0755" @@ -21,11 +24,11 @@ - name: change JVM tmpdir lineinfile: dest: /etc/logstash/jvm.options - line: "-Djava.io.tmpdir={{ logstash_custom_tmpdir or logstash_default_tmpdir | mandatory }}" + line: "-Djava.io.tmpdir={{ _logstash_custom_tmpdir }}" regexp: "^-Djava.io.tmpdir=" insertafter: "## JVM configuration" notify: - restart logstash tags: - logstash - when: (logstash_custom_tmpdir != '' and logstash_custom_tmpdir != None) or fstab_tmp_noexec.rc == 0 + when: (logstash_custom_tmpdir is not none and logstash_custom_tmpdir | length > 0) or fstab_tmp_noexec.rc == 0 diff --git a/lxc-php/tasks/misc.yml b/lxc-php/tasks/misc.yml index 297ee469..c5aa5245 100644 --- a/lxc-php/tasks/misc.yml +++ b/lxc-php/tasks/misc.yml @@ -28,6 +28,9 @@ name: "{{ lxc_php_version }}" container_config: - "lxc.mount.entry = /run/mysqld {{ php_conf_mysql_socket_dir | replace('/', '', 1) }} none bind,create=dir 0 0" - when: lxc_php_create_mysql_link and php_conf_mysql_socket_dir is string + when: + - lxc_php_create_mysql_link | bool + - php_conf_mysql_socket_dir is not none + - php_conf_mysql_socket_dir | length > 0 notify: "Restart container" diff --git a/lxc/tasks/create-container.yml b/lxc/tasks/create-container.yml index 8b8a68e3..ad4f35d6 100644 --- a/lxc/tasks/create-container.yml +++ b/lxc/tasks/create-container.yml @@ -12,7 +12,7 @@ template: debian state: stopped template_options: "--arch amd64 --release {{ release }}" - when: container_exists.stdout_lines == [] + when: container_exists.stdout_lines | length == 0 - name: "Disable network configuration inside container {{ name }}" replace: diff --git a/lxc/tasks/main.yml b/lxc/tasks/main.yml index df8dc86f..a3a31cf5 100644 --- a/lxc/tasks/main.yml +++ b/lxc/tasks/main.yml @@ -24,13 +24,13 @@ failed_when: false changed_when: false register: root_subuids - when: lxc_unprivilegied_containers + when: lxc_unprivilegied_containers | bool - name: Add subuid and subgid ranges to root command: usermod -v 100000-199999 -w 100000-109999 root when: - - lxc_unprivilegied_containers - - root_subuids.rc + - lxc_unprivilegied_containers | bool + - root_subuids.rc != 0 - name: Create containers include: create-container.yml diff --git a/memcached/tasks/main.yml b/memcached/tasks/main.yml index 0bf81713..0159f8d6 100644 --- a/memcached/tasks/main.yml +++ b/memcached/tasks/main.yml @@ -13,7 +13,7 @@ notify: restart memcached tags: - memcached - when: memcached_instance_name == "" + when: memcached_instance_name | length == 0 - name: Memcached is running and enabled on boot. service: @@ -22,7 +22,7 @@ state: started tags: - memcached - when: memcached_instance_name == "" + when: memcached_instance_name | length == 0 - name: Add systemd template copy: @@ -30,7 +30,7 @@ dest: /etc/systemd/system/memcached@.service tags: - memcached - when: memcached_instance_name != "" + when: memcached_instance_name | length > 0 - name: Delete default memcached systemd configuration file systemd: @@ -39,7 +39,7 @@ state: stopped tags: - memcached - when: memcached_instance_name != "" + when: memcached_instance_name | length > 0 - name: Make sure memcached.conf is absent file: @@ -47,7 +47,7 @@ state: absent tags: - memcached - when: memcached_instance_name != "" + when: memcached_instance_name | length > 0 - name: Create a configuration file template: @@ -56,7 +56,7 @@ mode: "0644" tags: - memcached - when: memcached_instance_name != "" + when: memcached_instance_name | length > 0 - name: Enable and start the memcached instance systemd: @@ -67,7 +67,7 @@ masked: no tags: - memcached - when: memcached_instance_name != "" + when: memcached_instance_name | length > 0 - include: munin.yml diff --git a/memcached/tasks/munin.yml b/memcached/tasks/munin.yml index cd75fa64..6e2f6d6f 100644 --- a/memcached/tasks/munin.yml +++ b/memcached/tasks/munin.yml @@ -2,7 +2,7 @@ - name: Choose packages (Oracle) set_fact: multi: "multi_" - when: memcached_instance_name !="" + when: memcached_instance_name | length > 0 - name: is Munin present ? stat: diff --git a/metricbeat/tasks/main.yml b/metricbeat/tasks/main.yml index 29b88fb6..2290626e 100644 --- a/metricbeat/tasks/main.yml +++ b/metricbeat/tasks/main.yml @@ -61,8 +61,7 @@ line: " hosts: [\"{{ metricbeat_elasticsearch_hosts | join('\", \"') }}\"]" insertafter: "output.elasticsearch:" notify: restart metricbeat - when: - - metricbeat_elasticsearch_hosts + when: metricbeat_elasticsearch_hosts | length > 0 - name: Metricbeat protocol for Elasticsearch lineinfile: @@ -84,8 +83,8 @@ - { regexp: '^ #?password: .*', line: ' password: "{{ metricbeat_elasticsearch_auth_password }}"' } notify: restart metricbeat when: - - metricbeat_elasticsearch_auth_username - - metricbeat_elasticsearch_auth_password + - metricbeat_elasticsearch_auth_username | length > 0 + - metricbeat_elasticsearch_auth_password | length > 0 - name: Metricbeat api_key for Elasticsearch are configured lineinfile: @@ -94,7 +93,7 @@ line: ' api_key: "{{ metricbeat_elasticsearch_auth_api_key }}"' insertafter: "output.elasticsearch:" notify: restart metricbeat - when: metricbeat_elasticsearch_auth_api_key + when: metricbeat_elasticsearch_auth_api_key | length > 0 - name: disable cloud_metadata replace: @@ -102,7 +101,7 @@ regexp: '^(\s+)(- add_cloud_metadata:)' replace: '\1# \2' notify: restart metricbeat - when: not metricbeat_processors_cloud_metadata + when: not (metricbeat_processors_cloud_metadata | bool) - name: cloud_metadata processor is disabled lineinfile: @@ -110,8 +109,8 @@ line: " - add_cloud_metadata: ~" insert_after: '^processors:' notify: restart metricbeat - when: metricbeat_processors_cloud_metadata - when: not metricbeat_use_config_template + when: metricbeat_processors_cloud_metadata | bool + when: not (metricbeat_use_config_template | bool) # When we use a config template - block: @@ -128,5 +127,5 @@ - "templates/metricbeat/metricbeat.default.yml.j2" - "templates/metricbeat.default.yml.j2" notify: restart metricbeat - when: metricbeat_update_config - when: metricbeat_use_config_template + when: metricbeat_update_config | bool + when: metricbeat_use_config_template | bool diff --git a/minifirewall/tasks/activate.yml b/minifirewall/tasks/activate.yml index 21fb8cfd..e971407b 100644 --- a/minifirewall/tasks/activate.yml +++ b/minifirewall/tasks/activate.yml @@ -12,7 +12,7 @@ replace: '/etc/init.d/minifirewall start' when: - initd_alert5.stat.exists - - minifirewall_autostart + - minifirewall_autostart | bool - name: check if /usr/share/scripts/alert5 exists stat: @@ -26,4 +26,4 @@ replace: '/etc/init.d/minifirewall start' when: - usr_share_scripts_alert5.stat.exists - - minifirewall_autostart + - minifirewall_autostart | bool diff --git a/minifirewall/tasks/config.yml b/minifirewall/tasks/config.yml index 1b556674..04ed3a9c 100644 --- a/minifirewall/tasks/config.yml +++ b/minifirewall/tasks/config.yml @@ -39,8 +39,7 @@ - name: Verify that at least 1 trusted IP is provided assert: - that: - - minifirewall_trusted_ips != [] + that: minifirewall_trusted_ips | length > 0 msg: You must provide at least 1 trusted IP - debug: @@ -191,7 +190,7 @@ dest: "{{ minifirewall_main_file }}" regexp: '^#.*(--sport 5432).*(-s X\.X\.X\.X)' state: absent - when: evomaintenance_hosts != [] + when: evomaintenance_hosts | length > 0 - name: Stat minifirewall config file (after) stat: @@ -207,7 +206,7 @@ failed_when: "'starting IPTables rules is now finish : OK' not in minifirewall_init_restart.stdout" changed_when: "'starting IPTables rules is now finish : OK' in minifirewall_init_restart.stdout" when: - - minifirewall_restart_if_needed + - minifirewall_restart_if_needed | bool - minifirewall_is_running.rc == 0 - minifirewall_before.stat.checksum != minifirewall_after.stat.checksum @@ -216,7 +215,7 @@ register: minifirewall_init_restart failed_when: False changed_when: False - when: not minifirewall_restart_if_needed + when: not (minifirewall_restart_if_needed | bool) - debug: var: minifirewall_init_restart diff --git a/minifirewall/tasks/main.yml b/minifirewall/tasks/main.yml index 99a478e0..2a053d4f 100644 --- a/minifirewall/tasks/main.yml +++ b/minifirewall/tasks/main.yml @@ -2,7 +2,7 @@ - name: Compose minifirewall_restart_handler_name variable set_fact: - minifirewall_restart_handler_name: "{{ minifirewall_restart_if_needed | ternary('restart minifirewall', 'restart minifirewall (noop)') }}" + minifirewall_restart_handler_name: "{{ minifirewall_restart_if_needed | bool | ternary('restart minifirewall', 'restart minifirewall (noop)') }}" - include: install.yml @@ -13,10 +13,10 @@ - include: activate.yml - include: tail.yml - when: minifirewall_tail_included + when: minifirewall_tail_included | bool - name: Force restart minifirewall command: /bin/true notify: restart minifirewall changed_when: False - when: minifirewall_restart_force + when: minifirewall_restart_force | bool diff --git a/minifirewall/tasks/tail.yml b/minifirewall/tasks/tail.yml index 629c2e59..a086ead9 100644 --- a/minifirewall/tasks/tail.yml +++ b/minifirewall/tasks/tail.yml @@ -39,14 +39,14 @@ changed_when: "'starting IPTables rules is now finish : OK' in minifirewall_init_restart.stdout" when: - minifirewall_tail_template is changed - - minifirewall_restart_if_needed + - minifirewall_restart_if_needed | bool - name: restart minifirewall (noop) meta: noop register: minifirewall_init_restart failed_when: False changed_when: False - when: not minifirewall_restart_if_needed + when: not (minifirewall_restart_if_needed | bool) - debug: var: minifirewall_init_restart diff --git a/mongodb/tasks/main_buster.yml b/mongodb/tasks/main_buster.yml index 8bad2bee..387a9c0a 100644 --- a/mongodb/tasks/main_buster.yml +++ b/mongodb/tasks/main_buster.yml @@ -32,7 +32,7 @@ name: mongod enabled: yes state: started - when: _mongodb_install_package.changed + when: _mongodb_install_package is changed - name: install dependency for monitoring apt: diff --git a/mysql-oracle/tasks/datadir.yml b/mysql-oracle/tasks/datadir.yml index 28beb1ed..c375f5d5 100644 --- a/mysql-oracle/tasks/datadir.yml +++ b/mysql-oracle/tasks/datadir.yml @@ -14,7 +14,7 @@ register: mysql_current_real_datadir_test tags: - mysql - when: mysql_custom_datadir != '' + when: mysql_custom_datadir | length > 0 - block: - name: MySQL is stopped @@ -40,6 +40,6 @@ tags: - mysql when: - - mysql_custom_datadir != '' + - mysql_custom_datadir | length > 0 - mysql_custom_datadir != mysql_current_real_datadir_test.stdout - not mysql_custom_datadir_test.stat.exists diff --git a/mysql-oracle/tasks/nrpe.yml b/mysql-oracle/tasks/nrpe.yml index 58820786..c3457699 100644 --- a/mysql-oracle/tasks/nrpe.yml +++ b/mysql-oracle/tasks/nrpe.yml @@ -47,9 +47,11 @@ loop: - { option: 'user', value: 'nrpe' } - { option: 'password', value: '{{ mysql_nrpe_password.stdout }}' } - when: create_nrpe_user.changed + when: create_nrpe_user is changed - when: nrpe_evolix_config.stat.exists and (not nrpe_my_cnf.stat.exists or mysql_force_new_nrpe_password) + when: + - nrpe_evolix_config.stat.exists + - (not nrpe_my_cnf.stat.exists or (mysql_force_new_nrpe_password | bool)) tags: - mysql - nrpe diff --git a/mysql-oracle/tasks/packages.yml b/mysql-oracle/tasks/packages.yml index af1a0460..5bf8848e 100644 --- a/mysql-oracle/tasks/packages.yml +++ b/mysql-oracle/tasks/packages.yml @@ -87,7 +87,7 @@ tags: - mysql - packages - when: mysql_install_libclient + when: mysql_install_libclient | bool - name: MySQL is started systemd: diff --git a/mysql-oracle/tasks/tmpdir.yml b/mysql-oracle/tasks/tmpdir.yml index 8d518160..790a9f2e 100644 --- a/mysql-oracle/tasks/tmpdir.yml +++ b/mysql-oracle/tasks/tmpdir.yml @@ -20,4 +20,4 @@ notify: "{{ mysql_restart_handler_name }}" tags: - mysql - when: mysql_custom_tmpdir != '' + when: mysql_custom_tmpdir | length > 0 diff --git a/mysql-oracle/tasks/utils.yml b/mysql-oracle/tasks/utils.yml index bf0013df..e7573afe 100644 --- a/mysql-oracle/tasks/utils.yml +++ b/mysql-oracle/tasks/utils.yml @@ -1,12 +1,15 @@ --- +- set_fact: + _mysql_scripts_dir: "{{ mysql_scripts_dir | default(general_scripts_dir, True) | mandatory }}" + - include_role: name: evolix/remount-usr - when: (mysql_scripts_dir or general_scripts_dir) is search ("/usr") + when: _mysql_scripts_dir is search ("/usr") - name: Scripts directory exists file: - dest: "{{ mysql_scripts_dir or general_scripts_dir | mandatory }}" + dest: "{{ _mysql_scripts_dir }}" mode: "0700" state: directory tags: @@ -95,12 +98,12 @@ name: evolix/remount-usr tags: - mysql - when: (mysql_scripts_dir or general_scripts_dir) is search ("/usr") + when: _mysql_scripts_dir is search ("/usr") - name: mysqltuner is installed # copy: # src: mysqltuner.pl - # dest: "{{ mysql_scripts_dir or general_scripts_dir | mandatory }}/mysqltuner.pl" + # dest: "{{ _mysql_scripts_dir }}/mysqltuner.pl" # mode: "0700" apt: name: mysqltuner @@ -121,12 +124,12 @@ name: evolix/remount-usr tags: - mysql - when: (mysql_scripts_dir or general_scripts_dir) is search ("/usr") + when: _mysql_scripts_dir is search ("/usr") - name: mysql-optimize.sh is installed copy: src: mysql-optimize.sh - dest: "{{ mysql_scripts_dir or general_scripts_dir | mandatory }}/mysql-optimize.sh" + dest: "{{ _mysql_scripts_dir }}/mysql-optimize.sh" mode: "0700" tags: - mysql @@ -143,7 +146,7 @@ - name: "Enable cron to optimize MySQL" file: - src: "{{ mysql_scripts_dir or general_scripts_dir | mandatory }}/mysql-optimize.sh" + src: "{{ _mysql_scripts_dir }}/mysql-optimize.sh" dest: /etc/cron.{{ mysql_cron_optimize_frequency | mandatory }}/mysql-optimize.sh state: link when: mysql_cron_optimize | bool @@ -192,12 +195,12 @@ - include_role: name: evolix/remount-usr - when: (mysql_scripts_dir or general_scripts_dir) is search ("/usr") + when: _mysql_scripts_dir is search ("/usr") - name: Install my-add.sh copy: src: my-add.sh - dest: "{{ mysql_scripts_dir or general_scripts_dir | mandatory }}/my-add.sh" + dest: "{{ _mysql_scripts_dir }}/my-add.sh" mode: "0700" tags: - mysql diff --git a/mysql/tasks/config_stretch.yml b/mysql/tasks/config_stretch.yml index d6d59efd..cfbeedfe 100644 --- a/mysql/tasks/config_stretch.yml +++ b/mysql/tasks/config_stretch.yml @@ -42,4 +42,4 @@ name: mysql daemon_reload: yes notify: "{{ mysql_restart_handler_name }}" - when: mariadb_systemd_override.changed + when: mariadb_systemd_override is changed diff --git a/mysql/tasks/datadir.yml b/mysql/tasks/datadir.yml index 28beb1ed..c375f5d5 100644 --- a/mysql/tasks/datadir.yml +++ b/mysql/tasks/datadir.yml @@ -14,7 +14,7 @@ register: mysql_current_real_datadir_test tags: - mysql - when: mysql_custom_datadir != '' + when: mysql_custom_datadir | length > 0 - block: - name: MySQL is stopped @@ -40,6 +40,6 @@ tags: - mysql when: - - mysql_custom_datadir != '' + - mysql_custom_datadir | length > 0 - mysql_custom_datadir != mysql_current_real_datadir_test.stdout - not mysql_custom_datadir_test.stat.exists diff --git a/mysql/tasks/logdir.yml b/mysql/tasks/logdir.yml index a1b3a8d8..bd6ecab2 100644 --- a/mysql/tasks/logdir.yml +++ b/mysql/tasks/logdir.yml @@ -14,7 +14,7 @@ register: mysql_current_real_logdir_test tags: - mysql - when: mysql_custom_logdir != '' + when: mysql_custom_logdir | length > 0 - block: - name: MySQL is stopped @@ -40,6 +40,6 @@ tags: - mysql when: - - mysql_custom_logdir != '' + - mysql_custom_logdir | length > 0 - mysql_custom_logdir != mysql_current_real_logdir_test.stdout - not mysql_custom_logdir_test.stat.exists diff --git a/mysql/tasks/main.yml b/mysql/tasks/main.yml index 11435c73..ace6299e 100644 --- a/mysql/tasks/main.yml +++ b/mysql/tasks/main.yml @@ -23,7 +23,7 @@ when: ansible_distribution_release == "jessie" - include: replication.yml - when: mysql_replication + when: mysql_replication | bool - include: datadir.yml diff --git a/mysql/tasks/nrpe.yml b/mysql/tasks/nrpe.yml index 58820786..c3457699 100644 --- a/mysql/tasks/nrpe.yml +++ b/mysql/tasks/nrpe.yml @@ -47,9 +47,11 @@ loop: - { option: 'user', value: 'nrpe' } - { option: 'password', value: '{{ mysql_nrpe_password.stdout }}' } - when: create_nrpe_user.changed + when: create_nrpe_user is changed - when: nrpe_evolix_config.stat.exists and (not nrpe_my_cnf.stat.exists or mysql_force_new_nrpe_password) + when: + - nrpe_evolix_config.stat.exists + - (not nrpe_my_cnf.stat.exists or (mysql_force_new_nrpe_password | bool)) tags: - mysql - nrpe diff --git a/mysql/tasks/packages_jessie.yml b/mysql/tasks/packages_jessie.yml index 8d27de52..48408433 100644 --- a/mysql/tasks/packages_jessie.yml +++ b/mysql/tasks/packages_jessie.yml @@ -33,7 +33,7 @@ tags: - mysql - packages - when: mysql_install_libclient + when: mysql_install_libclient | bool - name: MySQL is started service: diff --git a/mysql/tasks/packages_stretch.yml b/mysql/tasks/packages_stretch.yml index 901543af..98a8f69d 100644 --- a/mysql/tasks/packages_stretch.yml +++ b/mysql/tasks/packages_stretch.yml @@ -19,7 +19,7 @@ tags: - mysql - packages - when: mysql_install_libclient + when: mysql_install_libclient | bool - name: MySQL is started service: diff --git a/mysql/tasks/tmpdir.yml b/mysql/tasks/tmpdir.yml index e2c13dc5..79a3ac5e 100644 --- a/mysql/tasks/tmpdir.yml +++ b/mysql/tasks/tmpdir.yml @@ -20,4 +20,4 @@ notify: "{{ mysql_restart_handler_name }}" tags: - mysql - when: mysql_custom_tmpdir != '' + when: mysql_custom_tmpdir | length > 0 diff --git a/mysql/tasks/users_jessie.yml b/mysql/tasks/users_jessie.yml index 027d0bd8..99dd2d04 100644 --- a/mysql/tasks/users_jessie.yml +++ b/mysql/tasks/users_jessie.yml @@ -45,7 +45,7 @@ loop: - { option: 'user', value: 'mysqladmin' } - { option: 'password', value: '{{ mysql_admin_password.stdout }}' } - when: create_mysqladmin_user.changed + when: create_mysqladmin_user is changed tags: - mysql diff --git a/mysql/tasks/users_stretch.yml b/mysql/tasks/users_stretch.yml index bca16bc6..574399af 100644 --- a/mysql/tasks/users_stretch.yml +++ b/mysql/tasks/users_stretch.yml @@ -40,7 +40,7 @@ loop: - { option: 'user', value: 'mysqladmin' } - { option: 'password', value: '{{ mysql_admin_password.stdout }}' } - when: create_mysqladmin_user.changed + when: create_mysqladmin_user is changed tags: - mysql @@ -79,7 +79,7 @@ _credentials: - { option: 'user', value: 'debian-sys-maint' } - { option: 'password', value: '{{ mysql_debian_password.stdout }}' } - when: create_debian_user.changed + when: create_debian_user is changed tags: - mysql diff --git a/mysql/tasks/utils.yml b/mysql/tasks/utils.yml index fedda1ff..b4abf059 100644 --- a/mysql/tasks/utils.yml +++ b/mysql/tasks/utils.yml @@ -1,12 +1,15 @@ --- +- set_fact: + _mysql_scripts_dir: "{{ mysql_scripts_dir | default(general_scripts_dir, True) | mandatory }}" + - include_role: name: evolix/remount-usr - when: (mysql_scripts_dir or general_scripts_dir) is search ("/usr") + when: _mysql_scripts_dir is search ("/usr") - name: Ensure scripts directory exists file: - dest: "{{ mysql_scripts_dir or general_scripts_dir | mandatory }}" + dest: "{{ _mysql_scripts_dir }}" mode: "0700" state: directory tags: @@ -62,12 +65,12 @@ - include_role: name: evolix/remount-usr - when: (mysql_scripts_dir or general_scripts_dir) is search ("/usr") + when: _mysql_scripts_dir is search ("/usr") - name: Install mysqltuner # copy: # src: mysqltuner.pl - # dest: "{{ mysql_scripts_dir or general_scripts_dir | mandatory }}/mysqltuner.pl" + # dest: "{{ _mysql_scripts_dir }}/mysqltuner.pl" # mode: "0700" apt: name: mysqltuner @@ -98,12 +101,12 @@ - include_role: name: evolix/remount-usr - when: (mysql_scripts_dir or general_scripts_dir) is search ("/usr") + when: _mysql_scripts_dir is search ("/usr") - name: Optimize script for MySQL copy: src: mysql-optimize.sh - dest: "{{ mysql_scripts_dir or general_scripts_dir | mandatory }}/mysql-optimize.sh" + dest: "{{ _mysql_scripts_dir }}/mysql-optimize.sh" mode: "0700" tags: - mysql @@ -118,10 +121,10 @@ - name: "Enable cron to optimize MySQL" file: - src: "{{ mysql_scripts_dir or general_scripts_dir | mandatory }}/mysql-optimize.sh" + src: "{{ _mysql_scripts_dir }}/mysql-optimize.sh" dest: /etc/cron.{{ mysql_cron_optimize_frequency | mandatory }}/mysql-optimize.sh state: link - when: mysql_cron_optimize + when: mysql_cron_optimize | bool tags: - mysql @@ -129,7 +132,7 @@ file: dest: /etc/cron.{{ mysql_cron_optimize_frequency | mandatory }}/mysql-optimize.sh state: absent - when: not mysql_cron_optimize + when: not (mysql_cron_optimize | bool) tags: - mysql @@ -146,7 +149,7 @@ src: mysqltuner.cron.sh dest: /etc/cron.{{ mysql_cron_mysqltuner_frequency | mandatory }}/mysqltuner.sh mode: "0755" - when: mysql_cron_mysqltuner + when: mysql_cron_mysqltuner | bool tags: - mysql @@ -154,7 +157,7 @@ file: dest: /etc/cron.{{ mysql_cron_mysqltuner_frequency | mandatory }}/mysqltuner.sh state: absent - when: not mysql_cron_mysqltuner + when: not (mysql_cron_mysqltuner | bool) tags: - mysql @@ -162,12 +165,12 @@ - include_role: name: evolix/remount-usr - when: (mysql_scripts_dir or general_scripts_dir) is search ("/usr") + when: _mysql_scripts_dir is search ("/usr") - name: Install my-add.sh copy: src: my-add.sh - dest: "{{ mysql_scripts_dir or general_scripts_dir | mandatory }}/my-add.sh" + dest: "{{ _mysql_scripts_dir }}/my-add.sh" mode: "0700" force: "{{ mysql_force_myadd_script }}" tags: @@ -183,7 +186,7 @@ - name: "Install save_mysql_processlist.sh" copy: src: save_mysql_processlist.sh - dest: "{{ mysql_scripts_dir or general_scripts_dir | mandatory }}/save_mysql_processlist.sh" + dest: "{{ _mysql_scripts_dir }}/save_mysql_processlist.sh" mode: "0755" force: no tags: diff --git a/nagios-nrpe/tasks/main.yml b/nagios-nrpe/tasks/main.yml index 065ffacc..77770020 100644 --- a/nagios-nrpe/tasks/main.yml +++ b/nagios-nrpe/tasks/main.yml @@ -42,7 +42,7 @@ regexp: '^allowed_hosts=' insertafter: '# Allowed IPs' notify: restart nagios-nrpe-server - when: nagios_nrpe_force_update_allowed_hosts + when: nagios_nrpe_force_update_allowed_hosts | bool tags: - nagios-nrpe diff --git a/networkd-to-ifconfig/tasks/main.yml b/networkd-to-ifconfig/tasks/main.yml index 29ca3b4f..d1ac0ac4 100644 --- a/networkd-to-ifconfig/tasks/main.yml +++ b/networkd-to-ifconfig/tasks/main.yml @@ -7,7 +7,9 @@ - debug: msg: A /etc/network/interfaces file already exists, nothing is done. - when: interfaces_file.stat.exists and not force_update_eni_file + when: + - interfaces_file.stat.exists + - not (force_update_eni_file | bool) - block: - name: "Look for systemd network config" @@ -38,7 +40,7 @@ - eni_ipv6_address | ipv6 - eni_ipv6_gateway | ipv6 msg: "IPv6 configuration is invalid" - when: eni_ipv6_address or eni_ipv6_gateway + when: (eni_ipv6_address | length > 0) or (eni_ipv6_gateway | length > 0) - name: "A new /etc/network/interfaces is generated" template: @@ -63,4 +65,4 @@ - debug: msg: You should verify your configuration, then reboot the server. - when: force_update_eni_file or not interfaces_file.stat.exists + when: (force_update_eni_file | bool) or (not interfaces_file.stat.exists) diff --git a/networkd-to-ifconfig/tasks/set_facts_from_ansible.yml b/networkd-to-ifconfig/tasks/set_facts_from_ansible.yml index 21de7357..5f6f4011 100644 --- a/networkd-to-ifconfig/tasks/set_facts_from_ansible.yml +++ b/networkd-to-ifconfig/tasks/set_facts_from_ansible.yml @@ -4,10 +4,10 @@ set_fact: eni_ipv4_address: "{{ ansible_default_ipv4.address | ipv4 }}" eni_ipv4_gateway: "{{ ansible_default_ipv4.gateway | ipv4 }}" - when: ansible_default_ipv4 + when: ansible_default_ipv4 | length > 0 - name: Prepare variables (IPv6) set_fact: eni_ipv6_address: "{{ ansible_default_ipv6.address | ipv6 | first }}" eni_ipv6_gateway: "{{ ansible_default_ipv6.gateway | ipv6 | first }}" - when: ansible_default_ipv6 + when: ansible_default_ipv6 | length > 0 diff --git a/newrelic/tasks/main.yml b/newrelic/tasks/main.yml index 7537214d..a4e8f2b3 100644 --- a/newrelic/tasks/main.yml +++ b/newrelic/tasks/main.yml @@ -3,7 +3,7 @@ - include: sources.yml - include: php.yml - when: newrelic_php + when: newrelic_php | bool - include: sysmond.yml - when: newrelic_sysmond + when: newrelic_sysmond | bool diff --git a/newrelic/tasks/php.yml b/newrelic/tasks/php.yml index 5d44e8e5..c41dbac9 100644 --- a/newrelic/tasks/php.yml +++ b/newrelic/tasks/php.yml @@ -6,7 +6,7 @@ question: "newrelic-php5/application-name" value: "{{ newrelic_appname }}" vtype: string - when: newrelic_appname != "" + when: newrelic_appname | length > 0 - name: Pre-seed package configuration with license debconf: @@ -14,7 +14,7 @@ question: "newrelic-php5/license-key" value: "{{ newrelic_license }}" vtype: "string" - when: newrelic_license != "" + when: newrelic_license | length > 0 - name: list newrelic config files shell: "find /etc/php* -type f -name newrelic.ini" diff --git a/newrelic/tasks/sysmond.yml b/newrelic/tasks/sysmond.yml index 5d72a470..e5c5bab9 100644 --- a/newrelic/tasks/sysmond.yml +++ b/newrelic/tasks/sysmond.yml @@ -9,5 +9,5 @@ dest: /etc/newrelic/nrsysmond.cfg regexp: "license_key=REPLACE_WITH_REAL_KEY" replace: "license_key={{ newrelic_license }}" - when: newrelic_license != "" + when: newrelic_license | length > 0 notify: restart newrelic-sysmond diff --git a/nginx/tasks/main.yml b/nginx/tasks/main.yml index 58b9f95b..8a8fc264 100644 --- a/nginx/tasks/main.yml +++ b/nginx/tasks/main.yml @@ -2,7 +2,7 @@ - debug: msg: "Nginx minimal mode has been removed, falling back to normal mode." - when: nginx_minimal + when: nginx_minimal | bool - include: packages.yml @@ -112,7 +112,7 @@ state: link force: yes notify: reload nginx - when: nginx_evolinux_default_enabled + when: nginx_evolinux_default_enabled | bool tags: - nginx diff --git a/nginx/tasks/packages.yml b/nginx/tasks/packages.yml index 05c033b4..7d9eead5 100644 --- a/nginx/tasks/packages.yml +++ b/nginx/tasks/packages.yml @@ -2,10 +2,10 @@ - set_fact: nginx_package_name_default: nginx-light - when: nginx_minimal + when: nginx_minimal | bool - include: packages_backports.yml - when: nginx_backports + when: nginx_backports | bool # TODO: install "nginx" + only necessary modules, instead of "nginx-full" diff --git a/nginx/tasks/server_status_read.yml b/nginx/tasks/server_status_read.yml index 570febf9..652bc154 100644 --- a/nginx/tasks/server_status_read.yml +++ b/nginx/tasks/server_status_read.yml @@ -14,7 +14,7 @@ # The last character "\u000A" is a line feed (LF), it's better to keep it content: "{{ nginx_serverstatus_suffix }}\u000A" force: yes - when: nginx_serverstatus_suffix != "" + when: nginx_serverstatus_suffix | length > 0 - name: generate random string for server-status suffix shell: "apg -a 1 -M N -n 1 > {{ nginx_serverstatus_suffix_file }}" diff --git a/nodejs/tasks/main.yml b/nodejs/tasks/main.yml index af15112b..d0aa18b8 100644 --- a/nodejs/tasks/main.yml +++ b/nodejs/tasks/main.yml @@ -48,4 +48,4 @@ - nodejs - include: yarn.yml - when: nodejs_install_yarn + when: nodejs_install_yarn | bool diff --git a/packweb-apache/tasks/main.yml b/packweb-apache/tasks/main.yml index 6122c4a2..5e2f9e92 100644 --- a/packweb-apache/tasks/main.yml +++ b/packweb-apache/tasks/main.yml @@ -89,7 +89,7 @@ - include: awstats.yml - include: fhs_retrictions.yml - when: packweb_fhs_retrictions + when: packweb_fhs_retrictions | bool - name: Periodically cache ftp directory sizes for ftpadmin.sh cron: diff --git a/packweb-apache/tasks/phpmyadmin.yml b/packweb-apache/tasks/phpmyadmin.yml index 39fd1163..f83b0a5d 100644 --- a/packweb-apache/tasks/phpmyadmin.yml +++ b/packweb-apache/tasks/phpmyadmin.yml @@ -53,7 +53,7 @@ # The last character "\u000A" is a line feed (LF), it's better to keep it content: "{{ packweb_phpmyadmin_suffix }}\u000A" force: yes - when: packweb_phpmyadmin_suffix != "" + when: packweb_phpmyadmin_suffix | length > 0 - name: generate random string for phpmyadmin suffix shell: "apg -a 1 -M N -n 1 > {{ packweb_phpmyadmin_suffix_file }}" diff --git a/percona/tasks/main.yml b/percona/tasks/main.yml index ede6f394..4db87058 100644 --- a/percona/tasks/main.yml +++ b/percona/tasks/main.yml @@ -26,7 +26,7 @@ copy: src: "{{ percona__apt_config_package_file }}" dest: "/root/{{ percona__apt_config_package_file }}" - when: not percona__apt_config_package_installed + when: not (percona__apt_config_package_installed | bool) # - include_role: # name: evolix/remount-usr @@ -36,7 +36,7 @@ deb: "/root/{{ percona__apt_config_package_file }}" state: present register: percona__apt_config_deb - when: not percona__apt_config_package_installed + when: not (percona__apt_config_package_installed | bool) - name: Percona APT config package is installed from repository apt: @@ -51,4 +51,4 @@ when: percona__apt_config_deb is changed - include: xtrabackup.yml - when: percona__install_xtrabackup + when: percona__install_xtrabackup | bool diff --git a/php/tasks/config_apache.yml b/php/tasks/config_apache.yml index 3ae9738c..795678fd 100644 --- a/php/tasks/config_apache.yml +++ b/php/tasks/config_apache.yml @@ -44,4 +44,4 @@ mode: "0644" loop: - { option: "date.timezone", value: "Europe/Paris" } - when: php_symfony_requirements + when: php_symfony_requirements | bool diff --git a/php/tasks/config_cli.yml b/php/tasks/config_cli.yml index c4678cd5..d327690a 100644 --- a/php/tasks/config_cli.yml +++ b/php/tasks/config_cli.yml @@ -35,4 +35,4 @@ mode: "0644" loop: - { option: "date.timezone", value: "Europe/Paris" } - when: php_symfony_requirements + when: php_symfony_requirements | bool diff --git a/php/tasks/config_fpm.yml b/php/tasks/config_fpm.yml index 57680ea9..ad543f19 100644 --- a/php/tasks/config_fpm.yml +++ b/php/tasks/config_fpm.yml @@ -79,11 +79,11 @@ loop: - { option: "date.timezone", value: "Europe/Paris" } notify: "restart {{ php_fpm_service_name }}" - when: php_symfony_requirements + when: php_symfony_requirements | bool - name: Delete debian default pool file: - path: "{{ php_fpm_debian_default_pool_file }}" + path: "{{ php_fpm_debian_default_pool_file | mandatory }}" state: absent notify: "restart {{ php_fpm_service_name }}" - when: php_fpm_remove_default_pool + when: php_fpm_remove_default_pool | bool diff --git a/php/tasks/main.yml b/php/tasks/main.yml index 2fd1a250..e9687e67 100644 --- a/php/tasks/main.yml +++ b/php/tasks/main.yml @@ -2,8 +2,7 @@ - fail: msg: only compatible with Debian >= 8 - when: - - ansible_distribution != "Debian" or ansible_distribution_major_version is version('8', '<') + when: ansible_distribution != "Debian" or ansible_distribution_major_version is version('8', '<') - include: main_jessie.yml when: ansible_distribution_release == "jessie" diff --git a/php/tasks/main_buster.yml b/php/tasks/main_buster.yml index c757d539..fba952ab 100644 --- a/php/tasks/main_buster.yml +++ b/php/tasks/main_buster.yml @@ -36,7 +36,7 @@ - libphp-phpmailer - include: sury_pre.yml - when: php_sury_enable + when: php_sury_enable | bool - name: "Install PHP packages (Debian 9 or later)" apt: @@ -49,7 +49,7 @@ - libapache2-mod-php - php state: present - when: php_apache_enable + when: php_apache_enable | bool - name: "Install PHP FPM packages (Debian 9 or later)" apt: @@ -57,7 +57,7 @@ - php-fpm - php state: present - when: php_fpm_enable + when: php_fpm_enable | bool # Configuration @@ -76,22 +76,22 @@ mode: "0755" - include: config_fpm.yml - when: php_fpm_enable + when: php_fpm_enable | bool - name: Enforce permissions on PHP fpm directory file: dest: /etc/php/7.3/fpm mode: "0755" - when: php_fpm_enable + when: php_fpm_enable | bool - include: config_apache.yml - when: php_apache_enable + when: php_apache_enable | bool - name: Enforce permissions on PHP apache2 directory file: dest: /etc/php/7.3/apache2 mode: "0755" - when: php_apache_enable + when: php_apache_enable | bool - include: sury_post.yml - when: php_sury_enable + when: php_sury_enable | bool diff --git a/php/tasks/main_jessie.yml b/php/tasks/main_jessie.yml index 8e99280c..5ec3123d 100644 --- a/php/tasks/main_jessie.yml +++ b/php/tasks/main_jessie.yml @@ -40,7 +40,7 @@ - libapache2-mod-php5 - php5 state: present - when: php_apache_enable + when: php_apache_enable | bool - name: "Install PHP FPM packages (jessie)" apt: @@ -48,7 +48,7 @@ - php5-fpm - php5 state: present - when: php_fpm_enable + when: php_fpm_enable | bool # Configuration @@ -65,19 +65,19 @@ mode: "0755" - include: config_fpm.yml - when: php_fpm_enable + when: php_fpm_enable | bool - name: Enforce permissions on PHP fpm directory file: dest: /etc/php5/fpm mode: "0755" - when: php_fpm_enable + when: php_fpm_enable | bool - include: config_apache.yml - when: php_apache_enable + when: php_apache_enable | bool - name: Enforce permissions on PHP apache2 directory file: dest: /etc/php5/apache2 mode: "0755" - when: php_apache_enable + when: php_apache_enable | bool diff --git a/php/tasks/main_stretch.yml b/php/tasks/main_stretch.yml index 004aec02..dc16c6e4 100644 --- a/php/tasks/main_stretch.yml +++ b/php/tasks/main_stretch.yml @@ -36,7 +36,7 @@ - libphp-phpmailer - include: sury_pre.yml - when: php_sury_enable + when: php_sury_enable | bool - name: "Install PHP packages (Debian 9 or later)" apt: @@ -49,7 +49,7 @@ - libapache2-mod-php - php state: present - when: php_apache_enable + when: php_apache_enable | bool - name: "Install PHP FPM packages (Debian 9 or later)" apt: @@ -57,7 +57,7 @@ - php-fpm - php state: present - when: php_fpm_enable + when: php_fpm_enable | bool # Configuration @@ -77,22 +77,22 @@ mode: "0755" - include: config_fpm.yml - when: php_fpm_enable + when: php_fpm_enable | bool - name: Enforce permissions on PHP fpm directory file: dest: /etc/php/7.0/fpm mode: "0755" - when: php_fpm_enable + when: php_fpm_enable | bool - include: config_apache.yml - when: php_apache_enable + when: php_apache_enable | bool - name: Enforce permissions on PHP apache2 directory file: dest: /etc/php/7.0/apache2 mode: "0755" - when: php_apache_enable + when: php_apache_enable | bool - include: sury_post.yml - when: php_sury_enable + when: php_sury_enable | bool diff --git a/php/tasks/sury_post.yml b/php/tasks/sury_post.yml index 3f82d23d..4e706889 100644 --- a/php/tasks/sury_post.yml +++ b/php/tasks/sury_post.yml @@ -24,13 +24,13 @@ loop: - { src: "{{ php_apache_defaults_ini_file }}", dest: "/etc/php/7.4/apache2/conf.d/z-evolinux-defaults.ini" } - { src: "{{ php_apache_custom_ini_file }}", dest: "/etc/php/7.4/apache2/conf.d/zzz-evolinux-custom.ini" } - when: php_apache_enable + when: php_apache_enable | bool - name: Enforce permissions on PHP 7.4/cli directory file: dest: /etc/php/7.4/apache2 mode: "0755" - when: php_apache_enable + when: php_apache_enable | bool - name: Symlink Evolix FPM config files from 7.4 to 7.0 file: @@ -43,10 +43,10 @@ - { src: "{{ php_fpm_custom_ini_file }}", dest: "/etc/php/7.4/fpm/conf.d/zzz-evolinux-custom.ini" } - { src: "{{ php_fpm_defaults_conf_file }}", dest: "/etc/php/7.4/fpm/pool.d/z-evolinux-defaults.conf" } - { src: "{{ php_fpm_custom_conf_file }}", dest: "/etc/php/7.4/fpm/pool.d/zzz-evolinux-custom.conf" } - when: php_fpm_enable + when: php_fpm_enable | bool - name: Enforce permissions on PHP 7.4/cli directory file: dest: /etc/php/7.4/fpm mode: "0755" - when: php_fpm_enable + when: php_fpm_enable | bool diff --git a/postfix/tasks/main.yml b/postfix/tasks/main.yml index 0e0fff2d..d8caf2b2 100644 --- a/postfix/tasks/main.yml +++ b/postfix/tasks/main.yml @@ -3,10 +3,10 @@ - include: common.yml - include: minimal.yml - when: postfix_packmail == False + when: not (postfix_packmail | bool) - include: packmail.yml - when: postfix_packmail == True + when: postfix_packmail | bool - include: slow_transport.yml - when: postfix_slow_transport_include + when: postfix_slow_transport_include | bool diff --git a/postfix/tasks/minimal.yml b/postfix/tasks/minimal.yml index ad666532..970b9dcb 100644 --- a/postfix/tasks/minimal.yml +++ b/postfix/tasks/minimal.yml @@ -15,6 +15,6 @@ mode: "0644" force: yes notify: restart postfix - when: postfix_force_main_cf or postfix_maincf_md5_jessie in default_main_cf.stdout or postfix_maincf_md5_stretch in default_main_cf.stdout + when: (postfix_force_main_cf | bool) or (postfix_maincf_md5_jessie in default_main_cf.stdout) or (postfix_maincf_md5_stretch in default_main_cf.stdout) tags: - postfix diff --git a/postfix/tasks/packmail.yml b/postfix/tasks/packmail.yml index cf4482ed..2ba8eba9 100644 --- a/postfix/tasks/packmail.yml +++ b/postfix/tasks/packmail.yml @@ -19,7 +19,7 @@ mode: "0644" force: yes notify: restart postfix - when: postfix_force_main_cf or postfix_maincf_md5_jessie in default_main_cf.stdout or postfix_maincf_md5_stretch in default_main_cf.stdout + when: (postfix_force_main_cf | bool) or (postfix_maincf_md5_jessie in default_main_cf.stdout) or (postfix_maincf_md5_stretch in default_main_cf.stdout) tags: - postfix @@ -67,7 +67,7 @@ - sender.access - sender.access_local - spamd.cidr - when: postfix_copy_filter.changed + when: postfix_copy_filter is changed tags: - postfix diff --git a/postgresql/tasks/main.yml b/postgresql/tasks/main.yml index 292849a0..aecdf80d 100644 --- a/postgresql/tasks/main.yml +++ b/postgresql/tasks/main.yml @@ -19,4 +19,4 @@ - include: logrotate.yml - include: postgis.yml - when: postgresql_install_postgis + when: postgresql_install_postgis | bool diff --git a/postgresql/tasks/nrpe.yml b/postgresql/tasks/nrpe.yml index 8ce178e9..740c7b08 100644 --- a/postgresql/tasks/nrpe.yml +++ b/postgresql/tasks/nrpe.yml @@ -37,5 +37,5 @@ regexp: '^command\[check_pgsql\]=' line: 'command[check_pgsql]=/usr/lib/nagios/plugins/check_pgsql -H localhost -l nrpe -p "{{postgresql_nrpe_password.stdout}}"' notify: restart nagios-nrpe-server - when: postgresql_create_nrpe_user.changed + when: postgresql_create_nrpe_user is changed when: nrpe_evolix_config.stat.exists diff --git a/postgresql/tasks/packages_buster.yml b/postgresql/tasks/packages_buster.yml index 3a1a440e..76017545 100644 --- a/postgresql/tasks/packages_buster.yml +++ b/postgresql/tasks/packages_buster.yml @@ -3,7 +3,7 @@ - name: "Set variables (Debian 10)" set_fact: postgresql_version: '11' - when: postgresql_version == "" + when: postgresql_version is none or postgresql_version | length == 0 - include: pgdg-repo.yml when: postgresql_version != '11' diff --git a/postgresql/tasks/packages_jessie.yml b/postgresql/tasks/packages_jessie.yml index ba21632e..cf8f0879 100644 --- a/postgresql/tasks/packages_jessie.yml +++ b/postgresql/tasks/packages_jessie.yml @@ -3,7 +3,7 @@ - name: "Set variables (Debian 8)" set_fact: postgresql_version: '9.4' - when: postgresql_version == "" + when: postgresql_version is none or postgresql_version | length == 0 - include: pgdg-repo.yml when: postgresql_version != '9.4' diff --git a/postgresql/tasks/packages_stretch.yml b/postgresql/tasks/packages_stretch.yml index eff513f9..d8ebb9e4 100644 --- a/postgresql/tasks/packages_stretch.yml +++ b/postgresql/tasks/packages_stretch.yml @@ -3,7 +3,7 @@ - name: "Set variables (Debian 9)" set_fact: postgresql_version: '9.6' - when: postgresql_version == "" + when: postgresql_version is none or postgresql_version | length == 0 - include: pgdg-repo.yml when: postgresql_version != '9.6' diff --git a/postgresql/tests/test.yml b/postgresql/tests/test.yml index 06bd32ac..438eddee 100644 --- a/postgresql/tests/test.yml +++ b/postgresql/tests/test.yml @@ -24,7 +24,7 @@ - name: Reconfigure locales command: /usr/sbin/locale-gen changed_when: false - when: test_locales.changed + when: test_locales is changed roles: - role: postgresql diff --git a/proftpd/tasks/accounts.yml b/proftpd/tasks/accounts.yml index 20b1d3d2..756e0ff0 100644 --- a/proftpd/tasks/accounts.yml +++ b/proftpd/tasks/accounts.yml @@ -33,7 +33,7 @@ insertbefore: "DenyAll" loop: "{{ proftpd_accounts_final }}" notify: restart proftpd - when: proftpd_ftp_enable + when: proftpd_ftp_enable | bool tags: - proftpd @@ -45,7 +45,7 @@ insertbefore: "DenyAll" loop: "{{ proftpd_accounts_final }}" notify: restart proftpd - when: proftpd_ftps_enable + when: proftpd_ftps_enable | bool tags: - proftpd @@ -57,6 +57,6 @@ insertbefore: "DenyAll" loop: "{{ proftpd_accounts_final }}" notify: restart proftpd - when: proftpd_sftp_enable + when: proftpd_sftp_enable | bool tags: - proftpd diff --git a/proftpd/tasks/main.yml b/proftpd/tasks/main.yml index 71b95e9b..457887a1 100644 --- a/proftpd/tasks/main.yml +++ b/proftpd/tasks/main.yml @@ -22,7 +22,7 @@ mode: "0644" force: no notify: restart proftpd - when: proftpd_ftp_enable + when: proftpd_ftp_enable | bool tags: - proftpd @@ -33,7 +33,7 @@ mode: "0644" force: no notify: restart proftpd - when: proftpd_ftps_enable + when: proftpd_ftps_enable | bool tags: - proftpd @@ -44,7 +44,7 @@ mode: "0644" force: no notify: restart proftpd - when: proftpd_sftp_enable + when: proftpd_sftp_enable | bool tags: - proftpd @@ -80,4 +80,4 @@ - proftpd - include: accounts.yml - when: proftpd_accounts != "[]" + when: proftpd_accounts | length > 0 diff --git a/redis/tasks/default-munin.yml b/redis/tasks/default-munin.yml index c94f171a..3f0fe6f4 100644 --- a/redis/tasks/default-munin.yml +++ b/redis/tasks/default-munin.yml @@ -67,8 +67,8 @@ value: '{{ redis_password }}' notify: restart munin-node when: - - redis_password != '' - - redis_password != None + - redis_password is not none + - redis_password | length > 0 - (munin_redis_blocs_in_config.stdout | int) <= 1 tags: redis @@ -77,6 +77,6 @@ debug: msg: "WARNING - It seems you have multiple redis sections in your munin-node configuration - Munin config NOT changed" when: - - redis_password != '' - - redis_password != None + - redis_password is not none + - redis_password | length > 0 - (munin_redis_blocs_in_config.stdout | int) > 1 diff --git a/redis/tasks/instance-server.yml b/redis/tasks/instance-server.yml index d5f7e8e8..08430eb8 100644 --- a/redis/tasks/instance-server.yml +++ b/redis/tasks/instance-server.yml @@ -3,9 +3,9 @@ - name: Verify Redis port assert: that: - - redis_port != 6379 + - redis_port | int != 6379 msg: "If you want to use port 6379, use the default instance, not a named instance." - when: not redis_force_instance_port + when: not (redis_force_instance_port | bool) - name: "Instance '{{ redis_instance_name }}' group is present" group: @@ -162,6 +162,6 @@ name: "redis-server" enabled: no state: stopped - when: redis_default_server_disabled + when: redis_default_server_disabled | bool tags: - redis diff --git a/redis/tasks/main.yml b/redis/tasks/main.yml index 28fda65a..90f0aa12 100644 --- a/redis/tasks/main.yml +++ b/redis/tasks/main.yml @@ -1,7 +1,7 @@ --- - set_fact: - redis_restart_handler_name: "{{ redis_restart_if_needed | ternary('restart redis', 'restart redis (noop)') }}" + redis_restart_handler_name: "{{ redis_restart_if_needed | bool | ternary('restart redis', 'restart redis (noop)') }}" - name: Redis is installed. apt: @@ -20,7 +20,7 @@ tags: - redis - packages - when: redis_sentinel_install + when: redis_sentinel_install | bool - name: Get Redis version shell: "redis-server -v | grep -Eo '(v=\\S+)' | cut -d'=' -f 2 | grep -E '^([0-9]|\\.)+$'" @@ -137,4 +137,4 @@ - name: Force restart redis command: /bin/true notify: restart redis - when: redis_restart_force + when: redis_restart_force | bool diff --git a/redmine/tasks/mysql.yml b/redmine/tasks/mysql.yml index 64e42683..6c40a338 100644 --- a/redmine/tasks/mysql.yml +++ b/redmine/tasks/mysql.yml @@ -13,7 +13,7 @@ register: redmine_generate_mysql_password check_mode: no changed_when: False - when: redmine_get_mysql_password.stdout == "" + when: redmine_get_mysql_password.stdout | length == 0 tags: - redmine diff --git a/redmine/tasks/release.yml b/redmine/tasks/release.yml index 730b0877..548132fc 100644 --- a/redmine/tasks/release.yml +++ b/redmine/tasks/release.yml @@ -98,7 +98,7 @@ chdir: "/home/{{ redmine_user }}/www/" become_user: "{{ redmine_user }}" environment: "{{ user_env }}" - when: redmine_mysql_create.changed + when: redmine_mysql_create is changed tags: - redmine diff --git a/squid/tasks/main.yml b/squid/tasks/main.yml index bca2db5a..9e00dcb0 100644 --- a/squid/tasks/main.yml +++ b/squid/tasks/main.yml @@ -71,7 +71,9 @@ dest: /etc/squid/evolinux-acl.conf force: no notify: "reload squid" - when: squid_localproxy_enable and ansible_distribution_major_version is version('9', '>=') + when: + - squid_localproxy_enable | bool + - ansible_distribution_major_version is version('9', '>=') - name: "evolinux custom acl (Debian 9 or later)" copy: @@ -79,7 +81,9 @@ content: | # Put customized values here. force: no - when: squid_localproxy_enable == False and ansible_distribution_major_version is version('9', '>=') + when: + - not (squid_localproxy_enable | bool) + - ansible_distribution_major_version is version('9', '>=') - name: "evolinux http_access for local proxy (Debian 9 or later)" copy: @@ -87,7 +91,9 @@ dest: /etc/squid/evolinux-httpaccess.conf force: no notify: "reload squid" - when: squid_localproxy_enable and ansible_distribution_major_version is version('9', '>=') + when: + - squid_localproxy_enable | bool + - ansible_distribution_major_version is version('9', '>=') - name: "evolinux custom http_access (Debian 9 or later)" copy: @@ -95,7 +101,9 @@ content: | # Put customized values here. force: no - when: squid_localproxy_enable == False and ansible_distribution_major_version is version('9', '>=') + when: + - not (squid_localproxy_enable | bool) + - ansible_distribution_major_version is version('9', '>=') - name: "evolinux overrides for local proxy (Debian 9 or later)" template: @@ -103,7 +111,9 @@ dest: /etc/squid/evolinux-custom.conf force: no notify: "reload squid" - when: squid_localproxy_enable and ansible_distribution_major_version is version('9', '>=') + when: + - squid_localproxy_enable | bool + - ansible_distribution_major_version is version('9', '>=') - name: "evolinux custom overrides (Debian 9 or later)" copy: @@ -111,7 +121,9 @@ content: | # Put customized values here. force: no - when: squid_localproxy_enable == False and ansible_distribution_major_version is version('9', '>=') + when: + - not (squid_localproxy_enable | bool) + - ansible_distribution_major_version is version('9', '>=') - name: add some URL in whitelist (Debian 8) lineinfile: diff --git a/squid/tasks/systemd.yml b/squid/tasks/systemd.yml index 4d06fa5d..b3782d99 100644 --- a/squid/tasks/systemd.yml +++ b/squid/tasks/systemd.yml @@ -29,4 +29,4 @@ daemon_reload: yes when: - _squid_systemd_active.rc == 0 - - _squid_systemd_override.changed + - _squid_systemd_override is changed diff --git a/supervisord/tasks/main.yml b/supervisord/tasks/main.yml index 17d7737a..b35bd03f 100644 --- a/supervisord/tasks/main.yml +++ b/supervisord/tasks/main.yml @@ -12,6 +12,6 @@ mode: "0644" force: no notify: restart supervisor - when: supervisord_enable_http + when: supervisord_enable_http | bool tags: - supervisord diff --git a/tomcat-instance/tasks/check.yml b/tomcat-instance/tasks/check.yml index 3c2319d0..eff9d236 100644 --- a/tomcat-instance/tasks/check.yml +++ b/tomcat-instance/tasks/check.yml @@ -8,7 +8,7 @@ register: check_port_gid changed_when: false failed_when: - - check_port_gid|success + - check_port_gid | success - check_port_gid.stdout != "{{ tomcat_instance_name }}" - name: Check use of uid @@ -16,7 +16,7 @@ register: check_port_uid changed_when: false failed_when: - - check_port_uid|success + - check_port_uid | success - check_port_uid.stdout != "{{ tomcat_instance_name }}" #- name: Check use of http port diff --git a/tomcat-instance/tasks/user.yml b/tomcat-instance/tasks/user.yml index 64244799..d4fc8521 100644 --- a/tomcat-instance/tasks/user.yml +++ b/tomcat-instance/tasks/user.yml @@ -2,7 +2,7 @@ - fail: msg: "You must provide a value for the 'tomcat_instance_port' variable." - when: tomcat_instance_port is not defined or tomcat_instance_port == '' + when: tomcat_instance_port is not defined or tomcat_instance_port | length == 0 - name: "Test if uid '{{ tomcat_instance_port }}' exists" diff --git a/webapps/evoadmin-mail/tasks/apache.yml b/webapps/evoadmin-mail/tasks/apache.yml index e83fc09d..f975c5f9 100644 --- a/webapps/evoadmin-mail/tasks/apache.yml +++ b/webapps/evoadmin-mail/tasks/apache.yml @@ -13,7 +13,7 @@ dest: "/etc/apache2/sites-enabled/evoadminmail.conf" state: link notify: reload apache2 - when: evoadminmail_enable_vhost + when: evoadminmail_enable_vhost | bool tags: - evoadmin-mail @@ -22,6 +22,6 @@ dest: "/etc/apache2/sites-enabled/evoadminmail.conf" state: absent notify: reload apache2 - when: not evoadminmail_enable_vhost + when: not (evoadminmail_enable_vhost | bool) tags: - evoadmin-mail diff --git a/webapps/evoadmin-mail/tasks/nginx.yml b/webapps/evoadmin-mail/tasks/nginx.yml index 5ede64e7..6804984d 100644 --- a/webapps/evoadmin-mail/tasks/nginx.yml +++ b/webapps/evoadmin-mail/tasks/nginx.yml @@ -21,7 +21,7 @@ dest: "/etc/nginx/sites-enabled/evoadminmail.conf" state: link notify: reload nginx - when: evoadminmail_enable_vhost + when: evoadminmail_enable_vhost | bool tags: - evoadmin-mail @@ -30,6 +30,6 @@ dest: "/etc/nginx/sites-enabled/evoadminmail.conf" state: absent notify: reload nginx - when: not evoadminmail_enable_vhost + when: not (evoadminmail_enable_vhost | bool) tags: - evoadmin-mail diff --git a/webapps/evoadmin-web/tasks/main.yml b/webapps/evoadmin-web/tasks/main.yml index c03ef979..1acb2aa5 100644 --- a/webapps/evoadmin-web/tasks/main.yml +++ b/webapps/evoadmin-web/tasks/main.yml @@ -3,7 +3,7 @@ - name: "Ensure that evoadmin_contact_email is defined" fail: msg: Please configure var evoadmin_contact_email - when: evoadmin_contact_email is none + when: evoadmin_contact_email is none or evoadmin_contact_email | length == 0 - include: packages.yml diff --git a/webapps/evoadmin-web/tasks/web.yml b/webapps/evoadmin-web/tasks/web.yml index 251af4ea..dc5eb8a3 100644 --- a/webapps/evoadmin-web/tasks/web.yml +++ b/webapps/evoadmin-web/tasks/web.yml @@ -47,14 +47,14 @@ register: cmd_a2ensite changed_when: "'Enabling site' in cmd_a2ensite.stdout" notify: reload apache2 - when: evoadmin_enable_vhost + when: evoadmin_enable_vhost | bool - name: Disable evoadmin vhost command: "a2dissite evoadmin.conf" register: cmd_a2dissite changed_when: "'Disabling site' in cmd_a2dissite.stdout" notify: reload apache2 - when: not evoadmin_enable_vhost + when: not (evoadmin_enable_vhost | bool) - name: Copy htpasswd for evoadmin template: @@ -72,7 +72,7 @@ - "templates/evoadmin-web/htpasswd.j2" - "templates/htpasswd.j2" register: evoadmin_htpasswd_template - when: evoadmin_htpasswd + when: evoadmin_htpasswd | bool - name: Copy config file for evoadmin template: diff --git a/webapps/nextcloud/tasks/config.yml b/webapps/nextcloud/tasks/config.yml index a4e3a3e7..85142726 100644 --- a/webapps/nextcloud/tasks/config.yml +++ b/webapps/nextcloud/tasks/config.yml @@ -15,7 +15,7 @@ tags: - nextcloud - when: nextcloud_admin_password == "" + when: nextcloud_admin_password | length == 0 - name: Get Nextcloud Status shell: "php ./occ status --output json | grep -v 'Nextcloud is not installed'" diff --git a/webapps/wordpress/tasks/main.yml b/webapps/wordpress/tasks/main.yml index db94b9f4..e1f442c0 100644 --- a/webapps/wordpress/tasks/main.yml +++ b/webapps/wordpress/tasks/main.yml @@ -55,13 +55,13 @@ register: check_version check_mode: no failed_when: false - changed_when: check_version.rc + changed_when: check_version.rc == 1 - name: Update Wordpress shell: '{{ wordpress_wpcli }} core update --version={{ wordpress_version }}' args: removes: "{{ ansible_env.HOME }}/www/index.php" - when: check_version.rc + when: check_version.rc == 1 - name: Install default plugin shell: '{{ wordpress_wpcli }} plugin is-installed {{ item }} || {{ wordpress_wpcli }} plugin install {{ item }}' From 3c9be8d9135464de903c2d97d8c1549b399c412e Mon Sep 17 00:00:00 2001 From: Jeremy Lecour Date: Sun, 9 May 2021 23:20:15 +0200 Subject: [PATCH 38/86] fix more Ansible syntax --- apache/tasks/main.yml | 4 ++-- evolinux-base/tasks/main.yml | 2 +- evolinux-base/tasks/ssh.yml | 6 +++--- percona/tasks/main.yml | 2 +- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/apache/tasks/main.yml b/apache/tasks/main.yml index c55fc900..1a028205 100644 --- a/apache/tasks/main.yml +++ b/apache/tasks/main.yml @@ -130,7 +130,7 @@ state: link force: yes notify: reload apache - when: apache_evolinux_default_enabled + when: apache_evolinux_default_enabled | bool tags: - apache @@ -205,6 +205,6 @@ - apache - include: munin.yml - when: apache_munin_include + when: apache_munin_include | bool tags: - apache diff --git a/evolinux-base/tasks/main.yml b/evolinux-base/tasks/main.yml index 68a6d424..5ee935d6 100644 --- a/evolinux-base/tasks/main.yml +++ b/evolinux-base/tasks/main.yml @@ -56,7 +56,7 @@ - name: SSH configuration include: ssh.yml - when: evolinux_ssh_include + when: evolinux_ssh_include | bool ### disabled because of a memory leak # - name: Create evolinux users diff --git a/evolinux-base/tasks/ssh.yml b/evolinux-base/tasks/ssh.yml index 2816af7f..e063d164 100644 --- a/evolinux-base/tasks/ssh.yml +++ b/evolinux-base/tasks/ssh.yml @@ -51,7 +51,7 @@ regexp: '^AcceptEnv' replace: "#AcceptEnv" notify: reload sshd - when: evolinux_ssh_disable_acceptenv + when: evolinux_ssh_disable_acceptenv | bool - name: Set log level to verbose (for Debian >= 9) replace: @@ -66,7 +66,7 @@ changed_when: False register: logname check_mode: no - when: evolinux_ssh_allow_current_user + when: evolinux_ssh_allow_current_user | bool # we must double-escape caracters, because python - name: verify AllowUsers directive @@ -75,7 +75,7 @@ changed_when: False register: grep_allowusers_ssh check_mode: no - when: evolinux_ssh_allow_current_user + when: evolinux_ssh_allow_current_user | bool - name: "Add AllowUsers sshd directive for current user" lineinfile: diff --git a/percona/tasks/main.yml b/percona/tasks/main.yml index 4db87058..8740f758 100644 --- a/percona/tasks/main.yml +++ b/percona/tasks/main.yml @@ -43,7 +43,7 @@ name: percona-release state: latest register: percona__apt_config_deb - when: percona__apt_config_package_installed + when: percona__apt_config_package_installed | bool - name: APT cache is up-to-date apt: From d823c8116a577804a7f93960d2fe81fa20f0e08c Mon Sep 17 00:00:00 2001 From: Jeremy Lecour Date: Sun, 9 May 2021 23:21:21 +0200 Subject: [PATCH 39/86] update CHANGELOG --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 31f38bf3..098deb55 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -20,6 +20,7 @@ The **patch** part changes incrementally at each release. ### Changed * Use 'loop' syntax instead of 'with_first_found/with_items/with_dict/with_nested/with_list' +* Use Ansible syntax used in Ansible 2.8+ * apt: store keys in /etc/apt/trusted.gpg.d in ascii format * certbot: sync_remote.sh is configurable * evolinux-base: copy GPG key instead of using apt-key From 9b2a3a6db2a488d00fa2d12c886550c71c9c9f7f Mon Sep 17 00:00:00 2001 From: Jeremy Lecour Date: Mon, 10 May 2021 07:42:19 +0200 Subject: [PATCH 40/86] evolinux-users: convert uid to string --- evolinux-users/tasks/user.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/evolinux-users/tasks/user.yml b/evolinux-users/tasks/user.yml index 4939f533..0f8bd480 100644 --- a/evolinux-users/tasks/user.yml +++ b/evolinux-users/tasks/user.yml @@ -4,11 +4,11 @@ - fail: msg: "You must provide a value for the 'user.name ' variable." - when: user.name is not defined or user.name | length == 0 + when: (user.name is not defined) or (user.name | length == 0) - fail: msg: "You must provide a value for the 'user.uid ' variable." - when: user.uid is not defined or user.uid | length == 0 + when: (user.uid is not defined) or (user.uid | string | length == 0) - name: "Test if '{{ user.name }}' exists" command: 'id -u "{{ user.name }}"' From 9ca68a16dd7e0724b3caae2a948566e45f13628c Mon Sep 17 00:00:00 2001 From: Jeremy Lecour Date: Mon, 10 May 2021 09:07:18 +0200 Subject: [PATCH 41/86] evolinux-base: quote values --- evolinux-base/defaults/main.yml | 2 +- evolinux-base/tasks/kernel.yml | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/evolinux-base/defaults/main.yml b/evolinux-base/defaults/main.yml index 98ff43ef..26f6e4c8 100644 --- a/evolinux-base/defaults/main.yml +++ b/evolinux-base/defaults/main.yml @@ -51,7 +51,7 @@ evolinux_kernel_include: True evolinux_kernel_reboot_after_panic: True evolinux_kernel_disable_tcp_timestamps: True evolinux_kernel_customize_swappiness: True -evolinux_kernel_swappiness: 20 +evolinux_kernel_swappiness: "20" evolinux_kernel_cve20165696: True # fstab diff --git a/evolinux-base/tasks/kernel.yml b/evolinux-base/tasks/kernel.yml index 282e10eb..76965f47 100644 --- a/evolinux-base/tasks/kernel.yml +++ b/evolinux-base/tasks/kernel.yml @@ -44,7 +44,7 @@ - name: Patch for TCP stack vulnerability CVE-2016-5696 sysctl: name: net.ipv4.tcp_challenge_ack_limit - value: 1073741823 + value: "1073741823" sysctl_file: "{{ evolinux_kernel_sysctl_path }}" state: present reload: yes @@ -58,9 +58,9 @@ state: present reload: yes loop: - - { name: "net.ipv4.ipfrag_low_thresh", value: 196608 } - - { name: "net.ipv6.ip6frag_low_thresh", value: 196608 } - - { name: "net.ipv4.ipfrag_high_thresh", value: 262144 } - - { name: "net.ipv6.ip6frag_high_thresh", value: 262144 } + - { name: "net.ipv4.ipfrag_low_thresh", value: "196608" } + - { name: "net.ipv6.ip6frag_low_thresh", value: "196608" } + - { name: "net.ipv4.ipfrag_high_thresh", value: "262144" } + - { name: "net.ipv6.ip6frag_high_thresh", value: "262144" } - meta: flush_handlers From 7dc6f0b849dc1e47d3b8abc3ebfe09b04539e6a3 Mon Sep 17 00:00:00 2001 From: Jeremy Lecour Date: Thu, 13 May 2021 15:23:05 +0200 Subject: [PATCH 42/86] remove trailing whitespaces --- apache/tasks/auth.yml | 2 +- bind/tasks/main.yml | 2 +- etc-git/tasks/commit.yml | 4 ++-- evolinux-base/tasks/main.yml | 2 +- fluentd/defaults/main.yml | 8 ++++---- haproxy/defaults/main.yml | 2 +- ldap/tasks/ldapvirc.yml | 6 +++--- ldap/tasks/nagios.yml | 2 +- logstash/tasks/logs.yml | 2 +- lxc-php/tasks/php74.yml | 4 ++-- lxc/meta/main.yml | 2 +- percona/tasks/xtrabackup.yml | 2 +- postgresql/tasks/postgis.yml | 2 +- spamassasin/tasks/main.yml | 2 +- squid/tasks/systemd.yml | 2 +- webapps/evoadmin-mail/tasks/nginx.yml | 2 +- webapps/roundcube/tasks/main.yml | 2 +- 17 files changed, 24 insertions(+), 24 deletions(-) diff --git a/apache/tasks/auth.yml b/apache/tasks/auth.yml index b66fbe98..fd01517c 100644 --- a/apache/tasks/auth.yml +++ b/apache/tasks/auth.yml @@ -10,7 +10,7 @@ force: no tags: - apache - + - name: Load IP whitelist task include: ip_whitelist.yml diff --git a/bind/tasks/main.yml b/bind/tasks/main.yml index 67f8662f..d1348cd2 100644 --- a/bind/tasks/main.yml +++ b/bind/tasks/main.yml @@ -104,7 +104,7 @@ - debug: var: chrootbind_run.stdout_lines - when: + when: - bind_chroot_set | bool - chrootbind_run.stdout | length > 0 diff --git a/etc-git/tasks/commit.yml b/etc-git/tasks/commit.yml index 9833601e..db167f5d 100644 --- a/etc-git/tasks/commit.yml +++ b/etc-git/tasks/commit.yml @@ -8,7 +8,7 @@ - include: do_commit.yml vars: git_folder: "/etc" - when: + when: - _etc_git.stat.exists - _etc_git.stat.isdir @@ -23,5 +23,5 @@ vars: git_folder: "/usr/share/scripts" when: - - _usr_share_scripts_git.stat.exists + - _usr_share_scripts_git.stat.exists - _usr_share_scripts_git.stat.isdir diff --git a/evolinux-base/tasks/main.yml b/evolinux-base/tasks/main.yml index 5ee935d6..2da87162 100644 --- a/evolinux-base/tasks/main.yml +++ b/evolinux-base/tasks/main.yml @@ -57,7 +57,7 @@ - name: SSH configuration include: ssh.yml when: evolinux_ssh_include | bool - + ### disabled because of a memory leak # - name: Create evolinux users # include_role: diff --git a/fluentd/defaults/main.yml b/fluentd/defaults/main.yml index c17cb312..86475f51 100644 --- a/fluentd/defaults/main.yml +++ b/fluentd/defaults/main.yml @@ -3,10 +3,10 @@ fluentd_daemon: td-agent fluentd_conf_path: /etc/td-agent/td-agent.conf fluentd_port: 24230 -fluentd_bind_interface: +fluentd_bind_interface: -fluentd_host: -fluentd_host_port: +fluentd_host: +fluentd_host_port: -fluentd_flush_interval: +fluentd_flush_interval: fluentd_heartbeat_type: diff --git a/haproxy/defaults/main.yml b/haproxy/defaults/main.yml index 3e3ec047..b94d2872 100644 --- a/haproxy/defaults/main.yml +++ b/haproxy/defaults/main.yml @@ -19,7 +19,7 @@ haproxy_stats_external_url: "{% if haproxy_stats_ssl %}https:{% else %}http:{% e haproxy_stats_access_ips: [] haproxy_stats_admin_ips: [] haproxy_stats_users: [] -## use crypt(8) password encryption +## use crypt(8) password encryption # haproxy_stats_users: # - { login: "", password: "" } diff --git a/ldap/tasks/ldapvirc.yml b/ldap/tasks/ldapvirc.yml index 9b015249..f44249d6 100644 --- a/ldap/tasks/ldapvirc.yml +++ b/ldap/tasks/ldapvirc.yml @@ -9,7 +9,7 @@ - name: Warning when ldapvirc file is present and ldap_admin_password is given debug: msg: "WARNING: an LDAP admin password is given, but an ldapvirc file already exists. It will not be updated." - when: + when: - ldap_admin_password | length > 0 - root_ldapvirc_path.stat.exists @@ -28,7 +28,7 @@ - ldap_admin_password | length == 0 - not root_ldapvirc_path.stat.exists -# Use the generated password or the one found in the file +# Use the generated password or the one found in the file - name: overwrite ldap_admin_password set_fact: ldap_admin_password: "{{ new_ldap_admin_password.stdout }}" @@ -56,7 +56,7 @@ check_mode: no register: new_ldap_admin_password -# Use the password found in the file +# Use the password found in the file - name: overwrite ldap_admin_password set_fact: ldap_admin_password: "{{ new_ldap_admin_password.stdout }}" diff --git a/ldap/tasks/nagios.yml b/ldap/tasks/nagios.yml index 90921bf2..0c92f7b3 100644 --- a/ldap/tasks/nagios.yml +++ b/ldap/tasks/nagios.yml @@ -30,7 +30,7 @@ - ldap_nagios_password | length == 0 - not nagios_monitoring_plugins_path.stat.exists -# Use the generated password or the one found in the file +# Use the generated password or the one found in the file - name: overwrite ldap_nagios_password (from apg) set_fact: ldap_nagios_password: "{{ new_ldap_nagios_password.stdout }}" diff --git a/logstash/tasks/logs.yml b/logstash/tasks/logs.yml index 4417bd89..bfeb1a1b 100644 --- a/logstash/tasks/logs.yml +++ b/logstash/tasks/logs.yml @@ -4,7 +4,7 @@ failed_when: False changed_when: False register: is_cron_installed - + - name: "log rotation script" template: src: rotate_logstash_logs.j2 diff --git a/lxc-php/tasks/php74.yml b/lxc-php/tasks/php74.yml index 1f3bc516..43de6f3c 100644 --- a/lxc-php/tasks/php74.yml +++ b/lxc-php/tasks/php74.yml @@ -1,5 +1,5 @@ --- - + - name: "{{ lxc_php_version }} - Install dependency packages" lxc_container: name: "{{ lxc_php_version }}" @@ -32,7 +32,7 @@ lxc_container: name: "{{ lxc_php_version }}" container_command: "DEBIAN_FRONTEND=noninteractive apt update" - + - name: "{{ lxc_php_version }} - Install PHP packages" lxc_container: name: "{{ lxc_php_version }}" diff --git a/lxc/meta/main.yml b/lxc/meta/main.yml index f6af051d..6208702b 100644 --- a/lxc/meta/main.yml +++ b/lxc/meta/main.yml @@ -1,6 +1,6 @@ galaxy_info: author: Evolix - description: Creation of LXC Containers + description: Creation of LXC Containers issue_tracker_url: https://gitea.evolix.org/evolix/ansible-roles/issues diff --git a/percona/tasks/xtrabackup.yml b/percona/tasks/xtrabackup.yml index 2cf221bb..7d4e29d1 100644 --- a/percona/tasks/xtrabackup.yml +++ b/percona/tasks/xtrabackup.yml @@ -2,7 +2,7 @@ - name: Percona Tools is enabled command: percona-release enable tools release - # changed_when: + # changed_when: # register: percona__release_enable_tools - name: APT cache is up-to-date diff --git a/postgresql/tasks/postgis.yml b/postgresql/tasks/postgis.yml index 0c18cb51..f2300943 100644 --- a/postgresql/tasks/postgis.yml +++ b/postgresql/tasks/postgis.yml @@ -1,5 +1,5 @@ --- -- name: Install PostGIS extention +- name: Install PostGIS extention apt: name: - postgis diff --git a/spamassasin/tasks/main.yml b/spamassasin/tasks/main.yml index 5c46a65b..fa4ab928 100644 --- a/spamassasin/tasks/main.yml +++ b/spamassasin/tasks/main.yml @@ -70,7 +70,7 @@ failed_when: False changed_when: False register: is_cron_installed - + - name: enable sa-update.sh cron lineinfile: dest: /etc/cron.d/sa-update diff --git a/squid/tasks/systemd.yml b/squid/tasks/systemd.yml index b3782d99..82b8760c 100644 --- a/squid/tasks/systemd.yml +++ b/squid/tasks/systemd.yml @@ -6,7 +6,7 @@ failed_when: False check_mode: no register: _squid_systemd_active - + - name: Squid systemd overrides directory exists file: dest: /etc/systemd/system/squid.service.d/ diff --git a/webapps/evoadmin-mail/tasks/nginx.yml b/webapps/evoadmin-mail/tasks/nginx.yml index 6804984d..2cb490e8 100644 --- a/webapps/evoadmin-mail/tasks/nginx.yml +++ b/webapps/evoadmin-mail/tasks/nginx.yml @@ -15,7 +15,7 @@ tags: - evoadmin-mail -- name: Active evoadminmail VHost +- name: Active evoadminmail VHost file: src: "/etc/nginx/sites-available/evoadminmail.conf" dest: "/etc/nginx/sites-enabled/evoadminmail.conf" diff --git a/webapps/roundcube/tasks/main.yml b/webapps/roundcube/tasks/main.yml index 46eaa022..08fe73d1 100644 --- a/webapps/roundcube/tasks/main.yml +++ b/webapps/roundcube/tasks/main.yml @@ -116,7 +116,7 @@ src: "/etc/nginx/sites-available/roundcube.conf" dest: "/etc/nginx/sites-enabled/roundcube.conf" state: link - when: roundcube_webserver == "nginx" + when: roundcube_webserver == "nginx" notify: reload nginx - name: enable roundcube link in default site index From e65340cb567ac778a75e961da14e93a270726d5b Mon Sep 17 00:00:00 2001 From: Jeremy Lecour Date: Thu, 13 May 2021 15:34:27 +0200 Subject: [PATCH 43/86] Add pipefail option to shell invocations --- apt/tasks/hold_packages.yml | 4 ++-- elasticsearch/tasks/logs.yml | 2 +- etc-git/tasks/main.yml | 2 +- evocheck/tasks/cron.yml | 2 +- evolinux-base/tasks/hardware.yml | 2 +- evolinux-base/tasks/postfix.yml | 2 +- evolinux-base/tasks/system.yml | 2 +- logstash/tasks/logs.yml | 2 +- percona/tasks/main.yml | 2 +- postfix/tasks/packmail.yml | 2 +- spamassasin/tasks/main.yml | 2 +- ssl/tasks/main.yml | 2 +- 12 files changed, 13 insertions(+), 13 deletions(-) diff --git a/apt/tasks/hold_packages.yml b/apt/tasks/hold_packages.yml index 63643409..12774942 100644 --- a/apt/tasks/hold_packages.yml +++ b/apt/tasks/hold_packages.yml @@ -1,7 +1,7 @@ --- - name: "hold packages (apt)" - shell: "(dpkg -l {{ item }} 2>/dev/null | grep -q -E '^(i|h)i') && ((apt-mark showhold | grep --quiet {{ item }}) || apt-mark hold {{ item }})" + shell: "set -o pipefail && (dpkg -l {{ item }} 2>/dev/null | grep -q -E '^(i|h)i') && ((apt-mark showhold | grep --quiet {{ item }}) || apt-mark hold {{ item }})" register: apt_mark changed_when: "item + ' set on hold.' in apt_mark.stdout" failed_when: @@ -30,7 +30,7 @@ - apt - name: "unhold packages (apt)" - shell: "(dpkg -l {{ item }} 2>/dev/null | grep -q -E '^(i|h)i') && ((apt-mark showhold | grep --quiet {{ item }}) && apt-mark unhold {{ item }})" + shell: "set -o pipefail && (dpkg -l {{ item }} 2>/dev/null | grep -q -E '^(i|h)i') && ((apt-mark showhold | grep --quiet {{ item }}) && apt-mark unhold {{ item }})" register: apt_mark changed_when: "'Canceled hold on' + item in apt_mark.stdout" failed_when: apt_mark.rc != 0 and not apt_mark.stdout = '' diff --git a/elasticsearch/tasks/logs.yml b/elasticsearch/tasks/logs.yml index 16bbe5d6..b48e9373 100644 --- a/elasticsearch/tasks/logs.yml +++ b/elasticsearch/tasks/logs.yml @@ -1,7 +1,7 @@ --- - name: Check if cron is installed - shell: "dpkg -l cron 2> /dev/null | grep -q -E '^(i|h)i'" + shell: "set -o pipefail && dpkg -l cron 2> /dev/null | grep -q -E '^(i|h)i'" failed_when: False changed_when: False register: is_cron_installed diff --git a/etc-git/tasks/main.yml b/etc-git/tasks/main.yml index 8d16b79f..f707dab4 100644 --- a/etc-git/tasks/main.yml +++ b/etc-git/tasks/main.yml @@ -33,7 +33,7 @@ - ansible_distribution_major_version is version('10', '>=') - name: Check if cron is installed - shell: "dpkg -l cron 2> /dev/null | grep -q -E '^(i|h)i'" + shell: "set -o pipefail && dpkg -l cron 2> /dev/null | grep -q -E '^(i|h)i'" failed_when: False changed_when: False check_mode: no diff --git a/evocheck/tasks/cron.yml b/evocheck/tasks/cron.yml index 4ef10b05..4557ef2a 100644 --- a/evocheck/tasks/cron.yml +++ b/evocheck/tasks/cron.yml @@ -1,7 +1,7 @@ --- - name: Check if cron is installed - shell: "dpkg -l cron 2> /dev/null | grep -q -E '^(i|h)i'" + shell: "set -o pipefail && dpkg -l cron 2> /dev/null | grep -q -E '^(i|h)i'" failed_when: False changed_when: False check_mode: no diff --git a/evolinux-base/tasks/hardware.yml b/evolinux-base/tasks/hardware.yml index 08f7dd33..478e5015 100644 --- a/evolinux-base/tasks/hardware.yml +++ b/evolinux-base/tasks/hardware.yml @@ -29,7 +29,7 @@ # HP gen <10: Hewlett-Packard Company Smart Array # HP gen >=10: Adaptec Smart Storage PQI - name: Detect if RAID is installed - shell: lspci -q | grep -e "RAID bus controller" -e "Serial Attached SCSI controller" + shell: "set -o pipefila && lspci -q | grep -e 'RAID bus controller' -e 'Serial Attached SCSI controller'" check_mode: no register: raidmodel changed_when: "'FAILED' in raidmodel.stdout" diff --git a/evolinux-base/tasks/postfix.yml b/evolinux-base/tasks/postfix.yml index 5ae33aa7..6c1d8532 100644 --- a/evolinux-base/tasks/postfix.yml +++ b/evolinux-base/tasks/postfix.yml @@ -32,7 +32,7 @@ - postfix - name: fetch users list - shell: getent passwd | cut -d":" -f 1 | grep -v root + shell: "set -o pipefail && getent passwd | cut -d':' -f 1 | grep -v root" check_mode: no register: non_root_users_list diff --git a/evolinux-base/tasks/system.yml b/evolinux-base/tasks/system.yml index 6504655b..2e57b1e2 100644 --- a/evolinux-base/tasks/system.yml +++ b/evolinux-base/tasks/system.yml @@ -85,7 +85,7 @@ #- name: Customizing /etc/fstab - name: Check if cron is installed - shell: "dpkg -l cron 2> /dev/null | grep -q -E '^(i|h)i'" + shell: "set -o pipefail && dpkg -l cron 2> /dev/null | grep -q -E '^(i|h)i'" failed_when: False changed_when: False check_mode: no diff --git a/logstash/tasks/logs.yml b/logstash/tasks/logs.yml index bfeb1a1b..8ea07ddd 100644 --- a/logstash/tasks/logs.yml +++ b/logstash/tasks/logs.yml @@ -1,6 +1,6 @@ --- - name: Check if cron is installed - shell: "dpkg -l cron 2> /dev/null | grep -q -E '^(i|h)i'" + shell: "set -o pipefail && dpkg -l cron 2> /dev/null | grep -q -E '^(i|h)i'" failed_when: False changed_when: False register: is_cron_installed diff --git a/percona/tasks/main.yml b/percona/tasks/main.yml index 8740f758..28278e49 100644 --- a/percona/tasks/main.yml +++ b/percona/tasks/main.yml @@ -17,7 +17,7 @@ mode: "0644" - name: Check if percona-release is installed - command: "dpkg -l percona-release" + command: "set -o pipefail && dpkg -l percona-release 2> /dev/null | grep -q -E '^(i|h)i'" failed_when: False changed_when: False register: percona__apt_config_package_installed diff --git a/postfix/tasks/packmail.yml b/postfix/tasks/packmail.yml index 2ba8eba9..b2bdff22 100644 --- a/postfix/tasks/packmail.yml +++ b/postfix/tasks/packmail.yml @@ -98,7 +98,7 @@ - postfix - name: Check if cron is installed - shell: "dpkg -l cron 2> /dev/null | grep -q -E '^(i|h)i'" + shell: "set -o pipefail && dpkg -l cron 2> /dev/null | grep -q -E '^(i|h)i'" failed_when: False changed_when: False register: is_cron_installed diff --git a/spamassasin/tasks/main.yml b/spamassasin/tasks/main.yml index fa4ab928..df331af4 100644 --- a/spamassasin/tasks/main.yml +++ b/spamassasin/tasks/main.yml @@ -66,7 +66,7 @@ - spamassassin - name: Check if cron is installed - shell: "dpkg -l cron 2> /dev/null | grep -q -E '^(i|h)i'" + shell: "set -o pipefail && dpkg -l cron 2> /dev/null | grep -q -E '^(i|h)i'" failed_when: False changed_when: False register: is_cron_installed diff --git a/ssl/tasks/main.yml b/ssl/tasks/main.yml index c6594265..a21c15ff 100644 --- a/ssl/tasks/main.yml +++ b/ssl/tasks/main.yml @@ -29,7 +29,7 @@ - ssl - name: Check if Haproxy is installed - command: dpkg -l haproxy + command: "set -o pipefail && dpkg -l haproxy 2> /dev/null | grep -q -E '^(i|h)i'" register: haproxy_check check_mode: False changed_when: False From 60f2f1940227b08cc7a2299fbba94c1541a99ef9 Mon Sep 17 00:00:00 2001 From: Jeremy Dubois Date: Mon, 17 May 2021 10:40:34 +0200 Subject: [PATCH 44/86] Delete OpenBSD support The EvoBSD repository must be used for OpenBSD --- .../tasks/install_vendor_openbsd.yml | 66 ------------------- evomaintenance/tasks/main.yml | 4 -- 2 files changed, 70 deletions(-) delete mode 100644 evomaintenance/tasks/install_vendor_openbsd.yml diff --git a/evomaintenance/tasks/install_vendor_openbsd.yml b/evomaintenance/tasks/install_vendor_openbsd.yml deleted file mode 100644 index e82a9a39..00000000 --- a/evomaintenance/tasks/install_vendor_openbsd.yml +++ /dev/null @@ -1,66 +0,0 @@ ---- - -- name: Dependencies are installed - openbsd_pkg: - name: - - postgresql-client - - curl - state: present - tags: - - evomaintenance - -- name: /usr/share/scripts exists - file: - dest: /usr/share/scripts - mode: "0700" - owner: root - group: wheel - state: directory - tags: - - evomaintenance - -- name: Evomaintenance script and template are installed - copy: - src: "{{ item.src }}" - dest: "{{ item.dest }}" - owner: root - group: wheel - mode: "{{ item.mode }}" - force: yes - backup: yes - loop: - - { src: 'evomaintenance.sh', dest: '/usr/share/scripts/', mode: '0700' } - - { src: 'evomaintenance.tpl', dest: '/usr/share/scripts/', mode: '0600' } - tags: - - evomaintenance - -- name: Configuration is installed - template: - src: evomaintenance.j2 - dest: /etc/evomaintenance.cf - owner: root - group: wheel - mode: "0600" - force: "{{ evomaintenance_force_config | bool }}" - tags: - - evomaintenance - -- name: Copy mailevomaintenance - template: - src: mailevomaintenance.sh.j2 - dest: /usr/share/scripts/mailevomaintenance.sh - owner: root - group: wheel - mode: "0700" - tags: - - evomaintenance - -- name: Add mailevomaintenance cron - cron: - name: "mailevomaintenance" - job: "/usr/share/scripts/mailevomaintenance.sh" - minute: "50" - hour: "22" - disabled: yes - tags: - - mailevomaintenance diff --git a/evomaintenance/tasks/main.yml b/evomaintenance/tasks/main.yml index 642b2954..9826089b 100644 --- a/evomaintenance/tasks/main.yml +++ b/evomaintenance/tasks/main.yml @@ -19,10 +19,6 @@ - evomaintenance_install_vendor | bool - ansible_distribution == "Debian" -- include: install_vendor_openbsd.yml - when: - - ansible_distribution == "OpenBSD" - - include: minifirewall.yml when: - evomaintenance_hook_db | bool From 56af68e5b3dcb677fc39360d04494ba2a375739c Mon Sep 17 00:00:00 2001 From: Jeremy Lecour Date: Mon, 17 May 2021 12:19:54 +0200 Subject: [PATCH 45/86] listupgrade: print error if wget fails --- CHANGELOG.md | 1 + listupgrade/files/listupgrade.sh | 6 +++++- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 098deb55..d5883c17 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -32,6 +32,7 @@ The **patch** part changes incrementally at each release. ### Fixed * ldap: fix edge cases where passwords were not set/get properly +* listupgrade: print error if wget fails ### Removed diff --git a/listupgrade/files/listupgrade.sh b/listupgrade/files/listupgrade.sh index d2f4996b..fcd6cdd8 100644 --- a/listupgrade/files/listupgrade.sh +++ b/listupgrade/files/listupgrade.sh @@ -46,6 +46,11 @@ get_value() { fetch_upgrade_info() { upgradeInfo=$(mktemp --tmpdir=/tmp evoupdate.XXX) wget -q -O $upgradeInfo https://upgrades.evolix.org/upgrade + + if [ "$?" != "0" ]; then + printf >&2 "Error fetching upgrade directives.\n" + fi + r_releases="$(get_value $upgradeInfo "releases")" r_skip_releases="$(get_value $upgradeInfo "skip_releases")" r_packages="$(get_value $upgradeInfo "packages")" @@ -261,4 +266,3 @@ if which lxc-ls > /dev/null; then done fi - From cae0de17df90746a85850e9017a7d53cd0e32bc5 Mon Sep 17 00:00:00 2001 From: Jeremy Lecour Date: Mon, 17 May 2021 23:05:18 +0200 Subject: [PATCH 46/86] listupgrade: fix wget error + shellcheck cleanup --- CHANGELOG.md | 2 +- listupgrade/files/listupgrade.sh | 226 ++++++++++++++++--------------- 2 files changed, 120 insertions(+), 108 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d5883c17..42270191 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -32,7 +32,7 @@ The **patch** part changes incrementally at each release. ### Fixed * ldap: fix edge cases where passwords were not set/get properly -* listupgrade: print error if wget fails +* listupgrade: fix wget error + shellcheck cleanup ### Removed diff --git a/listupgrade/files/listupgrade.sh b/listupgrade/files/listupgrade.sh index fcd6cdd8..0c7beaaa 100644 --- a/listupgrade/files/listupgrade.sh +++ b/listupgrade/files/listupgrade.sh @@ -16,46 +16,52 @@ packagesHold=$(mktemp --tmpdir=/tmp evoupdate.XXX) servicesToRestart=$(mktemp --tmpdir=/tmp evoupdate.XXX) template=$(mktemp --tmpdir=/tmp evoupdate.XXX) clientmail=$(grep EVOMAINTMAIL /etc/evomaintenance.cf | cut -d'=' -f2) -mailto=$clientmail +mailto="${clientmail}" date="Ce jeudi entre 18h00 et 23h00." hostname=$(grep HOSTNAME /etc/evomaintenance.cf | cut -d'=' -f2) hostname=${hostname%%.evolix.net} + # If hostname is composed with -, remove the first part. -if [[ $hostname =~ "-" ]]; then - hostname=$(echo $hostname | cut -d'-' -f2-) +if [[ "${hostname}" =~ "-" ]]; then + hostname=$(echo "${hostname}" | cut -d'-' -f2-) fi # Edit $configFile to override some variables. -[ -r $configFile ] && . $configFile +# shellcheck disable=SC1090,SC1091 +[ -r "${configFile}" ] && . "${configFile}" # Remove temporary files on exit. -trap "rm $packages $packagesHold $servicesToRestart $template" EXIT +# shellcheck disable=SC2064 +trap "rm ${packages} ${packagesHold} ${servicesToRestart} ${template}" EXIT # Parse line in retrieved upgrade file and ensure there is no malicious values. get_value() { file="$1" variable="$2" - value="$(grep "^$2:" $1 |head -n 1 |cut -d ':' -f 2 |sed 's/^ //')" - if echo "$value" |grep -q -E '^[-.: [:alnum:]]*$'; then - echo $value + value="$(grep "^${variable}:" "${file}" | head -n 1 | cut -d ':' -f 2 | sed 's/^ //')" + + if echo "${value}" | grep -q -E '^[-.: [:alnum:]]*$'; then + echo "${value}" else - printf >&2 "Error parsing value \"$value\" for variable $variables.\n" + printf >&2 "Error parsing value \"%s\" for variable %s.\n" "${value}" "${variable}" fi } # Fetch which packages/releases will be upgraded. fetch_upgrade_info() { upgradeInfo=$(mktemp --tmpdir=/tmp evoupdate.XXX) - wget -q -O $upgradeInfo https://upgrades.evolix.org/upgrade + wget --no-check-certificate --quiet --output-document="${upgradeInfo}" https://upgrades.evolix.org/upgrade + # shellcheck disable=SC2181 if [ "$?" != "0" ]; then printf >&2 "Error fetching upgrade directives.\n" fi - r_releases="$(get_value $upgradeInfo "releases")" - r_skip_releases="$(get_value $upgradeInfo "skip_releases")" - r_packages="$(get_value $upgradeInfo "packages")" - r_skip_packages="$(get_value $upgradeInfo "skip_packages")" - rm $upgradeInfo + r_releases="$(get_value "${upgradeInfo}" "releases")" + r_skip_releases="$(get_value "${upgradeInfo}" "skip_releases")" + r_packages="$(get_value "${upgradeInfo}" "packages")" + r_skip_packages="$(get_value "${upgradeInfo}" "skip_packages")" + + rm "${upgradeInfo}" } # Check if element $element is in (space separated) list $list. @@ -63,142 +69,147 @@ is_in() { list="$1" element="$2" - for i in $list; do - if [ "$element" = "$i" ]; then + for i in ${list}; do + if [ "${element}" = "${i}" ]; then return 0 fi done + return 1 } - if [[ "$1" != "--cron" ]]; then echo "À quel date/heure allez vous planifier l'envoi ?" echo "Exemple : le jeudi 6 mars entre 18h00 et 23h00" - echo -n ">" - read date + echo -n "> " + read -r date echo "À qui envoyer le mail ?" - echo -n ">" - read mailto + echo -n "> " + read -r mailto fi # Update APT cache and get packages to upgrade and packages on hold. -aptUpdateOutput=$(apt update 2>&1 | (egrep -ve '^(Listing|WARNING|$)' -e upgraded -e 'up to date' || true )) +aptUpdateOutput=$(apt update 2>&1 | (grep -E -ve '^(Listing|WARNING|$)' -e upgraded -e 'up to date' || true )) -if (echo "$aptUpdateOutput" | egrep "^Err(:[0-9]+)? http"); then +if echo "${aptUpdateOutput}" | grep -E "^Err(:[0-9]+)? http"; then echo "FATAL - Not able to fetch all sources (probably a pesky (mini)firewall). Please, fix me" exit 100 fi -apt-mark showhold > $packagesHold -apt list --upgradable 2>&1 | grep -v -f $packagesHold | egrep -v '^(Listing|WARNING|$)' > $packages -packagesParsable=$(cut -f 1 -d / <$packages |tr '\n' ' ') +apt-mark showhold > "${packagesHold}" +apt list --upgradable 2>&1 | grep -v -f "${packagesHold}" | grep -Ev '^(Listing|WARNING|$)' > "${packages}" +packagesParsable=$(cut -f 1 -d / < "${packages}" |tr '\n' ' ') # No updates? Exit! -test ! -s $packages && exit 0 -test ! -s $packagesHold && echo 'Aucun' > $packagesHold +test ! -s "${packages}" && exit 0 +test ! -s "${packagesHold}" && echo 'Aucun' > "${packagesHold}" fetch_upgrade_info local_release=$(cut -f 1 -d . >$servicesToRestart - elif echo "$pkg" |grep -q "^nginx"; then - echo "Nginx" >>$servicesToRestart - elif echo "$pkg" |grep -q "^php5-fpm"; then - echo "PHP FPM" >>$servicesToRestart - elif echo "$pkg" |grep -q "^mysql-server"; then - echo "MySQL" >>$servicesToRestart - elif echo "$pkg" |grep -q "^mariadb-server"; then - echo "MariaDB" >>$servicesToRestart - elif echo "$pkg" |grep -qE "^postgresql-[[:digit:]]+\.[[:digit:]]+$"; then - echo "PostgreSQL" >>$servicesToRestart - elif echo "$pkg" |grep -qE "^tomcat[[:digit:]]+$"; then - echo "Tomcat" >>$servicesToRestart - elif [ "$pkg" = "redis-server" ]; then - echo "Redis" >>$servicesToRestart - elif [ "$pkg" = "mongodb-server" ]; then - echo "MondoDB" >>$servicesToRestart - elif echo "$pkg" |grep -qE "^courier-(pop|imap)"; then - echo "Courier POP/IMAP" >>$servicesToRestart - elif echo "$pkg" |grep -qE "^dovecot-(pop|imap)d"; then - echo "Dovecot POP/IMAP" >>$servicesToRestart - elif [ "$pkg" = "samba" ]; then - echo "Samba" >>$servicesToRestart - elif [ "$pkg" = "slapd" ]; then - echo "OpenLDAP" >>$servicesToRestart - elif [ "$pkg" = "bind9" ]; then - echo "Bind9" >>$servicesToRestart - elif [ "$pkg" = "postfix" ]; then - echo "Postfix" >>$servicesToRestart - elif [ "$pkg" = "haproxy" ]; then - echo "HAProxy" >>$servicesToRestart - elif [ "$pkg" = "varnish" ]; then - echo "Varnish" >>$servicesToRestart - elif [ "$pkg" = "squid" ]; then - echo "Squid" >>$servicesToRestart - elif [ "$pkg" = "elasticsearch" ]; then - echo "Elasticsearch" >>$servicesToRestart - elif [ "$pkg" = "logstash" ]; then - echo "Logstash" >>$servicesToRestart - - elif [ "$pkg" = "libc6" ]; then - echo "Tous les services sont susceptibles d'être redémarrés (mise à jour de libc6)." >$servicesToRestart +for pkg in ${packagesParsable}; do + if echo "${pkg}" | grep -qE "^(lib)?apache2"; then + echo "Apache2" >> "${servicesToRestart}" + elif echo "${pkg}" | grep -q "^nginx"; then + echo "Nginx" >> "${servicesToRestart}" + elif echo "${pkg}" | grep -q "^php5-fpm"; then + echo "PHP FPM" >> "${servicesToRestart}" + elif echo "${pkg}" | grep -q "^mysql-server"; then + echo "MySQL" >> "${servicesToRestart}" + elif echo "${pkg}" | grep -q "^mariadb-server"; then + echo "MariaDB" >> "${servicesToRestart}" + elif echo "${pkg}" | grep -qE "^postgresql-[[:digit:]]+\.[[:digit:]]+$"; then + echo "PostgreSQL" >> "${servicesToRestart}" + elif echo "${pkg}" | grep -qE "^tomcat[[:digit:]]+$"; then + echo "Tomcat" >> "${servicesToRestart}" + elif [ "${pkg}" = "redis-server" ]; then + echo "Redis" >> "${servicesToRestart}" + elif [ "${pkg}" = "mongodb-server" ]; then + echo "MondoDB" >> "${servicesToRestart}" + elif echo "${pkg}" | grep -qE "^courier-(pop|imap)"; then + echo "Courier POP/IMAP" >> "${servicesToRestart}" + elif echo "${pkg}" | grep -qE "^dovecot-(pop|imap)d"; then + echo "Dovecot POP/IMAP" >> "${servicesToRestart}" + elif [ "${pkg}" = "samba" ]; then + echo "Samba" >> "${servicesToRestart}" + elif [ "${pkg}" = "slapd" ]; then + echo "OpenLDAP" >> "${servicesToRestart}" + elif [ "${pkg}" = "bind9" ]; then + echo "Bind9" >> "${servicesToRestart}" + elif [ "${pkg}" = "postfix" ]; then + echo "Postfix" >> "${servicesToRestart}" + elif [ "${pkg}" = "haproxy" ]; then + echo "HAProxy" >> "${servicesToRestart}" + elif [ "${pkg}" = "varnish" ]; then + echo "Varnish" >> "${servicesToRestart}" + elif [ "${pkg}" = "squid" ]; then + echo "Squid" >> "${servicesToRestart}" + elif [ "${pkg}" = "elasticsearch" ]; then + echo "Elasticsearch" >> "${servicesToRestart}" + elif [ "${pkg}" = "logstash" ]; then + echo "Logstash" >> "${servicesToRestart}" + elif [ "${pkg}" = "kibana" ]; then + echo "Kibana" >> "${servicesToRestart}" + elif [ "${pkg}" = "libc6" ]; then + echo "Tous les services sont susceptibles d'être redémarrés (mise à jour de libc6)." > "${servicesToRestart}" break - elif [ "$pkg" = "libstdc++6" ]; then - echo "Tous les services sont susceptibles d'être redémarrés (mise à jour de libstdc++6)." >$servicesToRestart + elif [ "${pkg}" = "libstdc++6" ]; then + echo "Tous les services sont susceptibles d'être redémarrés (mise à jour de libstdc++6)." > "${servicesToRestart}" break - elif echo "$pkg" |grep -q "^libssl"; then - echo "Tous les services sont susceptibles d'être redémarrés (mise à jour de libssl)." >$servicesToRestart + elif echo "${pkg}" | grep -q "^libssl"; then + echo "Tous les services sont susceptibles d'être redémarrés (mise à jour de libssl)." > "${servicesToRestart}" break fi done -test ! -s $servicesToRestart && echo "Aucun" >$servicesToRestart +test ! -s "${servicesToRestart}" && echo "Aucun" > "${servicesToRestart}" -cat << EOT > $template +cat << EOT > "${template}" Content-Type: text/plain; charset="utf-8" Reply-To: equipe@evolix.fr From: equipe@evolix.net To: ${clientmail} -Subject: Prochain creneau pour mise a jour de votre serveur $hostname -X-Debian-Release: $local_release -X-Packages: $packagesParsable -X-Date: $date +Subject: Prochain creneau pour mise a jour de votre serveur ${hostname} +X-Debian-Release: ${local_release} +X-Packages: ${packagesParsable} +X-Date: ${date} Bonjour, @@ -215,15 +226,15 @@ semaine prochaine. Voici la listes de packages qui seront mis à jour : -$(cat $packages) +$(cat "${packages}") Liste des packages dont la mise-à-jour a été manuellement suspendue : -$(cat $packagesHold) +$(cat "${packagesHold}") Liste des services qui seront redémarrés : -$(cat $servicesToRestart) +$(cat "${servicesToRestart}") N'hésitez pas à nous faire toute remarque sur ce créneau d'intervention le plus tôt possible. @@ -234,14 +245,15 @@ Cordialement, http://evolix.com | Twitter: @Evolix @EvolixNOC | http://blog.evolix.com EOT -<$template /usr/sbin/sendmail $mailto +< "${template}" /usr/sbin/sendmail "${mailto}" # Now we try to fetch all the packages for the next update session downloadstatus=$(apt dist-upgrade --assume-yes --download-only -q2 2>&1) -echo "$downloadstatus" | grep -q 'Download complete and in download only mode' +echo "${downloadstatus}" | grep -q 'Download complete and in download only mode' +# shellcheck disable=SC2181 if [ $? -ne 0 ]; then - echo "$downloadstatus" + echo "${downloadstatus}" fi; @@ -249,19 +261,19 @@ fi; if which lxc-ls > /dev/null; then for container in $(lxc-ls); do - aptUpdateOutput=$(lxc-attach -n $container -- apt update 2>&1 | (egrep -ve '^(Listing|WARNING|$)' -e upgraded -e 'up to date' || true )) + aptUpdateOutput=$(lxc-attach -n "${container}" -- apt update 2>&1 | (grep -Eve '^(Listing|WARNING|$)' -e upgraded -e 'up to date' || true )) - if (echo "$aptUpdateOutput" | egrep "^Err(:[0-9]+)? http"); then + if (echo "${aptUpdateOutput}" | grep -E "^Err(:[0-9]+)? http"); then echo "FATAL CONTAINER - Not able to fetch all sources (probably a pesky (mini)firewall). Please, fix me" exit 150 fi # Now we try to fetch all the packages for the next update session - downloadstatus=$(lxc-attach -n $container -- apt dist-upgrade --assume-yes --download-only -q2 2>&1) - echo "$downloadstatus" | grep -q 'Download complete and in download only mode' + downloadstatus=$(lxc-attach -n "${container}" -- apt dist-upgrade --assume-yes --download-only -q2 2>&1) + echo "${downloadstatus}" | grep -q 'Download complete and in download only mode' if [ $? -ne 0 ]; then - echo "$downloadstatus" + echo "${downloadstatus}" fi; done From 4d83f25ae6a876f79b0413b234fb86e601365e24 Mon Sep 17 00:00:00 2001 From: Jeremy Lecour Date: Tue, 18 May 2021 14:04:54 +0200 Subject: [PATCH 47/86] fix pipefail option for shell invocations --- CHANGELOG.md | 1 + apt/tasks/hold_packages.yml | 6 ++++++ elasticsearch/tasks/logs.yml | 3 +++ etc-git/tasks/main.yml | 2 ++ evocheck/tasks/cron.yml | 2 ++ evolinux-base/tasks/postfix.yml | 3 ++- evolinux-base/tasks/system.yml | 3 +++ logstash/tasks/logs.yml | 3 +++ percona/tasks/main.yml | 5 ++++- postfix/tasks/packmail.yml | 3 +++ spamassasin/tasks/main.yml | 3 +++ ssl/tasks/main.yml | 6 ++++-- 12 files changed, 36 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 42270191..ef1aba95 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -31,6 +31,7 @@ The **patch** part changes incrementally at each release. ### Fixed +* fix pipefail option for shell invocations * ldap: fix edge cases where passwords were not set/get properly * listupgrade: fix wget error + shellcheck cleanup diff --git a/apt/tasks/hold_packages.yml b/apt/tasks/hold_packages.yml index 12774942..691f3763 100644 --- a/apt/tasks/hold_packages.yml +++ b/apt/tasks/hold_packages.yml @@ -2,6 +2,9 @@ - name: "hold packages (apt)" shell: "set -o pipefail && (dpkg -l {{ item }} 2>/dev/null | grep -q -E '^(i|h)i') && ((apt-mark showhold | grep --quiet {{ item }}) || apt-mark hold {{ item }})" + args: + executable: /bin/bash + check_mode: no register: apt_mark changed_when: "item + ' set on hold.' in apt_mark.stdout" failed_when: @@ -31,6 +34,9 @@ - name: "unhold packages (apt)" shell: "set -o pipefail && (dpkg -l {{ item }} 2>/dev/null | grep -q -E '^(i|h)i') && ((apt-mark showhold | grep --quiet {{ item }}) && apt-mark unhold {{ item }})" + args: + executable: /bin/bash + check_mode: no register: apt_mark changed_when: "'Canceled hold on' + item in apt_mark.stdout" failed_when: apt_mark.rc != 0 and not apt_mark.stdout = '' diff --git a/elasticsearch/tasks/logs.yml b/elasticsearch/tasks/logs.yml index b48e9373..f7e2c0c0 100644 --- a/elasticsearch/tasks/logs.yml +++ b/elasticsearch/tasks/logs.yml @@ -2,6 +2,9 @@ - name: Check if cron is installed shell: "set -o pipefail && dpkg -l cron 2> /dev/null | grep -q -E '^(i|h)i'" + args: + executable: /bin/bash + check_mode: no failed_when: False changed_when: False register: is_cron_installed diff --git a/etc-git/tasks/main.yml b/etc-git/tasks/main.yml index f707dab4..5d468f60 100644 --- a/etc-git/tasks/main.yml +++ b/etc-git/tasks/main.yml @@ -34,6 +34,8 @@ - name: Check if cron is installed shell: "set -o pipefail && dpkg -l cron 2> /dev/null | grep -q -E '^(i|h)i'" + args: + executable: /bin/bash failed_when: False changed_when: False check_mode: no diff --git a/evocheck/tasks/cron.yml b/evocheck/tasks/cron.yml index 4557ef2a..aac3f927 100644 --- a/evocheck/tasks/cron.yml +++ b/evocheck/tasks/cron.yml @@ -2,6 +2,8 @@ - name: Check if cron is installed shell: "set -o pipefail && dpkg -l cron 2> /dev/null | grep -q -E '^(i|h)i'" + args: + executable: /bin/bash failed_when: False changed_when: False check_mode: no diff --git a/evolinux-base/tasks/postfix.yml b/evolinux-base/tasks/postfix.yml index 6c1d8532..6a46548b 100644 --- a/evolinux-base/tasks/postfix.yml +++ b/evolinux-base/tasks/postfix.yml @@ -33,8 +33,9 @@ - name: fetch users list shell: "set -o pipefail && getent passwd | cut -d':' -f 1 | grep -v root" + args: + executable: /bin/bash check_mode: no - register: non_root_users_list changed_when: False tags: diff --git a/evolinux-base/tasks/system.yml b/evolinux-base/tasks/system.yml index 2e57b1e2..f9c72c54 100644 --- a/evolinux-base/tasks/system.yml +++ b/evolinux-base/tasks/system.yml @@ -86,6 +86,9 @@ - name: Check if cron is installed shell: "set -o pipefail && dpkg -l cron 2> /dev/null | grep -q -E '^(i|h)i'" + args: + executable: /bin/bash + check_mode: no failed_when: False changed_when: False check_mode: no diff --git a/logstash/tasks/logs.yml b/logstash/tasks/logs.yml index 8ea07ddd..9eb98c1a 100644 --- a/logstash/tasks/logs.yml +++ b/logstash/tasks/logs.yml @@ -1,6 +1,9 @@ --- - name: Check if cron is installed shell: "set -o pipefail && dpkg -l cron 2> /dev/null | grep -q -E '^(i|h)i'" + args: + executable: /bin/bash + check_mode: no failed_when: False changed_when: False register: is_cron_installed diff --git a/percona/tasks/main.yml b/percona/tasks/main.yml index 28278e49..b60a88a8 100644 --- a/percona/tasks/main.yml +++ b/percona/tasks/main.yml @@ -17,7 +17,10 @@ mode: "0644" - name: Check if percona-release is installed - command: "set -o pipefail && dpkg -l percona-release 2> /dev/null | grep -q -E '^(i|h)i'" + shell: "set -o pipefail && dpkg -l percona-release 2> /dev/null | grep -q -E '^(i|h)i'" + args: + executable: /bin/bash + check_mode: no failed_when: False changed_when: False register: percona__apt_config_package_installed diff --git a/postfix/tasks/packmail.yml b/postfix/tasks/packmail.yml index b2bdff22..b0476edd 100644 --- a/postfix/tasks/packmail.yml +++ b/postfix/tasks/packmail.yml @@ -99,6 +99,9 @@ - name: Check if cron is installed shell: "set -o pipefail && dpkg -l cron 2> /dev/null | grep -q -E '^(i|h)i'" + args: + executable: /bin/bash + check_mode: no failed_when: False changed_when: False register: is_cron_installed diff --git a/spamassasin/tasks/main.yml b/spamassasin/tasks/main.yml index df331af4..497c4698 100644 --- a/spamassasin/tasks/main.yml +++ b/spamassasin/tasks/main.yml @@ -67,6 +67,9 @@ - name: Check if cron is installed shell: "set -o pipefail && dpkg -l cron 2> /dev/null | grep -q -E '^(i|h)i'" + args: + executable: /bin/bash + check_mode: no failed_when: False changed_when: False register: is_cron_installed diff --git a/ssl/tasks/main.yml b/ssl/tasks/main.yml index a21c15ff..36de4b35 100644 --- a/ssl/tasks/main.yml +++ b/ssl/tasks/main.yml @@ -29,9 +29,11 @@ - ssl - name: Check if Haproxy is installed - command: "set -o pipefail && dpkg -l haproxy 2> /dev/null | grep -q -E '^(i|h)i'" + shell: "set -o pipefail && dpkg -l haproxy 2> /dev/null | grep -q -E '^(i|h)i'" + args: + executable: /bin/bash register: haproxy_check - check_mode: False + check_mode: no changed_when: False failed_when: False tags: From 02451f1e67930ba355fa7886bd1e842d18d11aa6 Mon Sep 17 00:00:00 2001 From: Jeremy Lecour Date: Wed, 19 May 2021 14:35:08 +0200 Subject: [PATCH 48/86] add default (useless) value for file lookup --- CHANGELOG.md | 1 + evobackup-client/tasks/upload_scripts.yml | 2 +- evolinux-base/tasks/motd.yml | 2 +- filebeat/tasks/main.yml | 2 +- listupgrade/defaults/main.yml | 2 ++ listupgrade/tasks/main.yml | 1 + logstash/tasks/main.yml | 2 +- metricbeat/tasks/main.yml | 2 +- minifirewall/tasks/tail.yml | 2 +- varnish/tasks/main.yml | 4 ++-- webapps/evoadmin-web/README.md | 12 ++++++------ webapps/evoadmin-web/tasks/config.yml | 4 ++-- webapps/evoadmin-web/tasks/user.yml | 2 +- webapps/evoadmin-web/tasks/web.yml | 6 +++--- 14 files changed, 24 insertions(+), 20 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ef1aba95..c159d47a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -31,6 +31,7 @@ The **patch** part changes incrementally at each release. ### Fixed +* add default (useless) value for file lookup (first_found) * fix pipefail option for shell invocations * ldap: fix edge cases where passwords were not set/get properly * listupgrade: fix wget error + shellcheck cleanup diff --git a/evobackup-client/tasks/upload_scripts.yml b/evobackup-client/tasks/upload_scripts.yml index f3f7de25..79e5d7db 100644 --- a/evobackup-client/tasks/upload_scripts.yml +++ b/evobackup-client/tasks/upload_scripts.yml @@ -10,7 +10,7 @@ vars: templates: - "templates/evobackup-client/{{ evobackup_client__cron_template_name }}.{{ inventory_hostname }}.sh.j2" - - "templates/evobackup-client/{{ evobackup_client__cron_template_name }}.{{ host_group }}.sh.j2" + - "templates/evobackup-client/{{ evobackup_client__cron_template_name }}.{{ host_group | default('all') }}.sh.j2" - "templates/evobackup-client/{{ evobackup_client__cron_template_name }}.sh.j2" - "templates/zzz_evobackup.default.sh.j2" tags: diff --git a/evolinux-base/tasks/motd.yml b/evolinux-base/tasks/motd.yml index 59076f8e..076a4226 100644 --- a/evolinux-base/tasks/motd.yml +++ b/evolinux-base/tasks/motd.yml @@ -11,7 +11,7 @@ vars: templates: - "motd/motd.{{ inventory_hostname }}.j2" - - "motd/motd.{{ host_group }}.j2" + - "motd/motd.{{ host_group | default('all') }}.j2" - "motd/motd.default.j2" tags: - motd diff --git a/filebeat/tasks/main.yml b/filebeat/tasks/main.yml index 06f7d564..4594d5ed 100644 --- a/filebeat/tasks/main.yml +++ b/filebeat/tasks/main.yml @@ -151,7 +151,7 @@ vars: templates: - "templates/filebeat/filebeat.{{ inventory_hostname }}.yml.j2" - - "templates/filebeat/filebeat.{{ host_group }}.yml.j2" + - "templates/filebeat/filebeat.{{ host_group | default('all') }}.yml.j2" - "templates/filebeat/filebeat.default.yml.j2" - "templates/filebeat.default.yml.j2" notify: restart filebeat diff --git a/listupgrade/defaults/main.yml b/listupgrade/defaults/main.yml index 3f72fbff..d3bdff78 100644 --- a/listupgrade/defaults/main.yml +++ b/listupgrade/defaults/main.yml @@ -1,3 +1,5 @@ --- general_alert_email: "root@localhost" listupgrade_alert_email: Null + +listupgrade_cron_enabled: true \ No newline at end of file diff --git a/listupgrade/tasks/main.yml b/listupgrade/tasks/main.yml index a1449b04..3ed23da3 100644 --- a/listupgrade/tasks/main.yml +++ b/listupgrade/tasks/main.yml @@ -53,6 +53,7 @@ owner: root group: root force: no + when: listupgrade_cron_enabled | bool - name: old-kernel-autoremoval script is present copy: diff --git a/logstash/tasks/main.yml b/logstash/tasks/main.yml index b4c71b3d..0b58dbe8 100644 --- a/logstash/tasks/main.yml +++ b/logstash/tasks/main.yml @@ -82,7 +82,7 @@ vars: templates: - "templates/logstash/logstash.{{ inventory_hostname }}.conf.j2" - - "templates/logstash/logstash.{{ host_group }}.conf.j2" + - "templates/logstash/logstash.{{ host_group | default('all') }}.conf.j2" - "templates/logstash/logstash.default.conf.j2" - "templates/logstash.default.conf.j2" register: logstash_template diff --git a/metricbeat/tasks/main.yml b/metricbeat/tasks/main.yml index 2290626e..14357f18 100644 --- a/metricbeat/tasks/main.yml +++ b/metricbeat/tasks/main.yml @@ -123,7 +123,7 @@ vars: templates: - "templates/metricbeat/metricbeat.{{ inventory_hostname }}.yml.j2" - - "templates/metricbeat/metricbeat.{{ host_group }}.yml.j2" + - "templates/metricbeat/metricbeat.{{ host_group | default('all') }}.yml.j2" - "templates/metricbeat/metricbeat.default.yml.j2" - "templates/metricbeat.default.yml.j2" notify: restart metricbeat diff --git a/minifirewall/tasks/tail.yml b/minifirewall/tasks/tail.yml index a086ead9..c8c4440e 100644 --- a/minifirewall/tasks/tail.yml +++ b/minifirewall/tasks/tail.yml @@ -8,7 +8,7 @@ vars: templates: - "templates/minifirewall-tail/minifirewall.{{ inventory_hostname }}.tail.j2" - - "templates/minifirewall-tail/minifirewall.{{ host_group }}.tail.j2" + - "templates/minifirewall-tail/minifirewall.{{ host_group | default('all') }}.tail.j2" - "templates/minifirewall-tail/minifirewall.default.tail.j2" - "templates/minifirewall.default.tail.j2" register: minifirewall_tail_template diff --git a/varnish/tasks/main.yml b/varnish/tasks/main.yml index 3d2a134d..95a720c8 100644 --- a/varnish/tasks/main.yml +++ b/varnish/tasks/main.yml @@ -89,8 +89,8 @@ templates: - "templates/varnish/varnish.{{ inventory_hostname }}.vcl.j2" - "templates/varnish/default.{{ inventory_hostname }}.vcl.j2" - - "templates/varnish/varnish.{{ host_group }}.vcl.j2" - - "templates/varnish/default.{{ host_group }}.vcl.j2" + - "templates/varnish/varnish.{{ host_group | default('all') }}.vcl.j2" + - "templates/varnish/default.{{ host_group | default('all') }}.vcl.j2" - "templates/varnish/varnish.default.vcl.j2" - "templates/varnish/default.default.vcl.j2" - "templates/varnish.vcl.j2" diff --git a/webapps/evoadmin-web/README.md b/webapps/evoadmin-web/README.md index 977764ad..24242d1b 100644 --- a/webapps/evoadmin-web/README.md +++ b/webapps/evoadmin-web/README.md @@ -1,34 +1,34 @@ # Set custom web-add.conf file - "templates/evoadmin-web/web-add.{{ inventory_hostname }}.conf.j2" -- "templates/evoadmin-web/web-add.{{ host_group }}.conf.j2" +- "templates/evoadmin-web/web-add.{{ host_group | default('all') }}.conf.j2" - "templates/evoadmin-web/web-add.conf.j2" And force it to update: evoadmin_add_conf_force: True # Set custom web-mail.tpl - "templates/evoadmin-web/web-mail.{{ inventory_hostname }}.tpl.j2" -- "templates/evoadmin-web/web-mail.{{ host_group }}.tpl.j2" +- "templates/evoadmin-web/web-mail.{{ host_group | default('all') }}.tpl.j2" - "templates/evoadmin-web/web-mail.tpl.j2" And force it to update: evoadmin_mail_tpl_force: True # Set custom evoadmin.conf VHost - "templates/evoadmin-web/evoadmin.{{ inventory_hostname }}.conf.j2" -- "templates/evoadmin-web/evoadmin.{{ host_group }}.conf.j2" +- "templates/evoadmin-web/evoadmin.{{ host_group | default('all') }}.conf.j2" - "templates/evoadmin-web/evoadmin.conf.j2" And force it to update: evoadmin_force_vhost: True # Set custom config.local.php - "templates/evoadmin-web/config.local.{{ inventory_hostname }}.php.j2" -- "templates/evoadmin-web/config.local.{{ host_group }}.php.j2" +- "templates/evoadmin-web/config.local.{{ host_group | default('all') }}.php.j2" - "templates/evoadmin-web/config.local.php.j2" And force it to update: evoadmin_config_local_php_force: True # Set evoadmin-web sudoers file - "templates/evoadmin-web/sudoers.{{ inventory_hostname }}.j2" -- "templates/evoadmin-web/sudoers.{{ host_group }}.j2" +- "templates/evoadmin-web/sudoers.{{ host_group | default('all') }}.j2" - "templates/evoadmin-web/sudoers.j2" - "sudoers.j2" And force it to update: @@ -39,7 +39,7 @@ evoadmin_htpasswd: True Overwrite its template: - "templates/evoadmin-web/htpasswd.{{ inventory_hostname }}.j2" -- "templates/evoadmin-web/htpasswd.{{ host_group }}.j2" +- "templates/evoadmin-web/htpasswd.{{ host_group | default('all') }}.j2" - "templates/evoadmin-web/htpasswd.j2" - "htpasswd.j2" And force it to update: diff --git a/webapps/evoadmin-web/tasks/config.yml b/webapps/evoadmin-web/tasks/config.yml index 9f16a2d6..d4bf9174 100644 --- a/webapps/evoadmin-web/tasks/config.yml +++ b/webapps/evoadmin-web/tasks/config.yml @@ -15,7 +15,7 @@ vars: templates: - "templates/evoadmin-web/web-add.{{ inventory_hostname }}.conf.j2" - - "templates/evoadmin-web/web-add.{{ host_group }}.conf.j2" + - "templates/evoadmin-web/web-add.{{ host_group | default('all') }}.conf.j2" - "templates/evoadmin-web/web-add.conf.j2" - "templates/web-add.conf.j2" register: evoadmin_add_conf_template @@ -29,7 +29,7 @@ vars: templates: - "templates/evoadmin-web/web-mail.{{ inventory_hostname }}.tpl.j2" - - "templates/evoadmin-web/web-mail.{{ host_group }}.tpl.j2" + - "templates/evoadmin-web/web-mail.{{ host_group | default('all') }}.tpl.j2" - "templates/evoadmin-web/web-mail.tpl.j2" - "templates/web-mail.tpl.j2" register: evoadmin_mail_tpl_template diff --git a/webapps/evoadmin-web/tasks/user.yml b/webapps/evoadmin-web/tasks/user.yml index 4593dcf3..68ac91de 100644 --- a/webapps/evoadmin-web/tasks/user.yml +++ b/webapps/evoadmin-web/tasks/user.yml @@ -116,7 +116,7 @@ vars: templates: - "templates/evoadmin-web/sudoers.{{ inventory_hostname }}.j2" - - "templates/evoadmin-web/sudoers.{{ host_group }}.j2" + - "templates/evoadmin-web/sudoers.{{ host_group | default('all') }}.j2" - "templates/evoadmin-web/sudoers.j2" - "templates/sudoers.j2" register: evoadmin_sudoers_conf diff --git a/webapps/evoadmin-web/tasks/web.yml b/webapps/evoadmin-web/tasks/web.yml index dc5eb8a3..7f95c96c 100644 --- a/webapps/evoadmin-web/tasks/web.yml +++ b/webapps/evoadmin-web/tasks/web.yml @@ -36,7 +36,7 @@ vars: templates: - "templates/evoadmin-web/evoadmin.{{ inventory_hostname }}.conf.j2" - - "templates/evoadmin-web/evoadmin.{{ host_group }}.conf.j2" + - "templates/evoadmin-web/evoadmin.{{ host_group | default('all') }}.conf.j2" - "templates/evoadmin-web/evoadmin.conf.j2" - "templates/evoadmin.conf.j2" register: evoadmin_vhost_template @@ -68,7 +68,7 @@ vars: templates: - "templates/evoadmin-web/htpasswd.{{ inventory_hostname }}.j2" - - "templates/evoadmin-web/htpasswd.{{ host_group }}.j2" + - "templates/evoadmin-web/htpasswd.{{ host_group | default('all') }}.j2" - "templates/evoadmin-web/htpasswd.j2" - "templates/htpasswd.j2" register: evoadmin_htpasswd_template @@ -86,7 +86,7 @@ vars: templates: - "templates/evoadmin-web/config.local.{{ inventory_hostname }}.php.j2" - - "templates/evoadmin-web/config.local.{{ host_group }}.php.j2" + - "templates/evoadmin-web/config.local.{{ host_group | default('all') }}.php.j2" - "templates/evoadmin-web/config.local.php.j2" - "templates/config.local.php.j2" register: evoadmin_config_local_php_template From 547272eefd1558efd48cf0c559b2510a8e53326a Mon Sep 17 00:00:00 2001 From: Eric Morino Date: Wed, 19 May 2021 16:17:08 +0200 Subject: [PATCH 49/86] Add create diretory for munin plugins --- mongodb/tasks/main_buster.yml | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/mongodb/tasks/main_buster.yml b/mongodb/tasks/main_buster.yml index 387a9c0a..9baf7c8a 100644 --- a/mongodb/tasks/main_buster.yml +++ b/mongodb/tasks/main_buster.yml @@ -53,6 +53,18 @@ force: yes backup: no +- name: Create plugin directory + file: + name: /usr/local/share/munin/ + state: directory + mode: "0755" + +- name: Create plugin directory + file: + name: /usr/local/share/munin/plugins/ + state: directory + mode: "0755" + - name: Munin plugins are present copy: src: "munin/{{ item }}" From 56c064d86b79ce794a3e7db06ff96c2295edd505 Mon Sep 17 00:00:00 2001 From: Ludovic Poujol Date: Wed, 19 May 2021 16:33:51 +0200 Subject: [PATCH 50/86] Update 'packweb-apache/meta/main.yml' Quick hot-fix : Add dependency for php 7.4 to packweb-apache --- packweb-apache/meta/main.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/packweb-apache/meta/main.yml b/packweb-apache/meta/main.yml index cd4b4f94..4494dcb4 100644 --- a/packweb-apache/meta/main.yml +++ b/packweb-apache/meta/main.yml @@ -27,5 +27,6 @@ dependencies: - { role: evolix/lxc-php, lxc_php_version: php56, lxc_php_create_mysql_link: True, when: "'php56' in packweb_multiphp_versions" } - { role: evolix/lxc-php, lxc_php_version: php70, lxc_php_create_mysql_link: True, when: "'php70' in packweb_multiphp_versions" } - { role: evolix/lxc-php, lxc_php_version: php73, lxc_php_create_mysql_link: True, when: "'php73' in packweb_multiphp_versions" } + - { role: evolix/lxc-php, lxc_php_version: php74, lxc_php_create_mysql_link: True, when: "'php74' in packweb_multiphp_versions" } - { role: evolix/webapps/evoadmin-web, evoadmin_enable_vhost: "{{ packweb_enable_evoadmin_vhost }}", evoadmin_multiphp_versions: "{{ packweb_multiphp_versions }}" } - { role: evolix/evoacme } From 06b8314211e4ee80ca2974a39288ac07c5da5c06 Mon Sep 17 00:00:00 2001 From: Jeremy Lecour Date: Wed, 19 May 2021 17:02:10 +0200 Subject: [PATCH 51/86] evolinux-base: fix motd lookup path --- CHANGELOG.md | 1 + evolinux-base/tasks/motd.yml | 8 ++++---- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c159d47a..2486d311 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -33,6 +33,7 @@ The **patch** part changes incrementally at each release. * add default (useless) value for file lookup (first_found) * fix pipefail option for shell invocations +* evolinux-base: fix motd lookup path * ldap: fix edge cases where passwords were not set/get properly * listupgrade: fix wget error + shellcheck cleanup diff --git a/evolinux-base/tasks/motd.yml b/evolinux-base/tasks/motd.yml index 076a4226..9d5a109d 100644 --- a/evolinux-base/tasks/motd.yml +++ b/evolinux-base/tasks/motd.yml @@ -7,11 +7,11 @@ owner: root group: root mode: "0644" - loop: "{{ query('first_found', templates, errors='ignore') }}" + loop: "{{ query('first_found', templates) }}" vars: templates: - - "motd/motd.{{ inventory_hostname }}.j2" - - "motd/motd.{{ host_group | default('all') }}.j2" - - "motd/motd.default.j2" + - "templates/motd/motd.{{ inventory_hostname }}.j2" + - "templates/motd/motd.{{ host_group | default('all') }}.j2" + - "templates/motd/motd.default.j2" tags: - motd From dd42c3673c96e066a450b4276e59855a43d80ff5 Mon Sep 17 00:00:00 2001 From: Jeremy Lecour Date: Wed, 19 May 2021 17:02:15 +0200 Subject: [PATCH 52/86] whitespaces --- webapps/evoadmin-web/tasks/config.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/webapps/evoadmin-web/tasks/config.yml b/webapps/evoadmin-web/tasks/config.yml index d4bf9174..1053360c 100644 --- a/webapps/evoadmin-web/tasks/config.yml +++ b/webapps/evoadmin-web/tasks/config.yml @@ -14,10 +14,10 @@ loop: "{{ query('first_found', templates) }}" vars: templates: - - "templates/evoadmin-web/web-add.{{ inventory_hostname }}.conf.j2" - - "templates/evoadmin-web/web-add.{{ host_group | default('all') }}.conf.j2" - - "templates/evoadmin-web/web-add.conf.j2" - - "templates/web-add.conf.j2" + - "templates/evoadmin-web/web-add.{{ inventory_hostname }}.conf.j2" + - "templates/evoadmin-web/web-add.{{ host_group | default('all') }}.conf.j2" + - "templates/evoadmin-web/web-add.conf.j2" + - "templates/web-add.conf.j2" register: evoadmin_add_conf_template - name: Configure web-add template file for mail From 89b0bd5a2b709ba5e694058f95513896387fcb5e Mon Sep 17 00:00:00 2001 From: Jeremy Dubois Date: Wed, 19 May 2021 18:19:30 +0200 Subject: [PATCH 53/86] Fix duplicate dict key : check_mode --- evolinux-base/tasks/system.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/evolinux-base/tasks/system.yml b/evolinux-base/tasks/system.yml index f9c72c54..51bcb6e3 100644 --- a/evolinux-base/tasks/system.yml +++ b/evolinux-base/tasks/system.yml @@ -91,7 +91,6 @@ check_mode: no failed_when: False changed_when: False - check_mode: no register: is_cron_installed - name: Set verbose logging for cron deamon From 2c47871fa7c5622a605b1185ddffa83008f24b99 Mon Sep 17 00:00:00 2001 From: Jeremy Lecour Date: Tue, 25 May 2021 15:10:00 +0200 Subject: [PATCH 54/86] Add Elastic GPG key to kibana, filebeat, logstash, metricbeat roles --- CHANGELOG.md | 1 + filebeat/files/elastic.asc | 31 +++++++++++++++++++++++++++++++ kibana/files/elastic.asc | 31 +++++++++++++++++++++++++++++++ logstash/files/elastic.asc | 31 +++++++++++++++++++++++++++++++ metricbeat/files/elastic.asc | 31 +++++++++++++++++++++++++++++++ 5 files changed, 125 insertions(+) create mode 100644 filebeat/files/elastic.asc create mode 100644 kibana/files/elastic.asc create mode 100644 logstash/files/elastic.asc create mode 100644 metricbeat/files/elastic.asc diff --git a/CHANGELOG.md b/CHANGELOG.md index 2486d311..217dc2bb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,7 @@ The **patch** part changes incrementally at each release. ### Added +* Add Elastic GPG key to kibana, filebeat, logstash, metricbeat roles * apache: new variable for mpm mode (+ updated default config accordingly) * evolinux-base: add default motd template * kvm-host: add migrate-vm script diff --git a/filebeat/files/elastic.asc b/filebeat/files/elastic.asc new file mode 100644 index 00000000..1b50dcca --- /dev/null +++ b/filebeat/files/elastic.asc @@ -0,0 +1,31 @@ +-----BEGIN PGP PUBLIC KEY BLOCK----- +Version: GnuPG v2.0.14 (GNU/Linux) + +mQENBFI3HsoBCADXDtbNJnxbPqB1vDNtCsqhe49vFYsZN9IOZsZXgp7aHjh6CJBD +A+bGFOwyhbd7at35jQjWAw1O3cfYsKAmFy+Ar3LHCMkV3oZspJACTIgCrwnkic/9 +CUliQe324qvObU2QRtP4Fl0zWcfb/S8UYzWXWIFuJqMvE9MaRY1bwUBvzoqavLGZ +j3SF1SPO+TB5QrHkrQHBsmX+Jda6d4Ylt8/t6CvMwgQNlrlzIO9WT+YN6zS+sqHd +1YK/aY5qhoLNhp9G/HxhcSVCkLq8SStj1ZZ1S9juBPoXV1ZWNbxFNGwOh/NYGldD +2kmBf3YgCqeLzHahsAEpvAm8TBa7Q9W21C8vABEBAAG0RUVsYXN0aWNzZWFyY2gg +KEVsYXN0aWNzZWFyY2ggU2lnbmluZyBLZXkpIDxkZXZfb3BzQGVsYXN0aWNzZWFy +Y2gub3JnPokBOAQTAQIAIgUCUjceygIbAwYLCQgHAwIGFQgCCQoLBBYCAwECHgEC +F4AACgkQ0n1mbNiOQrRzjAgAlTUQ1mgo3nK6BGXbj4XAJvuZDG0HILiUt+pPnz75 +nsf0NWhqR4yGFlmpuctgCmTD+HzYtV9fp9qW/bwVuJCNtKXk3sdzYABY+Yl0Cez/ +7C2GuGCOlbn0luCNT9BxJnh4mC9h/cKI3y5jvZ7wavwe41teqG14V+EoFSn3NPKm +TxcDTFrV7SmVPxCBcQze00cJhprKxkuZMPPVqpBS+JfDQtzUQD/LSFfhHj9eD+Xe +8d7sw+XvxB2aN4gnTlRzjL1nTRp0h2/IOGkqYfIG9rWmSLNlxhB2t+c0RsjdGM4/ +eRlPWylFbVMc5pmDpItrkWSnzBfkmXL3vO2X3WvwmSFiQbkBDQRSNx7KAQgA5JUl +zcMW5/cuyZR8alSacKqhSbvoSqqbzHKcUQZmlzNMKGTABFG1yRx9r+wa/fvqP6OT +RzRDvVS/cycws8YX7Ddum7x8uI95b9ye1/Xy5noPEm8cD+hplnpU+PBQZJ5XJ2I+ +1l9Nixx47wPGXeClLqcdn0ayd+v+Rwf3/XUJrvccG2YZUiQ4jWZkoxsA07xx7Bj+ +Lt8/FKG7sHRFvePFU0ZS6JFx9GJqjSBbHRRkam+4emW3uWgVfZxuwcUCn1ayNgRt +KiFv9jQrg2TIWEvzYx9tywTCxc+FFMWAlbCzi+m4WD+QUWWfDQ009U/WM0ks0Kww +EwSk/UDuToxGnKU2dQARAQABiQEfBBgBAgAJBQJSNx7KAhsMAAoJENJ9ZmzYjkK0 +c3MIAIE9hAR20mqJWLcsxLtrRs6uNF1VrpB+4n/55QU7oxA1iVBO6IFu4qgsF12J +TavnJ5MLaETlggXY+zDef9syTPXoQctpzcaNVDmedwo1SiL03uMoblOvWpMR/Y0j +6rm7IgrMWUDXDPvoPGjMl2q1iTeyHkMZEyUJ8SKsaHh4jV9wp9KmC8C+9CwMukL7 +vM5w8cgvJoAwsp3Fn59AxWthN3XJYcnMfStkIuWgR7U2r+a210W6vnUxU4oN0PmM +cursYPyeV0NX/KQeUeNMwGTFB6QHS/anRaGQewijkrYYoTNtfllxIu9XYmiBERQ/ +qPDlGRlOgVTd9xUfHFkzB52c70E= +=92oX +-----END PGP PUBLIC KEY BLOCK----- diff --git a/kibana/files/elastic.asc b/kibana/files/elastic.asc new file mode 100644 index 00000000..1b50dcca --- /dev/null +++ b/kibana/files/elastic.asc @@ -0,0 +1,31 @@ +-----BEGIN PGP PUBLIC KEY BLOCK----- +Version: GnuPG v2.0.14 (GNU/Linux) + +mQENBFI3HsoBCADXDtbNJnxbPqB1vDNtCsqhe49vFYsZN9IOZsZXgp7aHjh6CJBD +A+bGFOwyhbd7at35jQjWAw1O3cfYsKAmFy+Ar3LHCMkV3oZspJACTIgCrwnkic/9 +CUliQe324qvObU2QRtP4Fl0zWcfb/S8UYzWXWIFuJqMvE9MaRY1bwUBvzoqavLGZ +j3SF1SPO+TB5QrHkrQHBsmX+Jda6d4Ylt8/t6CvMwgQNlrlzIO9WT+YN6zS+sqHd +1YK/aY5qhoLNhp9G/HxhcSVCkLq8SStj1ZZ1S9juBPoXV1ZWNbxFNGwOh/NYGldD +2kmBf3YgCqeLzHahsAEpvAm8TBa7Q9W21C8vABEBAAG0RUVsYXN0aWNzZWFyY2gg +KEVsYXN0aWNzZWFyY2ggU2lnbmluZyBLZXkpIDxkZXZfb3BzQGVsYXN0aWNzZWFy +Y2gub3JnPokBOAQTAQIAIgUCUjceygIbAwYLCQgHAwIGFQgCCQoLBBYCAwECHgEC +F4AACgkQ0n1mbNiOQrRzjAgAlTUQ1mgo3nK6BGXbj4XAJvuZDG0HILiUt+pPnz75 +nsf0NWhqR4yGFlmpuctgCmTD+HzYtV9fp9qW/bwVuJCNtKXk3sdzYABY+Yl0Cez/ +7C2GuGCOlbn0luCNT9BxJnh4mC9h/cKI3y5jvZ7wavwe41teqG14V+EoFSn3NPKm +TxcDTFrV7SmVPxCBcQze00cJhprKxkuZMPPVqpBS+JfDQtzUQD/LSFfhHj9eD+Xe +8d7sw+XvxB2aN4gnTlRzjL1nTRp0h2/IOGkqYfIG9rWmSLNlxhB2t+c0RsjdGM4/ +eRlPWylFbVMc5pmDpItrkWSnzBfkmXL3vO2X3WvwmSFiQbkBDQRSNx7KAQgA5JUl +zcMW5/cuyZR8alSacKqhSbvoSqqbzHKcUQZmlzNMKGTABFG1yRx9r+wa/fvqP6OT +RzRDvVS/cycws8YX7Ddum7x8uI95b9ye1/Xy5noPEm8cD+hplnpU+PBQZJ5XJ2I+ +1l9Nixx47wPGXeClLqcdn0ayd+v+Rwf3/XUJrvccG2YZUiQ4jWZkoxsA07xx7Bj+ +Lt8/FKG7sHRFvePFU0ZS6JFx9GJqjSBbHRRkam+4emW3uWgVfZxuwcUCn1ayNgRt +KiFv9jQrg2TIWEvzYx9tywTCxc+FFMWAlbCzi+m4WD+QUWWfDQ009U/WM0ks0Kww +EwSk/UDuToxGnKU2dQARAQABiQEfBBgBAgAJBQJSNx7KAhsMAAoJENJ9ZmzYjkK0 +c3MIAIE9hAR20mqJWLcsxLtrRs6uNF1VrpB+4n/55QU7oxA1iVBO6IFu4qgsF12J +TavnJ5MLaETlggXY+zDef9syTPXoQctpzcaNVDmedwo1SiL03uMoblOvWpMR/Y0j +6rm7IgrMWUDXDPvoPGjMl2q1iTeyHkMZEyUJ8SKsaHh4jV9wp9KmC8C+9CwMukL7 +vM5w8cgvJoAwsp3Fn59AxWthN3XJYcnMfStkIuWgR7U2r+a210W6vnUxU4oN0PmM +cursYPyeV0NX/KQeUeNMwGTFB6QHS/anRaGQewijkrYYoTNtfllxIu9XYmiBERQ/ +qPDlGRlOgVTd9xUfHFkzB52c70E= +=92oX +-----END PGP PUBLIC KEY BLOCK----- diff --git a/logstash/files/elastic.asc b/logstash/files/elastic.asc new file mode 100644 index 00000000..1b50dcca --- /dev/null +++ b/logstash/files/elastic.asc @@ -0,0 +1,31 @@ +-----BEGIN PGP PUBLIC KEY BLOCK----- +Version: GnuPG v2.0.14 (GNU/Linux) + +mQENBFI3HsoBCADXDtbNJnxbPqB1vDNtCsqhe49vFYsZN9IOZsZXgp7aHjh6CJBD +A+bGFOwyhbd7at35jQjWAw1O3cfYsKAmFy+Ar3LHCMkV3oZspJACTIgCrwnkic/9 +CUliQe324qvObU2QRtP4Fl0zWcfb/S8UYzWXWIFuJqMvE9MaRY1bwUBvzoqavLGZ +j3SF1SPO+TB5QrHkrQHBsmX+Jda6d4Ylt8/t6CvMwgQNlrlzIO9WT+YN6zS+sqHd +1YK/aY5qhoLNhp9G/HxhcSVCkLq8SStj1ZZ1S9juBPoXV1ZWNbxFNGwOh/NYGldD +2kmBf3YgCqeLzHahsAEpvAm8TBa7Q9W21C8vABEBAAG0RUVsYXN0aWNzZWFyY2gg +KEVsYXN0aWNzZWFyY2ggU2lnbmluZyBLZXkpIDxkZXZfb3BzQGVsYXN0aWNzZWFy +Y2gub3JnPokBOAQTAQIAIgUCUjceygIbAwYLCQgHAwIGFQgCCQoLBBYCAwECHgEC +F4AACgkQ0n1mbNiOQrRzjAgAlTUQ1mgo3nK6BGXbj4XAJvuZDG0HILiUt+pPnz75 +nsf0NWhqR4yGFlmpuctgCmTD+HzYtV9fp9qW/bwVuJCNtKXk3sdzYABY+Yl0Cez/ +7C2GuGCOlbn0luCNT9BxJnh4mC9h/cKI3y5jvZ7wavwe41teqG14V+EoFSn3NPKm +TxcDTFrV7SmVPxCBcQze00cJhprKxkuZMPPVqpBS+JfDQtzUQD/LSFfhHj9eD+Xe +8d7sw+XvxB2aN4gnTlRzjL1nTRp0h2/IOGkqYfIG9rWmSLNlxhB2t+c0RsjdGM4/ +eRlPWylFbVMc5pmDpItrkWSnzBfkmXL3vO2X3WvwmSFiQbkBDQRSNx7KAQgA5JUl +zcMW5/cuyZR8alSacKqhSbvoSqqbzHKcUQZmlzNMKGTABFG1yRx9r+wa/fvqP6OT +RzRDvVS/cycws8YX7Ddum7x8uI95b9ye1/Xy5noPEm8cD+hplnpU+PBQZJ5XJ2I+ +1l9Nixx47wPGXeClLqcdn0ayd+v+Rwf3/XUJrvccG2YZUiQ4jWZkoxsA07xx7Bj+ +Lt8/FKG7sHRFvePFU0ZS6JFx9GJqjSBbHRRkam+4emW3uWgVfZxuwcUCn1ayNgRt +KiFv9jQrg2TIWEvzYx9tywTCxc+FFMWAlbCzi+m4WD+QUWWfDQ009U/WM0ks0Kww +EwSk/UDuToxGnKU2dQARAQABiQEfBBgBAgAJBQJSNx7KAhsMAAoJENJ9ZmzYjkK0 +c3MIAIE9hAR20mqJWLcsxLtrRs6uNF1VrpB+4n/55QU7oxA1iVBO6IFu4qgsF12J +TavnJ5MLaETlggXY+zDef9syTPXoQctpzcaNVDmedwo1SiL03uMoblOvWpMR/Y0j +6rm7IgrMWUDXDPvoPGjMl2q1iTeyHkMZEyUJ8SKsaHh4jV9wp9KmC8C+9CwMukL7 +vM5w8cgvJoAwsp3Fn59AxWthN3XJYcnMfStkIuWgR7U2r+a210W6vnUxU4oN0PmM +cursYPyeV0NX/KQeUeNMwGTFB6QHS/anRaGQewijkrYYoTNtfllxIu9XYmiBERQ/ +qPDlGRlOgVTd9xUfHFkzB52c70E= +=92oX +-----END PGP PUBLIC KEY BLOCK----- diff --git a/metricbeat/files/elastic.asc b/metricbeat/files/elastic.asc new file mode 100644 index 00000000..1b50dcca --- /dev/null +++ b/metricbeat/files/elastic.asc @@ -0,0 +1,31 @@ +-----BEGIN PGP PUBLIC KEY BLOCK----- +Version: GnuPG v2.0.14 (GNU/Linux) + +mQENBFI3HsoBCADXDtbNJnxbPqB1vDNtCsqhe49vFYsZN9IOZsZXgp7aHjh6CJBD +A+bGFOwyhbd7at35jQjWAw1O3cfYsKAmFy+Ar3LHCMkV3oZspJACTIgCrwnkic/9 +CUliQe324qvObU2QRtP4Fl0zWcfb/S8UYzWXWIFuJqMvE9MaRY1bwUBvzoqavLGZ +j3SF1SPO+TB5QrHkrQHBsmX+Jda6d4Ylt8/t6CvMwgQNlrlzIO9WT+YN6zS+sqHd +1YK/aY5qhoLNhp9G/HxhcSVCkLq8SStj1ZZ1S9juBPoXV1ZWNbxFNGwOh/NYGldD +2kmBf3YgCqeLzHahsAEpvAm8TBa7Q9W21C8vABEBAAG0RUVsYXN0aWNzZWFyY2gg +KEVsYXN0aWNzZWFyY2ggU2lnbmluZyBLZXkpIDxkZXZfb3BzQGVsYXN0aWNzZWFy +Y2gub3JnPokBOAQTAQIAIgUCUjceygIbAwYLCQgHAwIGFQgCCQoLBBYCAwECHgEC +F4AACgkQ0n1mbNiOQrRzjAgAlTUQ1mgo3nK6BGXbj4XAJvuZDG0HILiUt+pPnz75 +nsf0NWhqR4yGFlmpuctgCmTD+HzYtV9fp9qW/bwVuJCNtKXk3sdzYABY+Yl0Cez/ +7C2GuGCOlbn0luCNT9BxJnh4mC9h/cKI3y5jvZ7wavwe41teqG14V+EoFSn3NPKm +TxcDTFrV7SmVPxCBcQze00cJhprKxkuZMPPVqpBS+JfDQtzUQD/LSFfhHj9eD+Xe +8d7sw+XvxB2aN4gnTlRzjL1nTRp0h2/IOGkqYfIG9rWmSLNlxhB2t+c0RsjdGM4/ +eRlPWylFbVMc5pmDpItrkWSnzBfkmXL3vO2X3WvwmSFiQbkBDQRSNx7KAQgA5JUl +zcMW5/cuyZR8alSacKqhSbvoSqqbzHKcUQZmlzNMKGTABFG1yRx9r+wa/fvqP6OT +RzRDvVS/cycws8YX7Ddum7x8uI95b9ye1/Xy5noPEm8cD+hplnpU+PBQZJ5XJ2I+ +1l9Nixx47wPGXeClLqcdn0ayd+v+Rwf3/XUJrvccG2YZUiQ4jWZkoxsA07xx7Bj+ +Lt8/FKG7sHRFvePFU0ZS6JFx9GJqjSBbHRRkam+4emW3uWgVfZxuwcUCn1ayNgRt +KiFv9jQrg2TIWEvzYx9tywTCxc+FFMWAlbCzi+m4WD+QUWWfDQ009U/WM0ks0Kww +EwSk/UDuToxGnKU2dQARAQABiQEfBBgBAgAJBQJSNx7KAhsMAAoJENJ9ZmzYjkK0 +c3MIAIE9hAR20mqJWLcsxLtrRs6uNF1VrpB+4n/55QU7oxA1iVBO6IFu4qgsF12J +TavnJ5MLaETlggXY+zDef9syTPXoQctpzcaNVDmedwo1SiL03uMoblOvWpMR/Y0j +6rm7IgrMWUDXDPvoPGjMl2q1iTeyHkMZEyUJ8SKsaHh4jV9wp9KmC8C+9CwMukL7 +vM5w8cgvJoAwsp3Fn59AxWthN3XJYcnMfStkIuWgR7U2r+a210W6vnUxU4oN0PmM +cursYPyeV0NX/KQeUeNMwGTFB6QHS/anRaGQewijkrYYoTNtfllxIu9XYmiBERQ/ +qPDlGRlOgVTd9xUfHFkzB52c70E= +=92oX +-----END PGP PUBLIC KEY BLOCK----- From 454d4c6d30eba1044c047083d0d0c8ea1938e323 Mon Sep 17 00:00:00 2001 From: Jeremy Lecour Date: Wed, 26 May 2021 13:47:34 +0200 Subject: [PATCH 55/86] explicit permissions for APT GPG keys --- apt/tasks/evolix_public.yml | 2 ++ docker-host/tasks/main.yml | 2 ++ elasticsearch/tasks/packages.yml | 2 ++ evolinux-base/tasks/hardware.yml | 4 ++++ filebeat/tasks/main.yml | 2 ++ fluentd/tasks/main.yml | 2 ++ jenkins/tasks/main.yml | 2 ++ kibana/tasks/main.yml | 2 ++ logstash/tasks/main.yml | 2 ++ lxc-php/tasks/php74.yml | 4 ++++ metricbeat/tasks/main.yml | 2 ++ mongodb/tasks/main_buster.yml | 2 ++ newrelic/tasks/sources.yml | 2 ++ nodejs/tasks/main.yml | 3 +++ nodejs/tasks/yarn.yml | 3 +++ percona/tasks/main.yml | 2 ++ php/tasks/sury_pre.yml | 2 ++ postgresql/tasks/pgdg-repo.yml | 2 ++ 18 files changed, 42 insertions(+) diff --git a/apt/tasks/evolix_public.yml b/apt/tasks/evolix_public.yml index eefd008e..00067f46 100644 --- a/apt/tasks/evolix_public.yml +++ b/apt/tasks/evolix_public.yml @@ -14,6 +14,8 @@ dest: /etc/apt/trusted.gpg.d/reg.asc force: yes mode: "0644" + owner: root + group: root tags: - apt diff --git a/docker-host/tasks/main.yml b/docker-host/tasks/main.yml index c31405b8..d3a41a28 100644 --- a/docker-host/tasks/main.yml +++ b/docker-host/tasks/main.yml @@ -33,6 +33,8 @@ dest: /etc/apt/trusted.gpg.d/docker-debian.asc force: yes mode: "0644" + owner: root + group: root - name: Install docker and python-docker apt: diff --git a/elasticsearch/tasks/packages.yml b/elasticsearch/tasks/packages.yml index 57beb0cc..da154593 100644 --- a/elasticsearch/tasks/packages.yml +++ b/elasticsearch/tasks/packages.yml @@ -23,6 +23,8 @@ dest: /etc/apt/trusted.gpg.d/elastic.asc force: yes mode: "0644" + owner: root + group: root tags: - elasticsearch - packages diff --git a/evolinux-base/tasks/hardware.yml b/evolinux-base/tasks/hardware.yml index 478e5015..9ece740e 100644 --- a/evolinux-base/tasks/hardware.yml +++ b/evolinux-base/tasks/hardware.yml @@ -49,6 +49,8 @@ dest: /etc/apt/trusted.gpg.d/hpePublicKey2048_key1.asc force: yes mode: "0644" + owner: root + group: root - name: Add HPE repository apt_repository: @@ -114,6 +116,8 @@ dest: /etc/apt/trusted.gpg.d/hwraid.le-vert.net.asc force: yes mode: "0644" + owner: root + group: root when: ansible_distribution_major_version is version('9', '>=') - name: Add HW tool repository diff --git a/filebeat/tasks/main.yml b/filebeat/tasks/main.yml index 4594d5ed..034808d3 100644 --- a/filebeat/tasks/main.yml +++ b/filebeat/tasks/main.yml @@ -23,6 +23,8 @@ dest: /etc/apt/trusted.gpg.d/elastic.asc force: yes mode: "0644" + owner: root + group: root tags: - filebeat - packages diff --git a/fluentd/tasks/main.yml b/fluentd/tasks/main.yml index 4e165e2b..159748e6 100644 --- a/fluentd/tasks/main.yml +++ b/fluentd/tasks/main.yml @@ -15,6 +15,8 @@ dest: /etc/apt/trusted.gpg.d/fluentd.asc force: yes mode: "0644" + owner: root + group: root tags: - packages - fluentd diff --git a/jenkins/tasks/main.yml b/jenkins/tasks/main.yml index e6533e9d..da23e5f5 100644 --- a/jenkins/tasks/main.yml +++ b/jenkins/tasks/main.yml @@ -17,6 +17,8 @@ dest: /etc/apt/trusted.gpg.d/jenkins.asc force: yes mode: "0644" + owner: root + group: root - name: Add jenkins APT repository apt_repository: diff --git a/kibana/tasks/main.yml b/kibana/tasks/main.yml index 44bed1a6..1ed342e0 100644 --- a/kibana/tasks/main.yml +++ b/kibana/tasks/main.yml @@ -23,6 +23,8 @@ dest: /etc/apt/trusted.gpg.d/elastic.asc force: yes mode: "0644" + owner: root + group: root tags: - kibana - packages diff --git a/logstash/tasks/main.yml b/logstash/tasks/main.yml index 0b58dbe8..4ae70623 100644 --- a/logstash/tasks/main.yml +++ b/logstash/tasks/main.yml @@ -23,6 +23,8 @@ dest: /etc/apt/trusted.gpg.d/elastic.asc force: yes mode: "0644" + owner: root + group: root tags: - logstash - packages diff --git a/lxc-php/tasks/php74.yml b/lxc-php/tasks/php74.yml index 43de6f3c..2c4538e8 100644 --- a/lxc-php/tasks/php74.yml +++ b/lxc-php/tasks/php74.yml @@ -21,12 +21,16 @@ src: reg.asc dest: /var/lib/lxc/{{ lxc_php_version }}/rootfs/etc/apt/trusted.gpg.d/reg.asc mode: "0644" + owner: root + group: root - name: copy packages.sury.org GPG Key copy: src: sury.gpg dest: /var/lib/lxc/{{ lxc_php_version }}/rootfs/etc/apt/trusted.gpg.d/sury.gpg mode: "0644" + owner: root + group: root - name: "{{ lxc_php_version }} - Update APT cache" lxc_container: diff --git a/metricbeat/tasks/main.yml b/metricbeat/tasks/main.yml index 14357f18..640a8902 100644 --- a/metricbeat/tasks/main.yml +++ b/metricbeat/tasks/main.yml @@ -23,6 +23,8 @@ dest: /etc/apt/trusted.gpg.d/elastic.asc force: yes mode: "0644" + owner: root + group: root tags: - metricbeat - packages diff --git a/mongodb/tasks/main_buster.yml b/mongodb/tasks/main_buster.yml index 9baf7c8a..2e62255a 100644 --- a/mongodb/tasks/main_buster.yml +++ b/mongodb/tasks/main_buster.yml @@ -12,6 +12,8 @@ dest: /etc/apt/trusted.gpg.d/mongodb-server-4.2.asc force: yes mode: "0644" + owner: root + group: root - name: enable APT sources list apt_repository: diff --git a/newrelic/tasks/sources.yml b/newrelic/tasks/sources.yml index 330f1ecf..08a3ae51 100644 --- a/newrelic/tasks/sources.yml +++ b/newrelic/tasks/sources.yml @@ -12,6 +12,8 @@ dest: /etc/apt/trusted.gpg.d/newrelic.asc force: yes mode: "0644" + owner: root + group: root - name: Install NewRelic repository apt_repository: diff --git a/nodejs/tasks/main.yml b/nodejs/tasks/main.yml index d0aa18b8..96fb2f93 100644 --- a/nodejs/tasks/main.yml +++ b/nodejs/tasks/main.yml @@ -23,6 +23,9 @@ copy: src: nodesource.asc dest: /etc/apt/trusted.gpg.d/nodesource.asc + mode: "0644" + owner: root + group: root tags: - system - packages diff --git a/nodejs/tasks/yarn.yml b/nodejs/tasks/yarn.yml index 05438e64..31bce9c6 100644 --- a/nodejs/tasks/yarn.yml +++ b/nodejs/tasks/yarn.yml @@ -15,6 +15,9 @@ copy: src: yarnpkg.asc dest: /etc/apt/trusted.gpg.d/yarnpkg.asc + mode: "0644" + owner: root + group: root tags: - system - packages diff --git a/percona/tasks/main.yml b/percona/tasks/main.yml index b60a88a8..dc182e10 100644 --- a/percona/tasks/main.yml +++ b/percona/tasks/main.yml @@ -15,6 +15,8 @@ dest: /etc/apt/trusted.gpg.d/percona.asc force: yes mode: "0644" + owner: root + group: root - name: Check if percona-release is installed shell: "set -o pipefail && dpkg -l percona-release 2> /dev/null | grep -q -E '^(i|h)i'" diff --git a/php/tasks/sury_pre.yml b/php/tasks/sury_pre.yml index 45d5d005..f5253b09 100644 --- a/php/tasks/sury_pre.yml +++ b/php/tasks/sury_pre.yml @@ -5,6 +5,8 @@ url: https://packages.sury.org/php/apt.gpg dest: /etc/apt/trusted.gpg.d/sury.gpg mode: "0644" + owner: root + group: root - name: Setup deb.sury.org repository - Install apt-transport-https apt: diff --git a/postgresql/tasks/pgdg-repo.yml b/postgresql/tasks/pgdg-repo.yml index 11d7893b..5ea7b65a 100644 --- a/postgresql/tasks/pgdg-repo.yml +++ b/postgresql/tasks/pgdg-repo.yml @@ -25,6 +25,8 @@ dest: /etc/apt/trusted.gpg.d/pgdg.asc force: yes mode: "0644" + owner: root + group: root - name: Update and upgrade apt packages for PGDG repository apt: From dbc06c1c59193b0e4e26ed3af82504ec015ce27c Mon Sep 17 00:00:00 2001 From: Alexis Ben Miloud--Josselin Date: Mon, 7 Jun 2021 10:51:03 +0200 Subject: [PATCH 56/86] Update rbenv-installer version See https://github.com/rbenv/rbenv-installer/commit/e017714f3e4eba6b18c3e5c041d169df832fbb2f --- rbenv/defaults/main.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rbenv/defaults/main.yml b/rbenv/defaults/main.yml index 0645f476..5d6c5e6b 100644 --- a/rbenv/defaults/main.yml +++ b/rbenv/defaults/main.yml @@ -7,7 +7,7 @@ rbenv_plugins: - { name: "rbenv-vars", repo: "https://github.com/rbenv/rbenv-vars.git", version: "v1.2.0" } - { name: "ruby-build", repo: "https://github.com/rbenv/ruby-build.git", version: "master" } - { name: "rbenv-default-gems", repo: "https://github.com/rbenv/rbenv-default-gems.git", version: "master" } - - { name: "rbenv-installer", repo: "https://github.com/rbenv/rbenv-installer.git", version: "master" } + - { name: "rbenv-installer", repo: "https://github.com/rbenv/rbenv-installer.git", version: "main" } - { name: "rbenv-update", repo: "https://github.com/rkh/rbenv-update.git", version: "master" } - { name: "rbenv-whatis", repo: "https://github.com/rkh/rbenv-whatis.git", version: "v1.0.0" } - { name: "rbenv-use", repo: "https://github.com/rkh/rbenv-use.git", version: "v1.0.0" } From 856d11aced6239c4e0a8d4d0d672999b5ffd8e25 Mon Sep 17 00:00:00 2001 From: Jeremy Lecour Date: Mon, 7 Jun 2021 13:03:18 +0200 Subject: [PATCH 57/86] nodejs: update apt cache before installing the package --- CHANGELOG.md | 1 + nodejs/tasks/main.yml | 1 + 2 files changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 217dc2bb..dea9f18a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -17,6 +17,7 @@ The **patch** part changes incrementally at each release. * evolinux-base: add default motd template * kvm-host: add migrate-vm script * mysql: variable to disable myadd script overwrite (default: True) +* nodejs: update apt cache before installing the package ### Changed diff --git a/nodejs/tasks/main.yml b/nodejs/tasks/main.yml index 96fb2f93..4f8c2849 100644 --- a/nodejs/tasks/main.yml +++ b/nodejs/tasks/main.yml @@ -46,6 +46,7 @@ apt: name: nodejs state: present + update_cache: yes tags: - packages - nodejs From f6dcce239baba52c6a2ecebcc658a45c9d640d43 Mon Sep 17 00:00:00 2001 From: Jeremy Lecour Date: Mon, 7 Jun 2021 13:04:12 +0200 Subject: [PATCH 58/86] certbot move hooks --- certbot/files/hooks/{ => deploy}/apache.sh | 0 certbot/files/hooks/{ => deploy}/dovecot.sh | 0 certbot/files/hooks/{ => deploy}/haproxy.sh | 0 certbot/files/hooks/{ => deploy}/nginx.sh | 0 certbot/files/hooks/{ => deploy}/postfix.sh | 0 certbot/files/hooks/{ => deploy}/sync_remote.sh | 0 certbot/files/hooks/{ => deploy}/z-commit-etc.sh | 0 certbot/tasks/main.yml | 6 ++++-- 8 files changed, 4 insertions(+), 2 deletions(-) rename certbot/files/hooks/{ => deploy}/apache.sh (100%) rename certbot/files/hooks/{ => deploy}/dovecot.sh (100%) rename certbot/files/hooks/{ => deploy}/haproxy.sh (100%) rename certbot/files/hooks/{ => deploy}/nginx.sh (100%) rename certbot/files/hooks/{ => deploy}/postfix.sh (100%) rename certbot/files/hooks/{ => deploy}/sync_remote.sh (100%) rename certbot/files/hooks/{ => deploy}/z-commit-etc.sh (100%) diff --git a/certbot/files/hooks/apache.sh b/certbot/files/hooks/deploy/apache.sh similarity index 100% rename from certbot/files/hooks/apache.sh rename to certbot/files/hooks/deploy/apache.sh diff --git a/certbot/files/hooks/dovecot.sh b/certbot/files/hooks/deploy/dovecot.sh similarity index 100% rename from certbot/files/hooks/dovecot.sh rename to certbot/files/hooks/deploy/dovecot.sh diff --git a/certbot/files/hooks/haproxy.sh b/certbot/files/hooks/deploy/haproxy.sh similarity index 100% rename from certbot/files/hooks/haproxy.sh rename to certbot/files/hooks/deploy/haproxy.sh diff --git a/certbot/files/hooks/nginx.sh b/certbot/files/hooks/deploy/nginx.sh similarity index 100% rename from certbot/files/hooks/nginx.sh rename to certbot/files/hooks/deploy/nginx.sh diff --git a/certbot/files/hooks/postfix.sh b/certbot/files/hooks/deploy/postfix.sh similarity index 100% rename from certbot/files/hooks/postfix.sh rename to certbot/files/hooks/deploy/postfix.sh diff --git a/certbot/files/hooks/sync_remote.sh b/certbot/files/hooks/deploy/sync_remote.sh similarity index 100% rename from certbot/files/hooks/sync_remote.sh rename to certbot/files/hooks/deploy/sync_remote.sh diff --git a/certbot/files/hooks/z-commit-etc.sh b/certbot/files/hooks/deploy/z-commit-etc.sh similarity index 100% rename from certbot/files/hooks/z-commit-etc.sh rename to certbot/files/hooks/deploy/z-commit-etc.sh diff --git a/certbot/tasks/main.yml b/certbot/tasks/main.yml index 1ab9c1c6..e280875c 100644 --- a/certbot/tasks/main.yml +++ b/certbot/tasks/main.yml @@ -23,7 +23,7 @@ - name: Deploy hooks are present copy: - src: hooks/ + src: hooks/deploy/ dest: /etc/letsencrypt/renewal-hooks/deploy/ mode: "0700" owner: root @@ -36,11 +36,13 @@ line: "servers=\"{{ certbot_hooks_sync_remote_servers | join(' ') }}\"" create: yes -- name: Move commit-etc.sh to z-commit-etc.sh if present +# begining of backward compatibility tasks +- name: Move deploy/commit-etc.sh to deploy/z-commit-etc.sh if present command: "mv /etc/letsencrypt/renewal-hooks/deploy/commit-etc.sh /etc/letsencrypt/renewal-hooks/deploy/z-commit-etc.sh" args: removes: /etc/letsencrypt/renewal-hooks/deploy/commit-etc.sh creates: /etc/letsencrypt/renewal-hooks/deploy/z-commit-etc.sh +# end of backward compatibility tasks - name: "certbot lock is ignored by Git" lineinfile: From ca40fad18656bd4ed615ad75f951df87af258463 Mon Sep 17 00:00:00 2001 From: Jeremy Lecour Date: Tue, 8 Jun 2021 11:19:26 +0200 Subject: [PATCH 59/86] nodejs: change GPG key name --- CHANGELOG.md | 1 + nodejs/files/{yarnpkg.asc => yarn.asc} | 0 nodejs/tasks/yarn.yml | 12 ++++++------ 3 files changed, 7 insertions(+), 6 deletions(-) rename nodejs/files/{yarnpkg.asc => yarn.asc} (100%) diff --git a/CHANGELOG.md b/CHANGELOG.md index dea9f18a..23f3ed03 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -26,6 +26,7 @@ The **patch** part changes incrementally at each release. * apt: store keys in /etc/apt/trusted.gpg.d in ascii format * certbot: sync_remote.sh is configurable * evolinux-base: copy GPG key instead of using apt-key +* nodejs: change GPG key name * ntpd: Add leapfile configuration setting to ntpd on debian 10+ * packweb-apache: install phpMyAdmin from buster-backports * spamassassin: change dependency on evomaintenance diff --git a/nodejs/files/yarnpkg.asc b/nodejs/files/yarn.asc similarity index 100% rename from nodejs/files/yarnpkg.asc rename to nodejs/files/yarn.asc diff --git a/nodejs/tasks/yarn.yml b/nodejs/tasks/yarn.yml index 31bce9c6..44306d42 100644 --- a/nodejs/tasks/yarn.yml +++ b/nodejs/tasks/yarn.yml @@ -1,6 +1,6 @@ --- -- name: NodeJS embedded GPG key is absent +- name: Yarn embedded GPG key is absent apt_key: id: "86E50310" keyring: /etc/apt/trusted.gpg @@ -11,10 +11,10 @@ - nodejs - yarn -- name: NodeJS GPG key is installed +- name: Yarn GPG key is installed copy: - src: yarnpkg.asc - dest: /etc/apt/trusted.gpg.d/yarnpkg.asc + src: yarn.asc + dest: /etc/apt/trusted.gpg.d/yarn.asc mode: "0644" owner: root group: root @@ -24,7 +24,7 @@ - nodejs - yarn -- name: yarn sources list is available +- name: Yarn sources list is available apt_repository: repo: "deb https://dl.yarnpkg.com/debian/ stable main" filename: yarn @@ -36,7 +36,7 @@ - nodejs - yarn -- name: yarn is installed +- name: Yarn is installed apt: name: yarn state: present From e75eeb8c3fa6ed1dcb3f584f3408eb3f8e24b5e0 Mon Sep 17 00:00:00 2001 From: Eric Morino Date: Tue, 8 Jun 2021 15:54:25 +0200 Subject: [PATCH 60/86] Changement version nexcloud par defaut + modif droit home utilisateur --- webapps/nextcloud/defaults/main.yml | 2 +- webapps/nextcloud/tasks/user.yml | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/webapps/nextcloud/defaults/main.yml b/webapps/nextcloud/defaults/main.yml index cb8b70a0..3c1bf40a 100644 --- a/webapps/nextcloud/defaults/main.yml +++ b/webapps/nextcloud/defaults/main.yml @@ -1,6 +1,6 @@ --- nextcloud_webserver: 'nginx' -nextcloud_version: "20.0.0" +nextcloud_version: "21.0.0" nextcloud_archive_name: "nextcloud-{{ nextcloud_version }}.tar.bz2" nextcloud_releases_baseurl: "https://download.nextcloud.com/server/releases/" diff --git a/webapps/nextcloud/tasks/user.yml b/webapps/nextcloud/tasks/user.yml index dd1d7cc5..dd778f87 100644 --- a/webapps/nextcloud/tasks/user.yml +++ b/webapps/nextcloud/tasks/user.yml @@ -14,6 +14,7 @@ shell: '/bin/bash' createhome: True state: present + mode: "0755" tags: - nextcloud From 3d715bae35887f97383daad57c4a3c71fbe04342 Mon Sep 17 00:00:00 2001 From: Jeremy Lecour Date: Thu, 10 Jun 2021 11:09:44 +0200 Subject: [PATCH 61/86] kvm-host: replace the "kvm-tools" package with scripts deployed by Ansible --- CHANGELOG.md | 1 + kvm-host/defaults/main.yml | 1 + kvm-host/files/add-vm.sh | 221 ++++++++++++++++++++++++++++++++++++ kvm-host/files/kvmstats.sh | 94 +++++++++++++++ kvm-host/tasks/munin.yml | 35 +++++- kvm-host/tasks/packages.yml | 2 +- kvm-host/tasks/ssh.yml | 2 +- kvm-host/tasks/tools.yml | 49 +++++++- 8 files changed, 394 insertions(+), 11 deletions(-) create mode 100755 kvm-host/files/add-vm.sh create mode 100755 kvm-host/files/kvmstats.sh diff --git a/CHANGELOG.md b/CHANGELOG.md index 23f3ed03..710a4093 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -26,6 +26,7 @@ The **patch** part changes incrementally at each release. * apt: store keys in /etc/apt/trusted.gpg.d in ascii format * certbot: sync_remote.sh is configurable * evolinux-base: copy GPG key instead of using apt-key +* kvm-host: replace the "kvm-tools" package with scripts deployed by Ansible * nodejs: change GPG key name * ntpd: Add leapfile configuration setting to ntpd on debian 10+ * packweb-apache: install phpMyAdmin from buster-backports diff --git a/kvm-host/defaults/main.yml b/kvm-host/defaults/main.yml index bb97c0f9..bec20a12 100644 --- a/kvm-host/defaults/main.yml +++ b/kvm-host/defaults/main.yml @@ -1,3 +1,4 @@ --- kvm_custom_libvirt_images_path: '' kvm_install_drbd: True +kvm_scripts_dir: /usr/local/sbin \ No newline at end of file diff --git a/kvm-host/files/add-vm.sh b/kvm-host/files/add-vm.sh new file mode 100755 index 00000000..3186db43 --- /dev/null +++ b/kvm-host/files/add-vm.sh @@ -0,0 +1,221 @@ +#!/bin/bash +# Add-VM script to add a VM on evoKVM. +# _ ____ ____ __ ____ __ +# / \ | _ \| _ \ \ \ / / \/ | +# / _ \ | | | | | | |____\ \ / /| |\/| | +# / ___ \| |_| | |_| |_____\ V / | | | | +# /_/ \_\____/|____/ \_/ |_| |_| +# +# Need packages: dialog +# Bash strict mode +set -euo pipefail + +dryRun() { + + if ($doDryRun); then + echo -e "\e[34mDoing:" $* "\e[39m" + else + echo -e "\e[34mDoing:" $* "\e[39m" + $* + fi +} + +critical() { + echo -ne "\e[31m${1}\e[39m\n" && exit 1 +} + +warn() { + + echo -ne "\e[33m${1}\e[39m\n" +} + +[ -f "/etc/evolinux/add-vm.cnf" ] && . /etc/evolinux/add-vm.cnf +masterKVMIP="${masterKVMIP:-127.0.0.1}" +slaveKVMIP="${slaveKVMIP:-}" +disks="${disks:-}" +[ -n "${disks}" ] || disks=("ssd" "hdd") +bridgeName="${bridgeName:-br0}" +doDryRun=${doDryRun:-false} +isoImagePath="${isoImagePath:-}" + +export DIALOGOUT=$(mktemp --tmpdir=/tmp addvm.XXX) +# TODO: How to replace _ with a space?? +export DIALOG="$(which dialog) --backtitle Add-VM_Press_F1_for_help" +export DIALOGRC=.dialogrc +export HELPFILE=$(mktemp --tmpdir=/tmp addvm.XXX) +tmpResFile=$(mktemp --tmpdir=/tmp addvm.XXX) +xmlVM=$(mktemp --tmpdir=/tmp addvm.XXX) +masterKVM="$(hostname -s)" +slaveKVM="$(ssh $slaveKVMIP hostname -s)" + +# Exit & Cleanup function. +clean() { + + echo -e "\nBye! Cleaning..." + [ -f $DIALOGOUT ] && rm $DIALOGOUT + [ -f $HELPFILE ] && rm $HELPFILE +# [ -f $tmpResFile ] && rm $tmpResFile +# [ -f $xmlVM ] && rm $xmlVM + exit +} +trap clean EXIT SIGINT + +$DIALOG --hfile $HELPFILE --title "KVM Config" --form "Set the right config. "\ +"If you do not want a type of disk, type none." 0 0 0 \ + "vCPU" 1 1 "2" 1 10 20 0 \ + "memory" 2 1 "4G" 2 10 20 0 \ + "volroot" 3 1 "${disks[0]}-20G" 3 10 20 0 \ + "volhome" 4 1 "${disks[1]}-40G" 4 10 20 0 \ + "vmName" 5 1 "" 5 10 20 0 \ + 2>$DIALOGOUT +vCPU=$(sed 1'q;d' $DIALOGOUT) +memory=$(sed 2'q;d' $DIALOGOUT|tr -d 'G') +memory=$(($memory * 1024)) +volroot=$(sed 3'q;d' $DIALOGOUT) +volhome=$(sed 4'q;d' $DIALOGOUT) +vmName=$(sed 5'q;d' $DIALOGOUT) + +[ -z "$vmName" ] && critical "You need a VM Name!!" + +$DIALOG --title "Continue?" --clear "$@" \ + --yesno "Will create a VM named $vmName on $masterKVM with $vCPU vCPU, "\ +"$memory memory, $volroot for / (and /usr, ...) and $volhome for /home." 10 80 +if [[ $? -ne 0 ]]; then + exit 1 +fi + +if ! [[ "$volroot" =~ ([^-]+)-([0-9]+G) ]]; then + critical "No volume for root device (/dev/vda)?!!" +else + volrootDisk="${BASH_REMATCH[1]}" + volrootSize="${BASH_REMATCH[2]}" + [[ " ${disks[*]} " == *"$volrootDisk"* ]] || critical "Unknow disk $volrootDisk !" + dryRun lvcreate -L$volrootSize -n${vmName}_root $volrootDisk + dryRun ssh $slaveKVMIP lvcreate -L$volrootSize -n${vmName}_root $volrootDisk +fi + +if ! [[ "$volhome" =~ ([^-]+)-([0-9]+G) ]]; then + warn "No volume for home device (/dev/vdb)... Okay, not doing it!" + volhomeDisk="none" +else + volhomeDisk="${BASH_REMATCH[1]}" + volhomeSize="${BASH_REMATCH[2]}" + [[ " ${disks[*]} " == *"$volhomeDisk"* ]] || critical "Unknow disk $volhomeDisk !" + dryRun lvcreate -L$volhomeSize -n${vmName}_home $volhomeDisk + dryRun ssh $slaveKVMIP lvcreate -L$volhomeSize -n${vmName}_home $volhomeDisk +fi + +if [[ -f "/etc/drbd.d/${vmName}.res" ]]; then + warn "The DRBD resource file ${vmName}.res is already present! Continue? [y/N]" + read + if ! [[ "$REPLY" =~ (Y|y) ]]; then + exit 1 + fi +fi + +# Generates drbd resource file. + +if [ $(ls /etc/drbd.d/|wc -l) -gt 1 ]; then + lastdrbdPort=$(grep -hEo ':[0-9]{4}' /etc/drbd.d/*.res | sort | uniq | tail -1 | sed 's/://') + drbdPort=$((lastdrbdPort+1)) + lastMinor=$(grep -hEo 'minor [0-9]{1,}' /etc/drbd.d/*.res | sed 's/minor //' | sort -n | tail -1) + minorvol0=$((lastMinor+1)) + minorvol1=$((lastMinor+2)) +else + drbdPort=7900 + minorvol0=0 + minorvol1=1 +fi + +cat << EOT > $tmpResFile +resource "${vmName}" { + net { + cram-hmac-alg "sha1"; + shared-secret "$(apg -n 1 -m 16 -M lcN)"; + # Si pas de lien dedié 10G, passer en protocol A + # Et desactiver allow-two-primaries; + protocol C; + allow-two-primaries; + # Tuning perf. + max-buffers 8000; + max-epoch-size 8000; + sndbuf-size 0; + } + # A utiliser si RAID HW avec cache + batterie + disk { + disk-barrier no; + disk-flushes no; + } + volume 0 { + device minor ${minorvol0}; + disk /dev/${volrootDisk}/${vmName}_root; + meta-disk internal; + } +EOT +if [[ "$volhomeDisk" != "none" ]]; then + cat << EOT >> $tmpResFile + volume 1 { + device minor ${minorvol1}; + disk /dev/${volhomeDisk}/${vmName}_home; + meta-disk internal; + } +EOT +fi +cat << EOT >> $tmpResFile + on $masterKVM { + address ${masterKVMIP}:${drbdPort}; + } + on $slaveKVM { + address ${slaveKVMIP}:${drbdPort}; + } +} +EOT + +# Create/Activate the new drbd resources. +drbdadm="$(command -v drbdadm)" +($doDryRun) && drbdadm="${drbdadm} --dry-run" + +($doDryRun) && trap "rm /etc/drbd.d/${vmName}.res && ssh ${slaveKVMIP} rm /etc/drbd.d/${vmName}.res" 0 +install -m 600 $tmpResFile /etc/drbd.d/${vmName}.res +scp /etc/drbd.d/${vmName}.res ${slaveKVMIP}:/etc/drbd.d/ +${drbdadm} create-md "$vmName" +ssh $slaveKVMIP ${drbdadm} create-md "$vmName" +${drbdadm} adjust "$vmName" +ssh $slaveKVMIP ${drbdadm} adjust "$vmName" +${drbdadm} -- --overwrite-data-of-peer primary "$vmName" + +if !($doDryRun); then + sleep 5 && drbd-overview | tail -4 + + drbdDiskPath="/dev/drbd/by-res/${vmName}/0" + if ! [[ -b "$drbdDiskPath" ]]; then + warn "$drbdDiskPath not found! Continue? [y/N]" + read + if ! [[ "$REPLY" =~ (Y|y) ]]; then + exit 1 + fi + fi +fi + +virtHome="" +[ "$volhomeDisk" != "none" ] && virtHome="--disk path=/dev/drbd/by-disk/${volhomeDisk}/${vmName}_home,bus=virtio,io=threads,cache=none,format=raw" +bootMode="--pxe" +[ -f "$isoImagePath" ] && bootMode="--cdrom=$isoImagePath" + +dryRun virt-install --connect=qemu:///system \ + --name=${vmName} \ + --cpu mode=host-passthrough --vcpus=${vCPU} \ + --memory=${memory} \ + --disk path=/dev/drbd/by-disk/${volrootDisk}/${vmName}_root,bus=virtio,io=threads,cache=none,format=raw \ + $virtHome \ + $bootMode \ + --network=bridge:${bridgeName},model=virtio \ + --noautoconsole --graphics vnc,listen=127.0.0.1,keymap=fr \ + --rng /dev/random \ + --os-variant=none + +if [ -x /usr/share/scripts/evomaintenance.sh ]; then + ($doDryRun) || echo "Install VM ${vmName} (add-vm.sh)" | /usr/share/scripts/evomaintenance.sh +fi + +echo -e "\e[32mDone! Now you can install your VM with virt-manager.\e[39m" diff --git a/kvm-host/files/kvmstats.sh b/kvm-host/files/kvmstats.sh new file mode 100755 index 00000000..588ef863 --- /dev/null +++ b/kvm-host/files/kvmstats.sh @@ -0,0 +1,94 @@ +#!/bin/sh + +# NOTE: kvmstats relies on the hxselect(1) command to parse virsh' xml +# files. On Debian, this command is provided by the 'html-xml-utils' +# package. + +set -e -u + +usage () { + echo 'usage: kvmstats.sh [-a] [-u K|M|G]' + exit 1 +} + +for DEP in hxselect lvs tempfile bc +do + if [ -z "$(which $DEP)" ] + then + echo "kvmstats.sh: $DEP not found in \$PATH" 1>&2 + exit 1 + fi +done + +POW=$(echo 1024 ^ 3 | bc) +while [ $# -ne 0 ] && echo "$1" | grep -q '^-[[:alnum:]]' +do + case $1 in + '-u') + case $2 in + 'K') + POW=$(echo 1024 ^ 1 | bc) + ;; + 'M') + POW=$(echo 1024 ^ 2 | bc) + ;; + 'G') + POW=$(echo 1024 ^ 3 | bc) + ;; + *) + usage + esac + ;; + '-a') + SHOW_AVAIL=y + ;; + *) + usage + esac + shift +done + +# since libvirt seems to store memoy in KiB, POW must be lowered by 1 +POW=$((POW / 1024)) + +TMPFILE=$(tempfile -s kvmstats) +LVSOUT=$(tempfile -s kvmstats) + +lvs --units b --nosuffix >"$LVSOUT" + +for VM in $(virsh list --all --name) +do + VCPU=$(hxselect -c 'domain vcpu' "$TMPFILE" + +( + echo vm vcpu ram disk running + cat "$TMPFILE" + awk '/yes$/ { vcpu += $2; ram += $3; disk += $4; running++ } END { print "TOTAL(running)", vcpu, ram, disk, running }' <"$TMPFILE" + if [ $SHOW_AVAIL ] + then + AV_CPU=$(awk '/^processor/ { cpu++ } END { print cpu }' /proc/cpuinfo) + AV_MEM=$(awk '/^MemTotal:/ { print int($2 / 1024 ^ 2) }' /proc/meminfo) + echo AVAILABLE "$AV_CPU" "$AV_MEM" + fi +) | column -t + +rm "$TMPFILE" "$LVSOUT" diff --git a/kvm-host/tasks/munin.yml b/kvm-host/tasks/munin.yml index dc130238..400dcd49 100644 --- a/kvm-host/tasks/munin.yml +++ b/kvm-host/tasks/munin.yml @@ -1,14 +1,41 @@ --- +- include_role: + name: remount-usr + +- name: Create local munin directory + file: + name: /usr/local/share/munin/ + state: directory + mode: "0755" + +- name: Create plugin directory + file: + name: /usr/local/share/munin/plugins/ + state: directory + mode: "0755" + - name: Get Munin plugins get_url: url: "https://raw.githubusercontent.com/munin-monitoring/contrib/master/plugins/libvirt/{{ item }}" - dest: "/etc/munin/plugins/" + dest: "/usr/local/share/munin/plugins/" mode: "0755" + force: no loop: - - kvm_cpu - - kvm_io - - kvm_mem + - kvm_cpu + - kvm_io + - kvm_mem + notify: restart munin-node + +- name: Enable redis munin plugin + file: + src: "/usr/local/share/munin/plugins/{{item}}" + dest: "/etc/munin/plugins/{{item}}" + state: link + loop: + - kvm_cpu + - kvm_io + - kvm_mem notify: restart munin-node - name: Copy Munin plugins conf diff --git a/kvm-host/tasks/packages.yml b/kvm-host/tasks/packages.yml index 99790e84..d2a540e5 100644 --- a/kvm-host/tasks/packages.yml +++ b/kvm-host/tasks/packages.yml @@ -9,5 +9,5 @@ - virtinst - libvirt-daemon-system - libvirt-clients - - kvm-tools - vlan + state: present diff --git a/kvm-host/tasks/ssh.yml b/kvm-host/tasks/ssh.yml index 1b0f7915..fe71c287 100644 --- a/kvm-host/tasks/ssh.yml +++ b/kvm-host/tasks/ssh.yml @@ -44,7 +44,7 @@ state: present special_time: "daily" user: root - job: "virsh list | ssh {{ hostvars[item]['ansible_hostname'] }} 'cat >/root/libvirt-{{ inventory_hostname }}/virsh-list.txt'" + job: "virsh list --all | ssh {{ hostvars[item]['ansible_hostname'] }} 'cat >/root/libvirt-{{ inventory_hostname }}/virsh-list.txt'" loop: - "{{ groups['hypervisors'] }}" when: item != inventory_hostname diff --git a/kvm-host/tasks/tools.yml b/kvm-host/tasks/tools.yml index b3a4be0f..56caa6ea 100644 --- a/kvm-host/tasks/tools.yml +++ b/kvm-host/tasks/tools.yml @@ -1,13 +1,52 @@ --- +- name: remove old package + apt: + name: kvm-tools + purge: yes + state: absent + - include_role: name: remount-usr + when: kvm_scripts_dir is search ("/usr") -- name: migrate-vm scripts is present +- name: add-vm script is present copy: - src: migrate-vm.sh - dest: /usr/share/scripts/migrate-vm - mode: "0755" + src: add-vm.sh + dest: "{{ kvm_scripts_dir }}/add-vm" + mode: "0700" owner: root group: root - force: yes \ No newline at end of file + force: yes + +- name: migrate-vm script is present + copy: + src: migrate-vm.sh + dest: "{{ kvm_scripts_dir }}/migrate-vm" + mode: "0700" + owner: root + group: root + force: yes + +- name: kvmstats script is present + copy: + src: kvmstats.sh + dest: "{{ kvm_scripts_dir }}/kvmstats" + mode: "0700" + owner: root + group: root + force: yes + +# backward compatibility + +- name: remove old migrate-vm script + file: + path: /usr/share/scripts/migrate-vm + state: absent + when: "'/usr/share/scripts' not in kvm_scripts_dir" + +- name: remove old kvmstats script + file: + path: /usr/share/scripts/kvmstats + state: absent + when: "'/usr/share/scripts' not in kvm_scripts_dir" \ No newline at end of file From 4d7e6fd2710ec252bd38b63ee678716c904818cd Mon Sep 17 00:00:00 2001 From: Jeremy Lecour Date: Thu, 10 Jun 2021 11:24:16 +0200 Subject: [PATCH 62/86] kvm-host: update kvmstats and add-vm --- kvm-host/files/add-vm.sh | 5 +- kvm-host/files/kvmstats.cron.j2 | 4 + kvm-host/files/kvmstats.sh | 136 ++++++++++++++++---------------- kvm-host/tasks/tools.yml | 15 ++++ 4 files changed, 92 insertions(+), 68 deletions(-) create mode 100644 kvm-host/files/kvmstats.cron.j2 diff --git a/kvm-host/files/add-vm.sh b/kvm-host/files/add-vm.sh index 3186db43..49ca6f46 100755 --- a/kvm-host/files/add-vm.sh +++ b/kvm-host/files/add-vm.sh @@ -37,6 +37,8 @@ disks="${disks:-}" bridgeName="${bridgeName:-br0}" doDryRun=${doDryRun:-false} isoImagePath="${isoImagePath:-}" +debianVersion="${debianAuto:-stable}" +preseedURL="${preseedURL:-}" export DIALOGOUT=$(mktemp --tmpdir=/tmp addvm.XXX) # TODO: How to replace _ with a space?? @@ -184,7 +186,7 @@ ${drbdadm} adjust "$vmName" ssh $slaveKVMIP ${drbdadm} adjust "$vmName" ${drbdadm} -- --overwrite-data-of-peer primary "$vmName" -if !($doDryRun); then +if ! ($doDryRun); then sleep 5 && drbd-overview | tail -4 drbdDiskPath="/dev/drbd/by-res/${vmName}/0" @@ -200,6 +202,7 @@ fi virtHome="" [ "$volhomeDisk" != "none" ] && virtHome="--disk path=/dev/drbd/by-disk/${volhomeDisk}/${vmName}_home,bus=virtio,io=threads,cache=none,format=raw" bootMode="--pxe" +[ -n "${preseedURL}" ] && bootMode="--location https://deb.debian.org/debian/dists/${debianVersion}/main/installer-amd64/ --extra-args \"auto=true priority=critical url=${preseedURL} hostname=${vmName}\"" [ -f "$isoImagePath" ] && bootMode="--cdrom=$isoImagePath" dryRun virt-install --connect=qemu:///system \ diff --git a/kvm-host/files/kvmstats.cron.j2 b/kvm-host/files/kvmstats.cron.j2 new file mode 100644 index 00000000..d34d3d68 --- /dev/null +++ b/kvm-host/files/kvmstats.cron.j2 @@ -0,0 +1,4 @@ +#!/bin/sh + +{{ kvm_scripts_dir }}/kvmstats -a -o html > /var/www/kvmstats.html +/bin/chmod go+r /var/www/kvmstats.html \ No newline at end of file diff --git a/kvm-host/files/kvmstats.sh b/kvm-host/files/kvmstats.sh index 588ef863..cf2416b9 100755 --- a/kvm-host/files/kvmstats.sh +++ b/kvm-host/files/kvmstats.sh @@ -1,46 +1,54 @@ #!/bin/sh -# NOTE: kvmstats relies on the hxselect(1) command to parse virsh' xml -# files. On Debian, this command is provided by the 'html-xml-utils' -# package. - -set -e -u - -usage () { - echo 'usage: kvmstats.sh [-a] [-u K|M|G]' +error () { + echo "$0": "$@" >&2 exit 1 } -for DEP in hxselect lvs tempfile bc +usage () { + echo 'usage:' "$0" '[-a] [-u k|m|g] [-o human|html|csv]' >&2 + exit 1 +} + +for DEP in bc virsh do - if [ -z "$(which $DEP)" ] - then - echo "kvmstats.sh: $DEP not found in \$PATH" 1>&2 - exit 1 - fi + command -v "$DEP" > /dev/null || error "$DEP" 'command not found' done -POW=$(echo 1024 ^ 3 | bc) -while [ $# -ne 0 ] && echo "$1" | grep -q '^-[[:alnum:]]' +POW="$(echo '1024 ^ 3' | bc)" +FMT='human' +while [ "$#" -ne 0 ] do - case $1 in + case "$1" in + '-a') + SHOW_AVAIL='y' + ;; + '-o') + case "$2" in + 'csv'|'html'|'human') + FMT="$2" + ;; + *) + usage + ;; + esac + shift + ;; '-u') - case $2 in - 'K') - POW=$(echo 1024 ^ 1 | bc) + case "$2" in + 'k') + POW="$(echo '1024 ^ 1' | bc)" ;; - 'M') - POW=$(echo 1024 ^ 2 | bc) + 'm') + POW="$(echo '1024 ^ 2' | bc)" ;; - 'G') - POW=$(echo 1024 ^ 3 | bc) + 'g') + POW="$(echo '1024 ^ 3' | bc)" ;; *) usage esac - ;; - '-a') - SHOW_AVAIL=y + shift ;; *) usage @@ -48,47 +56,41 @@ do shift done -# since libvirt seems to store memoy in KiB, POW must be lowered by 1 -POW=$((POW / 1024)) - -TMPFILE=$(tempfile -s kvmstats) -LVSOUT=$(tempfile -s kvmstats) - -lvs --units b --nosuffix >"$LVSOUT" - -for VM in $(virsh list --all --name) +for VM in $(virsh list --name --all) do - VCPU=$(hxselect -c 'domain vcpu' /dev/null | awk 'BEGIN{ret=1}$1~/^actual$/{print $2 / '$((POW / 1024))';ret=0}END{exit ret}' || + virsh dumpxml "$VM" | awk -F'[<>]' '$2~/^memory unit/{print $3/'$((POW / 1024))'}' + + # disk + for BLK in $(virsh domblklist "$VM" | sed '1,2d;/-$/d;/^$/d' | awk '{print $1}') do - case $DEV in - /dev/drbd/*) - DISK=$(awk "/$VM/ { ans += \$NF } END { print ans / 1024 ^ 3 }" <"$LVSOUT") - break # avoid to compute DISK for each disk - ;; - *.qcow2) - DISK=$(du -sBG "$DEV" | awk '{ print substr($1, 0, length($1) - 1) }') - ;; - *) - DISK=0 - esac - done - RUNNING=$(virsh domstate "$VM" | grep -q '^running$' && echo yes || echo no) - echo "$VM" "$VCPU" "$RAM" "$DISK" "$RUNNING" -done >"$TMPFILE" + virsh domblkinfo "$VM" "$BLK" 2> /dev/null + done | awk '/Physical:/ { size += $2 } END { print int(size / '${POW}') }' -( + # state + virsh domstate "$VM" | grep -q '^running$' && echo yes || echo no +done | xargs -n5 | { echo vm vcpu ram disk running - cat "$TMPFILE" - awk '/yes$/ { vcpu += $2; ram += $3; disk += $4; running++ } END { print "TOTAL(running)", vcpu, ram, disk, running }' <"$TMPFILE" - if [ $SHOW_AVAIL ] - then - AV_CPU=$(awk '/^processor/ { cpu++ } END { print cpu }' /proc/cpuinfo) - AV_MEM=$(awk '/^MemTotal:/ { print int($2 / 1024 ^ 2) }' /proc/meminfo) - echo AVAILABLE "$AV_CPU" "$AV_MEM" - fi -) | column -t - -rm "$TMPFILE" "$LVSOUT" + awk '{ print } /yes$/ { vcpu += $2; ram += $3; disk += $4; running++ } END { print "TOTAL(running)", vcpu, ram, disk, running }' + test "$SHOW_AVAIL" && { + nproc + awk '/^MemTotal:/ { print int($2 / '$((POW / 1024))' ) }' /proc/meminfo + } | xargs -r printf 'AVAILABLE %s %s %s %s\n' +} | case "$FMT" in +'human') + column -t + ;; +'html') + awk 'BEGIN{print "\n"}{printf "";for(i=1;i<=NF;i++)printf "", $i;print ""}END{print "
%s
\n"}' + ;; +'csv') + tr ' ' ',' + ;; +esac diff --git a/kvm-host/tasks/tools.yml b/kvm-host/tasks/tools.yml index 56caa6ea..83845a31 100644 --- a/kvm-host/tasks/tools.yml +++ b/kvm-host/tasks/tools.yml @@ -37,6 +37,21 @@ group: root force: yes +- name: kvmstats cron is present + template: + src: kvmstats.cron.j2 + dest: "/etc/cron.hourly/kvmstats" + mode: "0755" + owner: root + group: root + +- name: entry for kvmstats in web page is present + lineinfile: + dest: /var/www/index.html + insertbefore: '' + line: '
' + + # backward compatibility - name: remove old migrate-vm script From 7f3eebcfc6fe189ebac4030ec180fa8b0999cf5b Mon Sep 17 00:00:00 2001 From: Jeremy Lecour Date: Thu, 10 Jun 2021 16:18:12 +0200 Subject: [PATCH 63/86] kvm-host: move cron template into templates directory --- kvm-host/{files => templates}/kvmstats.cron.j2 | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename kvm-host/{files => templates}/kvmstats.cron.j2 (100%) diff --git a/kvm-host/files/kvmstats.cron.j2 b/kvm-host/templates/kvmstats.cron.j2 similarity index 100% rename from kvm-host/files/kvmstats.cron.j2 rename to kvm-host/templates/kvmstats.cron.j2 From 4e8c622cc0884956a748159d86cb56dae63cc927 Mon Sep 17 00:00:00 2001 From: Jeremy Lecour Date: Thu, 10 Jun 2021 16:30:17 +0200 Subject: [PATCH 64/86] kvm-host: force link for munin plugins --- kvm-host/tasks/munin.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/kvm-host/tasks/munin.yml b/kvm-host/tasks/munin.yml index 400dcd49..d0bf1b0a 100644 --- a/kvm-host/tasks/munin.yml +++ b/kvm-host/tasks/munin.yml @@ -32,6 +32,7 @@ src: "/usr/local/share/munin/plugins/{{item}}" dest: "/etc/munin/plugins/{{item}}" state: link + force: yes loop: - kvm_cpu - kvm_io From 5d7d62b2842d9ea75b6e80f19e93061ccceac352 Mon Sep 17 00:00:00 2001 From: Jeremy Lecour Date: Thu, 10 Jun 2021 16:30:22 +0200 Subject: [PATCH 65/86] whitespaces --- kvm-host/templates/kvmstats.cron.j2 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kvm-host/templates/kvmstats.cron.j2 b/kvm-host/templates/kvmstats.cron.j2 index d34d3d68..947c8dbf 100644 --- a/kvm-host/templates/kvmstats.cron.j2 +++ b/kvm-host/templates/kvmstats.cron.j2 @@ -1,4 +1,4 @@ #!/bin/sh {{ kvm_scripts_dir }}/kvmstats -a -o html > /var/www/kvmstats.html -/bin/chmod go+r /var/www/kvmstats.html \ No newline at end of file +/bin/chmod go+r /var/www/kvmstats.html From edfcbbad0ab058272b8355249bdc2bc48d2c1ef7 Mon Sep 17 00:00:00 2001 From: Jeremy Lecour Date: Thu, 10 Jun 2021 18:03:32 +0200 Subject: [PATCH 66/86] kvm-host: add-vm: split assignment --- kvm-host/files/add-vm.sh | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/kvm-host/files/add-vm.sh b/kvm-host/files/add-vm.sh index 49ca6f46..b929fb96 100755 --- a/kvm-host/files/add-vm.sh +++ b/kvm-host/files/add-vm.sh @@ -13,9 +13,9 @@ set -euo pipefail dryRun() { if ($doDryRun); then - echo -e "\e[34mDoing:" $* "\e[39m" + echo -e "\e[34mDoing:" "$*" "\e[39m" else - echo -e "\e[34mDoing:" $* "\e[39m" + echo -e "\e[34mDoing:" "$*" "\e[39m" $* fi } @@ -40,11 +40,15 @@ isoImagePath="${isoImagePath:-}" debianVersion="${debianAuto:-stable}" preseedURL="${preseedURL:-}" -export DIALOGOUT=$(mktemp --tmpdir=/tmp addvm.XXX) +DIALOGOUT=$(mktemp --tmpdir=/tmp addvm.XXX) +export DIALOGOUT # TODO: How to replace _ with a space?? -export DIALOG="$(which dialog) --backtitle Add-VM_Press_F1_for_help" -export DIALOGRC=.dialogrc -export HELPFILE=$(mktemp --tmpdir=/tmp addvm.XXX) +DIALOG="$(which dialog) --backtitle Add-VM_Press_F1_for_help" +export DIALOG +DIALOGRC=.dialogrc +export DIALOGRC +HELPFILE=$(mktemp --tmpdir=/tmp addvm.XXX) +export HELPFILE tmpResFile=$(mktemp --tmpdir=/tmp addvm.XXX) xmlVM=$(mktemp --tmpdir=/tmp addvm.XXX) masterKVM="$(hostname -s)" From 9d0bfec87eeef17e97c0ae071904631a07b788e1 Mon Sep 17 00:00:00 2001 From: Jeremy Lecour Date: Thu, 10 Jun 2021 21:22:38 +0200 Subject: [PATCH 67/86] =?UTF-8?q?kvm-host:=20add-vm:=20shellcheck=20(quote?= =?UTF-8?q?s,=20braces=E2=80=A6)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- kvm-host/files/add-vm.sh | 217 +++++++++++++++++++++++---------------- 1 file changed, 130 insertions(+), 87 deletions(-) diff --git a/kvm-host/files/add-vm.sh b/kvm-host/files/add-vm.sh index b929fb96..51ad1850 100755 --- a/kvm-host/files/add-vm.sh +++ b/kvm-host/files/add-vm.sh @@ -10,9 +10,13 @@ # Bash strict mode set -euo pipefail +isDryRun() { + test "${doDryRun}" = "true" +} + dryRun() { - if ($doDryRun); then + if isDryRun; then echo -e "\e[34mDoing:" "$*" "\e[39m" else echo -e "\e[34mDoing:" "$*" "\e[39m" @@ -29,6 +33,7 @@ warn() { echo -ne "\e[33m${1}\e[39m\n" } +# shellcheck disable=SC1091 [ -f "/etc/evolinux/add-vm.cnf" ] && . /etc/evolinux/add-vm.cnf masterKVMIP="${masterKVMIP:-127.0.0.1}" slaveKVMIP="${slaveKVMIP:-}" @@ -39,89 +44,102 @@ doDryRun=${doDryRun:-false} isoImagePath="${isoImagePath:-}" debianVersion="${debianAuto:-stable}" preseedURL="${preseedURL:-}" +defaultVCPU="${defaultVCPU:-"2"}" +defaultRAM="${defaultRAM:-"4G"}" +defaultRootSize="${defaultRootSize:-"20G"}" +defaultHomeSize="${defaultHomeSize:-"40G"}" DIALOGOUT=$(mktemp --tmpdir=/tmp addvm.XXX) export DIALOGOUT # TODO: How to replace _ with a space?? -DIALOG="$(which dialog) --backtitle Add-VM_Press_F1_for_help" +DIALOG="$(command -v dialog) --backtitle Add-VM_Press_F1_for_help" export DIALOG DIALOGRC=.dialogrc export DIALOGRC HELPFILE=$(mktemp --tmpdir=/tmp addvm.XXX) export HELPFILE tmpResFile=$(mktemp --tmpdir=/tmp addvm.XXX) -xmlVM=$(mktemp --tmpdir=/tmp addvm.XXX) masterKVM="$(hostname -s)" -slaveKVM="$(ssh $slaveKVMIP hostname -s)" +slaveKVM="$(ssh "${slaveKVMIP}" hostname -s)" # Exit & Cleanup function. clean() { - echo -e "\nBye! Cleaning..." - [ -f $DIALOGOUT ] && rm $DIALOGOUT - [ -f $HELPFILE ] && rm $HELPFILE -# [ -f $tmpResFile ] && rm $tmpResFile -# [ -f $xmlVM ] && rm $xmlVM + rm -f "${DIALOGOUT}" + rm -f "${HELPFILE}" exit } trap clean EXIT SIGINT -$DIALOG --hfile $HELPFILE --title "KVM Config" --form "Set the right config. "\ -"If you do not want a type of disk, type none." 0 0 0 \ - "vCPU" 1 1 "2" 1 10 20 0 \ - "memory" 2 1 "4G" 2 10 20 0 \ - "volroot" 3 1 "${disks[0]}-20G" 3 10 20 0 \ - "volhome" 4 1 "${disks[1]}-40G" 4 10 20 0 \ - "vmName" 5 1 "" 5 10 20 0 \ - 2>$DIALOGOUT -vCPU=$(sed 1'q;d' $DIALOGOUT) -memory=$(sed 2'q;d' $DIALOGOUT|tr -d 'G') -memory=$(($memory * 1024)) -volroot=$(sed 3'q;d' $DIALOGOUT) -volhome=$(sed 4'q;d' $DIALOGOUT) -vmName=$(sed 5'q;d' $DIALOGOUT) +${DIALOG} \ + --hfile "${HELPFILE}" \ + --title "KVM Config" \ + --form "Set the right config. If you do not want a type of disk, type none." 0 0 0 \ + "vCPU" 1 1 "${defaultVCPU}" 1 10 20 0 \ + "memory" 2 1 "${defaultRAM}" 2 10 20 0 \ + "volRoot" 3 1 "${disks[0]}-${defaultRootSize}" 3 10 20 0 \ + "volHome" 4 1 "${disks[1]}-${defaultHomeSize}" 4 10 20 0 \ + "vmName" 5 1 "" 5 10 20 0 \ + 2> "${DIALOGOUT}" -[ -z "$vmName" ] && critical "You need a VM Name!!" +vCPU=$(sed 1'q;d' "${DIALOGOUT}") +memory=$(sed 2'q;d' "${DIALOGOUT}" | tr -d 'G') +memory=$((memory * 1024 )) +volRoot=$(sed 3'q;d' "${DIALOGOUT}") +volHome=$(sed 4'q;d' "${DIALOGOUT}") +vmName=$(sed 5'q;d' "${DIALOGOUT}") -$DIALOG --title "Continue?" --clear "$@" \ - --yesno "Will create a VM named $vmName on $masterKVM with $vCPU vCPU, "\ -"$memory memory, $volroot for / (and /usr, ...) and $volhome for /home." 10 80 -if [[ $? -ne 0 ]]; then +if [ -z "${vmName}" ]; then + critical "You need a VM Name!!" +fi + +${DIALOG} \ + --title "Continue?" \ + --clear "$@" \ + --yesno "Will create a VM named ${vmName} on ${masterKVM} with ${vCPU} vCPU, ${memory} memory, ${volRoot} for / (and /usr, ...) and ${volHome} for /home." 10 80 +dialog_rc=$? + +if [[ ${dialog_rc} -ne 0 ]]; then exit 1 fi -if ! [[ "$volroot" =~ ([^-]+)-([0-9]+G) ]]; then +if ! [[ "${volRoot}" =~ ([^-]+)-([0-9]+G) ]]; then critical "No volume for root device (/dev/vda)?!!" else - volrootDisk="${BASH_REMATCH[1]}" - volrootSize="${BASH_REMATCH[2]}" - [[ " ${disks[*]} " == *"$volrootDisk"* ]] || critical "Unknow disk $volrootDisk !" - dryRun lvcreate -L$volrootSize -n${vmName}_root $volrootDisk - dryRun ssh $slaveKVMIP lvcreate -L$volrootSize -n${vmName}_root $volrootDisk + volRootDisk="${BASH_REMATCH[1]}" + volRootSize="${BASH_REMATCH[2]}" + if [[ " ${disks[*]} " != *"${volRootDisk}"* ]]; then + critical "Unknow disk ${volRootDisk} !" + fi + dryRun lvcreate -L"${volRootSize}" -n"${vmName}_root" "${volRootDisk}" + dryRun ssh "${slaveKVMIP}" "lvcreate -L$volRootSize -n${vmName}_root ${volRootDisk}" fi -if ! [[ "$volhome" =~ ([^-]+)-([0-9]+G) ]]; then +if ! [[ "${volHome}" =~ ([^-]+)-([0-9]+G) ]]; then warn "No volume for home device (/dev/vdb)... Okay, not doing it!" - volhomeDisk="none" + volHomeDisk="none" else - volhomeDisk="${BASH_REMATCH[1]}" - volhomeSize="${BASH_REMATCH[2]}" - [[ " ${disks[*]} " == *"$volhomeDisk"* ]] || critical "Unknow disk $volhomeDisk !" - dryRun lvcreate -L$volhomeSize -n${vmName}_home $volhomeDisk - dryRun ssh $slaveKVMIP lvcreate -L$volhomeSize -n${vmName}_home $volhomeDisk + volHomeDisk="${BASH_REMATCH[1]}" + volHomeSize="${BASH_REMATCH[2]}" + if [[ " ${disks[*]} " != *"${volHomeDisk}"* ]]; then + critical "Unknow disk ${volHomeDisk} !" + fi + dryRun lvcreate -L"${volHomeSize}" -n"${vmName}_home" "${volHomeDisk}" + dryRun ssh "${slaveKVMIP}" "lvcreate -L$volHomeSize -n${vmName}_home ${volHomeDisk}" fi -if [[ -f "/etc/drbd.d/${vmName}.res" ]]; then +if [ -f "/etc/drbd.d/${vmName}.res" ]; then warn "The DRBD resource file ${vmName}.res is already present! Continue? [y/N]" - read - if ! [[ "$REPLY" =~ (Y|y) ]]; then + read -r + if ! [[ "${REPLY}" =~ (Y|y) ]]; then exit 1 fi fi # Generates drbd resource file. -if [ $(ls /etc/drbd.d/|wc -l) -gt 1 ]; then +# shellcheck disable=SC2012 +if [ "$(ls /etc/drbd.d/ | wc -l)" -gt 1 ]; then lastdrbdPort=$(grep -hEo ':[0-9]{4}' /etc/drbd.d/*.res | sort | uniq | tail -1 | sed 's/://') drbdPort=$((lastdrbdPort+1)) lastMinor=$(grep -hEo 'minor [0-9]{1,}' /etc/drbd.d/*.res | sed 's/minor //' | sort -n | tail -1) @@ -133,7 +151,7 @@ else minorvol1=1 fi -cat << EOT > $tmpResFile +cat << EOT > "${tmpResFile}" resource "${vmName}" { net { cram-hmac-alg "sha1"; @@ -154,24 +172,24 @@ resource "${vmName}" { } volume 0 { device minor ${minorvol0}; - disk /dev/${volrootDisk}/${vmName}_root; + disk /dev/${volRootDisk}/${vmName}_root; meta-disk internal; } EOT -if [[ "$volhomeDisk" != "none" ]]; then - cat << EOT >> $tmpResFile +if [[ "${volHomeDisk}" != "none" ]]; then + cat << EOT >> "${tmpResFile}" volume 1 { device minor ${minorvol1}; - disk /dev/${volhomeDisk}/${vmName}_home; + disk /dev/${volHomeDisk}/${vmName}_home; meta-disk internal; } EOT fi -cat << EOT >> $tmpResFile - on $masterKVM { +cat << EOT >> "${tmpResFile}" + on ${masterKVM} { address ${masterKVMIP}:${drbdPort}; } - on $slaveKVM { + on ${slaveKVM} { address ${slaveKVMIP}:${drbdPort}; } } @@ -179,50 +197,75 @@ EOT # Create/Activate the new drbd resources. drbdadm="$(command -v drbdadm)" -($doDryRun) && drbdadm="${drbdadm} --dry-run" +if isDryRun; then + drbdadm="${drbdadm} --dry-run" +fi -($doDryRun) && trap "rm /etc/drbd.d/${vmName}.res && ssh ${slaveKVMIP} rm /etc/drbd.d/${vmName}.res" 0 -install -m 600 $tmpResFile /etc/drbd.d/${vmName}.res -scp /etc/drbd.d/${vmName}.res ${slaveKVMIP}:/etc/drbd.d/ -${drbdadm} create-md "$vmName" -ssh $slaveKVMIP ${drbdadm} create-md "$vmName" -${drbdadm} adjust "$vmName" -ssh $slaveKVMIP ${drbdadm} adjust "$vmName" -${drbdadm} -- --overwrite-data-of-peer primary "$vmName" +if isDryRun; then + # shellcheck disable=SC2064 + trap "rm /etc/drbd.d/${vmName}.res && ssh ${slaveKVMIP} rm /etc/drbd.d/${vmName}.res" 0 +fi +install -m 600 "${tmpResFile}" "/etc/drbd.d/${vmName}.res" +scp "/etc/drbd.d/${vmName}.res" "${slaveKVMIP}:/etc/drbd.d/" +${drbdadm} create-md "${vmName}" +# shellcheck disable=SC2029 +ssh "${slaveKVMIP}" "${drbdadm} create-md ${vmName}" +${drbdadm} adjust "${vmName}" +# shellcheck disable=SC2029 +ssh "${slaveKVMIP}" "${drbdadm} adjust ${vmName}" +${drbdadm} -- --overwrite-data-of-peer primary "${vmName}" -if ! ($doDryRun); then - sleep 5 && drbd-overview | tail -4 +if ! isDryRun; then + sleep 5 + drbd-overview | tail -4 drbdDiskPath="/dev/drbd/by-res/${vmName}/0" - if ! [[ -b "$drbdDiskPath" ]]; then - warn "$drbdDiskPath not found! Continue? [y/N]" - read - if ! [[ "$REPLY" =~ (Y|y) ]]; then + if ! [ -b "${drbdDiskPath}" ]; then + warn "${drbdDiskPath} not found! Continue? [y/N]" + read -r + if ! [[ "${REPLY}" =~ (Y|y) ]]; then exit 1 fi fi fi -virtHome="" -[ "$volhomeDisk" != "none" ] && virtHome="--disk path=/dev/drbd/by-disk/${volhomeDisk}/${vmName}_home,bus=virtio,io=threads,cache=none,format=raw" -bootMode="--pxe" -[ -n "${preseedURL}" ] && bootMode="--location https://deb.debian.org/debian/dists/${debianVersion}/main/installer-amd64/ --extra-args \"auto=true priority=critical url=${preseedURL} hostname=${vmName}\"" -[ -f "$isoImagePath" ] && bootMode="--cdrom=$isoImagePath" +virtRootDisk="--disk path=/dev/drbd/by-disk/${volRootDisk}/${vmName}_root,bus=virtio,io=threads,cache=none,format=raw" +virtHomeDisk="" +if [ "${volHomeDisk}" != "none" ]; then + virtHomeDisk="--disk path=/dev/drbd/by-disk/${volHomeDisk}/${vmName}_home,bus=virtio,io=threads,cache=none,format=raw" +fi +if [ -n "${preseedURL}" ]; then + bootMode="--location https://deb.debian.org/debian/dists/${debianVersion}/main/installer-amd64/ --extra-args auto=true priority=critical url=${preseedURL} hostname=${vmName}" +fi +if [ -f "${isoImagePath}" ]; then + bootMode="--cdrom=${isoImagePath}" +fi +bootMode=${bootMode:-"--pxe"} -dryRun virt-install --connect=qemu:///system \ - --name=${vmName} \ - --cpu mode=host-passthrough --vcpus=${vCPU} \ - --memory=${memory} \ - --disk path=/dev/drbd/by-disk/${volrootDisk}/${vmName}_root,bus=virtio,io=threads,cache=none,format=raw \ - $virtHome \ - $bootMode \ - --network=bridge:${bridgeName},model=virtio \ - --noautoconsole --graphics vnc,listen=127.0.0.1,keymap=fr \ - --rng /dev/random \ - --os-variant=none +dryRun virt-install \ + --connect=qemu:///system \ + --name="${vmName}" \ + --cpu "mode=host-passthrough" \ + --vcpus="${vCPU}" \ + --memory="${memory}" \ + "${virtRootDisk}" \ + "${virtHomeDisk}" \ + "${bootMode}" \ + --network="bridge:${bridgeName},model=virtio" \ + --noautoconsole \ + --graphics "vnc,listen=127.0.0.1,keymap=fr" \ + --rng /dev/random \ + --os-variant=none +virst_install_rc=$? -if [ -x /usr/share/scripts/evomaintenance.sh ]; then - ($doDryRun) || echo "Install VM ${vmName} (add-vm.sh)" | /usr/share/scripts/evomaintenance.sh +if [ "${virt_install_rc}" = "0" ]; then + echo -e "\e[32mDone! Now you can install your VM with virt-manager.\e[39m" +else + echo -e "\e[31mError! VM couldn't be created.\e[39m" fi -echo -e "\e[32mDone! Now you can install your VM with virt-manager.\e[39m" +if ! isDryRun && [ -x /usr/share/scripts/evomaintenance.sh ]; then + echo "Install VM ${vmName} (add-vm.sh)" | /usr/share/scripts/evomaintenance.sh +fi + + From 53eaf085f56edd232a40cc910b38f021d7f9d66c Mon Sep 17 00:00:00 2001 From: Jeremy Lecour Date: Thu, 10 Jun 2021 22:30:00 +0200 Subject: [PATCH 68/86] kvm-host: manage dependencies --- kvm-host/meta/main.yml | 15 ++++++++------- kvm-host/tasks/main.yml | 4 ++++ kvm-host/tasks/packages.yml | 8 ++++++++ 3 files changed, 20 insertions(+), 7 deletions(-) diff --git a/kvm-host/meta/main.yml b/kvm-host/meta/main.yml index 0976cf88..c10a727c 100644 --- a/kvm-host/meta/main.yml +++ b/kvm-host/meta/main.yml @@ -1,19 +1,20 @@ +--- + galaxy_info: author: Evolix + company: Evolix description: Install tools to set-up a KVM host + galaxy_tags: [] issue_tracker_url: https://gitea.evolix.org/evolix/ansible-roles/issues license: GPLv2 - min_ansible_version: 2.2 + min_ansible_version: "2.2" platforms: - name: Debian versions: - - jessie - - stretch - - buster - -dependencies: - - { role: evolix/drbd, when: kvm_install_drbd } + - jessie + - stretch + - buster diff --git a/kvm-host/tasks/main.yml b/kvm-host/tasks/main.yml index 5bb6bc9b..95cb7090 100644 --- a/kvm-host/tasks/main.yml +++ b/kvm-host/tasks/main.yml @@ -1,5 +1,9 @@ --- +- include_role: + name: evolix/drbd + when: kvm_install_drbd + ## TODO: check why it's disabled #- include: ssh.yml diff --git a/kvm-host/tasks/packages.yml b/kvm-host/tasks/packages.yml index d2a540e5..1b58b324 100644 --- a/kvm-host/tasks/packages.yml +++ b/kvm-host/tasks/packages.yml @@ -1,4 +1,5 @@ --- + - name: Install packages for kvm/libvirt apt: name: @@ -11,3 +12,10 @@ - libvirt-clients - vlan state: present + +- name: Install packages for kvmstats + apt: + name: + - dialog + - html-xml-utils + state: present From fe9b7ee5f7c05ffa4a3d4e419946113066b2401f Mon Sep 17 00:00:00 2001 From: Jeremy Lecour Date: Thu, 17 Jun 2021 10:57:07 +0200 Subject: [PATCH 69/86] evomaintenance: upstream release 0.6.4 --- CHANGELOG.md | 1 + evomaintenance/files/evomaintenance.sh | 10 ++++++---- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 710a4093..947af670 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -26,6 +26,7 @@ The **patch** part changes incrementally at each release. * apt: store keys in /etc/apt/trusted.gpg.d in ascii format * certbot: sync_remote.sh is configurable * evolinux-base: copy GPG key instead of using apt-key +* evomaintenance: upstream release 0.6.4 * kvm-host: replace the "kvm-tools" package with scripts deployed by Ansible * nodejs: change GPG key name * ntpd: Add leapfile configuration setting to ntpd on debian 10+ diff --git a/evomaintenance/files/evomaintenance.sh b/evomaintenance/files/evomaintenance.sh index 1cd4ce7f..1961ebf2 100644 --- a/evomaintenance/files/evomaintenance.sh +++ b/evomaintenance/files/evomaintenance.sh @@ -4,16 +4,16 @@ # Dependencies (all OS): git postgresql-client # Dependencies (Debian): sudo -# Copyright 2007-2019 Evolix , Gregory Colpart , +# Copyright 2007-2021 Evolix , Gregory Colpart , # Jérémy Lecour and others. -VERSION="0.6.3" +VERSION="0.6.4" show_version() { cat <, +Copyright 2007-2021 Evolix , Gregory Colpart , Jérémy Lecour and others. @@ -178,9 +178,11 @@ is_repository_readonly() { if [ "$(get_system)" = "OpenBSD" ]; then partition=$(stat -f '%Sd' $1) mount | grep ${partition} | grep -q "read-only" - else + elif command -v findmnt >/dev/null; then mountpoint=$(stat -c '%m' $1) findmnt ${mountpoint} --noheadings --output OPTIONS -O ro + else + grep /usr /proc/mounts | grep -E '\bro\b' fi } remount_repository_readwrite() { From 4c7fed77c4b3a966d6b54e81efaff5ff31ff9002 Mon Sep 17 00:00:00 2001 From: Jeremy Lecour Date: Thu, 17 Jun 2021 18:19:20 +0200 Subject: [PATCH 70/86] squid: add Yarn apt repository in default whitelist --- CHANGELOG.md | 1 + squid/files/evolinux-whitelist-defaults.conf | 1 + 2 files changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 947af670..eacc510d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -18,6 +18,7 @@ The **patch** part changes incrementally at each release. * kvm-host: add migrate-vm script * mysql: variable to disable myadd script overwrite (default: True) * nodejs: update apt cache before installing the package +* squid: add Yarn apt repository in default whitelist ### Changed diff --git a/squid/files/evolinux-whitelist-defaults.conf b/squid/files/evolinux-whitelist-defaults.conf index c0d691c0..83b5e827 100644 --- a/squid/files/evolinux-whitelist-defaults.conf +++ b/squid/files/evolinux-whitelist-defaults.conf @@ -11,6 +11,7 @@ ^pear\.php\.net$ ^repo\.mysql\.com$ ^deb\.nodesource\.com$ +^dl\.yarnpkg\.com$ # Let's Encrypt ^.*\.letsencrypt.org$ From 81730de78b9c96e3d4c9b513be89437b52711a58 Mon Sep 17 00:00:00 2001 From: Jeremy Lecour Date: Thu, 17 Jun 2021 18:20:32 +0200 Subject: [PATCH 71/86] kvm-host: fix typo in add-vm --- kvm-host/files/add-vm.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kvm-host/files/add-vm.sh b/kvm-host/files/add-vm.sh index 51ad1850..ec50763d 100755 --- a/kvm-host/files/add-vm.sh +++ b/kvm-host/files/add-vm.sh @@ -256,7 +256,7 @@ dryRun virt-install \ --graphics "vnc,listen=127.0.0.1,keymap=fr" \ --rng /dev/random \ --os-variant=none -virst_install_rc=$? +virt_install_rc=$? if [ "${virt_install_rc}" = "0" ]; then echo -e "\e[32mDone! Now you can install your VM with virt-manager.\e[39m" From dbc853a815bc74a6938596d43e1dd3980b3e876b Mon Sep 17 00:00:00 2001 From: Jeremy Lecour Date: Thu, 17 Jun 2021 18:23:13 +0200 Subject: [PATCH 72/86] listupgrade: upstream release 21.06 --- CHANGELOG.md | 1 + listupgrade/files/listupgrade.sh | 452 +++++++++++++++++++------------ 2 files changed, 285 insertions(+), 168 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index eacc510d..77b9cea2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -29,6 +29,7 @@ The **patch** part changes incrementally at each release. * evolinux-base: copy GPG key instead of using apt-key * evomaintenance: upstream release 0.6.4 * kvm-host: replace the "kvm-tools" package with scripts deployed by Ansible +* listupgrade: upstream release 21.06 * nodejs: change GPG key name * ntpd: Add leapfile configuration setting to ntpd on debian 10+ * packweb-apache: install phpMyAdmin from buster-backports diff --git a/listupgrade/files/listupgrade.sh b/listupgrade/files/listupgrade.sh index 0c7beaaa..809c6ce2 100644 --- a/listupgrade/files/listupgrade.sh +++ b/listupgrade/files/listupgrade.sh @@ -7,31 +7,24 @@ # - 60 : current release is not in the $r_releases list # - 70 : at least an upgradable package is not in the $r_packages list -set -e +VERSION="21.06" -configFile="/etc/evolinux/listupgrade.cnf" +show_version() { + cat <, + Gregory Colpart , + Romain Dessort , + Ludovic Poujol , + Jérémy Lecour + and others. -# If hostname is composed with -, remove the first part. -if [[ "${hostname}" =~ "-" ]]; then - hostname=$(echo "${hostname}" | cut -d'-' -f2-) -fi -# Edit $configFile to override some variables. -# shellcheck disable=SC1090,SC1091 -[ -r "${configFile}" ] && . "${configFile}" - -# Remove temporary files on exit. -# shellcheck disable=SC2064 -trap "rm ${packages} ${packagesHold} ${servicesToRestart} ${template}" EXIT +listupgrade.sh comes with ABSOLUTELY NO WARRANTY. This is free software, +and you are welcome to redistribute it under certain conditions. +See the GNU General Public Licence for details. +END +} # Parse line in retrieved upgrade file and ensure there is no malicious values. get_value() { @@ -48,7 +41,7 @@ get_value() { # Fetch which packages/releases will be upgraded. fetch_upgrade_info() { - upgradeInfo=$(mktemp --tmpdir=/tmp evoupdate.XXX) + upgradeInfo=$(mktemp --tmpdir=/tmp listupgrade.XXX) wget --no-check-certificate --quiet --output-document="${upgradeInfo}" https://upgrades.evolix.org/upgrade # shellcheck disable=SC2181 @@ -78,130 +71,9 @@ is_in() { return 1 } -if [[ "$1" != "--cron" ]]; then - echo "À quel date/heure allez vous planifier l'envoi ?" - echo "Exemple : le jeudi 6 mars entre 18h00 et 23h00" - echo -n "> " - read -r date - echo "À qui envoyer le mail ?" - echo -n "> " - read -r mailto -fi - -# Update APT cache and get packages to upgrade and packages on hold. -aptUpdateOutput=$(apt update 2>&1 | (grep -E -ve '^(Listing|WARNING|$)' -e upgraded -e 'up to date' || true )) - -if echo "${aptUpdateOutput}" | grep -E "^Err(:[0-9]+)? http"; then - echo "FATAL - Not able to fetch all sources (probably a pesky (mini)firewall). Please, fix me" - exit 100 -fi - -apt-mark showhold > "${packagesHold}" -apt list --upgradable 2>&1 | grep -v -f "${packagesHold}" | grep -Ev '^(Listing|WARNING|$)' > "${packages}" -packagesParsable=$(cut -f 1 -d / < "${packages}" |tr '\n' ' ') - -# No updates? Exit! -test ! -s "${packages}" && exit 0 -test ! -s "${packagesHold}" && echo 'Aucun' > "${packagesHold}" - -fetch_upgrade_info -local_release=$(cut -f 1 -d . > "${servicesToRestart}" - elif echo "${pkg}" | grep -q "^nginx"; then - echo "Nginx" >> "${servicesToRestart}" - elif echo "${pkg}" | grep -q "^php5-fpm"; then - echo "PHP FPM" >> "${servicesToRestart}" - elif echo "${pkg}" | grep -q "^mysql-server"; then - echo "MySQL" >> "${servicesToRestart}" - elif echo "${pkg}" | grep -q "^mariadb-server"; then - echo "MariaDB" >> "${servicesToRestart}" - elif echo "${pkg}" | grep -qE "^postgresql-[[:digit:]]+\.[[:digit:]]+$"; then - echo "PostgreSQL" >> "${servicesToRestart}" - elif echo "${pkg}" | grep -qE "^tomcat[[:digit:]]+$"; then - echo "Tomcat" >> "${servicesToRestart}" - elif [ "${pkg}" = "redis-server" ]; then - echo "Redis" >> "${servicesToRestart}" - elif [ "${pkg}" = "mongodb-server" ]; then - echo "MondoDB" >> "${servicesToRestart}" - elif echo "${pkg}" | grep -qE "^courier-(pop|imap)"; then - echo "Courier POP/IMAP" >> "${servicesToRestart}" - elif echo "${pkg}" | grep -qE "^dovecot-(pop|imap)d"; then - echo "Dovecot POP/IMAP" >> "${servicesToRestart}" - elif [ "${pkg}" = "samba" ]; then - echo "Samba" >> "${servicesToRestart}" - elif [ "${pkg}" = "slapd" ]; then - echo "OpenLDAP" >> "${servicesToRestart}" - elif [ "${pkg}" = "bind9" ]; then - echo "Bind9" >> "${servicesToRestart}" - elif [ "${pkg}" = "postfix" ]; then - echo "Postfix" >> "${servicesToRestart}" - elif [ "${pkg}" = "haproxy" ]; then - echo "HAProxy" >> "${servicesToRestart}" - elif [ "${pkg}" = "varnish" ]; then - echo "Varnish" >> "${servicesToRestart}" - elif [ "${pkg}" = "squid" ]; then - echo "Squid" >> "${servicesToRestart}" - elif [ "${pkg}" = "elasticsearch" ]; then - echo "Elasticsearch" >> "${servicesToRestart}" - elif [ "${pkg}" = "logstash" ]; then - echo "Logstash" >> "${servicesToRestart}" - elif [ "${pkg}" = "kibana" ]; then - echo "Kibana" >> "${servicesToRestart}" - elif [ "${pkg}" = "libc6" ]; then - echo "Tous les services sont susceptibles d'être redémarrés (mise à jour de libc6)." > "${servicesToRestart}" - break - elif [ "${pkg}" = "libstdc++6" ]; then - echo "Tous les services sont susceptibles d'être redémarrés (mise à jour de libstdc++6)." > "${servicesToRestart}" - break - elif echo "${pkg}" | grep -q "^libssl"; then - echo "Tous les services sont susceptibles d'être redémarrés (mise à jour de libssl)." > "${servicesToRestart}" - break - fi -done -test ! -s "${servicesToRestart}" && echo "Aucun" > "${servicesToRestart}" - -cat << EOT > "${template}" +render_mail_template() { + local template_file=$1 + cat <"${template_file}" Content-Type: text/plain; charset="utf-8" Reply-To: equipe@evolix.fr From: equipe@evolix.net @@ -244,37 +116,281 @@ Cordialement, Équipe Evolix - Hébergement et Infogérance Open Source http://evolix.com | Twitter: @Evolix @EvolixNOC | http://blog.evolix.com EOT +} +# Files found in the directory passed as 1st argument +# are executed if they are executable +# and if their name doesn't contain a dot +exec_hooks_in_dir() { + hooks=$(find "${1}" -type f -executable -not -name '*.*') + for hook in ${hooks}; do + if ! cron_mode; then + printf "Running '%s\`\n" "${hook}" + fi + ${hook} + done +} +pre_hooks() { + if [ -d "${hooksDir}/pre" ]; then + exec_hooks_in_dir "${hooksDir}/pre" + fi +} +post_hooks_and_exit() { + status=${1:-0} + if [ -d "${hooksDir}/post" ]; then + exec_hooks_in_dir "${hooksDir}/post" + fi + exit ${status} +} -< "${template}" /usr/sbin/sendmail "${mailto}" +cron_mode() { + test "${cron_mode}" = "1" +} -# Now we try to fetch all the packages for the next update session -downloadstatus=$(apt dist-upgrade --assume-yes --download-only -q2 2>&1) -echo "${downloadstatus}" | grep -q 'Download complete and in download only mode' +force_mode() { + test "${force_mode}" = "1" +} -# shellcheck disable=SC2181 -if [ $? -ne 0 ]; then - echo "${downloadstatus}" -fi; +main() { + # Update APT cache and get packages to upgrade and packages on hold. + aptUpdateOutput=$(apt update 2>&1 | (grep -E -ve '^(Listing|WARNING|$)' -e upgraded -e 'up to date' || true)) + if echo "${aptUpdateOutput}" | grep -E "^Err(:[0-9]+)? http"; then + echo "FATAL - Not able to fetch all sources (probably a pesky (mini)firewall). Please, fix me" + post_hooks_and_exit 100 + fi -# Also, we try to update each container apt sources -if which lxc-ls > /dev/null; then - for container in $(lxc-ls); do + apt-mark showhold | sed -e 's/\(.\+\)/^\1\//' >"${packagesHold}" + apt list --upgradable 2>&1 | grep -v -f "${packagesHold}" | grep -v -E '^(Listing|WARNING|$)' >"${packages}" + packagesParsable=$(cut -f 1 -d / <"${packages}" | tr '\n' ' ') - aptUpdateOutput=$(lxc-attach -n "${container}" -- apt update 2>&1 | (grep -Eve '^(Listing|WARNING|$)' -e upgraded -e 'up to date' || true )) + # No updates? Exit! + if [ ! -s "${packages}" ]; then + if ! cron_mode; then + echo "There is nothing to upgrade. Bye." + fi + post_hooks_and_exit 0 + fi - if (echo "${aptUpdateOutput}" | grep -E "^Err(:[0-9]+)? http"); then - echo "FATAL CONTAINER - Not able to fetch all sources (probably a pesky (mini)firewall). Please, fix me" - exit 150 + if [ ! -s "${packagesHold}" ]; then + echo 'Aucun' >"${packagesHold}" + fi + + if force_mode; then + if ! cron_mode; then + echo "Force mode is enabled, as if every release/package is available for upgrade." + fi + else + fetch_upgrade_info + local_release=$(cut -f 1 -d . &1) - echo "${downloadstatus}" | grep -q 'Download complete and in download only mode' + # Exit if the server's release is in skip_releases. + if [ -n "${r_skip_releases}" ] && is_in "${r_skip_releases}" "${local_release}"; then + post_hooks_and_exit 40 + fi - if [ $? -ne 0 ]; then - echo "${downloadstatus}" - fi; + # Exit if all packages to upgrade are listed in skip_packages: + # we remove each package to skip from the $packageToUpgrade list. At the end, + # if there is no additional packages to upgrade, we can exit. + if [ -n "${r_skip_packages}" ]; then + packageToUpgrade="${packagesParsable}" + for pkg in ${r_skip_packages}; do + packageToUpgrade="${packageToUpgrade}/${pkg}" + done + # shellcheck disable=SC2001 + packageToUpgrade=$(echo "${packageToUpgrade}" | sed 's/ \+//g') + if [ -z "${packageToUpgrade}" ]; then + post_hooks_and_exit 50 + fi + fi + # Exit if the server's release is not in releases. + if [ -n "${r_releases}" ] && [ "${r_releases}" != "all" ]; then + is_in "${r_releases}" "${local_release}" || post_hooks_and_exit 60 + fi + + # Exit if there is packages to upgrades that are not in packages list: + # we exit at the first package encountered that is not in packages list. + if [ -n "${r_packages}" ] && [ "${r_packages}" != "all" ]; then + for pkg in ${packagesParsable}; do + is_in "${r_packages}" "${pkg}" || post_hooks_and_exit 70 + done + fi + fi + + # Guess which services will be restarted. + for pkg in ${packagesParsable}; do + if echo "${pkg}" | grep -qE "^(lib)?apache2"; then + echo "Apache2" >>"${servicesToRestart}" + elif echo "${pkg}" | grep -q "^nginx"; then + echo "Nginx" >>"${servicesToRestart}" + elif echo "${pkg}" | grep -q "^php5-fpm"; then + echo "PHP FPM" >>"${servicesToRestart}" + elif echo "${pkg}" | grep -q "^mysql-server"; then + echo "MySQL" >>"${servicesToRestart}" + elif echo "${pkg}" | grep -q "^mariadb-server"; then + echo "MariaDB" >>"${servicesToRestart}" + elif echo "${pkg}" | grep -qE "^postgresql-[[:digit:]]+\.[[:digit:]]+$"; then + echo "PostgreSQL" >>"${servicesToRestart}" + elif echo "${pkg}" | grep -qE "^tomcat[[:digit:]]+$"; then + echo "Tomcat" >>"${servicesToRestart}" + elif [ "${pkg}" = "redis-server" ]; then + echo "Redis" >>"${servicesToRestart}" + elif [ "${pkg}" = "mongodb-server" ]; then + echo "MondoDB" >>"${servicesToRestart}" + elif echo "${pkg}" | grep -qE "^courier-(pop|imap)"; then + echo "Courier POP/IMAP" >>"${servicesToRestart}" + elif echo "${pkg}" | grep -qE "^dovecot-(pop|imap)d"; then + echo "Dovecot POP/IMAP" >>"${servicesToRestart}" + elif [ "${pkg}" = "samba" ]; then + echo "Samba" >>"${servicesToRestart}" + elif [ "${pkg}" = "slapd" ]; then + echo "OpenLDAP" >>"${servicesToRestart}" + elif [ "${pkg}" = "bind9" ]; then + echo "Bind9" >>"${servicesToRestart}" + elif [ "${pkg}" = "postfix" ]; then + echo "Postfix" >>"${servicesToRestart}" + elif [ "${pkg}" = "haproxy" ]; then + echo "HAProxy" >>"${servicesToRestart}" + elif [ "${pkg}" = "varnish" ]; then + echo "Varnish" >>"${servicesToRestart}" + elif [ "${pkg}" = "squid" ]; then + echo "Squid" >>"${servicesToRestart}" + elif [ "${pkg}" = "elasticsearch" ]; then + echo "Elasticsearch" >>"${servicesToRestart}" + elif [ "${pkg}" = "logstash" ]; then + echo "Logstash" >>"${servicesToRestart}" + elif [ "${pkg}" = "kibana" ]; then + echo "Kibana" >>"${servicesToRestart}" + elif [ "${pkg}" = "libc6" ]; then + echo "Tous les services sont susceptibles d'être redémarrés (mise à jour de libc6)." >"${servicesToRestart}" + break + elif [ "${pkg}" = "libstdc++6" ]; then + echo "Tous les services sont susceptibles d'être redémarrés (mise à jour de libstdc++6)." >"${servicesToRestart}" + break + elif echo "${pkg}" | grep -q "^libssl"; then + echo "Tous les services sont susceptibles d'être redémarrés (mise à jour de libssl)." >"${servicesToRestart}" + break + fi done + test ! -s "${servicesToRestart}" && echo "Aucun" >"${servicesToRestart}" + + render_mail_template "${template}" + /usr/sbin/sendmail "${mailto}" <"${template}" + + # Now we try to fetch all the packages for the next update session + downloadstatus=$(apt dist-upgrade --assume-yes --download-only -q2 2>&1) + echo "${downloadstatus}" | grep -q 'Download complete and in download only mode' + + # shellcheck disable=SC2181 + if [ $? -ne 0 ]; then + echo "${downloadstatus}" + fi + + # Also, we try to update each container apt sources + if which lxc-ls >/dev/null; then + for container in $(lxc-ls); do + + aptUpdateOutput=$(lxc-attach -n "${container}" -- apt update 2>&1 | (grep -Eve '^(Listing|WARNING|$)' -e upgraded -e 'up to date' || true)) + + if (echo "${aptUpdateOutput}" | grep -E "^Err(:[0-9]+)? http"); then + echo "FATAL CONTAINER - Not able to fetch all sources (probably a pesky (mini)firewall). Please, fix me" + post_hooks_and_exit 150 + fi + + # Now we try to fetch all the packages for the next update session + downloadstatus=$(lxc-attach -n "${container}" -- apt dist-upgrade --assume-yes --download-only -q2 2>&1) + + if echo "${downloadstatus}" | grep -q 'Download complete and in download only mode'; then + echo "${downloadstatus}" + fi + + done + fi +} + +# Options parsing. +while :; do + case ${1} in + -V | --version) + show_version + exit 0 + ;; + --cron) + cron_mode=1 + ;; + -f | --force) + # Ignore exclusions from "upgrade info" and do as if all releases and packages are to be upgraded + force_mode=1 + ;; + -?* | [[:alnum:]]*) + # ignore unknown options + printf 'ERROR: Unknown option : %s\n' "$1" >&2 + exit 1 + ;; + *) + # Default case: If no more options then break out of the loop. + break + ;; + esac + + shift +done + +## Do not stop on error. Instead we should catch them manually +# set -e +## Error on unassigned variables +set -u + +export LC_ALL=C + +configFile="/etc/evolinux/listupgrade.cnf" + +cron_mode=${cron_mode:-0} +force_mode=${force_mode:-0} +clientmail=$(grep EVOMAINTMAIL /etc/evomaintenance.cf | cut -d'=' -f2) +mailto="${clientmail}" +date="Ce jeudi entre 18h00 et 23h00." +hostname=$(grep HOSTNAME /etc/evomaintenance.cf | cut -d'=' -f2) +hostname=${hostname%%.evolix.net} +hooksDir="/etc/evolinux/listupgrade-hooks" + +# If hostname is composed with -, remove the first part. +if [[ "${hostname}" =~ "-" ]]; then + hostname=$(echo "${hostname}" | cut -d'-' -f2-) fi +# Edit $configFile to override some variables. +# shellcheck disable=SC1090,SC1091 +[ -r "${configFile}" ] && . "${configFile}" + +# Create temporary files +packages=$(mktemp --tmpdir=/tmp listupgrade.XXX) +packagesHold=$(mktemp --tmpdir=/tmp listupgrade.XXX) +servicesToRestart=$(mktemp --tmpdir=/tmp listupgrade.XXX) +template=$(mktemp --tmpdir=/tmp listupgrade.XXX) +# Remove temporary files on exit. +# shellcheck disable=SC2064 +trap "rm ${packages} ${packagesHold} ${servicesToRestart} ${template}" EXIT + +if ! cron_mode; then + echo "À quelle date/heure allez vous planifier les mises à jour ?" + echo "Exemple : le jeudi 6 mars entre 18h00 et 23h00" + echo -n "> " + read -r date + echo "À qui envoyer le mail ?" + echo -n "> " + read -r mailto +fi + +# Execute pre hooks +pre_hooks + +# call main function +main + +# Execute post hooks and exit +post_hooks_and_exit 0 From dd32ab5688da570fd55aeecdc9b1b7d36eb8a18a Mon Sep 17 00:00:00 2001 From: Jeremy Lecour Date: Sun, 20 Jun 2021 10:32:16 +0200 Subject: [PATCH 73/86] listupgrade: upstream release 21.06.1 --- CHANGELOG.md | 2 +- listupgrade/files/listupgrade.sh | 19 ++++++++++--------- 2 files changed, 11 insertions(+), 10 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 77b9cea2..4343e4db 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -29,7 +29,7 @@ The **patch** part changes incrementally at each release. * evolinux-base: copy GPG key instead of using apt-key * evomaintenance: upstream release 0.6.4 * kvm-host: replace the "kvm-tools" package with scripts deployed by Ansible -* listupgrade: upstream release 21.06 +* listupgrade: upstream release 21.06.1 * nodejs: change GPG key name * ntpd: Add leapfile configuration setting to ntpd on debian 10+ * packweb-apache: install phpMyAdmin from buster-backports diff --git a/listupgrade/files/listupgrade.sh b/listupgrade/files/listupgrade.sh index 809c6ce2..d3499098 100644 --- a/listupgrade/files/listupgrade.sh +++ b/listupgrade/files/listupgrade.sh @@ -7,7 +7,7 @@ # - 60 : current release is not in the $r_releases list # - 70 : at least an upgradable package is not in the $r_packages list -VERSION="21.06" +VERSION="21.06.1" show_version() { cat <&1 | (grep -E -ve '^(Listing|WARNING|$)' -e upgraded -e 'up to date' || true)) + aptUpdateOutput=$(apt -o Dir::State::Lists="${listupgrade_state_dir}" update 2>&1 | (grep -E -ve '^(Listing|WARNING|$)' -e upgraded -e 'up to date' || true)) if echo "${aptUpdateOutput}" | grep -E "^Err(:[0-9]+)? http"; then - echo "FATAL - Not able to fetch all sources (probably a pesky (mini)firewall). Please, fix me" + echo "FATAL - Not able to fetch all sources (probably a pesky (mini)firewall). Please, fix me" >&2 post_hooks_and_exit 100 fi apt-mark showhold | sed -e 's/\(.\+\)/^\1\//' >"${packagesHold}" - apt list --upgradable 2>&1 | grep -v -f "${packagesHold}" | grep -v -E '^(Listing|WARNING|$)' >"${packages}" + apt -o Dir::State::Lists="${listupgrade_state_dir}" list --upgradable 2>&1 | grep -v -f "${packagesHold}" | grep -v -E '^(Listing|WARNING|$)' >"${packages}" packagesParsable=$(cut -f 1 -d / <"${packages}" | tr '\n' ' ') # No updates? Exit! if [ ! -s "${packages}" ]; then if ! cron_mode; then - echo "There is nothing to upgrade. Bye." + echo "There is nothing to upgrade. Bye." >&2 fi post_hooks_and_exit 0 fi @@ -283,7 +283,7 @@ main() { /usr/sbin/sendmail "${mailto}" <"${template}" # Now we try to fetch all the packages for the next update session - downloadstatus=$(apt dist-upgrade --assume-yes --download-only -q2 2>&1) + downloadstatus=$(apt -o Dir::State::Lists="${listupgrade_state_dir}" dist-upgrade --assume-yes --download-only -q2 2>&1) echo "${downloadstatus}" | grep -q 'Download complete and in download only mode' # shellcheck disable=SC2181 @@ -295,15 +295,15 @@ main() { if which lxc-ls >/dev/null; then for container in $(lxc-ls); do - aptUpdateOutput=$(lxc-attach -n "${container}" -- apt update 2>&1 | (grep -Eve '^(Listing|WARNING|$)' -e upgraded -e 'up to date' || true)) + aptUpdateOutput=$(lxc-attach -n "${container}" -- apt -o Dir::State::Lists="${listupgrade_state_dir}" update 2>&1 | (grep -Eve '^(Listing|WARNING|$)' -e upgraded -e 'up to date' || true)) if (echo "${aptUpdateOutput}" | grep -E "^Err(:[0-9]+)? http"); then - echo "FATAL CONTAINER - Not able to fetch all sources (probably a pesky (mini)firewall). Please, fix me" + echo "FATAL CONTAINER - Not able to fetch all sources (probably a pesky (mini)firewall). Please, fix me" >&2 post_hooks_and_exit 150 fi # Now we try to fetch all the packages for the next update session - downloadstatus=$(lxc-attach -n "${container}" -- apt dist-upgrade --assume-yes --download-only -q2 2>&1) + downloadstatus=$(lxc-attach -n "${container}" -- apt -o Dir::State::Lists="${listupgrade_state_dir}" dist-upgrade --assume-yes --download-only -q2 2>&1) if echo "${downloadstatus}" | grep -q 'Download complete and in download only mode'; then echo "${downloadstatus}" @@ -357,6 +357,7 @@ mailto="${clientmail}" date="Ce jeudi entre 18h00 et 23h00." hostname=$(grep HOSTNAME /etc/evomaintenance.cf | cut -d'=' -f2) hostname=${hostname%%.evolix.net} +listupgrade_state_dir="${listupgrade_state_dir:-/var/lib/listupgrade}" hooksDir="/etc/evolinux/listupgrade-hooks" # If hostname is composed with -, remove the first part. From 6190c664451fdf01a23a4ffb8d91e076603acd43 Mon Sep 17 00:00:00 2001 From: Jeremy Lecour Date: Sun, 20 Jun 2021 12:06:49 +0200 Subject: [PATCH 74/86] listupgrade: upstream release 21.06.2 --- CHANGELOG.md | 2 +- listupgrade/files/listupgrade.sh | 8 +++++++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4343e4db..5e20ac91 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -29,7 +29,7 @@ The **patch** part changes incrementally at each release. * evolinux-base: copy GPG key instead of using apt-key * evomaintenance: upstream release 0.6.4 * kvm-host: replace the "kvm-tools" package with scripts deployed by Ansible -* listupgrade: upstream release 21.06.1 +* listupgrade: upstream release 21.06.2 * nodejs: change GPG key name * ntpd: Add leapfile configuration setting to ntpd on debian 10+ * packweb-apache: install phpMyAdmin from buster-backports diff --git a/listupgrade/files/listupgrade.sh b/listupgrade/files/listupgrade.sh index d3499098..3c64f37e 100644 --- a/listupgrade/files/listupgrade.sh +++ b/listupgrade/files/listupgrade.sh @@ -7,7 +7,7 @@ # - 60 : current release is not in the $r_releases list # - 70 : at least an upgradable package is not in the $r_packages list -VERSION="21.06.1" +VERSION="21.06.2" show_version() { cat <&1 | (grep -E -ve '^(Listing|WARNING|$)' -e upgraded -e 'up to date' || true)) @@ -282,6 +285,9 @@ main() { render_mail_template "${template}" /usr/sbin/sendmail "${mailto}" <"${template}" + if ! cron_mode; then + echo "Dowloading packages..." + fi # Now we try to fetch all the packages for the next update session downloadstatus=$(apt -o Dir::State::Lists="${listupgrade_state_dir}" dist-upgrade --assume-yes --download-only -q2 2>&1) echo "${downloadstatus}" | grep -q 'Download complete and in download only mode' From cb257ef92734f3913d95880698a96ef5601eeaf6 Mon Sep 17 00:00:00 2001 From: Eric Morino Date: Mon, 21 Jun 2021 11:31:03 +0200 Subject: [PATCH 75/86] =?UTF-8?q?Add=20support=20debian=2013=20for=20postg?= =?UTF-8?q?resql=20r=C3=B4le=20and=20PG13?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- postgresql/tasks/main.yml | 3 +++ postgresql/tasks/packages_bullseye.yml | 16 ++++++++++++++++ 2 files changed, 19 insertions(+) create mode 100644 postgresql/tasks/packages_bullseye.yml diff --git a/postgresql/tasks/main.yml b/postgresql/tasks/main.yml index aecdf80d..40b73da9 100644 --- a/postgresql/tasks/main.yml +++ b/postgresql/tasks/main.yml @@ -10,6 +10,9 @@ - include: packages_buster.yml when: ansible_distribution_major_version is version('10', '>=') +- include: packages_bullseye.yml + when: ansible_distribution_major_version is version('11', '>=') + - include: config.yml - include: nrpe.yml diff --git a/postgresql/tasks/packages_bullseye.yml b/postgresql/tasks/packages_bullseye.yml new file mode 100644 index 00000000..558578f2 --- /dev/null +++ b/postgresql/tasks/packages_bullseye.yml @@ -0,0 +1,16 @@ +--- + +- name: "Set variables (Debian 11)" + set_fact: + postgresql_version: '13' + when: postgresql_version is none or postgresql_version | length == 0 + +- include: pgdg-repo.yml + when: postgresql_version != '13' + +- name: Install postgresql package + apt: + name: + - postgresql + - pgtop + - libdbd-pg-perl From af9b1a4766c962b2171466d40c3ba817c021a68e Mon Sep 17 00:00:00 2001 From: Eric Morino Date: Mon, 21 Jun 2021 11:35:17 +0200 Subject: [PATCH 76/86] Fix main.yml for postgresql role --- postgresql/tasks/main.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/postgresql/tasks/main.yml b/postgresql/tasks/main.yml index 40b73da9..fbe22989 100644 --- a/postgresql/tasks/main.yml +++ b/postgresql/tasks/main.yml @@ -8,7 +8,7 @@ when: ansible_distribution_major_version is version('9', '=') - include: packages_buster.yml - when: ansible_distribution_major_version is version('10', '>=') + when: ansible_distribution_major_version is version('10', '=') - include: packages_bullseye.yml when: ansible_distribution_major_version is version('11', '>=') From 22145a29b206a36671d2892a5fb23bb4a18cb852 Mon Sep 17 00:00:00 2001 From: Jeremy Lecour Date: Sun, 20 Jun 2021 15:38:53 +0200 Subject: [PATCH 77/86] whitespaces --- etc-git/tasks/commit.yml | 10 ++++------ etc-git/tasks/do_commit.yml | 1 - 2 files changed, 4 insertions(+), 7 deletions(-) diff --git a/etc-git/tasks/commit.yml b/etc-git/tasks/commit.yml index db167f5d..4bcf8e5c 100644 --- a/etc-git/tasks/commit.yml +++ b/etc-git/tasks/commit.yml @@ -9,10 +9,8 @@ vars: git_folder: "/etc" when: - - _etc_git.stat.exists - - _etc_git.stat.isdir - - + - _etc_git.stat.exists + - _etc_git.stat.isdir - name: Is /usr/share/scripts a git repository stat: @@ -23,5 +21,5 @@ vars: git_folder: "/usr/share/scripts" when: - - _usr_share_scripts_git.stat.exists - - _usr_share_scripts_git.stat.isdir + - _usr_share_scripts_git.stat.exists + - _usr_share_scripts_git.stat.isdir diff --git a/etc-git/tasks/do_commit.yml b/etc-git/tasks/do_commit.yml index 806aefd2..6b09eaaf 100644 --- a/etc-git/tasks/do_commit.yml +++ b/etc-git/tasks/do_commit.yml @@ -5,7 +5,6 @@ name: remount-usr when: git_folder is match('/usr/.*') - - name: "is {{ git_folder }} clean?" command: git status --porcelain args: From 4c1ef1bd56a473a28eba4b8225cddd64ba072a7c Mon Sep 17 00:00:00 2001 From: Jeremy Lecour Date: Wed, 23 Jun 2021 22:37:35 +0200 Subject: [PATCH 78/86] elasticsearch: recent versiond don't depend on external JRE --- CHANGELOG.md | 2 ++ elasticsearch/meta/main.yml | 3 --- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5e20ac91..4fb29b9f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -46,6 +46,8 @@ The **patch** part changes incrementally at each release. ### Removed +* elasticsearch: recent versiond don't depend on external JRE + ### Security ## [10.5.1] 2021-04-13 diff --git a/elasticsearch/meta/main.yml b/elasticsearch/meta/main.yml index 736c0a42..9bd6757b 100644 --- a/elasticsearch/meta/main.yml +++ b/elasticsearch/meta/main.yml @@ -24,6 +24,3 @@ galaxy_info: # # NOTE: A tag is limited to a single word comprised of # alphanumeric characters. Maximum 20 tags per role. - -dependencies: - - { role: evolix/java, alternative: 'openjdk' } From 1890a7970271505865ac1040bcc277fde2eceda6 Mon Sep 17 00:00:00 2001 From: Jeremy Lecour Date: Wed, 23 Jun 2021 22:38:22 +0200 Subject: [PATCH 79/86] elasticsearch: inline YAML formatting of seed_hosts and initial_master_nodes --- CHANGELOG.md | 1 + elasticsearch/tasks/configuration.yml | 26 ++++++++++++++++++++++---- 2 files changed, 23 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4fb29b9f..bac6d542 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -40,6 +40,7 @@ The **patch** part changes incrementally at each release. * add default (useless) value for file lookup (first_found) * fix pipefail option for shell invocations +* elasticsearch: inline YAML formatting of seed_hosts and initial_master_nodes * evolinux-base: fix motd lookup path * ldap: fix edge cases where passwords were not set/get properly * listupgrade: fix wget error + shellcheck cleanup diff --git a/elasticsearch/tasks/configuration.yml b/elasticsearch/tasks/configuration.yml index 72d36bb3..5afa94b0 100644 --- a/elasticsearch/tasks/configuration.yml +++ b/elasticsearch/tasks/configuration.yml @@ -52,18 +52,36 @@ - name: Configure discovery seed hosts lineinfile: dest: /etc/elasticsearch/elasticsearch.yml - line: "discovery.seed_hosts: {{ elasticsearch_discovery_seed_hosts | to_yaml }}" + line: "discovery.seed_hosts: {{ elasticsearch_discovery_seed_hosts | to_yaml(default_flow_style=True) }}" regexp: "^discovery.seed_hosts:" - when: elasticsearch_discovery_seed_hosts | length > 0 + when: elasticsearch_discovery_seed_hosts | default([], True) | length > 0 + tags: + - config + +- name: Configure empty discovery seed hosts + lineinfile: + dest: /etc/elasticsearch/elasticsearch.yml + regexp: "^discovery.seed_hosts:" + state: absent + when: elasticsearch_discovery_seed_hosts | default([], True) | length <= 0 tags: - config - name: Configure initial master nodes lineinfile: dest: /etc/elasticsearch/elasticsearch.yml - line: "cluster.initial_master_nodes: {{ elasticsearch_cluster_initial_master_nodes | to_yaml }}" + line: "cluster.initial_master_nodes: {{ elasticsearch_cluster_initial_master_nodes | to_yaml(default_flow_style=True) }}" regexp: "^cluster.initial_master_nodes:" - when: elasticsearch_cluster_initial_master_nodes | length > 0 + when: elasticsearch_cluster_initial_master_nodes | default([], True) | length > 0 + tags: + - config + +- name: Configure empty initial master nodes + lineinfile: + dest: /etc/elasticsearch/elasticsearch.yml + regexp: "^cluster.initial_master_nodes:" + state: absent + when: elasticsearch_cluster_initial_master_nodes | default([], True) | length <= 0 tags: - config From 0fe02441165eaca1da2cfd4666a53729794a5c20 Mon Sep 17 00:00:00 2001 From: Jeremy Lecour Date: Mon, 28 Jun 2021 15:19:29 +0200 Subject: [PATCH 80/86] Update Galaxy metadata (company, platforms and galaxy_tags) --- CHANGELOG.md | 1 + apache/meta/main.yml | 18 ++++++++++++------ apt/meta/main.yml | 16 +++++++++++----- bind/meta/main.yml | 16 +++++++++++----- dhcpd/meta/main.yml | 16 +++++++++++----- drbd/meta/main.yml | 16 +++++++++++----- elasticsearch/meta/main.yml | 14 +++++++------- etc-git/meta/main.yml | 21 ++++++++++++++++----- evoacme/meta/main.yml | 22 ++++++++++++++++------ evocheck/meta/main.yml | 11 ++++++----- evolinux-base/meta/main.yml | 22 ++++++++++++++++------ evolinux-todo/meta/main.yml | 11 ++++++----- evolinux-users/meta/main.yml | 22 ++++++++++++++++------ evomaintenance/meta/main.yml | 12 ++++++------ fail2ban/meta/main.yml | 21 ++++++++++++++++----- filebeat/meta/main.yml | 22 ++++++++++++++++------ fluentd/meta/main.yml | 22 ++++++++++++++++------ haproxy/meta/main.yml | 21 ++++++++++++++++----- java/meta/main.yml | 22 ++++++++++++++++------ jenkins/meta/main.yml | 12 +++++++----- kibana/meta/main.yml | 22 ++++++++++++++++------ kvm-host/meta/main.yml | 21 ++++++++++++++------- ldap/meta/main.yml | 21 ++++++++++++++++----- listupgrade/meta/main.yml | 12 +++++++----- logstash/meta/main.yml | 21 ++++++++++++++++----- lxc-php/meta/main.yml | 23 +++++++++++++++++------ lxc/meta/main.yml | 23 +++++++++++++++++------ memcached/meta/main.yml | 22 +++++++++++++++++----- metricbeat/meta/main.yml | 22 ++++++++++++++++------ minifirewall/meta/main.yml | 21 ++++++++++++++++----- mongodb/meta/main.yml | 10 ++++++---- monit/meta/main.yml | 21 ++++++++++++++++----- munin/meta/main.yml | 21 ++++++++++++++++----- mysql-oracle/meta/main.yml | 22 ++++++++++++++++------ mysql/meta/main.yml | 21 ++++++++++++++++----- nagios-nrpe/meta/main.yml | 21 ++++++++++++++++----- networkd-to-ifconfig/meta/main.yml | 21 ++++++++++++++++----- newrelic/meta/main.yml | 21 ++++++++++++++++----- nginx/meta/main.yml | 21 ++++++++++++++++----- nodejs/meta/main.yml | 21 ++++++++++++++++----- packweb-apache/meta/main.yml | 23 ++++++++++++++++------- php/meta/main.yml | 22 ++++++++++++++++------ postfix/meta/main.yml | 21 ++++++++++++++++----- postgresql/meta/main.yml | 21 ++++++++++++++++----- proftpd/meta/main.yml | 22 ++++++++++++++++------ rabbitmq/meta/main.yml | 22 ++++++++++++++++------ rbenv/meta/main.yml | 21 ++++++++++++++++----- redis/meta/main.yml | 21 ++++++++++++++++----- squid/meta/main.yml | 22 ++++++++++++++++------ ssl/meta/main.yml | 22 ++++++++++++++++------ tomcat-instance/meta/main.yml | 21 ++++++++++++++++----- tomcat/meta/main.yml | 21 ++++++++++++++++----- varnish/meta/main.yml | 21 ++++++++++++++++----- vrrpd/meta/main.yml | 21 ++++++++++++++++----- webapps/evoadmin-web/meta/main.yml | 14 ++++++++++++-- webapps/wordpress/meta/main.yml | 21 ++++++++++++++++----- 56 files changed, 787 insertions(+), 295 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index bac6d542..004caa76 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -22,6 +22,7 @@ The **patch** part changes incrementally at each release. ### Changed +* Update Galaxy metadata (company, platforms and galaxy_tags) * Use 'loop' syntax instead of 'with_first_found/with_items/with_dict/with_nested/with_list' * Use Ansible syntax used in Ansible 2.8+ * apt: store keys in /etc/apt/trusted.gpg.d in ascii format diff --git a/apache/meta/main.yml b/apache/meta/main.yml index 3f717653..c4daabd5 100644 --- a/apache/meta/main.yml +++ b/apache/meta/main.yml @@ -1,18 +1,24 @@ +--- galaxy_info: - author: Evolix + company: Evolix description: Installation and basic configuration of Apache issue_tracker_url: https://gitea.evolix.org/evolix/ansible-roles/issues license: GPLv2 - min_ansible_version: 2.2 + min_ansible_version: "2.2" platforms: - - name: Debian - versions: - - jessie - - stretch + - name: Debian + versions: + - jessie + - stretch + - buster + + galaxy_tags: [] + # Be sure to remove the '[]' above if you add dependencies + # to this list. dependencies: [] # List your role dependencies here, one per line. diff --git a/apt/meta/main.yml b/apt/meta/main.yml index b9fd3b76..c1872414 100644 --- a/apt/meta/main.yml +++ b/apt/meta/main.yml @@ -1,17 +1,23 @@ galaxy_info: - author: Evolix + company: Evolix description: Add repositories to APT sources list. issue_tracker_url: https://gitea.evolix.org/evolix/ansible-roles/issues license: GPLv2 - min_ansible_version: 2.2 + min_ansible_version: "2.2" platforms: - - name: Debian - versions: - - jessie + - name: Debian + versions: + - jessie + - stretch + - buster + + galaxy_tags: [] + # Be sure to remove the '[]' above if you add dependencies + # to this list. dependencies: [] # List your role dependencies here, one per line. diff --git a/bind/meta/main.yml b/bind/meta/main.yml index 5f082615..6cf180b1 100644 --- a/bind/meta/main.yml +++ b/bind/meta/main.yml @@ -1,17 +1,23 @@ galaxy_info: - author: Evolix + company: Evolix description: Installation and basic configuration of bind9. issue_tracker_url: https://gitea.evolix.org/evolix/ansible-roles/issues license: GPLv2 - min_ansible_version: 2.2 + min_ansible_version: "2.2" platforms: - - name: Debian - versions: - - jessie + - name: Debian + versions: + - jessie + - stretch + - buster + + galaxy_tags: [] + # Be sure to remove the '[]' above if you add dependencies + # to this list. dependencies: [] # List your role dependencies here, one per line. diff --git a/dhcpd/meta/main.yml b/dhcpd/meta/main.yml index 74b43142..44edbee0 100644 --- a/dhcpd/meta/main.yml +++ b/dhcpd/meta/main.yml @@ -1,17 +1,23 @@ galaxy_info: - author: Evolix + company: Evolix description: Installation and basic configuration of isc-dhcp-server. issue_tracker_url: https://gitea.evolix.org/evolix/ansible-roles/issues license: GPLv2 - min_ansible_version: 2.2 + min_ansible_version: "2.2" platforms: - - name: Debian - versions: - - jessie + - name: Debian + versions: + - jessie + - stretch + - buster + + galaxy_tags: [] + # Be sure to remove the '[]' above if you add dependencies + # to this list. dependencies: [] # List your role dependencies here, one per line. diff --git a/drbd/meta/main.yml b/drbd/meta/main.yml index f07ce45d..511001b0 100644 --- a/drbd/meta/main.yml +++ b/drbd/meta/main.yml @@ -1,17 +1,23 @@ galaxy_info: - author: Evolix + company: Evolix description: Install tools to setup DRBD replication accross servers. issue_tracker_url: https://gitea.evolix.org/evolix/ansible-roles/issues license: GPLv2 - min_ansible_version: 2.2 + min_ansible_version: "2.2" platforms: - - name: Debian - versions: - - jessie + - name: Debian + versions: + - jessie + - stretch + - buster + + galaxy_tags: [] + # Be sure to remove the '[]' above if you add dependencies + # to this list. dependencies: [] # List your role dependencies here, one per line. diff --git a/elasticsearch/meta/main.yml b/elasticsearch/meta/main.yml index 9bd6757b..fa608e85 100644 --- a/elasticsearch/meta/main.yml +++ b/elasticsearch/meta/main.yml @@ -1,20 +1,20 @@ --- galaxy_info: - author: Evolix + company: Evolix description: Install Elasticsearch issue_tracker_url: https://gitea.evolix.org/evolix/ansible-roles/issues license: GPLv2 - min_ansible_version: 2.2 + min_ansible_version: "2.2" platforms: - - name: Debian - versions: - - jessie - - stretch - - buster + - name: Debian + versions: + - jessie + - stretch + - buster galaxy_tags: [] # List tags for your role here, one per line. A tag is diff --git a/etc-git/meta/main.yml b/etc-git/meta/main.yml index ef9d621e..cb666d15 100644 --- a/etc-git/meta/main.yml +++ b/etc-git/meta/main.yml @@ -1,17 +1,28 @@ galaxy_info: - author: Evolix + company: Evolix description: Put /etc under Git version control. issue_tracker_url: https://gitea.evolix.org/evolix/ansible-roles/issues license: GPLv2 - min_ansible_version: 2.2 + min_ansible_version: "2.2" platforms: - - name: Debian - versions: - - jessie + - name: Debian + versions: + - jessie + - stretch + - buster + + galaxy_tags: [] + # List tags for your role here, one per line. A tag is + # a keyword that describes and categorizes the role. + # Users find roles by searching for tags. Be sure to + # remove the '[]' above if you add tags to this list. + # + # NOTE: A tag is limited to a single word comprised of + # alphanumeric characters. Maximum 20 tags per role. dependencies: [] # List your role dependencies here, one per line. diff --git a/evoacme/meta/main.yml b/evoacme/meta/main.yml index ea0c5551..c238d701 100644 --- a/evoacme/meta/main.yml +++ b/evoacme/meta/main.yml @@ -1,18 +1,28 @@ galaxy_info: - author: Evolix + company: Evolix description: Install evoacme ; a wrapper for Certbot (Let's Encrypt) issue_tracker_url: https://gitea.evolix.org/evolix/ansible-roles/issues license: GPLv2 - min_ansible_version: 2.2 + min_ansible_version: "2.2" platforms: - - name: Debian - versions: - - stretch - - buster + - name: Debian + versions: + - jessie + - stretch + - buster + + galaxy_tags: [] + # List tags for your role here, one per line. A tag is + # a keyword that describes and categorizes the role. + # Users find roles by searching for tags. Be sure to + # remove the '[]' above if you add tags to this list. + # + # NOTE: A tag is limited to a single word comprised of + # alphanumeric characters. Maximum 20 tags per role. dependencies: [] # List your role dependencies here, one per line. diff --git a/evocheck/meta/main.yml b/evocheck/meta/main.yml index 35c76d72..9f435be4 100644 --- a/evocheck/meta/main.yml +++ b/evocheck/meta/main.yml @@ -7,13 +7,14 @@ galaxy_info: license: GPLv2 - min_ansible_version: 2.2 + min_ansible_version: "2.2" platforms: - - name: Debian - versions: - - jessie - - squeeze + - name: Debian + versions: + - jessie + - stretch + - buster galaxy_tags: [] # List tags for your role here, one per line. A tag is diff --git a/evolinux-base/meta/main.yml b/evolinux-base/meta/main.yml index 58265332..84c001c1 100644 --- a/evolinux-base/meta/main.yml +++ b/evolinux-base/meta/main.yml @@ -1,18 +1,28 @@ galaxy_info: - author: Evolix + company: Evolix description: Evolix usual customizations for a Debian installation. issue_tracker_url: https://gitea.evolix.org/evolix/ansible-roles/issues license: GPLv2 - min_ansible_version: 2.2 + min_ansible_version: "2.2" platforms: - - name: Debian - versions: - - jessie - - stretch + - name: Debian + versions: + - jessie + - stretch + - buster + + galaxy_tags: [] + # List tags for your role here, one per line. A tag is + # a keyword that describes and categorizes the role. + # Users find roles by searching for tags. Be sure to + # remove the '[]' above if you add tags to this list. + # + # NOTE: A tag is limited to a single word comprised of + # alphanumeric characters. Maximum 20 tags per role. dependencies: [] # List your role dependencies here, one per line. diff --git a/evolinux-todo/meta/main.yml b/evolinux-todo/meta/main.yml index b1936540..bf350519 100644 --- a/evolinux-todo/meta/main.yml +++ b/evolinux-todo/meta/main.yml @@ -7,13 +7,14 @@ galaxy_info: license: GPLv2 - min_ansible_version: 2.2 + min_ansible_version: "2.2" platforms: - - name: Debian - versions: - - jessie - - stretch + - name: Debian + versions: + - jessie + - stretch + - buster galaxy_tags: [] # List tags for your role here, one per line. A tag is diff --git a/evolinux-users/meta/main.yml b/evolinux-users/meta/main.yml index 8e019209..bac538ed 100644 --- a/evolinux-users/meta/main.yml +++ b/evolinux-users/meta/main.yml @@ -1,18 +1,28 @@ galaxy_info: - author: Evolix + company: Evolix description: Creates evolinux users accounts. issue_tracker_url: https://gitea.evolix.org/evolix/ansible-roles/issues license: GPLv2 - min_ansible_version: 2.2 + min_ansible_version: "2.2" platforms: - - name: Debian - versions: - - jessie - - stretch + - name: Debian + versions: + - jessie + - stretch + - buster + + galaxy_tags: [] + # List tags for your role here, one per line. A tag is + # a keyword that describes and categorizes the role. + # Users find roles by searching for tags. Be sure to + # remove the '[]' above if you add tags to this list. + # + # NOTE: A tag is limited to a single word comprised of + # alphanumeric characters. Maximum 20 tags per role. dependencies: [] # List your role dependencies here, one per line. diff --git a/evomaintenance/meta/main.yml b/evomaintenance/meta/main.yml index cb592aea..0e672054 100644 --- a/evomaintenance/meta/main.yml +++ b/evomaintenance/meta/main.yml @@ -7,14 +7,14 @@ galaxy_info: license: GPLv2 - min_ansible_version: 2.2 + min_ansible_version: "2.2" platforms: - - name: Debian - versions: - - stretch - - jessie - - squeeze + - name: Debian + versions: + - jessie + - stretch + - buster galaxy_tags: [] # List tags for your role here, one per line. A tag is diff --git a/fail2ban/meta/main.yml b/fail2ban/meta/main.yml index 5b80af79..54bdf4e8 100644 --- a/fail2ban/meta/main.yml +++ b/fail2ban/meta/main.yml @@ -1,17 +1,28 @@ galaxy_info: - author: Evolix + company: Evolix description: Install Fail2ban and a few filters. issue_tracker_url: https://gitea.evolix.org/evolix/ansible-roles/issues license: GPLv2 - min_ansible_version: 2.2 + min_ansible_version: "2.2" platforms: - - name: Debian - versions: - - jessie + - name: Debian + versions: + - jessie + - stretch + - buster + + galaxy_tags: [] + # List tags for your role here, one per line. A tag is + # a keyword that describes and categorizes the role. + # Users find roles by searching for tags. Be sure to + # remove the '[]' above if you add tags to this list. + # + # NOTE: A tag is limited to a single word comprised of + # alphanumeric characters. Maximum 20 tags per role. dependencies: [] # List your role dependencies here, one per line. diff --git a/filebeat/meta/main.yml b/filebeat/meta/main.yml index 97898e88..ce487942 100644 --- a/filebeat/meta/main.yml +++ b/filebeat/meta/main.yml @@ -1,18 +1,28 @@ galaxy_info: - author: Evolix + company: Evolix description: Installation and basic configuration of Filebeat. issue_tracker_url: https://gitea.evolix.org/evolix/ansible-roles/issues license: GPLv2 - min_ansible_version: 2.2 + min_ansible_version: "2.2" platforms: - - name: Debian - versions: - - jessie - - stretch + - name: Debian + versions: + - jessie + - stretch + - buster + + galaxy_tags: [] + # List tags for your role here, one per line. A tag is + # a keyword that describes and categorizes the role. + # Users find roles by searching for tags. Be sure to + # remove the '[]' above if you add tags to this list. + # + # NOTE: A tag is limited to a single word comprised of + # alphanumeric characters. Maximum 20 tags per role. dependencies: [] # List your role dependencies here, one per line. diff --git a/fluentd/meta/main.yml b/fluentd/meta/main.yml index 3bbff0c4..ff74528b 100644 --- a/fluentd/meta/main.yml +++ b/fluentd/meta/main.yml @@ -1,18 +1,28 @@ galaxy_info: - author: Evolix + company: Evolix description: Installation and basic configuration of Fluentd. issue_tracker_url: https://gitea.evolix.org/evolix/ansible-roles/issues license: GPLv2 - min_ansible_version: 2.2 + min_ansible_version: "2.2" platforms: - - name: Debian - versions: - - jessie - - stretch + - name: Debian + versions: + - jessie + - stretch + - buster + + galaxy_tags: [] + # List tags for your role here, one per line. A tag is + # a keyword that describes and categorizes the role. + # Users find roles by searching for tags. Be sure to + # remove the '[]' above if you add tags to this list. + # + # NOTE: A tag is limited to a single word comprised of + # alphanumeric characters. Maximum 20 tags per role. dependencies: [] # List your role dependencies here, one per line. diff --git a/haproxy/meta/main.yml b/haproxy/meta/main.yml index 32b06065..be1f56a8 100644 --- a/haproxy/meta/main.yml +++ b/haproxy/meta/main.yml @@ -1,17 +1,28 @@ galaxy_info: - author: Evolix + company: Evolix description: Installation and basic configuration of HAProxy issue_tracker_url: https://gitea.evolix.org/evolix/ansible-roles/issues license: GPLv2 - min_ansible_version: 2.2 + min_ansible_version: "2.2" platforms: - - name: Debian - versions: - - jessie + - name: Debian + versions: + - jessie + - stretch + - buster + + galaxy_tags: [] + # List tags for your role here, one per line. A tag is + # a keyword that describes and categorizes the role. + # Users find roles by searching for tags. Be sure to + # remove the '[]' above if you add tags to this list. + # + # NOTE: A tag is limited to a single word comprised of + # alphanumeric characters. Maximum 20 tags per role. dependencies: [] # List your role dependencies here, one per line. diff --git a/java/meta/main.yml b/java/meta/main.yml index 9f4d9ab5..719b9ee0 100644 --- a/java/meta/main.yml +++ b/java/meta/main.yml @@ -1,16 +1,26 @@ --- galaxy_info: - author: Evolix + company: Evolix description: Installation of Java issue_tracker_url: https://gitea.evolix.org/evolix/ansible-roles/issues license: GPLv2 - min_ansible_version: 2.2 + min_ansible_version: "2.2" platforms: - - name: Debian - versions: - - jessie - - stretch + - name: Debian + versions: + - jessie + - stretch + - buster + + galaxy_tags: [] + # List tags for your role here, one per line. A tag is + # a keyword that describes and categorizes the role. + # Users find roles by searching for tags. Be sure to + # remove the '[]' above if you add tags to this list. + # + # NOTE: A tag is limited to a single word comprised of + # alphanumeric characters. Maximum 20 tags per role. diff --git a/jenkins/meta/main.yml b/jenkins/meta/main.yml index 7120e512..253b4372 100644 --- a/jenkins/meta/main.yml +++ b/jenkins/meta/main.yml @@ -1,18 +1,20 @@ --- galaxy_info: - author: Evolix + company: Evolix description: Install Jenkins issue_tracker_url: https://gitea.evolix.org/evolix/ansible-roles/issues license: GPLv2 - min_ansible_version: 2.2 + min_ansible_version: "2.2" platforms: - - name: Debian - versions: - - jessie + - name: Debian + versions: + - jessie + - stretch + - buster galaxy_tags: [] # List tags for your role here, one per line. A tag is diff --git a/kibana/meta/main.yml b/kibana/meta/main.yml index 4b8408f6..25034e03 100644 --- a/kibana/meta/main.yml +++ b/kibana/meta/main.yml @@ -1,18 +1,28 @@ galaxy_info: - author: Evolix + company: Evolix description: Installation and basic configuration of Kibana. issue_tracker_url: https://gitea.evolix.org/evolix/ansible-roles/issues license: GPLv2 - min_ansible_version: 2.2 + min_ansible_version: "2.2" platforms: - - name: Debian - versions: - - jessie - - stretch + - name: Debian + versions: + - jessie + - stretch + - buster + + galaxy_tags: [] + # List tags for your role here, one per line. A tag is + # a keyword that describes and categorizes the role. + # Users find roles by searching for tags. Be sure to + # remove the '[]' above if you add tags to this list. + # + # NOTE: A tag is limited to a single word comprised of + # alphanumeric characters. Maximum 20 tags per role. dependencies: [] # List your role dependencies here, one per line. diff --git a/kvm-host/meta/main.yml b/kvm-host/meta/main.yml index c10a727c..c8c8988c 100644 --- a/kvm-host/meta/main.yml +++ b/kvm-host/meta/main.yml @@ -1,10 +1,8 @@ --- galaxy_info: - author: Evolix company: Evolix description: Install tools to set-up a KVM host - galaxy_tags: [] issue_tracker_url: https://gitea.evolix.org/evolix/ansible-roles/issues @@ -13,8 +11,17 @@ galaxy_info: min_ansible_version: "2.2" platforms: - - name: Debian - versions: - - jessie - - stretch - - buster + - name: Debian + versions: + - jessie + - stretch + - buster + + galaxy_tags: [] + # List tags for your role here, one per line. A tag is + # a keyword that describes and categorizes the role. + # Users find roles by searching for tags. Be sure to + # remove the '[]' above if you add tags to this list. + # + # NOTE: A tag is limited to a single word comprised of + # alphanumeric characters. Maximum 20 tags per role. diff --git a/ldap/meta/main.yml b/ldap/meta/main.yml index aace73c2..94ed8c34 100644 --- a/ldap/meta/main.yml +++ b/ldap/meta/main.yml @@ -1,17 +1,28 @@ galaxy_info: - author: Evolix + company: Evolix description: Installation and basic configuration of ldap. issue_tracker_url: https://gitea.evolix.org/evolix/ansible-roles/issues license: GPLv2 - min_ansible_version: 2.2 + min_ansible_version: "2.2" platforms: - - name: Debian - versions: - - jessie + - name: Debian + versions: + - jessie + - stretch + - buster + + galaxy_tags: [] + # List tags for your role here, one per line. A tag is + # a keyword that describes and categorizes the role. + # Users find roles by searching for tags. Be sure to + # remove the '[]' above if you add tags to this list. + # + # NOTE: A tag is limited to a single word comprised of + # alphanumeric characters. Maximum 20 tags per role. dependencies: [] # List your role dependencies here, one per line. diff --git a/listupgrade/meta/main.yml b/listupgrade/meta/main.yml index 29c56478..1d75ceff 100644 --- a/listupgrade/meta/main.yml +++ b/listupgrade/meta/main.yml @@ -1,17 +1,19 @@ galaxy_info: - author: Evolix + company: Evolix description: Installation and configuration of the listupgrade script issue_tracker_url: https://gitea.evolix.org/evolix/ansible-roles/issues license: GPLv2 - min_ansible_version: 2.2 + min_ansible_version: "2.2" platforms: - - name: Debian - versions: - - jessie + - name: Debian + versions: + - jessie + - stretch + - buster galaxy_tags: [] # List tags for your role here, one per line. A tag is diff --git a/logstash/meta/main.yml b/logstash/meta/main.yml index 489fa419..b2ef1210 100644 --- a/logstash/meta/main.yml +++ b/logstash/meta/main.yml @@ -1,17 +1,28 @@ galaxy_info: - author: Evolix + company: Evolix description: Installation and basic configuration of Logstash. issue_tracker_url: https://gitea.evolix.org/evolix/ansible-roles/issues license: GPLv2 - min_ansible_version: 2.2 + min_ansible_version: "2.2" platforms: - - name: Debian - versions: - - jessie + - name: Debian + versions: + - jessie + - stretch + - buster + + galaxy_tags: [] + # List tags for your role here, one per line. A tag is + # a keyword that describes and categorizes the role. + # Users find roles by searching for tags. Be sure to + # remove the '[]' above if you add tags to this list. + # + # NOTE: A tag is limited to a single word comprised of + # alphanumeric characters. Maximum 20 tags per role. dependencies: - { role: evolix/java, java_alternative: 'openjdk', java_version: 8 } diff --git a/lxc-php/meta/main.yml b/lxc-php/meta/main.yml index 3c965d43..58c2298c 100644 --- a/lxc-php/meta/main.yml +++ b/lxc-php/meta/main.yml @@ -1,18 +1,29 @@ +--- galaxy_info: - author: Evolix + company: Evolix description: Creation of LXC Containers & Setting up PHP-FPM for a multiphp setup issue_tracker_url: https://gitea.evolix.org/evolix/ansible-roles/issues license: GPLv2 - min_ansible_version: 2.2 + min_ansible_version: "2.2" platforms: - - name: Debian - versions: - - stretch - - buster + - name: Debian + versions: + - jessie + - stretch + - buster + + galaxy_tags: [] + # List tags for your role here, one per line. A tag is + # a keyword that describes and categorizes the role. + # Users find roles by searching for tags. Be sure to + # remove the '[]' above if you add tags to this list. + # + # NOTE: A tag is limited to a single word comprised of + # alphanumeric characters. Maximum 20 tags per role. allow_duplicates: yes diff --git a/lxc/meta/main.yml b/lxc/meta/main.yml index 6208702b..cd47f609 100644 --- a/lxc/meta/main.yml +++ b/lxc/meta/main.yml @@ -1,17 +1,28 @@ +--- galaxy_info: - author: Evolix + company: Evolix description: Creation of LXC Containers issue_tracker_url: https://gitea.evolix.org/evolix/ansible-roles/issues license: GPLv2 - min_ansible_version: 2.2 + min_ansible_version: "2.2" platforms: - - name: Debian - versions: - - stretch - - buster + - name: Debian + versions: + - jessie + - stretch + - buster + + galaxy_tags: [] + # List tags for your role here, one per line. A tag is + # a keyword that describes and categorizes the role. + # Users find roles by searching for tags. Be sure to + # remove the '[]' above if you add tags to this list. + # + # NOTE: A tag is limited to a single word comprised of + # alphanumeric characters. Maximum 20 tags per role. allow_duplicates: yes diff --git a/memcached/meta/main.yml b/memcached/meta/main.yml index 6e4ba6d8..022facc7 100644 --- a/memcached/meta/main.yml +++ b/memcached/meta/main.yml @@ -1,17 +1,29 @@ +--- galaxy_info: - author: Evolix + company: Evolix description: Installation and basic configuration of memcached. issue_tracker_url: https://gitea.evolix.org/evolix/ansible-roles/issues license: GPLv2 - min_ansible_version: 2.2 + min_ansible_version: "2.2" platforms: - - name: Debian - versions: - - jessie + - name: Debian + versions: + - jessie + - stretch + - buster + + galaxy_tags: [] + # List tags for your role here, one per line. A tag is + # a keyword that describes and categorizes the role. + # Users find roles by searching for tags. Be sure to + # remove the '[]' above if you add tags to this list. + # + # NOTE: A tag is limited to a single word comprised of + # alphanumeric characters. Maximum 20 tags per role. dependencies: [] # List your role dependencies here, one per line. diff --git a/metricbeat/meta/main.yml b/metricbeat/meta/main.yml index 880790f5..697726d8 100644 --- a/metricbeat/meta/main.yml +++ b/metricbeat/meta/main.yml @@ -1,18 +1,28 @@ galaxy_info: - author: Evolix + company: Evolix description: Installation and basic configuration of Metricbeat. issue_tracker_url: https://gitea.evolix.org/evolix/ansible-roles/issues license: GPLv2 - min_ansible_version: 2.2 + min_ansible_version: "2.2" platforms: - - name: Debian - versions: - - jessie - - stretch + - name: Debian + versions: + - jessie + - stretch + - buster + + galaxy_tags: [] + # List tags for your role here, one per line. A tag is + # a keyword that describes and categorizes the role. + # Users find roles by searching for tags. Be sure to + # remove the '[]' above if you add tags to this list. + # + # NOTE: A tag is limited to a single word comprised of + # alphanumeric characters. Maximum 20 tags per role. dependencies: [] # List your role dependencies here, one per line. diff --git a/minifirewall/meta/main.yml b/minifirewall/meta/main.yml index b8cca373..51dcd9cb 100644 --- a/minifirewall/meta/main.yml +++ b/minifirewall/meta/main.yml @@ -1,17 +1,28 @@ galaxy_info: - author: Evolix + company: Evolix description: Installation and configuration of Minifirewall issue_tracker_url: https://gitea.evolix.org/evolix/ansible-roles/issues license: GPLv2 - min_ansible_version: 2.2 + min_ansible_version: "2.2" platforms: - - name: Debian - versions: - - jessie + - name: Debian + versions: + - jessie + - stretch + - buster + + galaxy_tags: [] + # List tags for your role here, one per line. A tag is + # a keyword that describes and categorizes the role. + # Users find roles by searching for tags. Be sure to + # remove the '[]' above if you add tags to this list. + # + # NOTE: A tag is limited to a single word comprised of + # alphanumeric characters. Maximum 20 tags per role. dependencies: [] # List your role dependencies here, one per line. diff --git a/mongodb/meta/main.yml b/mongodb/meta/main.yml index 72e764e2..cf463d73 100644 --- a/mongodb/meta/main.yml +++ b/mongodb/meta/main.yml @@ -5,12 +5,14 @@ galaxy_info: license: GPLv2 - min_ansible_version: 2.2 + min_ansible_version: "2.2" platforms: - - name: Debian - versions: - - jessie + - name: Debian + versions: + - jessie + - stretch + - buster galaxy_tags: [] # List tags for your role here, one per line. A tag is diff --git a/monit/meta/main.yml b/monit/meta/main.yml index 4a22e18c..64d96a7d 100644 --- a/monit/meta/main.yml +++ b/monit/meta/main.yml @@ -1,17 +1,28 @@ galaxy_info: - author: Evolix + company: Evolix description: Installation and basic configuration of Monit. issue_tracker_url: https://gitea.evolix.org/evolix/ansible-roles/issues license: GPLv2 - min_ansible_version: 2.2 + min_ansible_version: "2.2" platforms: - - name: Debian - versions: - - jessie + - name: Debian + versions: + - jessie + - stretch + - buster + + galaxy_tags: [] + # List tags for your role here, one per line. A tag is + # a keyword that describes and categorizes the role. + # Users find roles by searching for tags. Be sure to + # remove the '[]' above if you add tags to this list. + # + # NOTE: A tag is limited to a single word comprised of + # alphanumeric characters. Maximum 20 tags per role. dependencies: [] # List your role dependencies here, one per line. diff --git a/munin/meta/main.yml b/munin/meta/main.yml index 7b95e655..40eee676 100644 --- a/munin/meta/main.yml +++ b/munin/meta/main.yml @@ -1,17 +1,28 @@ galaxy_info: - author: Evolix + company: Evolix description: Installation of Munin with a selection of plugins issue_tracker_url: https://gitea.evolix.org/evolix/ansible-roles/issues license: GPLv2 - min_ansible_version: 2.2 + min_ansible_version: "2.2" platforms: - - name: Debian - versions: - - jessie + - name: Debian + versions: + - jessie + - stretch + - buster + + galaxy_tags: [] + # List tags for your role here, one per line. A tag is + # a keyword that describes and categorizes the role. + # Users find roles by searching for tags. Be sure to + # remove the '[]' above if you add tags to this list. + # + # NOTE: A tag is limited to a single word comprised of + # alphanumeric characters. Maximum 20 tags per role. dependencies: [] # List your role dependencies here, one per line. diff --git a/mysql-oracle/meta/main.yml b/mysql-oracle/meta/main.yml index 963a0494..5479f9db 100644 --- a/mysql-oracle/meta/main.yml +++ b/mysql-oracle/meta/main.yml @@ -1,18 +1,28 @@ galaxy_info: - author: Evolix + company: Evolix description: Install and configure MySQL 5.7 (with Oracle packages) issue_tracker_url: https://gitea.evolix.org/evolix/ansible-roles/issues license: GPLv2 - min_ansible_version: 2.2 + min_ansible_version: "2.2" platforms: - - name: Debian - versions: - - jessie - - stretch + - name: Debian + versions: + - jessie + - stretch + - buster + + galaxy_tags: [] + # List tags for your role here, one per line. A tag is + # a keyword that describes and categorizes the role. + # Users find roles by searching for tags. Be sure to + # remove the '[]' above if you add tags to this list. + # + # NOTE: A tag is limited to a single word comprised of + # alphanumeric characters. Maximum 20 tags per role. dependencies: [] # List your role dependencies here, one per line. diff --git a/mysql/meta/main.yml b/mysql/meta/main.yml index 82be1e3c..bd21f0c6 100644 --- a/mysql/meta/main.yml +++ b/mysql/meta/main.yml @@ -1,17 +1,28 @@ galaxy_info: - author: Evolix + company: Evolix description: your description issue_tracker_url: https://gitea.evolix.org/evolix/ansible-roles/issues license: GPLv2 - min_ansible_version: 2.2 + min_ansible_version: "2.2" platforms: - - name: Debian - versions: - - jessie + - name: Debian + versions: + - jessie + - stretch + - buster + + galaxy_tags: [] + # List tags for your role here, one per line. A tag is + # a keyword that describes and categorizes the role. + # Users find roles by searching for tags. Be sure to + # remove the '[]' above if you add tags to this list. + # + # NOTE: A tag is limited to a single word comprised of + # alphanumeric characters. Maximum 20 tags per role. dependencies: [] # List your role dependencies here, one per line. diff --git a/nagios-nrpe/meta/main.yml b/nagios-nrpe/meta/main.yml index acdb111c..0a9458d5 100644 --- a/nagios-nrpe/meta/main.yml +++ b/nagios-nrpe/meta/main.yml @@ -1,17 +1,28 @@ galaxy_info: - author: Evolix + company: Evolix description: Installation and custom configuration of Nagios NRPE server. issue_tracker_url: https://gitea.evolix.org/evolix/ansible-roles/issues license: GPLv2 - min_ansible_version: 2.2 + min_ansible_version: "2.2" platforms: - - name: Debian - versions: - - jessie + - name: Debian + versions: + - jessie + - stretch + - buster + + galaxy_tags: [] + # List tags for your role here, one per line. A tag is + # a keyword that describes and categorizes the role. + # Users find roles by searching for tags. Be sure to + # remove the '[]' above if you add tags to this list. + # + # NOTE: A tag is limited to a single word comprised of + # alphanumeric characters. Maximum 20 tags per role. dependencies: [] # List your role dependencies here, one per line. diff --git a/networkd-to-ifconfig/meta/main.yml b/networkd-to-ifconfig/meta/main.yml index 7040a19e..4ecab164 100644 --- a/networkd-to-ifconfig/meta/main.yml +++ b/networkd-to-ifconfig/meta/main.yml @@ -1,17 +1,28 @@ galaxy_info: - author: Evolix + company: Evolix description: Switch back from systemd "networkd" to plain old /etc/network/interfaces. issue_tracker_url: https://gitea.evolix.org/evolix/ansible-roles/issues license: GPLv2 - min_ansible_version: 2.2 + min_ansible_version: "2.2" platforms: - - name: Debian - versions: - - stretch + - name: Debian + versions: + - jessie + - stretch + - buster + + galaxy_tags: [] + # List tags for your role here, one per line. A tag is + # a keyword that describes and categorizes the role. + # Users find roles by searching for tags. Be sure to + # remove the '[]' above if you add tags to this list. + # + # NOTE: A tag is limited to a single word comprised of + # alphanumeric characters. Maximum 20 tags per role. dependencies: [] # List your role dependencies here, one per line. diff --git a/newrelic/meta/main.yml b/newrelic/meta/main.yml index 0436c6ae..dc077c68 100644 --- a/newrelic/meta/main.yml +++ b/newrelic/meta/main.yml @@ -1,17 +1,28 @@ galaxy_info: - author: Evolix + company: Evolix description: Installation of NewRelic tools. issue_tracker_url: https://gitea.evolix.org/evolix/ansible-roles/issues license: GPLv2 - min_ansible_version: 2.2 + min_ansible_version: "2.2" platforms: - - name: Debian - versions: - - jessie + - name: Debian + versions: + - jessie + - stretch + - buster + + galaxy_tags: [] + # List tags for your role here, one per line. A tag is + # a keyword that describes and categorizes the role. + # Users find roles by searching for tags. Be sure to + # remove the '[]' above if you add tags to this list. + # + # NOTE: A tag is limited to a single word comprised of + # alphanumeric characters. Maximum 20 tags per role. dependencies: [] # List your role dependencies here, one per line. diff --git a/nginx/meta/main.yml b/nginx/meta/main.yml index 39382693..d4530276 100644 --- a/nginx/meta/main.yml +++ b/nginx/meta/main.yml @@ -1,17 +1,28 @@ galaxy_info: - author: Evolix + company: Evolix description: Installation and basic configuration of Nginx issue_tracker_url: https://gitea.evolix.org/evolix/ansible-roles/issues license: GPLv2 - min_ansible_version: 2.2 + min_ansible_version: "2.2" platforms: - - name: Debian - versions: - - jessie + - name: Debian + versions: + - jessie + - stretch + - buster + + galaxy_tags: [] + # List tags for your role here, one per line. A tag is + # a keyword that describes and categorizes the role. + # Users find roles by searching for tags. Be sure to + # remove the '[]' above if you add tags to this list. + # + # NOTE: A tag is limited to a single word comprised of + # alphanumeric characters. Maximum 20 tags per role. dependencies: [] # List your role dependencies here, one per line. diff --git a/nodejs/meta/main.yml b/nodejs/meta/main.yml index fa8e2dd2..1e928446 100644 --- a/nodejs/meta/main.yml +++ b/nodejs/meta/main.yml @@ -1,17 +1,28 @@ galaxy_info: - author: Evolix + company: Evolix description: Installation of NodeJS from NPM repositories issue_tracker_url: https://gitea.evolix.org/evolix/ansible-roles/issues license: GPLv2 - min_ansible_version: 2.2 + min_ansible_version: "2.2" platforms: - - name: Debian - versions: - - jessie + - name: Debian + versions: + - jessie + - stretch + - buster + + galaxy_tags: [] + # List tags for your role here, one per line. A tag is + # a keyword that describes and categorizes the role. + # Users find roles by searching for tags. Be sure to + # remove the '[]' above if you add tags to this list. + # + # NOTE: A tag is limited to a single word comprised of + # alphanumeric characters. Maximum 20 tags per role. dependencies: [] # List your role dependencies here, one per line. diff --git a/packweb-apache/meta/main.yml b/packweb-apache/meta/main.yml index 4494dcb4..7033e7e9 100644 --- a/packweb-apache/meta/main.yml +++ b/packweb-apache/meta/main.yml @@ -1,19 +1,28 @@ galaxy_info: - author: Evolix + company: Evolix description: Installation of Evolix "Pack Web" meta-role issue_tracker_url: https://gitea.evolix.org/evolix/ansible-roles/issues license: GPLv2 - min_ansible_version: 2.2 + min_ansible_version: "2.2" platforms: - - name: Debian - versions: - - jessie - - stretch - - buster + - name: Debian + versions: + - jessie + - stretch + - buster + + galaxy_tags: [] + # List tags for your role here, one per line. A tag is + # a keyword that describes and categorizes the role. + # Users find roles by searching for tags. Be sure to + # remove the '[]' above if you add tags to this list. + # + # NOTE: A tag is limited to a single word comprised of + # alphanumeric characters. Maximum 20 tags per role. allow_duplicates: true diff --git a/php/meta/main.yml b/php/meta/main.yml index 7f5ff289..3d9f77c3 100644 --- a/php/meta/main.yml +++ b/php/meta/main.yml @@ -1,18 +1,28 @@ galaxy_info: - author: Evolix + company: Evolix description: Installation and basic configuration of php-fpm. issue_tracker_url: https://gitea.evolix.org/evolix/ansible-roles/issues license: GPLv2 - min_ansible_version: 2.2 + min_ansible_version: "2.2" platforms: - - name: Debian - versions: - - jessie - - stretch + - name: Debian + versions: + - jessie + - stretch + - buster + + galaxy_tags: [] + # List tags for your role here, one per line. A tag is + # a keyword that describes and categorizes the role. + # Users find roles by searching for tags. Be sure to + # remove the '[]' above if you add tags to this list. + # + # NOTE: A tag is limited to a single word comprised of + # alphanumeric characters. Maximum 20 tags per role. dependencies: [] # List your role dependencies here, one per line. diff --git a/postfix/meta/main.yml b/postfix/meta/main.yml index fe59228a..188769a2 100644 --- a/postfix/meta/main.yml +++ b/postfix/meta/main.yml @@ -1,17 +1,28 @@ galaxy_info: - author: Evolix + company: Evolix description: Installation and basic configuration of Postfix. issue_tracker_url: https://gitea.evolix.org/evolix/ansible-roles/issues license: GPLv2 - min_ansible_version: 2.2 + min_ansible_version: "2.2" platforms: - - name: Debian - versions: - - jessie + - name: Debian + versions: + - jessie + - stretch + - buster + + galaxy_tags: [] + # List tags for your role here, one per line. A tag is + # a keyword that describes and categorizes the role. + # Users find roles by searching for tags. Be sure to + # remove the '[]' above if you add tags to this list. + # + # NOTE: A tag is limited to a single word comprised of + # alphanumeric characters. Maximum 20 tags per role. dependencies: - { role: evolix/ldap, ldap_schema: 'cn4evolix.ldif', when: postfix_packmail == True } diff --git a/postgresql/meta/main.yml b/postgresql/meta/main.yml index 53ee0fcb..ccdc1dda 100644 --- a/postgresql/meta/main.yml +++ b/postgresql/meta/main.yml @@ -1,17 +1,28 @@ galaxy_info: - author: Evolix + company: Evolix description: Installation and basic configuration of PostgreSQL issue_tracker_url: https://gitea.evolix.org/evolix/ansible-roles/issues license: GPLv2 - min_ansible_version: 2.2 + min_ansible_version: "2.2" platforms: - - name: Debian - versions: - - jessie + - name: Debian + versions: + - jessie + - stretch + - buster + + galaxy_tags: [] + # List tags for your role here, one per line. A tag is + # a keyword that describes and categorizes the role. + # Users find roles by searching for tags. Be sure to + # remove the '[]' above if you add tags to this list. + # + # NOTE: A tag is limited to a single word comprised of + # alphanumeric characters. Maximum 20 tags per role. dependencies: [] # List your role dependencies here, one per line. diff --git a/proftpd/meta/main.yml b/proftpd/meta/main.yml index 1632f33a..60fb0fa9 100644 --- a/proftpd/meta/main.yml +++ b/proftpd/meta/main.yml @@ -1,18 +1,28 @@ galaxy_info: - author: Evolix + company: Evolix description: Installation and basic configuration of ProFTPd issue_tracker_url: https://gitea.evolix.org/evolix/ansible-roles/issues license: GPLv2 - min_ansible_version: 2.2 + min_ansible_version: "2.2" platforms: - - name: Debian - versions: - - jessie - - stretch + - name: Debian + versions: + - jessie + - stretch + - buster + + galaxy_tags: [] + # List tags for your role here, one per line. A tag is + # a keyword that describes and categorizes the role. + # Users find roles by searching for tags. Be sure to + # remove the '[]' above if you add tags to this list. + # + # NOTE: A tag is limited to a single word comprised of + # alphanumeric characters. Maximum 20 tags per role. dependencies: [] # List your role dependencies here, one per line. diff --git a/rabbitmq/meta/main.yml b/rabbitmq/meta/main.yml index a5c7d425..1fd89e27 100644 --- a/rabbitmq/meta/main.yml +++ b/rabbitmq/meta/main.yml @@ -1,18 +1,28 @@ galaxy_info: - author: Evolix + company: Evolix description: Installation and basic configuration of RabbitMq issue_tracker_url: https://gitea.evolix.org/evolix/ansible-roles/issues license: GPLv2 - min_ansible_version: 2.2 + min_ansible_version: "2.2" platforms: - - name: Debian - versions: - - jessie - - buster + - name: Debian + versions: + - jessie + - stretch + - buster + + galaxy_tags: [] + # List tags for your role here, one per line. A tag is + # a keyword that describes and categorizes the role. + # Users find roles by searching for tags. Be sure to + # remove the '[]' above if you add tags to this list. + # + # NOTE: A tag is limited to a single word comprised of + # alphanumeric characters. Maximum 20 tags per role. dependencies: [] # List your role dependencies here, one per line. diff --git a/rbenv/meta/main.yml b/rbenv/meta/main.yml index 5da4ee43..41113441 100644 --- a/rbenv/meta/main.yml +++ b/rbenv/meta/main.yml @@ -1,17 +1,28 @@ galaxy_info: - author: Evolix + company: Evolix description: Installation of Rbenv, Ruby and some default gems. issue_tracker_url: https://gitea.evolix.org/evolix/ansible-roles/issues license: GPLv2 - min_ansible_version: 2.2 + min_ansible_version: "2.2" platforms: - - name: Debian - versions: - - jessie + - name: Debian + versions: + - jessie + - stretch + - buster + + galaxy_tags: [] + # List tags for your role here, one per line. A tag is + # a keyword that describes and categorizes the role. + # Users find roles by searching for tags. Be sure to + # remove the '[]' above if you add tags to this list. + # + # NOTE: A tag is limited to a single word comprised of + # alphanumeric characters. Maximum 20 tags per role. dependencies: [] # List your role dependencies here, one per line. diff --git a/redis/meta/main.yml b/redis/meta/main.yml index 339e926c..f465a547 100644 --- a/redis/meta/main.yml +++ b/redis/meta/main.yml @@ -1,17 +1,28 @@ galaxy_info: - author: Evolix + company: Evolix description: Installation and basic configuration of Redis. issue_tracker_url: https://gitea.evolix.org/evolix/ansible-roles/issues license: GPLv2 - min_ansible_version: 2.2 + min_ansible_version: "2.2" platforms: - - name: Debian - versions: - - jessie + - name: Debian + versions: + - jessie + - stretch + - buster + + galaxy_tags: [] + # List tags for your role here, one per line. A tag is + # a keyword that describes and categorizes the role. + # Users find roles by searching for tags. Be sure to + # remove the '[]' above if you add tags to this list. + # + # NOTE: A tag is limited to a single word comprised of + # alphanumeric characters. Maximum 20 tags per role. dependencies: [] # List your role dependencies here, one per line. diff --git a/squid/meta/main.yml b/squid/meta/main.yml index 1c6287ea..ee20ff5f 100644 --- a/squid/meta/main.yml +++ b/squid/meta/main.yml @@ -1,18 +1,28 @@ galaxy_info: - author: Evolix + company: Evolix description: Installatin and configuration of Squid as an outgoing proxy. issue_tracker_url: https://gitea.evolix.org/evolix/ansible-roles/issues license: GPLv2 - min_ansible_version: 2.2 + min_ansible_version: "2.2" platforms: - - name: Debian - versions: - - jessie - - stretch + - name: Debian + versions: + - jessie + - stretch + - buster + + galaxy_tags: [] + # List tags for your role here, one per line. A tag is + # a keyword that describes and categorizes the role. + # Users find roles by searching for tags. Be sure to + # remove the '[]' above if you add tags to this list. + # + # NOTE: A tag is limited to a single word comprised of + # alphanumeric characters. Maximum 20 tags per role. dependencies: [] # List your role dependencies here, one per line. diff --git a/ssl/meta/main.yml b/ssl/meta/main.yml index 19ef50ef..575baa70 100644 --- a/ssl/meta/main.yml +++ b/ssl/meta/main.yml @@ -1,18 +1,28 @@ galaxy_info: - author: Evolix + company: Evolix description: Deployment of SSL certificate, key and dhparams issue_tracker_url: https://gitea.evolix.org/evolix/ansible-roles/issues license: GPLv2 - min_ansible_version: 2.2 + min_ansible_version: "2.2" platforms: - - name: Debian - versions: - - jessie - - stretch + - name: Debian + versions: + - jessie + - stretch + - buster + + galaxy_tags: [] + # List tags for your role here, one per line. A tag is + # a keyword that describes and categorizes the role. + # Users find roles by searching for tags. Be sure to + # remove the '[]' above if you add tags to this list. + # + # NOTE: A tag is limited to a single word comprised of + # alphanumeric characters. Maximum 20 tags per role. dependencies: [] # List your role dependencies here, one per line. diff --git a/tomcat-instance/meta/main.yml b/tomcat-instance/meta/main.yml index 692e2d44..98a9de51 100644 --- a/tomcat-instance/meta/main.yml +++ b/tomcat-instance/meta/main.yml @@ -1,18 +1,29 @@ --- galaxy_info: - author: Evolix + company: Evolix description: Configuration of a Tomcat instance. issue_tracker_url: https://gitea.evolix.org/evolix/ansible-roles/issues license: GPLv2 - min_ansible_version: 2.2 + min_ansible_version: "2.2" platforms: - - name: Debian - versions: - - jessie + - name: Debian + versions: + - jessie + - stretch + - buster + + galaxy_tags: [] + # List tags for your role here, one per line. A tag is + # a keyword that describes and categorizes the role. + # Users find roles by searching for tags. Be sure to + # remove the '[]' above if you add tags to this list. + # + # NOTE: A tag is limited to a single word comprised of + # alphanumeric characters. Maximum 20 tags per role. dependencies: - { role: evolix/tomcat } diff --git a/tomcat/meta/main.yml b/tomcat/meta/main.yml index 28ecbd53..e612c99c 100644 --- a/tomcat/meta/main.yml +++ b/tomcat/meta/main.yml @@ -1,17 +1,28 @@ galaxy_info: - author: Evolix + company: Evolix description: Installation of a Tomcat. issue_tracker_url: https://gitea.evolix.org/evolix/ansible-roles/issues license: GPLv2 - min_ansible_version: 2.2 + min_ansible_version: "2.2" platforms: - - name: Debian - versions: - - jessie + - name: Debian + versions: + - jessie + - stretch + - buster + + galaxy_tags: [] + # List tags for your role here, one per line. A tag is + # a keyword that describes and categorizes the role. + # Users find roles by searching for tags. Be sure to + # remove the '[]' above if you add tags to this list. + # + # NOTE: A tag is limited to a single word comprised of + # alphanumeric characters. Maximum 20 tags per role. dependencies: [] # List your role dependencies here, one per line. diff --git a/varnish/meta/main.yml b/varnish/meta/main.yml index 855101e1..d969cd4b 100644 --- a/varnish/meta/main.yml +++ b/varnish/meta/main.yml @@ -1,17 +1,28 @@ galaxy_info: - author: Evolix + company: Evolix description: Installation and basic configuration of Varnish issue_tracker_url: https://gitea.evolix.org/evolix/ansible-roles/issues license: GPLv2 - min_ansible_version: 2.2 + min_ansible_version: "2.2" platforms: - - name: Debian - versions: - - jessie + - name: Debian + versions: + - jessie + - stretch + - buster + + galaxy_tags: [] + # List tags for your role here, one per line. A tag is + # a keyword that describes and categorizes the role. + # Users find roles by searching for tags. Be sure to + # remove the '[]' above if you add tags to this list. + # + # NOTE: A tag is limited to a single word comprised of + # alphanumeric characters. Maximum 20 tags per role. dependencies: [] # List your role dependencies here, one per line. diff --git a/vrrpd/meta/main.yml b/vrrpd/meta/main.yml index 222df302..82eca7a2 100644 --- a/vrrpd/meta/main.yml +++ b/vrrpd/meta/main.yml @@ -1,14 +1,25 @@ galaxy_info: - author: Evolix + company: Evolix description: Install Evolix's patched vrrpd and adjust sysctl params. issue_tracker_url: https://gitea.evolix.org/evolix/ansible-roles/issues license: GPLv2 - min_ansible_version: 2.2 + min_ansible_version: "2.2" platforms: - - name: Debian - versions: - - jessie + - name: Debian + versions: + - jessie + - stretch + - buster + + galaxy_tags: [] + # List tags for your role here, one per line. A tag is + # a keyword that describes and categorizes the role. + # Users find roles by searching for tags. Be sure to + # remove the '[]' above if you add tags to this list. + # + # NOTE: A tag is limited to a single word comprised of + # alphanumeric characters. Maximum 20 tags per role. \ No newline at end of file diff --git a/webapps/evoadmin-web/meta/main.yml b/webapps/evoadmin-web/meta/main.yml index cf2ad4e5..2c6da2f4 100644 --- a/webapps/evoadmin-web/meta/main.yml +++ b/webapps/evoadmin-web/meta/main.yml @@ -1,19 +1,29 @@ --- galaxy_info: - author: Evolix + company: Evolix description: Installation of evoadmin-web issue_tracker_url: https://gitea.evolix.org/evolix/ansible-roles/issues license: GPLv2 - min_ansible_version: 2.2 + min_ansible_version: "2.2" platforms: - name: Debian versions: - jessie - stretch + - buster + + galaxy_tags: [] + # List tags for your role here, one per line. A tag is + # a keyword that describes and categorizes the role. + # Users find roles by searching for tags. Be sure to + # remove the '[]' above if you add tags to this list. + # + # NOTE: A tag is limited to a single word comprised of + # alphanumeric characters. Maximum 20 tags per role. dependencies: - { role: evolix/proftpd } diff --git a/webapps/wordpress/meta/main.yml b/webapps/wordpress/meta/main.yml index 2adf765b..89f9b27b 100644 --- a/webapps/wordpress/meta/main.yml +++ b/webapps/wordpress/meta/main.yml @@ -1,17 +1,28 @@ galaxy_info: - author: Evolix + company: Evolix description: Install Wordpress site issue_tracker_url: https://gitea.evolix.org/evolix/ansible-roles/issues license: GPLv2 - min_ansible_version: 2.2 + min_ansible_version: "2.2" platforms: - - name: Debian - versions: - - jessie + - name: Debian + versions: + - jessie + - stretch + - buster + + galaxy_tags: [] + # List tags for your role here, one per line. A tag is + # a keyword that describes and categorizes the role. + # Users find roles by searching for tags. Be sure to + # remove the '[]' above if you add tags to this list. + # + # NOTE: A tag is limited to a single word comprised of + # alphanumeric characters. Maximum 20 tags per role. dependencies: [] # List your role dependencies here, one per line. From 55ad6882b594ecb3a59738cf3a6d9d42b7ece1cb Mon Sep 17 00:00:00 2001 From: Jeremy Lecour Date: Mon, 28 Jun 2021 15:26:54 +0200 Subject: [PATCH 81/86] evolinux-base: forgotten case for first-found lookup --- evolinux-base/tasks/motd.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/evolinux-base/tasks/motd.yml b/evolinux-base/tasks/motd.yml index 9d5a109d..70079463 100644 --- a/evolinux-base/tasks/motd.yml +++ b/evolinux-base/tasks/motd.yml @@ -13,5 +13,6 @@ - "templates/motd/motd.{{ inventory_hostname }}.j2" - "templates/motd/motd.{{ host_group | default('all') }}.j2" - "templates/motd/motd.default.j2" + - "templates/motd.default.j2" tags: - motd From 6d757f971eccf4649ff05cb222605d5d14c1b8f8 Mon Sep 17 00:00:00 2001 From: Jeremy Lecour Date: Mon, 28 Jun 2021 15:36:50 +0200 Subject: [PATCH 82/86] typo --- evolinux-base/tasks/hardware.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/evolinux-base/tasks/hardware.yml b/evolinux-base/tasks/hardware.yml index 9ece740e..7f4ebf36 100644 --- a/evolinux-base/tasks/hardware.yml +++ b/evolinux-base/tasks/hardware.yml @@ -29,7 +29,7 @@ # HP gen <10: Hewlett-Packard Company Smart Array # HP gen >=10: Adaptec Smart Storage PQI - name: Detect if RAID is installed - shell: "set -o pipefila && lspci -q | grep -e 'RAID bus controller' -e 'Serial Attached SCSI controller'" + shell: "set -o pipefail && lspci -q | grep -e 'RAID bus controller' -e 'Serial Attached SCSI controller'" check_mode: no register: raidmodel changed_when: "'FAILED' in raidmodel.stdout" From b8c5ac3097ee2ef059c89e413b0d5e34d920a7e7 Mon Sep 17 00:00:00 2001 From: Jeremy Lecour Date: Mon, 28 Jun 2021 15:39:04 +0200 Subject: [PATCH 83/86] remove whitespace for stream redirection --- certbot/files/letsencrypt-auto | 6 +++--- elasticsearch/tasks/logs.yml | 2 +- etc-git/tasks/main.yml | 2 +- evoacme/files/make-csr.sh | 6 +++--- evobackup-client/templates/zzz_evobackup.default.sh.j2 | 2 +- evocheck/files/evocheck.sh | 2 +- evocheck/tasks/cron.yml | 2 +- evolinux-base/tasks/system.yml | 2 +- kvm-host/files/kvmstats.sh | 4 ++-- logstash/tasks/logs.yml | 2 +- percona/tasks/main.yml | 2 +- postfix/tasks/packmail.yml | 2 +- spamassasin/tasks/main.yml | 2 +- ssl/tasks/main.yml | 2 +- 14 files changed, 19 insertions(+), 19 deletions(-) diff --git a/certbot/files/letsencrypt-auto b/certbot/files/letsencrypt-auto index 2a0cda9b..0e26e29a 100644 --- a/certbot/files/letsencrypt-auto +++ b/certbot/files/letsencrypt-auto @@ -497,7 +497,7 @@ Python36SclIsAvailable() { # Try to enable rh-python36 from SCL if it is necessary and possible. EnablePython36SCL() { - if "$EXISTS" python3.6 > /dev/null 2> /dev/null; then + if "$EXISTS" python3.6 > /dev/null 2>/dev/null; then return 0 fi if [ ! -f /opt/rh/rh-python36/enable ]; then @@ -815,7 +815,7 @@ elif [ -f /etc/redhat-release ]; then unset LE_PYTHON DeterminePythonVersion "NOCRASH" - RPM_DIST_NAME=`(. /etc/os-release 2> /dev/null && echo $ID) || echo "unknown"` + RPM_DIST_NAME=`(. /etc/os-release 2>/dev/null && echo $ID) || echo "unknown"` if [ "$PYVER" -eq 26 -a $(uname -m) != 'x86_64' ]; then # 32 bits CentOS 6 and affiliates are not supported anymore by certbot-auto. @@ -825,7 +825,7 @@ elif [ -f /etc/redhat-release ]; then # Set RPM_DIST_VERSION to VERSION_ID from /etc/os-release after splitting on # '.' characters (e.g. "8.0" becomes "8"). If the command exits with an # error, RPM_DIST_VERSION is set to "unknown". - RPM_DIST_VERSION=$( (. /etc/os-release 2> /dev/null && echo "$VERSION_ID") | cut -d '.' -f1 || echo "unknown") + RPM_DIST_VERSION=$( (. /etc/os-release 2>/dev/null && echo "$VERSION_ID") | cut -d '.' -f1 || echo "unknown") # If RPM_DIST_VERSION is an empty string or it contains any nonnumeric # characters, the value is unexpected so we set RPM_DIST_VERSION to 0. diff --git a/elasticsearch/tasks/logs.yml b/elasticsearch/tasks/logs.yml index f7e2c0c0..01829dc9 100644 --- a/elasticsearch/tasks/logs.yml +++ b/elasticsearch/tasks/logs.yml @@ -1,7 +1,7 @@ --- - name: Check if cron is installed - shell: "set -o pipefail && dpkg -l cron 2> /dev/null | grep -q -E '^(i|h)i'" + shell: "set -o pipefail && dpkg -l cron 2>/dev/null | grep -q -E '^(i|h)i'" args: executable: /bin/bash check_mode: no diff --git a/etc-git/tasks/main.yml b/etc-git/tasks/main.yml index 5d468f60..37d1c692 100644 --- a/etc-git/tasks/main.yml +++ b/etc-git/tasks/main.yml @@ -33,7 +33,7 @@ - ansible_distribution_major_version is version('10', '>=') - name: Check if cron is installed - shell: "set -o pipefail && dpkg -l cron 2> /dev/null | grep -q -E '^(i|h)i'" + shell: "set -o pipefail && dpkg -l cron 2>/dev/null | grep -q -E '^(i|h)i'" args: executable: /bin/bash failed_when: False diff --git a/evoacme/files/make-csr.sh b/evoacme/files/make-csr.sh index edec8787..0641c1d5 100755 --- a/evoacme/files/make-csr.sh +++ b/evoacme/files/make-csr.sh @@ -112,9 +112,9 @@ openssl_selfsigned() { [ -r "${key}" ] || error "File ${key} is not readable" [ -w "${crt_dir}" ] || error "Directory ${crt_dir} is not writable" if grep -q SAN "${cfg}"; then - "${OPENSSL_BIN}" x509 -req -sha256 -days 365 -in "${csr}" -extensions SAN -extfile "${cfg}" -signkey "${key}" -out "${crt}" 2> /dev/null + "${OPENSSL_BIN}" x509 -req -sha256 -days 365 -in "${csr}" -extensions SAN -extfile "${cfg}" -signkey "${key}" -out "${crt}" 2>/dev/null else - "${OPENSSL_BIN}" x509 -req -sha256 -days 365 -in "${csr}" -signkey "${key}" -out "${crt}" 2> /dev/null + "${OPENSSL_BIN}" x509 -req -sha256 -days 365 -in "${csr}" -signkey "${key}" -out "${crt}" 2>/dev/null fi [ -r "${crt}" ] || error "Something went wrong, ${crt} has not been generated" @@ -126,7 +126,7 @@ openssl_key(){ [ -w "${key_dir}" ] || error "Directory ${key_dir} is not writable" - "${OPENSSL_BIN}" genrsa -out "${key}" "${size}" 2> /dev/null + "${OPENSSL_BIN}" genrsa -out "${key}" "${size}" 2>/dev/null [ -r "${key}" ] || error "Something went wrong, ${key} has not been generated" } diff --git a/evobackup-client/templates/zzz_evobackup.default.sh.j2 b/evobackup-client/templates/zzz_evobackup.default.sh.j2 index 49de9744..fd2be5b4 100644 --- a/evobackup-client/templates/zzz_evobackup.default.sh.j2 +++ b/evobackup-client/templates/zzz_evobackup.default.sh.j2 @@ -124,7 +124,7 @@ pick_server() { if [ -e "${PIDFILE}" ]; then pid=$(cat "${PIDFILE}") # Does process still exist ? - if kill -0 "${pid}" 2> /dev/null; then + if kill -0 "${pid}" 2>/dev/null; then # Killing the childs of evobackup. for ppid in $(pgrep -P "${pid}"); do kill -9 "${ppid}"; diff --git a/evocheck/files/evocheck.sh b/evocheck/files/evocheck.sh index 287982e2..7adf5757 100644 --- a/evocheck/files/evocheck.sh +++ b/evocheck/files/evocheck.sh @@ -109,7 +109,7 @@ is_pack_samba(){ } is_installed(){ for pkg in "$@"; do - dpkg -l "$pkg" 2> /dev/null | grep -q -E '^(i|h)i' || return 1 + dpkg -l "$pkg" 2>/dev/null | grep -q -E '^(i|h)i' || return 1 done } minifirewall_file() { diff --git a/evocheck/tasks/cron.yml b/evocheck/tasks/cron.yml index aac3f927..ecf1e1d0 100644 --- a/evocheck/tasks/cron.yml +++ b/evocheck/tasks/cron.yml @@ -1,7 +1,7 @@ --- - name: Check if cron is installed - shell: "set -o pipefail && dpkg -l cron 2> /dev/null | grep -q -E '^(i|h)i'" + shell: "set -o pipefail && dpkg -l cron 2>/dev/null | grep -q -E '^(i|h)i'" args: executable: /bin/bash failed_when: False diff --git a/evolinux-base/tasks/system.yml b/evolinux-base/tasks/system.yml index 51bcb6e3..53fa243c 100644 --- a/evolinux-base/tasks/system.yml +++ b/evolinux-base/tasks/system.yml @@ -85,7 +85,7 @@ #- name: Customizing /etc/fstab - name: Check if cron is installed - shell: "set -o pipefail && dpkg -l cron 2> /dev/null | grep -q -E '^(i|h)i'" + shell: "set -o pipefail && dpkg -l cron 2>/dev/null | grep -q -E '^(i|h)i'" args: executable: /bin/bash check_mode: no diff --git a/kvm-host/files/kvmstats.sh b/kvm-host/files/kvmstats.sh index cf2416b9..5fa20ccb 100755 --- a/kvm-host/files/kvmstats.sh +++ b/kvm-host/files/kvmstats.sh @@ -65,13 +65,13 @@ do # mem # libvirt stores memory in KiB, POW must be lowered by 1 - virsh dommemstat "$VM" 2> /dev/null | awk 'BEGIN{ret=1}$1~/^actual$/{print $2 / '$((POW / 1024))';ret=0}END{exit ret}' || + virsh dommemstat "$VM" 2>/dev/null | awk 'BEGIN{ret=1}$1~/^actual$/{print $2 / '$((POW / 1024))';ret=0}END{exit ret}' || virsh dumpxml "$VM" | awk -F'[<>]' '$2~/^memory unit/{print $3/'$((POW / 1024))'}' # disk for BLK in $(virsh domblklist "$VM" | sed '1,2d;/-$/d;/^$/d' | awk '{print $1}') do - virsh domblkinfo "$VM" "$BLK" 2> /dev/null + virsh domblkinfo "$VM" "$BLK" 2>/dev/null done | awk '/Physical:/ { size += $2 } END { print int(size / '${POW}') }' # state diff --git a/logstash/tasks/logs.yml b/logstash/tasks/logs.yml index 9eb98c1a..975cd8bc 100644 --- a/logstash/tasks/logs.yml +++ b/logstash/tasks/logs.yml @@ -1,6 +1,6 @@ --- - name: Check if cron is installed - shell: "set -o pipefail && dpkg -l cron 2> /dev/null | grep -q -E '^(i|h)i'" + shell: "set -o pipefail && dpkg -l cron 2>/dev/null | grep -q -E '^(i|h)i'" args: executable: /bin/bash check_mode: no diff --git a/percona/tasks/main.yml b/percona/tasks/main.yml index dc182e10..b14c4876 100644 --- a/percona/tasks/main.yml +++ b/percona/tasks/main.yml @@ -19,7 +19,7 @@ group: root - name: Check if percona-release is installed - shell: "set -o pipefail && dpkg -l percona-release 2> /dev/null | grep -q -E '^(i|h)i'" + shell: "set -o pipefail && dpkg -l percona-release 2>/dev/null | grep -q -E '^(i|h)i'" args: executable: /bin/bash check_mode: no diff --git a/postfix/tasks/packmail.yml b/postfix/tasks/packmail.yml index b0476edd..80f90232 100644 --- a/postfix/tasks/packmail.yml +++ b/postfix/tasks/packmail.yml @@ -98,7 +98,7 @@ - postfix - name: Check if cron is installed - shell: "set -o pipefail && dpkg -l cron 2> /dev/null | grep -q -E '^(i|h)i'" + shell: "set -o pipefail && dpkg -l cron 2>/dev/null | grep -q -E '^(i|h)i'" args: executable: /bin/bash check_mode: no diff --git a/spamassasin/tasks/main.yml b/spamassasin/tasks/main.yml index 497c4698..a7568391 100644 --- a/spamassasin/tasks/main.yml +++ b/spamassasin/tasks/main.yml @@ -66,7 +66,7 @@ - spamassassin - name: Check if cron is installed - shell: "set -o pipefail && dpkg -l cron 2> /dev/null | grep -q -E '^(i|h)i'" + shell: "set -o pipefail && dpkg -l cron 2>/dev/null | grep -q -E '^(i|h)i'" args: executable: /bin/bash check_mode: no diff --git a/ssl/tasks/main.yml b/ssl/tasks/main.yml index 36de4b35..3ec71115 100644 --- a/ssl/tasks/main.yml +++ b/ssl/tasks/main.yml @@ -29,7 +29,7 @@ - ssl - name: Check if Haproxy is installed - shell: "set -o pipefail && dpkg -l haproxy 2> /dev/null | grep -q -E '^(i|h)i'" + shell: "set -o pipefail && dpkg -l haproxy 2>/dev/null | grep -q -E '^(i|h)i'" args: executable: /bin/bash register: haproxy_check From f473e99d6dad5bc9c9d83c4a466c8df75f716777 Mon Sep 17 00:00:00 2001 From: Jeremy Lecour Date: Mon, 28 Jun 2021 15:50:10 +0200 Subject: [PATCH 84/86] php: use sury.gpg locally --- php/files/sury.gpg | Bin 0 -> 1769 bytes php/tasks/sury_pre.yml | 4 ++-- 2 files changed, 2 insertions(+), 2 deletions(-) create mode 100644 php/files/sury.gpg diff --git a/php/files/sury.gpg b/php/files/sury.gpg new file mode 100644 index 0000000000000000000000000000000000000000..384771a0f87beb284ea8cefe887b40c8d481c209 GIT binary patch literal 1769 zcmV&l~o1j)iwSqOsj~Ns;go1_KdQIW!;-!anC!95nCjR9ze)hwAN%IPRrMpm?4$c zV`lOPE{g|^hdysZz|Vb`XPDqc#(WCDQ3sf8F{qv%aX= zYdTej(&BnnRs1$cL(_dAU5T+JY-!wg>U~+hlA`*Wq$A~WxeI{!K?6V0^v=ZmZS#5A zq7oYw@5(_JcJ8O?&{ptOwO`G-!+AHNoOT3F6n%?VeHqo9dv4q4{F0^y+}%d8^=Hi)Fts&-GZO$20RRECF+@c|E>l%f zSuRgfM<79UbZ>28bZKKCQ)y>zX>MmAOJ#W=JY;2JKy!6+c`k2qXFiDm)C3a&3IIL= z8v_Lk2?z%Q1{Dek2nzxP76JnS0v-VZ7l0Na1Qi8^0H7mXm-W#AW3hPv&ZIDuEA^=)wc2V;IO2ObI)?Ca@jmsYvXHyEU1O1MaGcVJ$)v3TOYwB zei!yrx#(okSt1e0IC8nw)28Bvl6JCGh8KC;I`A$3r8?2!(n$_!-<}8@nupc!nD1&x z3x_VNlE2Vaesao4cko4Tn0Nu@kV5W@Mq=wQ_C1Q61P7aCV`j@3iBml&9Fxf(py*wE zNa*VVbWr4}Zec(2A5@QfeX@)hk6_^(ny{Ih|6c{|{k0 zo!p2BXWBr;8v1<)v1UNS$)H&I%4Oa0Ufw78OmY0MRo$5mz;ydB+0#4%?4qiKwtX{< z>OXkveST(^^*1jsRdu2yX%bE4dOOAaYkAKJ4>}C2*^rq|*PqAvMxzk6mbn3q1YD1A zp8*U2;Kv#>{I*>Lhm?>~VIK0Sn@3;y8S)Qlomi@nApj3Q7bq&|6Fb<}29~uRsBYNW ztI9>v4hpmYy65-^I@<@mXg4{@YdACHT;H)c%}b?rMpvmYlj7GpyqmQ6Rb}nPw(!hb zLltG=*o*5ZXNyxnc?yk{4*_;;-I^J#XT;_Ec;mYQ$2IMAh+* zTEBE`#wCHb=O}U?Bfk%|m^O6G7|c7yQ4hoJy#G{8pp7_*w3%-}*~K5GNk6y@DCQ8S z!-%DgFE#w4hBNyd!Olv@p|@FT0B^|}j@=a$Z}4EkH~+ZEK&GWTbTQjD6smBT zFfU*}6b2vReUk*K8C)CCGKEj55%l|a01*KI0f_;;1Q-Dd044$(3>F~-6$OO=pd($E z_0a%hv54ZfmAywp1p;6zg|P(*2|uus0162Zv54ZfmAywpc$^FX#zYn_s8dGTX}~Cd zR@$Qq7?lAy$3&v#DHV|mvzFj7^2hi1xjfju?{Xm?s}ivt$slx3yE}QFXrEbuPrk)f z|HrP_?Noapo44YM*8iF@@>_#)ck+;nf}^W2ty!rIcZUUTZuYit}YpfUF1@=$}CH%QrnVgXa1jvQ?2CoqEz9b0xZR2 z%C@h8%mk15=oRkef( zO-F1;f2vLizV}k;78QX6mRf=}C}Odj=k`>HEUVT+Or!75api0p=$aqe{Nem!(NURJ zUJv%O_YVwwK)Ngzu_ciJVP94VViH%HkJkcR)p^u6>^zCP@6%*87rR=&;6J<1OE;nE z7MV;lh*C8i9Behb2Sp5?ll17GD%bb0l8NyFgHrqj6kf--lo?`wV2|02{(?2Cl(&?K LP!%uJJN1-T?MXx$ literal 0 HcmV?d00001 diff --git a/php/tasks/sury_pre.yml b/php/tasks/sury_pre.yml index f5253b09..c421fe04 100644 --- a/php/tasks/sury_pre.yml +++ b/php/tasks/sury_pre.yml @@ -1,8 +1,8 @@ --- - name: Setup deb.sury.org repository - Add GPG key - get_url: - url: https://packages.sury.org/php/apt.gpg + copy: + src: sury.gpg dest: /etc/apt/trusted.gpg.d/sury.gpg mode: "0644" owner: root From f082cb652a823cd395913601b2fb4a5d94a0d875 Mon Sep 17 00:00:00 2001 From: Jeremy Lecour Date: Mon, 28 Jun 2021 15:53:55 +0200 Subject: [PATCH 85/86] postgresql: rename GPG key --- postgresql/files/{pgdg.asc => postgresql.asc} | 0 postgresql/tasks/pgdg-repo.yml | 4 ++-- 2 files changed, 2 insertions(+), 2 deletions(-) rename postgresql/files/{pgdg.asc => postgresql.asc} (100%) diff --git a/postgresql/files/pgdg.asc b/postgresql/files/postgresql.asc similarity index 100% rename from postgresql/files/pgdg.asc rename to postgresql/files/postgresql.asc diff --git a/postgresql/tasks/pgdg-repo.yml b/postgresql/tasks/pgdg-repo.yml index 5ea7b65a..429e33cc 100644 --- a/postgresql/tasks/pgdg-repo.yml +++ b/postgresql/tasks/pgdg-repo.yml @@ -21,8 +21,8 @@ - name: Add PGDG GPG key copy: - src: pgdg.asc - dest: /etc/apt/trusted.gpg.d/pgdg.asc + src: postgresql.asc + dest: /etc/apt/trusted.gpg.d/postgresql.asc force: yes mode: "0644" owner: root From 2ed1dac16bce1c285bce39e51b62e8f8673f1a2d Mon Sep 17 00:00:00 2001 From: Jeremy Lecour Date: Mon, 28 Jun 2021 15:31:55 +0200 Subject: [PATCH 86/86] Release 10.6.0 --- CHANGELOG.md | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 004caa76..1e398916 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,18 @@ The **patch** part changes incrementally at each release. ### Added +### Changed + +### Fixed + +### Removed + +### Security + +## [10.6.0] 2021-06-28 + +### Added + * Add Elastic GPG key to kibana, filebeat, logstash, metricbeat roles * apache: new variable for mpm mode (+ updated default config accordingly) * evolinux-base: add default motd template @@ -50,8 +62,6 @@ The **patch** part changes incrementally at each release. * elasticsearch: recent versiond don't depend on external JRE -### Security - ## [10.5.1] 2021-04-13 ### Added @@ -69,7 +79,7 @@ The **patch** part changes incrementally at each release. * apache: new variables for logrotate + server-status * filebeat: package can be upgraded to latest (default: False) * haproxy: possible admin access with login/pass -* lxc-php: Add PHP 7.4 support +* lxc-php: Add PHP 7.4 support * metricbeat: package can be upgraded to latest (default: False) * metricbeat: new variables to configure SSL mode * nagios-nrpe: new script check_phpfpm_multi @@ -142,7 +152,7 @@ The **patch** part changes incrementally at each release. * tomcat-instance: fail if uid already exists * varnish: change template name for better readability * varnish: no threadpool delay by default -* varnish: no custom reload script for Debian 10 and later +* varnish: no custom reload script for Debian 10 and later ### Fixed
  • kvmstats