diff --git a/CHANGELOG.md b/CHANGELOG.md
index 930d2696..871c7b29 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -4,52 +4,105 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/).
This project does not follow semantic versioning.
-The **major** part of the version is aligned with the stable version of Debian.
-The **minor** part changes with big changes (probably incompatible).
-The **patch** part changes incrementally at each release.
+The **major** part of the version is the year
+The **minor** part changes is the month
+The **patch** part changes is incremented if multiple releases happen the same month
## [Unreleased]
### Added
-* Preliminary support for Debian 11 « Bullseye »
-* apache: new variable for mpm mode (+ updated default config accordingly)
+### Changed
+
+### Fixed
+
+### Removed
+
+### Security
+
+## [22.01] 2022-01-25
+
+### Added
+
+* Support for Debian 11 « Bullseye » (with possible remaining blind spots)
+* apache: new variable for MPM mode (+ updated default config accordingly)
+* apache: prevent accessing Git or "env" related files
* certbot: add script for manual deploy hooks execution
+* docker-host: install additional dependencies
+* dovecot: switch to TLS 1.2+ and external DH params
+* etc-git: centralize cron jobs in dedicated crontab
+* etc-git: manage commits with an optimized shell script instead of many slow Ansible tasks
+* evolinux-base: add script backup-server-state
+* evolinux-base: install molly-guard by default
+* generate-ldif: detect RAID controller
+* generate-ldif: detect mdadm
* listupgrade: crontab is configurable
+* logstash: logging to syslog is configurable (default: True)
* mongodb: create munin plugins directory if missing
+* munin: systemd override to unprotect home directory
+* mysql: add evomariabackup 21.11
+* mysql: improve Bullseye compatibility
* mysql: script "mysql_connections" to display a compact list of connections
+* mysql: script "mysql-queries-killer.sh" to kill MySQL queries
+* nagios-nrpe + evolinux-users: new check for ipmi
+* nagios-nrpe + evolinux-users: new check for RAID (soft + hard)
+* nagios-nrpe + evolinux-users: new checks for bkctld
+* nagios-nrpe: new check influxdb
+* openvpn: new role (beta)
* redis: instance service for Debian 11
+* squid: add *.o.lencr.org to default whitelist
### Changed
-* Use python3 modules for Debian 11 and later
+* Change version pattern
+* Install python 2 or 3 libraries according to running python version
* Remove embedded GPG keys only if legacy keyring is present
* apt: remove workaround for Evolix public repositories with Debian 11
* apt: use the new security repository for Bullseye
* certbot: silence letsencrypt deprecation warnings
-* elasticsearch: 7.x by default
+* elasticsearch: elastic_stack_version = 7.x
+* evoacme: exclude renewal-hooks directory from cron
* evoadmin-web: simpler PHP packages lists
-* evocheck: upstream release 21.07
+* evocheck: upstream release 21.10.4
* evolinux-base: alert5 comes after the network
* evolinux-base: force Debian version to buster for Evolix repository (temporary)
-* kibana: 7.x by default
+* evolinux-base: install freeipmi by default on dedicated hw
+* evolinux-base: logs are rotated with dateext by default
+* evolinux-base: split dpkg logrotate configuration
+* evolinux-users + nagios-nrpe: Add support for php-fpm80 in lxc
+* evomaintenance: extract a config.yml tasks file
+* evomaintenance: upstream release 22.01
+* filebeat/metricbeat: elastic_stack_version = 7.x
+* kibana: elastic_stack_version = 7.x
+* listupgrade: old-kernel-removal version 21.10
* listupgrade: upstream release 21.06.3
-* mysql: mariadb-client-10.5 on Debian 11
-* mysql: use python3 with Debian 11 and later
+* logstash: elastic_stack_version = 7.x
+* mongodb: Allow to specify a mongodb version for buster & bullseye
+* mongodb: Deny the install on Debian 11 « Bullseye » when the version is unsupported
+* mongodb: Support version 5.0 (for buster)
+* mysql: use python3 and mariadb-client-10.5 with Debian 11 and later
+* nodejs: default to version 16 LTS
+* php: enforce Debian version with assert instead of fail
* squid: improve default whitelist (more specific patterns)
* squid: must be started in foreground mode for systemd
* squid: remove obsolete variable on Squid 4
### Fixed
+* evolinux-base: fix alert5.service dependency syntax
* certbot: sync_remote excludes itself
+* lxc-php: fix config for opensmtpd on bullseye containers
+* mysql : Create a default ~root/.my.cnf for compatibility reasons
+* nginx : fix variable name and debug to actually use nginx-light
+* packweb-apache : Support php 8.0
+* nagios-nrpe: Fix check_nfsserver for buster and bullseye
### Removed
+* evocheck: package install is not supported anymore
+* logstash: no more dependency on Java
* php: remove php-gettext for 7.4
-### Security
-
## [10.6.0] 2021-06-28
### Added
diff --git a/apache/files/evolinux-defaults.conf b/apache/files/evolinux-defaults.conf
index 06e28d9e..65c8c921 100644
--- a/apache/files/evolinux-defaults.conf
+++ b/apache/files/evolinux-defaults.conf
@@ -48,12 +48,23 @@ MaxKeepAliveRequests 10
Deny from env=GoAway
+
+ # We don't want to let the client know a file exist on the server,
+ # so we return 404 "Not found" instead of 403 "Forbidden".
+ Redirect 404
+
-
- Require all denied
-
+# File names starting with
+
+ Redirect 404
+
+# File names ending with
+
+ Redirect 404
+
Require all denied
+
diff --git a/certbot/files/hooks/deploy/sync_remote.sh b/certbot/files/hooks/deploy/sync_remote.sh
index d1721fdb..7fc3ecf4 100644
--- a/certbot/files/hooks/deploy/sync_remote.sh
+++ b/certbot/files/hooks/deploy/sync_remote.sh
@@ -14,8 +14,15 @@ debug() {
found_renewed_lineage() {
test -f "${RENEWED_LINEAGE}/fullchain.pem" && test -f "${RENEWED_LINEAGE}/privkey.pem"
}
+cert_content() {
+ openssl x509 -text -in "${RENEWED_LINEAGE}/fullchain.pem"
+}
domain_from_cert() {
- openssl x509 -noout -subject -in "${RENEWED_LINEAGE}/fullchain.pem" | sed 's/^.*CN\ *=\ *//'
+ if cert_content | grep -q "X509v3 Subject Alternative Name:" && cert_content | grep -q "DNS:"; then
+ cert_content | grep "DNS:" | sed -e 's/\s\+//g' -e 's/DNS://g'
+ else
+ cert_content | sed 's/^.*CN\ *=\ *//'
+ fi
}
main() {
if [ -z "${RENEWED_LINEAGE}" ]; then
@@ -44,7 +51,7 @@ main() {
|| error "Couldn't sync hooks on ${server}"
# 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 {} \;" \
+ 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
diff --git a/certbot/tasks/install-legacy.yml b/certbot/tasks/install-legacy.yml
index d9dfb382..446e557a 100644
--- a/certbot/tasks/install-legacy.yml
+++ b/certbot/tasks/install-legacy.yml
@@ -56,5 +56,5 @@
dest: "/etc/letsencrypt/cli.ini"
section: null
option: "no-self-upgrade"
- value: 0
+ value: "no"
state: present
diff --git a/certbot/tasks/main.yml b/certbot/tasks/main.yml
index 9259e027..cede35a6 100644
--- a/certbot/tasks/main.yml
+++ b/certbot/tasks/main.yml
@@ -7,17 +7,17 @@
- ansible_distribution_major_version is version('8', '>=')
msg: only compatible with Debian 9+
-- name: Install legacy script on Debian 8 and 9
+- name: Install legacy script on Debian 8
include: install-legacy.yml
when:
- ansible_distribution == "Debian"
- - ansible_distribution_major_version is version('10', '<')
+ - ansible_distribution_major_version is version('9', '<')
-- name: Install package on Debian 10+
+- name: Install package on Debian 9+
include: install-package.yml
when:
- ansible_distribution == "Debian"
- - ansible_distribution_major_version is version('10', '>=')
+ - ansible_distribution_major_version is version('9', '>=')
- include: acme-challenge.yml
diff --git a/clamav/tasks/main.yml b/clamav/tasks/main.yml
index be9e5b00..6d1da3eb 100644
--- a/clamav/tasks/main.yml
+++ b/clamav/tasks/main.yml
@@ -6,48 +6,48 @@
value: "{{ item.value }}"
vtype: "{{ item.type }}"
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' }
- - { key: 'clamav-daemon/FollowDirectorySymlinks', type: 'boolean', value: 'false' }
- - { key: 'clamav-daemon/StreamMaxLength', type: 'string', value: '25' }
- - { key: 'clamav-daemon/ReadTimeout', type: 'string', value: '180' }
- - { key: 'clamav-daemon/StatsEnabled', type: 'boolean', value: 'false' }
- - { key: 'clamav-daemon/MaxConnectionQueueLength', type: 'string', value: '15' }
- - { key: 'clamav-daemon/LogRotate', type: 'boolean', value: 'true' }
- - { key: 'clamav-daemon/AllowAllMatchScan', type: 'boolean', value: 'true' }
- - { key: 'clamav-daemon/ScanOnAccess', type: 'boolean', value: 'false' }
- - { key: 'clamav-daemon/LogFile', type: 'string', value: '/var/log/clamav/clamav.log' }
- - { key: 'clamav-daemon/ScanMail', type: 'boolean', value: 'true' }
- - { key: 'clamav-daemon/BytecodeTimeout', type: 'string', value: '60000' }
- - { key: 'clamav-daemon/LogTime', type: 'boolean', value: 'true' }
- - { key: 'clamav-daemon/OnAccessMaxFileSize', type: 'string', value: '5M' }
- - { key: 'clamav-daemon/TcpOrLocal', type: 'select', value: 'UNIX' }
- - { key: 'clamav-daemon/MaxEmbeddedPE', type: 'string', value: '10M' }
- - { key: 'clamav-daemon/FixStaleSocket', type: 'boolean', value: 'true' }
- - { key: 'clamav-daemon/User', type: 'string', value: 'clamav' }
- - { key: 'clamav-daemon/BytecodeSecurity', type: 'select', value: 'TrustSigned' }
- - { key: 'clamav-daemon/ScanSWF', type: 'boolean', value: 'true' }
- - { key: 'clamav-daemon/MaxDirectoryRecursion', type: 'string', value: '0' }
- - { key: 'clamav-daemon/MaxThreads', type: 'string', value: '12' }
- - { key: 'clamav-daemon/LocalSocketGroup', type: 'string', value: 'clamav' }
- - { key: 'clamav-daemon/MaxScriptNormalize', type: 'string', value: '5M' }
- - { key: 'clamav-daemon/ForceToDisk', type: 'boolean', value: 'false' }
- - { key: 'clamav-daemon/StatsHostID', type: 'string', value: 'auto' }
- - { key: 'clamav-daemon/FollowFileSymlinks', type: 'boolean', value: 'false' }
- - { key: 'clamav-daemon/TCPSocket', type: 'string', value: '3310' }
- - { key: 'clamav-daemon/TCPAddr', type: 'string', value: 'any' }
- - { key: 'clamav-daemon/DisableCertCheck', type: 'boolean', value: 'false' }
- - { key: 'clamav-daemon/SelfCheck', type: 'string', value: '3600' }
- - { key: 'clamav-daemon/LocalSocket', type: 'string', value: '/var/run/clamav/clamd.ctl' }
- - { key: 'clamav-daemon/LocalSocketMode', type: 'string', value: '666' }
- - { key: 'clamav-daemon/StatsTimeout', type: 'string', value: '10' }
- - { key: 'clamav-daemon/MaxZipTypeRcg', type: 'string', value: '1M' }
- - { key: 'clamav-daemon/MaxHTMLNoTags', type: 'string', value: '2M' }
- - { key: 'clamav-daemon/LogSyslog', type: 'boolean', value: 'false' }
- - { key: 'clamav-daemon/AddGroups', type: 'string', value: '' }
- - { key: 'clamav-daemon/Bytecode', type: 'boolean', value: 'true' }
- - { key: 'clamav-daemon/ScanArchive', type: 'boolean', value: 'true' }
+ - { key: 'clamav-daemon/debconf', type: 'boolean', value: 'true' }
+ - { key: 'clamav-daemon/MaxHTMLNormalize', type: 'string', value: '10M' }
+ - { key: 'clamav-daemon/StatsPEDisabled', type: 'boolean', value: 'true' }
+ - { key: 'clamav-daemon/FollowDirectorySymlinks', type: 'boolean', value: 'false' }
+ - { key: 'clamav-daemon/StreamMaxLength', type: 'string', value: '25' }
+ - { key: 'clamav-daemon/ReadTimeout', type: 'string', value: '180' }
+ - { key: 'clamav-daemon/StatsEnabled', type: 'boolean', value: 'false' }
+ - { key: 'clamav-daemon/MaxConnectionQueueLength', type: 'string', value: '15' }
+ - { key: 'clamav-daemon/LogRotate', type: 'boolean', value: 'true' }
+ - { key: 'clamav-daemon/AllowAllMatchScan', type: 'boolean', value: 'true' }
+ - { key: 'clamav-daemon/ScanOnAccess', type: 'boolean', value: 'false' }
+ - { key: 'clamav-daemon/LogFile', type: 'string', value: '/var/log/clamav/clamav.log' }
+ - { key: 'clamav-daemon/ScanMail', type: 'boolean', value: 'true' }
+ - { key: 'clamav-daemon/BytecodeTimeout', type: 'string', value: '60000' }
+ - { key: 'clamav-daemon/LogTime', type: 'boolean', value: 'true' }
+ - { key: 'clamav-daemon/OnAccessMaxFileSize', type: 'string', value: '5M' }
+ - { key: 'clamav-daemon/TcpOrLocal', type: 'select', value: 'UNIX' }
+ - { key: 'clamav-daemon/MaxEmbeddedPE', type: 'string', value: '10M' }
+ - { key: 'clamav-daemon/FixStaleSocket', type: 'boolean', value: 'true' }
+ - { key: 'clamav-daemon/User', type: 'string', value: 'clamav' }
+ - { key: 'clamav-daemon/BytecodeSecurity', type: 'select', value: 'TrustSigned' }
+ - { key: 'clamav-daemon/ScanSWF', type: 'boolean', value: 'true' }
+ - { key: 'clamav-daemon/MaxDirectoryRecursion', type: 'string', value: '0' }
+ - { key: 'clamav-daemon/MaxThreads', type: 'string', value: '12' }
+ - { key: 'clamav-daemon/LocalSocketGroup', type: 'string', value: 'clamav' }
+ - { key: 'clamav-daemon/MaxScriptNormalize', type: 'string', value: '5M' }
+ - { key: 'clamav-daemon/ForceToDisk', type: 'boolean', value: 'false' }
+ - { key: 'clamav-daemon/StatsHostID', type: 'string', value: 'auto' }
+ - { key: 'clamav-daemon/FollowFileSymlinks', type: 'boolean', value: 'false' }
+ - { key: 'clamav-daemon/TCPSocket', type: 'string', value: '3310' }
+ - { key: 'clamav-daemon/TCPAddr', type: 'string', value: 'any' }
+ - { key: 'clamav-daemon/DisableCertCheck', type: 'boolean', value: 'false' }
+ - { key: 'clamav-daemon/SelfCheck', type: 'string', value: '3600' }
+ - { key: 'clamav-daemon/LocalSocket', type: 'string', value: '/var/run/clamav/clamd.ctl' }
+ - { key: 'clamav-daemon/LocalSocketMode', type: 'string', value: '666' }
+ - { key: 'clamav-daemon/StatsTimeout', type: 'string', value: '10' }
+ - { key: 'clamav-daemon/MaxZipTypeRcg', type: 'string', value: '1M' }
+ - { key: 'clamav-daemon/MaxHTMLNoTags', type: 'string', value: '2M' }
+ - { key: 'clamav-daemon/LogSyslog', type: 'boolean', value: 'false' }
+ - { key: 'clamav-daemon/AddGroups', type: 'string', value: '' }
+ - { key: 'clamav-daemon/Bytecode', type: 'boolean', value: 'true' }
+ - { key: 'clamav-daemon/ScanArchive', type: 'boolean', value: 'true' }
tags:
- clamav
@@ -58,17 +58,17 @@
value: "{{ item.value }}"
vtype: "{{ item.type }}"
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' }
- - { key: 'clamav-freshclam/local_mirror', type: 'select', value: 'db.fr.clamav.net' }
- - { key: 'clamav-freshclam/http_proxy', type: 'string', value: '' }
- - { key: 'clamav-freshclam/LogRotate', type: 'boolean', value: 'true' }
- - { key: 'clamav-freshclam/Bytecode', type: 'boolean', value: 'true' }
- - { key: 'clamav-freshclam/update_interval', type: 'string', value: '24' }
- - { key: 'clamav-freshclam/SafeBrowsing', type: 'boolean', value: 'false' }
- - { key: 'clamav-freshclam/PrivateMirror', type: 'string', value: '' }
- - { key: 'clamav-freshclam/internet_interface', type: 'string', value: '' }
+ - { 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' }
+ - { key: 'clamav-freshclam/local_mirror', type: 'select', value: 'db.fr.clamav.net' }
+ - { key: 'clamav-freshclam/http_proxy', type: 'string', value: '' }
+ - { key: 'clamav-freshclam/LogRotate', type: 'boolean', value: 'true' }
+ - { key: 'clamav-freshclam/Bytecode', type: 'boolean', value: 'true' }
+ - { key: 'clamav-freshclam/update_interval', type: 'string', value: '24' }
+ - { key: 'clamav-freshclam/SafeBrowsing', type: 'boolean', value: 'false' }
+ - { key: 'clamav-freshclam/PrivateMirror', type: 'string', value: '' }
+ - { key: 'clamav-freshclam/internet_interface', type: 'string', value: '' }
tags:
- clamav
diff --git a/docker-host/tasks/main.yml b/docker-host/tasks/main.yml
index 796c800d..026181f6 100644
--- a/docker-host/tasks/main.yml
+++ b/docker-host/tasks/main.yml
@@ -36,23 +36,25 @@
owner: root
group: root
-- name: Install docker and python-docker
+- name: Install Docker
apt:
name:
- docker-ce
+ - docker-ce-cli
+ - containerd.io
update_cache: yes
- name: python-docker is installed
apt:
name: python-docker
state: present
- when: ansible_distribution_major_version is version('10', '<=')
+ when: ansible_python_version is version('3', '<')
- name: python3-docker is installed
apt:
name: python3-docker
state: present
- when: ansible_distribution_major_version is version('10', '>')
+ when: ansible_python_version is version('3', '>=')
- name: Copy Docker daemon configuration file
template:
diff --git a/dovecot/tasks/main.yml b/dovecot/tasks/main.yml
index aa817086..1bebbafc 100644
--- a/dovecot/tasks/main.yml
+++ b/dovecot/tasks/main.yml
@@ -10,6 +10,11 @@
tags:
- dovecot
+- name: Generate 4096 bits Diffie-Hellman parameters (may take several minutes)
+ openssl_dhparam:
+ path: /etc/ssl/dhparams.pem
+ size: 4096
+
- name: disable pam auth
replace:
dest: /etc/dovecot/conf.d/10-auth.conf
diff --git a/dovecot/templates/z-evolinux-defaults.conf.j2 b/dovecot/templates/z-evolinux-defaults.conf.j2
index 2c067b99..f913ff38 100644
--- a/dovecot/templates/z-evolinux-defaults.conf.j2
+++ b/dovecot/templates/z-evolinux-defaults.conf.j2
@@ -35,12 +35,27 @@ service login {
}
mail_max_userip_connections = 42
+# Configuration pour stats dovecot
+service stats {
+ unix_listener stats-reader {
+ user = vmail
+ group = vmail
+ mode = 0660
+ }
+
+ unix_listener stats-writer {
+ user = vmail
+ group = vmail
+ mode = 0660
+ }
+}
+
# SSL/TLS
ssl = yes
ssl_prefer_server_ciphers = yes
-ssl_dh_parameters_length = 2048
+ssl_dh=,
+ Jérémy Lecour
+ and others.
+
+evocommit 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 </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() {
+ if [ "$(get_system)" = "OpenBSD" ]; then
+ partition=$(stat -f '%Sd' $1)
+ mount -u -w /dev/${partition} 2>/dev/null
+ else
+ mountpoint=$(stat -c '%m' $1)
+ mount -o remount,rw ${mountpoint}
+ syslog "Re-mount ${mountpoint} as read-write to commit in repository $1"
+ fi
+}
+remount_repository_readonly() {
+ if [ "$(get_system)" = "OpenBSD" ]; then
+ partition=$(stat -f '%Sd' $1)
+ mount -u -r /dev/${partition} 2>/dev/null
+ else
+ mountpoint=$(stat -c '%m' $1)
+ mount -o remount,ro ${mountpoint} 2>/dev/null
+ syslog "Re-mount ${mountpoint} as read-only after commit to repository $1"
+ fi
+}
+is_dry_run() {
+ test "${DRY_RUN}" = "1"
+}
+is_verbose() {
+ test "${VERBOSE}" = "1"
+}
+is_ansible() {
+ test "${ANSIBLE}" = "1"
+}
+main() {
+ rc=0
+ lock="${GIT_DIR}/index.lock"
+ if [ -f "${lock}" ]; then
+ limit=$(date +"%s" -d "now - 1 hour")
+ updated_at=$(stat -c "%Y" "${lock}")
+ if [ "$updated_at" -lt "$limit" ]; then
+ rm -f "${lock}"
+ fi
+ fi
+
+ git_status=$(${GIT_BIN} status --porcelain)
+
+ if [ -n "${git_status}" ]; then
+ if is_dry_run; then
+ ${GIT_BIN} status
+ else
+ readonly_orig=0
+ # remount mount point read-write if currently readonly
+ if is_repository_readonly "${REPOSITORY}"; then
+ readonly_orig=1;
+ remount_repository_readwrite "${REPOSITORY}";
+ fi
+ author=$(logname)
+ email=$(git config --get user.email)
+ email=${email:-"${author}@evolix.net"}
+
+ # commit changes
+ git_add_result=$(${GIT_BIN} add --all)
+ git_add_rc=$?
+
+ if is_ansible; then
+ if [ ${git_add_rc} -ne 0 ]; then
+ printf "FAILED: %s\n%s" "can't add changes in ${REPOSITORY}" "${git_add_result}"
+ rc=1
+ fi
+ fi
+
+ git_commit_result=$(${GIT_BIN} commit --message "${MESSAGE}" --author "${author} <${email}>")
+ git_commit_rc=$?
+
+ if is_ansible; then
+ if [ ${git_commit_rc} -eq 0 ]; then
+ printf "CHANGED: %s\n" "commit done in ${REPOSITORY} with \`${MESSAGE}'"
+ else
+ printf "FAILED: %s\n%s" "can't commit in ${REPOSITORY} \`${MESSAGE}'" "${git_commit_result}"
+ rc=1
+ fi
+ fi
+
+ # remount mount point read-only if it was before
+ if [ ${readonly_orig} -eq 1 ]; then
+ remount_repository_readonly "${REPOSITORY}"
+ fi
+ fi
+ else
+ if is_ansible; then
+ printf "INFO: %s\n" "no commit in ${REPOSITORY}'"
+ fi
+ fi
+
+ unset GIT_DIR
+ unset GIT_WORK_TREE
+
+ exit ${rc}
+}
+# 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
+ ;;
+ --message)
+ # message options, with value speparated by space
+ if [ -n "$2" ]; then
+ MESSAGE=$2
+ shift
+ else
+ printf 'ERROR: "--message" requires a non-empty option argument.\n' >&2
+ exit 1
+ fi
+ ;;
+ --message=?*)
+ # message options, with value speparated by =
+ MESSAGE=${1#*=}
+ ;;
+ --message=)
+ # message options, without value
+ printf 'ERROR: "--message" requires a non-empty option argument.\n' >&2
+ exit 1
+ ;;
+ --repository)
+ # repository options, with value speparated by space
+ if [ -n "$2" ]; then
+ REPOSITORY=$2
+ shift
+ else
+ printf 'ERROR: "--repository" requires a non-empty option argument.\n' >&2
+ exit 1
+ fi
+ ;;
+ --repository=?*)
+ # repository options, with value speparated by =
+ REPOSITORY=${1#*=}
+ ;;
+ --repository=)
+ # repository options, without value
+ printf 'ERROR: "--repository" requires a non-empty option argument.\n' >&2
+ exit 1
+ ;;
+ -n|--dry-run)
+ # disable actual commands
+ DRY_RUN=1
+ ;;
+ -v|--verbose)
+ # print verbose information
+ VERBOSE=1
+ ;;
+ --ansible)
+ # print information for Ansible
+ ANSIBLE=1
+ ;;
+ --)
+ # End of all options.
+ shift
+ break
+ ;;
+ -?*|[[:alnum:]]*)
+ # ignore unknown options
+ printf 'WARN: Unknown option (ignored): %s\n' "$1" >&2
+ ;;
+ *)
+ # Default case: If no more options then break out of the loop.
+ break
+ ;;
+ esac
+
+ shift
+done
+
+if [ -z "${MESSAGE}" ]; then
+ echo "Error: missing message parameter" >&2
+ show_usage
+ exit 1
+fi
+if [ -z "${REPOSITORY}" ]; then
+ echo "Error: missing repository parameter" >&2
+ show_usage
+ exit 1
+fi
+DRY_RUN=${DRY_RUN:-0}
+VERBOSE=${VERBOSE:-0}
+ANSIBLE=${ANSIBLE:-0}
+
+GIT_BIN=$(command -v git)
+readonly GIT_BIN
+
+LOGGER_BIN=$(command -v logger)
+readonly LOGGER_BIN
+
+export GIT_DIR="${REPOSITORY}/.git"
+export GIT_WORK_TREE="${REPOSITORY}"
+
+if [ -d "${GIT_DIR}" ]; then
+ main
+else
+ echo "There is no Git repository in '${REPOSITORY}'" >&2
+ exit 1
+fi
\ No newline at end of file
diff --git a/etc-git/files/optimize-etc-git b/etc-git/files/optimize-etc-git
deleted file mode 100644
index a7b7510f..00000000
--- a/etc-git/files/optimize-etc-git
+++ /dev/null
@@ -1,3 +0,0 @@
-#!/bin/sh
-
-git --git-dir /etc/.git gc --quiet
diff --git a/etc-git/tasks/commit.yml b/etc-git/tasks/commit.yml
index 4bcf8e5c..3f993771 100644
--- a/etc-git/tasks/commit.yml
+++ b/etc-git/tasks/commit.yml
@@ -1,25 +1,52 @@
---
+# /etc
- name: Is /etc a git repository
stat:
path: /etc/.git
register: _etc_git
-- include: do_commit.yml
- vars:
- git_folder: "/etc"
+- name: "evocommit /etc"
+ command: "/usr/local/bin/evocommit --ansible --repository /etc --message \"{{ commit_message | mandatory }}\""
+ changed_when:
+ - _etc_git_commit.stdout
+ - "'CHANGED:' in _etc_git_commit.stdout"
+ ignore_errors: yes
+ register: _etc_git_commit
when:
- _etc_git.stat.exists
- _etc_git.stat.isdir
+# /etc/bind
+- name: Is /etc/bind a git repository
+ stat:
+ path: /etc/bind/.git
+ register: _etc_bind_git
+
+- name: "evocommit /etc/bind"
+ command: "/usr/local/bin/evocommit --ansible --repository /etc/bind --message \"{{ commit_message | mandatory }}\""
+ changed_when:
+ - _etc_bind_git_commit.stdout
+ - "'CHANGED:' in _etc_bind_git_commit.stdout"
+ ignore_errors: yes
+ register: _etc_bind_git_commit
+ when:
+ - _etc_bind_git.stat.exists
+ - _etc_bind_git.stat.isdir
+
+# /usr/share/scripts
- name: Is /usr/share/scripts a git repository
stat:
path: /usr/share/scripts/.git
register: _usr_share_scripts_git
-- include: do_commit.yml
- vars:
- git_folder: "/usr/share/scripts"
+- name: "evocommit /usr/share/scripts"
+ command: "/usr/local/bin/evocommit --ansible --repository /usr/share/scripts --message \"{{ commit_message | mandatory }}\""
+ changed_when:
+ - _usr_share_scripts_git_commit.stdout
+ - "'CHANGED:' in _usr_share_scripts_git_commit.stdout"
+ ignore_errors: yes
+ register: _usr_share_scripts_git_commit
when:
- _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
deleted file mode 100644
index 6b09eaaf..00000000
--- a/etc-git/tasks/do_commit.yml
+++ /dev/null
@@ -1,63 +0,0 @@
----
-
-- name: "Remount /usr if needed"
- include_role:
- name: remount-usr
- when: git_folder is match('/usr/.*')
-
-- name: "is {{ git_folder }} clean?"
- command: git status --porcelain
- args:
- chdir: "{{ git_folder }}"
- changed_when: False
- register: git_status
- when: not ansible_check_mode
- ignore_errors: yes
- tags:
- - etc-git
- - commit
-
-- debug:
- var: git_status
- verbosity: 3
- tags:
- - etc-git
- - commit
-
-- name: fetch current Git user.email
- git_config:
- name: user.email
- repo: "{{ git_folder }}"
- register: git_config_user_email
- ignore_errors: yes
- tags:
- - etc-git
- - commit
-
-- name: "set commit author"
- set_fact:
- commit_author: '{% if ansible_env.SUDO_USER is not defined %}root{% else %}{{ ansible_env.SUDO_USER }}{% endif %}'
- commit_email: '{% if git_config_user_email.config_value is not defined or not git_config_user_email.config_value %}root@localhost{% else %}{{ git_config_user_email.config_value }}{% endif %}' # noqa 204
- tags:
- - etc-git
- - commit
-
-- name: "{{ git_folder }} modifications are committed"
- shell: "git add -A . && git commit -m \"{{ commit_message | mandatory }}\" --author \"{{ commit_author | mandatory }} <{{ commit_email | mandatory }}>\""
- args:
- chdir: "{{ git_folder }}"
- register: commit_end_run
- when:
- - not ansible_check_mode
- - git_status.stdout | length > 0
- ignore_errors: yes
- tags:
- - etc-git
- - commit
-
-- debug:
- var: commit_end_run
- verbosity: 4
- tags:
- - etc-git
- - commit
diff --git a/etc-git/tasks/main.yml b/etc-git/tasks/main.yml
index 37d1c692..11be1899 100644
--- a/etc-git/tasks/main.yml
+++ b/etc-git/tasks/main.yml
@@ -7,6 +7,18 @@
tags:
- etc-git
+- include_role:
+ name: evolix/remount-usr
+
+- name: "evocommit script is installed"
+ copy:
+ src: evocommit
+ dest: /usr/local/bin/evocommit
+ mode: "0755"
+ force: yes
+ tags:
+ - etc-git
+
- include: repository.yml
vars:
repository_path: "/etc"
@@ -32,6 +44,24 @@
- _usr_share_scripts.stat.isdir
- ansible_distribution_major_version is version('10', '>=')
+- name: "etc-git-optimize script is installed"
+ copy:
+ src: etc-git-optimize
+ dest: /usr/share/scripts/etc-git-optimize
+ mode: "0755"
+ force: yes
+ tags:
+ - etc-git
+
+- name: "etc-git-status script is installed"
+ copy:
+ src: etc-git-status
+ dest: /usr/share/scripts/etc-git-status
+ mode: "0755"
+ force: yes
+ tags:
+ - etc-git
+
- name: Check if cron is installed
shell: "set -o pipefail && dpkg -l cron 2>/dev/null | grep -q -E '^(i|h)i'"
args:
@@ -41,29 +71,44 @@
check_mode: no
register: is_cron_installed
-- name: Optimize script is installed in monthly crontab
- copy:
- src: optimize-etc-git
- dest: /etc/cron.monthly/optimize-etc-git
- mode: "0750"
- force: no
+- block:
+ - name: Legacy cron jobs for /etc/.git status are absent
+ file:
+ dest: "{{ item }}"
+ state: absent
+ loop:
+ - /etc/cron.monthly/optimize-etc-git
+ - /etc/cron.d/etc-git-status
+
+ - name: Cron job for monthly git optimization
+ cron:
+ name: "Monthly optimization"
+ cron_file: etc-git
+ special_time: "monthly"
+ user: root
+ job: "/usr/share/scripts/etc-git-optimize"
+
+ - name: Cron job for hourly git status
+ cron:
+ name: "Hourly warning for unclean Git repository if nobody is connected"
+ cron_file: etc-git
+ special_time: "hourly"
+ user: root
+ job: "who > /dev/null || /usr/share/scripts/etc-git-status"
+ state: "{{ etc_git_monitor_status | bool | ternary('present','absent') }}"
+
+ - name: Cron job for daily git status
+ cron:
+ name: "Daily warning for unclean Git repository"
+ cron_file: etc-git
+ user: root
+ job: "/usr/share/scripts/etc-git-status"
+ minute: "21"
+ hour: "21"
+ weekday: "*"
+ day: "*"
+ month: "*"
+ state: "{{ etc_git_monitor_status | bool | ternary('present','absent') }}"
when: is_cron_installed.rc == 0
tags:
- - etc-git
-
-- name: Cron job for /etc/.git status is installed
- template:
- src: etc-git-status.j2
- dest: /etc/cron.d/etc-git-status
- mode: "0644"
- when: is_cron_installed.rc == 0 and etc_git_monitor_status
- tags:
- - etc-git
-
-- name: Cron job for /etc/.git status is removed
- file:
- dest: /etc/cron.d/etc-git-status
- state: absent
- when: is_cron_installed.rc == 0 and not etc_git_monitor_status
- tags:
- - etc-git
+ - etc-git
\ No newline at end of file
diff --git a/etc-git/tasks/repository.yml b/etc-git/tasks/repository.yml
index e8599c1e..80987da2 100644
--- a/etc-git/tasks/repository.yml
+++ b/etc-git/tasks/repository.yml
@@ -70,4 +70,4 @@
register: git_commit
when: git_log.rc != 0 or (git_init is defined and git_init is changed)
tags:
- - etc-git
+ - etc-git
\ No newline at end of file
diff --git a/etc-git/templates/etc-git-status.j2 b/etc-git/templates/etc-git-status.j2
deleted file mode 100644
index e1696c54..00000000
--- a/etc-git/templates/etc-git-status.j2
+++ /dev/null
@@ -1,4 +0,0 @@
-# {{ ansible_managed }}
-
-@hourly root who > /dev/null || git --git-dir=/etc/.git --work-tree=/etc status --short
-21 21 * * * root git --git-dir=/etc/.git --work-tree=/etc status --short
diff --git a/evoacme/files/evoacme.cron b/evoacme/files/evoacme.cron
index 4d849673..7d4b598c 100755
--- a/evoacme/files/evoacme.cron
+++ b/evoacme/files/evoacme.cron
@@ -15,12 +15,13 @@ find "${CRT_DIR}" \
-maxdepth 1 \
-mindepth 1 \
-type d \
- ! -path "*accounts" \
- ! -path "*archive" \
- ! -path "*csr" \
- ! -path "*hooks" \
- ! -path "*keys" \
- ! -path "*live" \
- ! -path "*renewal" \
+ ! -path "${CRT_DIR}/accounts" \
+ ! -path "${CRT_DIR}/archive" \
+ ! -path "${CRT_DIR}/csr" \
+ ! -path "${CRT_DIR}/hooks" \
+ ! -path "${CRT_DIR}/keys" \
+ ! -path "${CRT_DIR}/live" \
+ ! -path "${CRT_DIR}/renewal" \
+ ! -path "${CRT_DIR}/renewal-hooks" \
-printf "%f\n" \
| xargs --max-args=1 --no-run-if-empty evoacme
diff --git a/evocheck/README.md b/evocheck/README.md
index ce9999c0..6739bef8 100644
--- a/evocheck/README.md
+++ b/evocheck/README.md
@@ -16,6 +16,4 @@ A separate `exec.yml` file can be imported manually in playbooks or roles to exe
## Variables
We can force install via :
-* `evocheck_force_install: local` : will copy the script provided by the role
-* `evocheck_force_install: package` : will install the package via repositories
* `evocheck_update_crontab` : will update the crontab (default: `True`)
diff --git a/evocheck/defaults/main.yml b/evocheck/defaults/main.yml
index e2d80c2a..6dc43677 100644
--- a/evocheck/defaults/main.yml
+++ b/evocheck/defaults/main.yml
@@ -1,4 +1,4 @@
---
-evocheck_force_install: False
+
evocheck_update_crontab: True
evocheck_bin_dir: /usr/share/scripts
diff --git a/evocheck/files/evocheck.sh b/evocheck/files/evocheck.sh
index 02fa4a6b..fb8a6eeb 100644
--- a/evocheck/files/evocheck.sh
+++ b/evocheck/files/evocheck.sh
@@ -4,7 +4,7 @@
# Script to verify compliance of a Debian/OpenBSD server
# powered by Evolix
-VERSION="21.07"
+VERSION="21.10.4"
readonly VERSION
# base functions
@@ -74,7 +74,7 @@ detect_os() {
}
is_debian() {
- test -n "${DEBIAN_RELEASE}"
+ test -n "${DEBIAN_RELEASE}"
}
is_debian_lenny() {
test "${DEBIAN_RELEASE}" = "lenny"
@@ -220,7 +220,6 @@ check_vartmpfs() {
else
df /var/tmp | grep -q tmpfs || failed "IS_VARTMPFS" "/var/tmp is not a tmpfs"
fi
-
}
check_serveurbase() {
is_installed serveur-base || failed "IS_SERVEURBASE" "serveur-base package is not installed"
@@ -233,8 +232,19 @@ check_syslogconf() {
|| failed "IS_SYSLOGCONF" "syslog evolix config file missing"
}
check_debiansecurity() {
- grep -q "^deb.*security" /etc/apt/sources.list \
- || failed "IS_DEBIANSECURITY" "missing debian security repository"
+ if is_debian_bullseye; then
+ # https://www.debian.org/releases/bullseye/amd64/release-notes/ch-information.html#security-archive
+ pattern="^deb https://deb\.debian\.org/debian-security/? bullseye-security main"
+ elif is_debian_buster; then
+ pattern="^deb http://security\.debian\.org/debian-security/? buster/updates main"
+ elif is_debian_stretch; then
+ pattern="^deb http://security\.debian\.org/debian-security/? stretch/updates main"
+ else
+ pattern="^deb.*security"
+ fi
+
+ source_file="/etc/apt/sources.list"
+ grep -qE "${pattern}" "${source_file}" || failed "IS_DEBIANSECURITY" "missing debian security repository"
}
check_aptitudeonly() {
if is_debian_squeeze || is_debian_wheezy; then
@@ -305,7 +315,7 @@ check_customcrontab() {
test "$found_lines" = 4 && failed "IS_CUSTOMCRONTAB" "missing custom field in crontab"
}
check_sshallowusers() {
- grep -E -qi "(AllowUsers|AllowGroups)" /etc/ssh/sshd_config \
+ grep -E -qir "(AllowUsers|AllowGroups)" /etc/ssh/sshd_config /etc/ssh/sshd_config.d \
|| failed "IS_SSHALLOWUSERS" "missing AllowUsers or AllowGroups directive in sshd_config"
}
check_diskperf() {
@@ -345,6 +355,13 @@ check_minifw() {
/sbin/iptables -L -n | grep -q -E "^ACCEPT\s*all\s*--\s*31\.170\.8\.4\s*0\.0\.0\.0/0\s*$" \
|| failed "IS_MINIFW" "minifirewall seems not starded"
}
+check_minifw_includes() {
+ if is_debian_bullseye; then
+ if grep -q -e '/sbin/iptables' -e '/sbin/ip6tables' "${MINIFW_FILE}"; then
+ failed "IS_MINIFWINCLUDES" "minifirewall has direct iptables invocations in ${MINIFW_FILE} that should go in /etc/minifirewall.d/"
+ fi
+ fi
+}
check_nrpeperms() {
if [ -d /etc/nagios ]; then
nagiosDir="/etc/nagios"
@@ -405,17 +422,20 @@ check_apachemunin() {
check_mysqlutils() {
MYSQL_ADMIN=${MYSQL_ADMIN:-mysqladmin}
if is_installed mysql-server; then
- # You can configure MYSQL_ADMIN in evocheck.cf
- if ! grep -qs "$MYSQL_ADMIN" /root/.my.cnf; then
- failed "IS_MYSQLUTILS" "mysqladmin missing in /root/.my.cnf"
+ # With Debian 11 and later, root can connect to MariaDB with the socket
+ if is_debian_wheezy || is_debian_jessie || is_debian_stretch || is_debian_buster; then
+ # You can configure MYSQL_ADMIN in evocheck.cf
+ if ! grep -qs "^user *= *${MYSQL_ADMIN}" /root/.my.cnf; then
+ failed "IS_MYSQLUTILS" "${MYSQL_ADMIN} missing in /root/.my.cnf"
+ fi
fi
if ! test -x /usr/bin/mytop; then
if ! test -x /usr/local/bin/mytop; then
failed "IS_MYSQLUTILS" "mytop binary missing"
fi
fi
- if ! grep -qs debian-sys-maint /root/.mytop; then
- failed "IS_MYSQLUTILS" "debian-sys-maint missing in /root/.mytop"
+ if ! grep -qs '^user *=' /root/.mytop; then
+ failed "IS_MYSQLUTILS" "credentials missing in /root/.mytop"
fi
fi
}
@@ -457,7 +477,8 @@ check_squid() {
&& grep -qE "^[^#]*iptables -t nat -A OUTPUT -p tcp --dport 80 -d $host -j ACCEPT" "$MINIFW_FILE" \
&& grep -qE "^[^#]*iptables -t nat -A OUTPUT -p tcp --dport 80 -d 127.0.0.(1|0/8) -j ACCEPT" "$MINIFW_FILE" \
&& grep -qE "^[^#]*iptables -t nat -A OUTPUT -p tcp --dport 80 -j REDIRECT --to-port.* $http_port" "$MINIFW_FILE";
- } || failed "IS_SQUID" "missing squid rules in minifirewall"
+ } || grep -qE "^PROXY='?on'?" "$MINIFW_FILE" \
+ || failed "IS_SQUID" "missing squid rules in minifirewall"
fi
}
check_evomaintenance_fw() {
@@ -582,6 +603,7 @@ check_evobackup_exclude_mount() {
failed "IS_EVOBACKUP_EXCLUDE_MOUNT" "${mount} is not excluded from ${evobackup_file} backup script"
done
done
+ rm -rf "${excludes_file}"
}
# Verification de la presence du userlogrotate
check_userlogrotate() {
@@ -1018,7 +1040,7 @@ check_phpevolinuxconf() {
check_squidlogrotate() {
if is_debian_stretch || is_debian_buster || is_debian_bullseye; then
if is_installed squid; then
- grep -q monthly /etc/logrotate.d/squid \
+ grep -q -e monthly -e daily /etc/logrotate.d/squid \
|| failed "IS_SQUIDLOGROTATE" "missing squid logrotate file"
fi
fi
@@ -1331,6 +1353,133 @@ check_lxc_container_resolv_conf() {
done
fi
}
+download_versions() {
+ local file
+ file=${1:-}
+
+ ## The file is supposed to list programs : each on a line, then its latest version number
+ ## Examples:
+ # evoacme 21.06
+ # evomaintenance 0.6.4
+
+ if is_debian; then
+ versions_url="https://upgrades.evolix.org/versions-${DEBIAN_RELEASE}"
+ elif is_openbsd; then
+ versions_url="https://upgrades.evolix.org/versions-${OPENBSD_RELEASE}"
+ else
+ failed "IS_VERSIONS_CHECK" "error determining os release"
+ fi
+
+ # fetch timeout, in seconds
+ timeout=10
+
+ if command -v curl > /dev/null; then
+ curl --max-time ${timeout} --fail --silent --output "${versions_file}" "${versions_url}"
+ elif command -v wget > /dev/null; then
+ wget --timeout=${timeout} --quiet "${versions_url}" -O "${versions_file}"
+ elif command -v GET; then
+ GET -t ${timeout}s "${versions_url}" > "${versions_file}"
+ else
+ failed "IS_VERSIONS_CHECK" "failed to find curl, wget or GET"
+ fi
+ test "$?" -eq 0 || failed "IS_VERSIONS_CHECK" "failed to download ${versions_url} to ${versions_file}"
+}
+get_command() {
+ local program
+ program=${1:-}
+
+ case "${program}" in
+ ## Special cases where the program name is different than the command name
+ evocheck) echo "${0}" ;;
+ evomaintenance) command -v "evomaintenance.sh" ;;
+ listupgrade) command -v "evolistupgrade.sh" ;;
+ old-kernel-autoremoval) command -v "old-kernel-autoremoval.sh" ;;
+ mysql-queries-killer) command -v "mysql-queries-killer.sh" ;;
+
+ ## General case, where the program name is the same as the command name
+ *) command -v "${program}" ;;
+ esac
+}
+get_version() {
+ local program
+ local command
+ program=${1:-}
+ command=${2:-}
+
+ case "${program}" in
+ ## Special case if `command --version => 'command` is not the standard way to get the version
+ # my_command)
+ # /path/to/my_command --get-version
+ # ;;
+
+ add-vm)
+ grep '^VERSION=' "${command}" | head -1 | cut -d '=' -f 2
+ ;;
+ ## Let's try the --version flag before falling back to grep for the constant
+ kvmstats)
+ if ${command} --version > /dev/null 2> /dev/null; then
+ ${command} --version 2> /dev/null | head -1 | cut -d ' ' -f 3
+ else
+ grep '^VERSION=' "${command}" | head -1 | cut -d '=' -f 2
+ fi
+ ;;
+
+ ## General case to get the version
+ *) ${command} --version 2> /dev/null | head -1 | cut -d ' ' -f 3 ;;
+ esac
+}
+check_version() {
+ local program
+ local expected_version
+ program=${1:-}
+ expected_version=${2:-}
+
+ command=$(get_command "${program}")
+ if [ -n "${command}" ]; then
+ # shellcheck disable=SC2086
+ actual_version=$(get_version "${program}" "${command}")
+ # printf "program:%s expected:%s actual:%s\n" "${program}" "${expected_version}" "${actual_version}"
+ if [ -z "${actual_version}" ]; then
+ failed "IS_VERSIONS_CHECK" "failed to lookup actual version of ${program}"
+ elif dpkg --compare-versions "${actual_version}" lt "${expected_version}"; then
+ failed "IS_VERSIONS_CHECK" "${program} version ${actual_version} is older than expected version ${expected_version}"
+ elif dpkg --compare-versions "${actual_version}" gt "${expected_version}"; then
+ failed "IS_VERSIONS_CHECK" "${program} version ${actual_version} is newer than expected version ${expected_version}, you should update tour index."
+ else
+ : # Version check OK
+ fi
+ fi
+}
+add_to_path() {
+ local new_path
+ new_path=${1:-}
+
+ echo "$PATH" | grep -qF "${new_path}" || export PATH="${PATH}:${new_path}"
+}
+check_versions() {
+ versions_file=$(mktemp --tmpdir=/tmp "evocheck-versions.XXXXX")
+ # shellcheck disable=SC2064
+ trap "rm -f ${versions_file}" 0
+ download_versions "${versions_file}"
+ add_to_path "/usr/share/scripts"
+
+ grep -v '^ *#' < "${versions_file}" | while IFS= read -r line; do
+ local program
+ local version
+ program=$(echo "${line}" | cut -d ' ' -f 1)
+ version=$(echo "${line}" | cut -d ' ' -f 2)
+
+ if [ -n "${program}" ]; then
+ if [ -n "${version}" ]; then
+ check_version "${program}" "${version}"
+ else
+ failed "IS_VERSIONS_CHECK" "failed to lookup expected version for ${program}"
+ fi
+ fi
+ done
+
+ rm -f "${versions_file}"
+}
main() {
# Default return code : 0 = no error
@@ -1386,6 +1535,8 @@ main() {
test "${IS_ALERT5MINIFW:=1}" = 1 && test "${IS_MINIFW:=1}" = 1 && check_minifw
test "${IS_NRPEPERMS:=1}" = 1 && check_nrpeperms
test "${IS_MINIFWPERMS:=1}" = 1 && check_minifwperms
+ # Enable when minifirewall is released
+ test "${IS_MINIFWINCLUDES:=0}" = 1 && check_minifw_includes
test "${IS_NRPEDISKS:=0}" = 1 && check_nrpedisks
test "${IS_NRPEPID:=1}" = 1 && check_nrpepid
test "${IS_GRSECPROCS:=1}" = 1 && check_grsecprocs
@@ -1459,6 +1610,7 @@ main() {
test "${IS_CHROOTED_BINARY_UPTODATE:=1}" = 1 && check_chrooted_binary_uptodate
test "${IS_NGINX_LETSENCRYPT_UPTODATE:=1}" = 1 && check_nginx_letsencrypt_uptodate
test "${IS_LXC_CONTAINER_RESOLV_CONF:=1}" = 1 && check_lxc_container_resolv_conf
+ test "${IS_CHECK_VERSIONS:=1}" = 1 && check_versions
fi
#-----------------------------------------------------------
@@ -1598,6 +1750,7 @@ while :; do
IS_KERNELUPTODATE=0
IS_UPTIME=0
IS_MELTDOWN_SPECTRE=0
+ IS_CHECK_VERSIONS=0
;;
-v|--verbose)
VERBOSE=1
diff --git a/evocheck/tasks/install_local.yml b/evocheck/tasks/install.yml
similarity index 100%
rename from evocheck/tasks/install_local.yml
rename to evocheck/tasks/install.yml
diff --git a/evocheck/tasks/install_package.yml b/evocheck/tasks/install_package.yml
deleted file mode 100644
index 34e672e5..00000000
--- a/evocheck/tasks/install_package.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-- name: install evocheck from package
- apt:
- name: evocheck
- state: present
diff --git a/evocheck/tasks/main.yml b/evocheck/tasks/main.yml
index 87e2d636..2032740b 100644
--- a/evocheck/tasks/main.yml
+++ b/evocheck/tasks/main.yml
@@ -1,10 +1,13 @@
---
-- include: install_local.yml
- when: evocheck_force_install == "local"
+- name: Package install is not supported anymore
+ fail:
+ msg: Package install is not supported anymore
+ when:
+ - evocheck_force_install is defined
+ - evocheck_force_install == "package"
-- include: install_package.yml
- when: evocheck_force_install == "package"
+- include: install.yml
- include: cron.yml
when: evocheck_update_crontab | bool
diff --git a/evolinux-base/defaults/main.yml b/evolinux-base/defaults/main.yml
index 26f6e4c8..591bc62b 100644
--- a/evolinux-base/defaults/main.yml
+++ b/evolinux-base/defaults/main.yml
@@ -89,6 +89,7 @@ evolinux_packages_invalid_mta: True
evolinux_packages_delete_nfs: True
evolinux_packages_listchanges: True
evolinux_packages_logcheck_recipient: False
+evolinux_packages_delete_aptlistchanges: True
# system
@@ -164,8 +165,10 @@ evolinux_logs_include: True
evolinux_logs_logrotate_confs: True
evolinux_logs_default_rotate: True
+evolinux_logs_default_dateext : True
evolinux_logs_disable_logrotate_rsyslog: True
evolinux_logs_rsyslog_conf: True
+evolinux_logrotate_dateformat: "-%Y%m%d%H"
# default www
@@ -206,7 +209,6 @@ evolinux_fail2ban_include: False
# Evocheck
evolinux_evocheck_include: True
-evolinux_evocheck_force_install: "local"
# Listupgrade
@@ -218,3 +220,6 @@ evolinux_generateldif_include: True
# Cron check_hpraid
evolinux_cron_checkhpraid_frequency: daily
+
+# Motd
+evolinux_motd_include: True
\ No newline at end of file
diff --git a/evolinux-base/files/alert5.service b/evolinux-base/files/alert5.service
index eb5c72a9..ea966b37 100644
--- a/evolinux-base/files/alert5.service
+++ b/evolinux-base/files/alert5.service
@@ -1,10 +1,10 @@
[Unit]
Description=Evolix alert5 script
+After=network.target
[Service]
Type=oneshot
ExecStart=/usr/share/scripts/alert5.sh
[Install]
-WantedBy=multi-user.target
-After=network.target
\ No newline at end of file
+WantedBy=multi-user.target
\ No newline at end of file
diff --git a/evolinux-base/files/backup-server-state.sh b/evolinux-base/files/backup-server-state.sh
new file mode 100644
index 00000000..0c503c37
--- /dev/null
+++ b/evolinux-base/files/backup-server-state.sh
@@ -0,0 +1,635 @@
+#!/bin/sh
+
+PROGNAME="backup-server-state"
+
+VERSION="22.01"
+readonly VERSION
+
+backup_dir=
+rc=0
+
+# base functions
+
+show_version() {
+ cat <,
+ Jérémy Lecour
+ and others.
+
+${PROGNAME} comes with ABSOLUTELY NO WARRANTY.This is free software,
+and you are welcome to redistribute it under certain conditions.
+See the GNU General Public License v3.0 for details.
+END
+}
+show_help() {
+ cat < "${backup_dir}/current_packages.txt")
+ last_rc=$?
+
+ if [ ${last_rc} -eq 0 ]; then
+ debug "* dpkg OK"
+ else
+ debug "* dpkg ERROR :"
+ debug "${last_result}"
+ rc=10
+ fi
+}
+
+backup_uptime() {
+ debug "Backup uptime"
+
+ last_result=$(uptime > "${backup_dir}/uptime.txt")
+ last_rc=$?
+
+ if [ ${last_rc} -eq 0 ]; then
+ debug "* uptime OK"
+ else
+ debug "* uptime ERROR"
+ debug "${last_result}"
+ rc=10
+ fi
+}
+
+backup_processes() {
+ debug "Backup process list"
+
+ last_result=$(ps fauxw > "${backup_dir}/ps.txt")
+ last_rc=$?
+
+ if [ ${last_rc} -eq 0 ]; then
+ debug "* ps OK"
+ else
+ debug "* ps ERROR"
+ debug "${last_result}"
+ rc=10
+ fi
+
+ pstree_bin=$(command -v pstree)
+
+ if [ -z "${pstree_bin}" ]; then
+ last_result=$(pstree -pan > "${backup_dir}/pstree.txt")
+ last_rc=$?
+
+ if [ ${last_rc} -eq 0 ]; then
+ debug "* pstree OK"
+ else
+ debug "* pstree ERROR"
+ debug "${last_result}"
+ rc=10
+ fi
+ fi
+}
+
+backup_netstat() {
+ debug "Backup network status"
+
+ ss_bin=$(command -v ss)
+ if [ -z "${ss_bin}" ]; then
+ last_result=$(${ss_bin} -tanpul > "${backup_dir}/netstat-ss.txt")
+ last_rc=$?
+
+ if [ ${last_rc} -eq 0 ]; then
+ debug "* ss OK"
+ else
+ debug "* ss ERROR"
+ debug "${last_result}"
+ rc=10
+ fi
+ fi
+
+ netstat_bin=$(command -v netstat)
+ if [ -z "${netstat_bin}" ]; then
+ last_result=$(netstat -laputen > "${backup_dir}/netstat-legacy.txt")
+ last_rc=$?
+
+ if [ ${last_rc} -eq 0 ]; then
+ debug "* netstat OK"
+ else
+ debug "* netstat ERROR"
+ debug "${last_result}"
+ rc=10
+ fi
+ fi
+}
+
+backup_netcfg() {
+ debug "Backup network configuration"
+
+ last_result=$(ip address show > "${backup_dir}/ip-address.txt")
+ last_rc=$?
+
+ if [ ${last_rc} -eq 0 ]; then
+ debug "* ip address OK"
+ else
+ debug "* ip address ERROR"
+ debug "${last_result}"
+ rc=10
+ fi
+
+ last_result=$(ip route show > "${backup_dir}/ip-route.txt")
+ last_rc=$?
+
+ if [ ${last_rc} -eq 0 ]; then
+ debug "* ip route OK"
+ else
+ debug "* ip route ERROR"
+ debug "${last_result}"
+ rc=10
+ fi
+}
+
+backup_iptables() {
+ debug "Backup iptables"
+
+ last_result=$({ /sbin/iptables -L -n -v; /sbin/iptables -t filter -L -n -v; } > "${backup_dir}/iptables.txt")
+ last_rc=$?
+
+ if [ ${last_rc} -eq 0 ]; then
+ debug "* iptables OK"
+ else
+ debug "* iptables ERROR"
+ debug "${last_result}"
+ rc=10
+ fi
+}
+
+backup_sysctl() {
+ debug "Backup sysctl values"
+
+ last_result=$(sysctl -a | sort -h > "${backup_dir}/sysctl.txt")
+ last_rc=$?
+
+ if [ ${last_rc} -eq 0 ]; then
+ debug "* sysctl OK"
+ else
+ debug "* sysctl ERROR"
+ debug "${last_result}"
+ rc=10
+ fi
+}
+
+backup_virsh() {
+ debug "Backup virsh list"
+
+ virsh_bin=$(command -v virsh)
+
+ if [ -n "${virsh_bin}" ]; then
+ last_result=$(${virsh_bin} list --all > "${backup_dir}/virsh-list.txt")
+ last_rc=$?
+
+ if [ ${last_rc} -eq 0 ]; then
+ debug "* virsh list OK"
+ else
+ debug "* virsh list ERROR"
+ debug "${last_result}"
+ rc=10
+ fi
+ else
+ debug "* virsh not installed"
+ fi
+}
+
+backup_lxc() {
+ debug "Backup lxc list"
+
+ lxc_ls_bin=$(command -v lxc-ls)
+
+ if [ -n "${lxc_ls_bin}" ]; then
+ last_result=$(${lxc_ls_bin} --fancy > "${backup_dir}/lxc-list.txt")
+ last_rc=$?
+
+ if [ ${last_rc} -eq 0 ]; then
+ debug "* lxc list OK"
+ else
+ debug "* lxc list ERROR"
+ debug "${last_result}"
+ rc=10
+ fi
+ else
+ debug "* lxc-ls not installed"
+ fi
+}
+
+backup_mount() {
+ debug "Backup mount points"
+
+ findmnt_bin=$(command -v findmnt)
+ mount_bin=$(command -v mount)
+
+ if [ -n "${findmnt_bin}" ]; then
+ last_result=$(${findmnt_bin} > "${backup_dir}/mount.txt")
+ last_rc=$?
+
+ if [ ${last_rc} -eq 0 ]; then
+ debug "* mount points OK"
+ else
+ debug "* mount points ERROR"
+ debug "${last_result}"
+ rc=10
+ fi
+ elif [ -n "${mount_bin}" ]; then
+ last_result=$(${mount_bin} > "${backup_dir}/mount.txt")
+ last_rc=$?
+
+ if [ ${last_rc} -eq 0 ]; then
+ debug "* mount points OK"
+ else
+ debug "* mount points ERROR"
+ debug "${last_result}"
+ rc=10
+ fi
+ else
+ debug "* findmnt and mount not installed"
+ fi
+}
+
+backup_df() {
+ debug "Backup df"
+
+ df_bin=$(command -v df)
+
+ if [ -n "${df_bin}" ]; then
+ last_result=$(${df_bin} --portability > "${backup_dir}/df.txt")
+ last_rc=$?
+
+ if [ ${last_rc} -eq 0 ]; then
+ debug "* df OK"
+ else
+ debug "* df ERROR"
+ debug "${last_result}"
+ rc=10
+ fi
+ else
+ debug "* df not installed"
+ fi
+}
+
+main() {
+ if [ -z "${backup_dir}" ]; then
+ echo "ERROR: You must provide the --backup-dir argument" >&2
+ exit 1
+ fi
+
+ if [ -d "${backup_dir}" ]; then
+ echo "ERROR: The backup directory ${backup_dir} already exists. Delete it first." >&2
+ exit 2
+ else
+ create_backup_dir
+ fi
+
+ if [ "${DO_ETC}" -eq 1 ]; then
+ backup_etc
+ fi
+ if [ "${DO_DPKG}" -eq 1 ]; then
+ backup_dpkg
+ fi
+ if [ "${DO_APT}" -eq 1 ]; then
+ backup_apt
+ fi
+ if [ "${DO_PACKAGES}" -eq 1 ]; then
+ backup_packages
+ fi
+ if [ "${DO_PROCESSES}" -eq 1 ]; then
+ backup_processes
+ fi
+ if [ "${DO_UPTIME}" -eq 1 ]; then
+ backup_uptime
+ fi
+ if [ "${DO_NETSTAT}" -eq 1 ]; then
+ backup_netstat
+ fi
+ if [ "${DO_NETCFG}" -eq 1 ]; then
+ backup_netcfg
+ fi
+ if [ "${DO_IPTABLES}" -eq 1 ]; then
+ backup_iptables
+ fi
+ if [ "${DO_SYSCTL}" -eq 1 ]; then
+ backup_sysctl
+ fi
+ if [ "${DO_VIRSH}" -eq 1 ]; then
+ backup_virsh
+ fi
+ if [ "${DO_LXC}" -eq 1 ]; then
+ backup_lxc
+ fi
+ if [ "${DO_MOUNT}" -eq 1 ]; then
+ backup_mount
+ fi
+ if [ "${DO_DF}" -eq 1 ]; then
+ backup_df
+ fi
+
+ debug "=> Your backup is available at ${backup_dir}"
+ exit ${rc}
+}
+
+# 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
+ ;;
+ -v|--verbose)
+ VERBOSE=1
+ ;;
+
+ -d|--backup-dir)
+ # with value separated by space
+ if [ -n "$2" ]; then
+ backup_dir=$2
+ shift
+ else
+ printf 'ERROR: "-d|--backup-dir" requires a non-empty option argument.\n' >&2
+ exit 1
+ fi
+ ;;
+ --backup-dir=?*)
+ # with value speparated by =
+ backup_dir=${1#*=}
+ ;;
+ --backup-dir=)
+ # without value
+ printf 'ERROR: "--backup-dir" requires a non-empty option argument.\n' >&2
+ exit 1
+ ;;
+
+ --etc)
+ DO_ETC=1
+ ;;
+ --no-etc)
+ DO_ETC=0
+ ;;
+
+ --dpkg)
+ DO_DPKG=1
+ ;;
+ --no-dpkg)
+ DO_DPKG=0
+ ;;
+
+ --apt)
+ DO_APT=1
+ ;;
+ --no-apt)
+ DO_APT=0
+ ;;
+
+ --packages)
+ DO_PACKAGES=1
+ ;;
+ --no-packages)
+ DO_PACKAGES=0
+ ;;
+
+ --processes)
+ DO_PROCESSES=1
+ ;;
+ --no-processes)
+ DO_PROCESSES=0
+ ;;
+
+ --uptime)
+ DO_UPTIME=1
+ ;;
+ --no-uptime)
+ DO_UPTIME=0
+ ;;
+
+ --netstat)
+ DO_NETSTAT=1
+ ;;
+ --no-netstat)
+ DO_NETSTAT=0
+ ;;
+
+ --netcfg)
+ DO_NETCFG=1
+ ;;
+ --no-netcfg)
+ DO_NETCFG=0
+ ;;
+
+ --iptables)
+ DO_IPTABLES=1
+ ;;
+ --no-iptables)
+ DO_IPTABLES=0
+ ;;
+
+ --sysctl)
+ DO_SYSCTL=1
+ ;;
+ --no-sysctl)
+ DO_SYSCTL=0
+ ;;
+
+ --virsh)
+ DO_VIRSH=1
+ ;;
+ --no-virsh)
+ DO_VIRSH=0
+ ;;
+
+ --lxc)
+ DO_LXC=1
+ ;;
+ --no-lxc)
+ DO_LXC=0
+ ;;
+
+ --mount)
+ DO_MOUNT=1
+ ;;
+ --no-mount)
+ DO_MOUNT=0
+ ;;
+
+ --df)
+ DO_DF=1
+ ;;
+ --no-df)
+ DO_DF=0
+ ;;
+
+ --)
+ # End of all options.
+ shift
+ break
+ ;;
+ -?*)
+ # ignore unknown options
+ printf 'WARN: Unknown option : %s\n' "$1" >&2
+ exit 1
+ ;;
+ *)
+ # Default case: If no more options then break out of the loop.
+ break
+ ;;
+ esac
+
+ shift
+done
+
+# Default values
+: "${VERBOSE:=0}"
+: "${DO_ETC:=0}"
+: "${DO_DPKG:=0}"
+: "${DO_APT:=1}"
+: "${DO_PACKAGES:=1}"
+: "${DO_PROCESSES:=1}"
+: "${DO_UPTIME:=1}"
+: "${DO_NETSTAT:=1}"
+: "${DO_NETCFG:=1}"
+: "${DO_IPTABLES:=1}"
+: "${DO_SYSCTL:=1}"
+: "${DO_VIRSH:=1}"
+: "${DO_LXC:=1}"
+: "${DO_MOUNT:=1}"
+: "${DO_DF:=1}"
+
+export LC_ALL=C
+
+set -u
+
+main
diff --git a/evolinux-base/files/logs/logrotate.d/alternatives b/evolinux-base/files/logs/logrotate.d/alternatives
new file mode 100644
index 00000000..5fa5b7a1
--- /dev/null
+++ b/evolinux-base/files/logs/logrotate.d/alternatives
@@ -0,0 +1,9 @@
+/var/log/alternatives.log {
+ monthly
+ rotate 120
+ compress
+ delaycompress
+ missingok
+ notifempty
+ create 644 root root
+}
diff --git a/evolinux-base/files/logs/logrotate.d/dpkg b/evolinux-base/files/logs/logrotate.d/dpkg
index 16ac22fe..81f71969 100644
--- a/evolinux-base/files/logs/logrotate.d/dpkg
+++ b/evolinux-base/files/logs/logrotate.d/dpkg
@@ -6,14 +6,4 @@
missingok
notifempty
create 644 root root
-}
-/var/log/alternatives.log {
- monthly
- rotate 120
- compress
- delaycompress
- missingok
- notifempty
- create 644 root root
-}
-
+}
\ No newline at end of file
diff --git a/evolinux-base/files/logs/logrotate.disabled/ldap b/evolinux-base/files/logs/logrotate.disabled/ldap
index 59372a33..4be35fa8 100644
--- a/evolinux-base/files/logs/logrotate.disabled/ldap
+++ b/evolinux-base/files/logs/logrotate.disabled/ldap
@@ -2,8 +2,8 @@
weekly
missingok
rotate 3
- compress
- notifempty
+ compress
+ notifempty
create 640 root adm
}
diff --git a/evolinux-base/files/logs/logrotate.disabled/procmail b/evolinux-base/files/logs/logrotate.disabled/procmail
index d42323f1..29dd2d7a 100644
--- a/evolinux-base/files/logs/logrotate.disabled/procmail
+++ b/evolinux-base/files/logs/logrotate.disabled/procmail
@@ -1,11 +1,7 @@
/var/log/procmail.log {
daily
rotate 365
- dateext
- dateyesterday
- dateformat .%Y%m%d
missingok
- rotate 365
create 640 root adm
}
diff --git a/evolinux-base/tasks/fstab.yml b/evolinux-base/tasks/fstab.yml
index e10f483e..a3933844 100644
--- a/evolinux-base/tasks/fstab.yml
+++ b/evolinux-base/tasks/fstab.yml
@@ -1,5 +1,6 @@
---
# TODO: trouver comment faire une copie initiale de /etc/fstab
+# - piste : paramètre "backup" du module mount https://docs.ansible.com/ansible/latest/collections/ansible/posix/mount_module.html
# TODO: try to use the custom mount_uuid module for a different approach
- name: Fetch fstab content
diff --git a/evolinux-base/tasks/hardware.yml b/evolinux-base/tasks/hardware.yml
index 9f0c6da3..e072f95c 100644
--- a/evolinux-base/tasks/hardware.yml
+++ b/evolinux-base/tasks/hardware.yml
@@ -30,13 +30,25 @@
- packages
when: broadcom_netextreme_search.rc == 0
+
+## Dedicated hardware
+- name: Install freepmi when it's dedicated hardware
+ apt:
+ name:
+ - libipc-run-perl
+ - freeipmi
+ state: present
+ tags:
+ - packages
+ when: ansible_virtualization_role == "host"
+
## RAID
# Dell and others: MegaRAID SAS
# HP gen <10: Hewlett-Packard Company Smart Array
# HP gen >=10: Adaptec Smart Storage PQI
- name: Detect if RAID is installed
- shell:
- cmd: "set -o pipefail && lspci -q | grep -e 'RAID bus controller' -e 'Serial Attached SCSI controller'"
+ shell:
+ cmd: "lspci -q | grep -e 'RAID bus controller' -e 'Serial Attached SCSI controller'"
executable: /bin/bash
check_mode: no
register: raidmodel
diff --git a/evolinux-base/tasks/kernel.yml b/evolinux-base/tasks/kernel.yml
index b49968f1..6ddeb57f 100644
--- a/evolinux-base/tasks/kernel.yml
+++ b/evolinux-base/tasks/kernel.yml
@@ -8,8 +8,8 @@
state: present
reload: yes
loop:
- - { name: kernel.panic_on_oops, value: 1 }
- - { name: kernel.panic, value: 60 }
+ - { name: kernel.panic_on_oops, value: 1 }
+ - { name: kernel.panic, value: 60 }
when: evolinux_kernel_reboot_after_panic | bool
- name: Don't reboot after panic
@@ -19,8 +19,8 @@
state: absent
reload: yes
loop:
- - kernel.panic_on_oops
- - kernel.panic
+ - kernel.panic_on_oops
+ - kernel.panic
when: not evolinux_kernel_reboot_after_panic | bool
- name: Disable net.ipv4.tcp_timestamps
diff --git a/evolinux-base/tasks/logs.yml b/evolinux-base/tasks/logs.yml
index 2bf28b98..8298486e 100644
--- a/evolinux-base/tasks/logs.yml
+++ b/evolinux-base/tasks/logs.yml
@@ -30,11 +30,34 @@
dest: /etc/logrotate.d/zsyslog
when: evolinux_logs_logrotate_confs | bool
-- name: Configure logrotate.conf
+- name: Configure logrotate.conf default rotate value
replace:
dest: /etc/logrotate.conf
regexp: "rotate [0-9]+"
replace: "rotate 12"
when: evolinux_logs_default_rotate | bool
+- name: Enable logrotate.conf dateext option
+ lineinfile:
+ dest: /etc/logrotate.conf
+ line: "dateext"
+ regexp: "^#?\\s*dateext"
+ when: evolinux_logs_default_dateext | bool
+
+- name: Enable logrotate.conf dateformat option
+ lineinfile:
+ dest: /etc/logrotate.conf
+ line: "dateformat {{ evolinux_logrotate_dateformat | mandatory }}"
+ regexp: "^#?\\s*dateformat.*"
+ insertafter: 'dateext'
+ when: evolinux_logs_default_dateext | bool
+
+- name: Disable logrotate.conf dateyesterday option
+ lineinfile:
+ dest: /etc/logrotate.conf
+ line: "# dateyesterday"
+ regexp: "^\\s*dateyesterday"
+ insertafter: 'dateext'
+ when: evolinux_logs_default_dateext | bool
+
- meta: flush_handlers
diff --git a/evolinux-base/tasks/main.yml b/evolinux-base/tasks/main.yml
index b64badd6..bc11c030 100644
--- a/evolinux-base/tasks/main.yml
+++ b/evolinux-base/tasks/main.yml
@@ -97,6 +97,9 @@
when: evolinux_log2mail_include | bool
- include: motd.yml
+ when: evolinux_motd_include | bool
+
+- include: utils.yml
- name: Munin
include_role:
@@ -116,8 +119,6 @@
- name: Evocheck
include_role:
name: evolix/evocheck
- vars:
- evocheck_force_install: "{{ evolinux_evocheck_force_install }}"
when: evolinux_evocheck_include | bool
- name: Listupgrade
diff --git a/evolinux-base/tasks/packages.yml b/evolinux-base/tasks/packages.yml
index 8df64abd..f4eafc6c 100644
--- a/evolinux-base/tasks/packages.yml
+++ b/evolinux-base/tasks/packages.yml
@@ -16,6 +16,7 @@
- ssl-cert
- ca-certificates
- rename
+ - dmidecode
when: evolinux_packages_system | bool
- name: Install/Update diagnostic tools
@@ -34,6 +35,7 @@
- telnet
- traceroute
- man
+ - molly-guard
when: evolinux_packages_diagnostic | bool
- name: Install/Update hardware tools
@@ -143,5 +145,6 @@
when:
- ansible_distribution == "Debian"
- ansible_distribution_major_version is version('9', '>=')
+ - evolinux_packages_delete_aptlistchanges
- meta: flush_handlers
diff --git a/evolinux-base/tasks/system.yml b/evolinux-base/tasks/system.yml
index 554bb02a..4b6c95b4 100644
--- a/evolinux-base/tasks/system.yml
+++ b/evolinux-base/tasks/system.yml
@@ -119,10 +119,10 @@
regexp: "{{ item.regexp }}"
replace: "{{ item.replace }}"
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' }
- - { regexp: '^52\s*6(\s*1(\s*\*){2})', replace: '{{ 59|random(start=1) }} {{ [0,1,3,4,5,6,7]|random }}\1' }
+ - { 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' }
+ - { 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
- evolinux_system_cron_random | bool
@@ -182,6 +182,7 @@
- evolinux_system_alert5_init | bool
- evolinux_system_alert5_enable | bool
- ansible_distribution_major_version is version('10', '>=')
+ - not ansible_check_mode
## network interfaces
diff --git a/evolinux-base/tasks/utils.yml b/evolinux-base/tasks/utils.yml
new file mode 100644
index 00000000..ede5f4e8
--- /dev/null
+++ b/evolinux-base/tasks/utils.yml
@@ -0,0 +1,13 @@
+---
+
+- include_role:
+ name: evolix/remount-usr
+
+- name: backup-server-state script is present
+ copy:
+ src: "backup-server-state.sh"
+ dest: /usr/local/sbin/backup-server-state
+ force: True
+ owner: root
+ group: root
+ mode: "0750"
diff --git a/evolinux-base/templates/logs/zsyslog.j2 b/evolinux-base/templates/logs/zsyslog.j2
index 2fc2bd1a..cb6d931e 100644
--- a/evolinux-base/templates/logs/zsyslog.j2
+++ b/evolinux-base/templates/logs/zsyslog.j2
@@ -1,8 +1,13 @@
# Custom EvoLinux
create 640 root adm
+{% if not evolinux_logs_default_dateext %}
+# BEGIN legacy setting
+# … when global dateext and dateformat are not enabled
dateext
dateyesterday
dateformat .%Y%m%d
+# END legacy setting
+{% endif %}
missingok
notifempty
delaycompress
diff --git a/evolinux-users/templates/sudoers_jessie.j2 b/evolinux-users/templates/sudoers_jessie.j2
index b82c67ac..c0703c49 100644
--- a/evolinux-users/templates/sudoers_jessie.j2
+++ b/evolinux-users/templates/sudoers_jessie.j2
@@ -7,6 +7,8 @@ nagios ALL = NOPASSWD: /usr/lib/nagios/plugins/check_procs
nagios ALL = NOPASSWD: /usr/local/lib/nagios/plugins/check_minifirewall
nagios ALL = NOPASSWD: /usr/local/lib/nagios/plugins/check_haproxy_stats
nagios ALL = NOPASSWD: /usr/sbin/bkctld check
+nagios ALL = NOPASSWD: /usr/sbin/bkctld check-jails
+nagios ALL = NOPASSWD: /usr/sbin/bkctld check-setup
nagios ALL = (clamav) NOPASSWD: /usr/bin/clamscan /tmp/safe.txt
ADMINS ALL = (ALL:ALL) ALL
diff --git a/evolinux-users/templates/sudoers_stretch.j2 b/evolinux-users/templates/sudoers_stretch.j2
index 539f871e..4a522e1b 100644
--- a/evolinux-users/templates/sudoers_stretch.j2
+++ b/evolinux-users/templates/sudoers_stretch.j2
@@ -6,10 +6,22 @@ nagios ALL = NOPASSWD: /usr/lib/nagios/plugins/check_procs
nagios ALL = NOPASSWD: /usr/local/lib/nagios/plugins/check_minifirewall
nagios ALL = NOPASSWD: /usr/local/lib/nagios/plugins/check_haproxy_stats
nagios ALL = NOPASSWD: /usr/sbin/bkctld check
+nagios ALL = NOPASSWD: /usr/sbin/bkctld check-jails
+nagios ALL = NOPASSWD: /usr/sbin/bkctld check-setup
nagios ALL = NOPASSWD: /usr/local/lib/nagios/plugins/check_phpfpm_multi /var/lib/lxc/php56/rootfs/etc/php5/fpm/pool.d/
nagios ALL = NOPASSWD: /usr/local/lib/nagios/plugins/check_phpfpm_multi /var/lib/lxc/php70/rootfs/etc/php/7.0/fpm/pool.d/
nagios ALL = NOPASSWD: /usr/local/lib/nagios/plugins/check_phpfpm_multi /var/lib/lxc/php73/rootfs/etc/php/7.3/fpm/pool.d/
nagios ALL = NOPASSWD: /usr/local/lib/nagios/plugins/check_phpfpm_multi /var/lib/lxc/php74/rootfs/etc/php/7.4/fpm/pool.d/
+nagios ALL = NOPASSWD: /usr/local/lib/nagios/plugins/check_phpfpm_multi /var/lib/lxc/php74/rootfs/etc/php/8.0/fpm/pool.d/
+nagios ALL = NOPASSWD: /usr/sbin/megaclisas-status --nagios
+nagios ALL = NOPASSWD: /usr/lib/nagios/plugins/check_ipmi_sensor
+nagios ALL = NOPASSWD: /sbin/dmsetup status --noflush
+nagios ALL = NOPASSWD: /sbin/megacli -PDList -aALL -NoLog
+nagios ALL = NOPASSWD: /sbin/megacli -LdInfo -Lall -aALL -NoLog
+nagios ALL = NOPASSWD: /sbin/megacli -AdpBbuCmd -GetBbuStatus -aALL -NoLog
+nagios ALL = NOPASSWD: /sbin/ssacli controller all show status
+nagios ALL = NOPASSWD: /sbin/ssacli controller slot=0 logicaldrive all show
+
nagios ALL = (clamav) NOPASSWD: /usr/bin/clamscan /tmp/safe.txt
%{{ evolinux_sudo_group }} ALL=(ALL:ALL) ALL
diff --git a/evomaintenance/files/evomaintenance.sh b/evomaintenance/files/evomaintenance.sh
index 1961ebf2..3903f2ef 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-2021 Evolix , Gregory Colpart ,
+# Copyright 2007-2022 Evolix , Gregory Colpart ,
# Jérémy Lecour and others.
-VERSION="0.6.4"
+VERSION="22.01"
show_version() {
cat <,
+Copyright 2007-2022 Evolix ,
Gregory Colpart ,
Jérémy Lecour
and others.
@@ -303,6 +303,9 @@ From: ${FULLFROM}
Content-Type: text/plain; charset=UTF-8
MIME-Version: 1.0
Content-Transfer-Encoding: 8bit
+X-Evomaintenance-Version: ${VERSION}
+X-Evomaintenance-Host: ${HOSTNAME_TEXT}
+X-Evomaintenance-User: ${USER}
To: ${EVOMAINTMAIL}
Subject: [evomaintenance] Intervention sur ${HOSTNAME_TEXT} (${USER})
diff --git a/evomaintenance/tasks/config.yml b/evomaintenance/tasks/config.yml
new file mode 100644
index 00000000..097e9770
--- /dev/null
+++ b/evomaintenance/tasks/config.yml
@@ -0,0 +1,18 @@
+---
+
+- assert:
+ that:
+ - evomaintenance_api_endpoint is not none
+ - evomaintenance_api_key is not none
+ msg: evomaintenance api variables must be set
+
+- name: Configuration is installed
+ template:
+ src: evomaintenance.j2
+ dest: /etc/evomaintenance.cf
+ owner: root
+ group: root
+ mode: "0600"
+ force: "{{ evomaintenance_force_config | bool }}"
+ tags:
+ - evomaintenance
diff --git a/evomaintenance/tasks/install_package_debian.yml b/evomaintenance/tasks/install_package_debian.yml
index a5da77ea..ce9d90e7 100644
--- a/evomaintenance/tasks/install_package_debian.yml
+++ b/evomaintenance/tasks/install_package_debian.yml
@@ -12,15 +12,4 @@
name: evomaintenance
allow_unauthenticated: yes
tags:
- - evomaintenance
-
-- name: Configuration is installed
- template:
- src: evomaintenance.j2
- dest: /etc/evomaintenance.cf
- owner: root
- group: root
- mode: "0600"
- force: "{{ evomaintenance_force_config | bool }}"
- tags:
- - evomaintenance
+ - evomaintenance
\ No newline at end of file
diff --git a/evomaintenance/tasks/install_vendor_debian.yml b/evomaintenance/tasks/install_vendor_debian.yml
index 2faaac79..99448e3c 100644
--- a/evomaintenance/tasks/install_vendor_debian.yml
+++ b/evomaintenance/tasks/install_vendor_debian.yml
@@ -46,15 +46,4 @@
- { 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: root
- mode: "0600"
- force: "{{ evomaintenance_force_config | bool }}"
- tags:
- - evomaintenance
+ - evomaintenance
\ No newline at end of file
diff --git a/evomaintenance/tasks/main.yml b/evomaintenance/tasks/main.yml
index 9826089b..0a4e5010 100644
--- a/evomaintenance/tasks/main.yml
+++ b/evomaintenance/tasks/main.yml
@@ -1,14 +1,5 @@
---
-- set_fact:
- minifirewall_restart_handler_name: "{{ minifirewall_restart_if_needed | bool | ternary('restart minifirewall', 'restart minifirewall (noop)') }}"
-
-- assert:
- that:
- - evomaintenance_api_endpoint is not none
- - evomaintenance_api_key is not none
- msg: evomaintenance api variables must be set
-
- include: install_package_debian.yml
when:
- not (evomaintenance_install_vendor | bool)
@@ -19,6 +10,8 @@
- evomaintenance_install_vendor | bool
- ansible_distribution == "Debian"
+- include: config.yml
+
- include: minifirewall.yml
when:
- evomaintenance_hook_db | bool
diff --git a/evomaintenance/tasks/minifirewall.yml b/evomaintenance/tasks/minifirewall.yml
index ad48e856..98dad15b 100644
--- a/evomaintenance/tasks/minifirewall.yml
+++ b/evomaintenance/tasks/minifirewall.yml
@@ -1,5 +1,8 @@
---
+- set_fact:
+ minifirewall_restart_handler_name: "{{ minifirewall_restart_if_needed | bool | ternary('restart minifirewall', 'restart minifirewall (noop)') }}"
+
- name: Is minifirewall installed?
stat:
path: /etc/default/minifirewall
diff --git a/filebeat/defaults/main.yml b/filebeat/defaults/main.yml
index 598a08ed..deed1508 100644
--- a/filebeat/defaults/main.yml
+++ b/filebeat/defaults/main.yml
@@ -1,5 +1,5 @@
---
-elastic_stack_version: "6.x"
+elastic_stack_version: "7.x"
filebeat_logstash_plugin: False
diff --git a/filebeat/handlers/main.yml b/filebeat/handlers/main.yml
index 0a6d83f9..3ad08a63 100644
--- a/filebeat/handlers/main.yml
+++ b/filebeat/handlers/main.yml
@@ -4,3 +4,4 @@
systemd:
name: filebeat
state: restarted
+ when: not ansible_check_mode
diff --git a/filebeat/tasks/main.yml b/filebeat/tasks/main.yml
index c84c4db8..dd326cc8 100644
--- a/filebeat/tasks/main.yml
+++ b/filebeat/tasks/main.yml
@@ -62,6 +62,7 @@
name: filebeat
enabled: yes
notify: restart filebeat
+ when: not ansible_check_mode
- name: is logstash-plugin available?
stat:
@@ -140,7 +141,9 @@
when:
- filebeat_elasticsearch_auth_username | length > 0
- filebeat_elasticsearch_auth_password | length > 0
- when: not (filebeat_use_config_template | bool)
+ when:
+ - not (filebeat_use_config_template | bool)
+ - not ansible_check_mode
- name: Filebeat api_key for Elasticsearch are configured
lineinfile:
diff --git a/generate-ldif/templates/generateldif.sh.j2 b/generate-ldif/templates/generateldif.sh.j2
index d5c19411..aa3ec7dd 100755
--- a/generate-ldif/templates/generateldif.sh.j2
+++ b/generate-ldif/templates/generateldif.sh.j2
@@ -31,17 +31,30 @@ computerKernel=$(uname -r)
HardwareSerial=$(dmidecode -s system-serial-number | grep -v '^#')
type="baremetal"
-lscpu | grep -q KVM && type="kvm"
+lscpu | grep "Hypervisor vendor:" | grep -q KVM && type="kvm"
+lscpu | grep "Hypervisor vendor:" | grep -q VMware && type="vmware"
lscpu | grep -q Oracle && type="virtualbox"
if [ "$type" = "kvm" ]; then
+ ComputerType="VM"
HardwareMark="KVM"
HardwareModel="Virtual Machine"
cpuMark=$(lscpu | grep Vendor | tr -s '\t' ' ' | cut -d' ' -f3)
cpuModel="Virtual $(lscpu | grep "Model name" | tr -s '\t' ' ' | cut -d' ' -f3-), $(nproc) vCPU"
cpuFreq="$(lscpu | grep "CPU MHz" | tr -s '\t' ' ' | cut -d' ' -f3-)MHz"
+
+elif [ "$type" = "vmware" ]; then
+ ComputerType="VM"
+ HardwareMark="VMWare"
+ HardwareModel="Virtual Machine"
+
+ cpuMark=$(lscpu | grep Vendor | tr -s '\t' ' ' | cut -d' ' -f3)
+ cpuModel="Virtual $(lscpu | grep "Model name" | tr -s '\t' ' ' | cut -d' ' -f3-), $(nproc) vCPU"
+ cpuFreq="$(lscpu | grep "CPU MHz" | tr -s '\t' ' ' | cut -d' ' -f3-)MHz"
+
elif [ "$type" = "virtualbox" ]; then
+ ComputerType="VM"
HardwareMark="VirtualBox"
HardwareModel="Virtual Machine"
@@ -49,6 +62,7 @@ elif [ "$type" = "virtualbox" ]; then
cpuModel="Virtual $(lscpu | grep "Model name" | tr -s '\t' ' ' | cut -d' ' -f3-), $(nproc) vCPU"
cpuFreq="$(lscpu | grep "CPU MHz" | tr -s '\t' ' ' | cut -d' ' -f3-)MHz"
else
+ ComputerType="Baremetal"
HardwareModel=$(dmidecode -s system-product-name | grep -v '^#')
cpuMark=$(dmidecode -s processor-manufacturer | grep -v '^#' | head -1)
@@ -115,6 +129,7 @@ NagiosEnabled: ${NagiosEnabled}
NagiosComments: ${monitoringType},${monitoringMode},${monitoringTimeout}
HardwareSerial: ${HardwareSerial}
clientNumber: ${clientNumber}
+ComputerType: ${ComputerType}
EOT
# CPU
@@ -174,6 +189,19 @@ NagiosEnabled: TRUE
EOT
fi
+# raid hardware
+if [ -n "${raidModel}" ]; then
+ cat <> "${ldif_file}"
+
+dn: HardwareName=raid_card,${computer_dn}
+objectClass: EvoHardware
+HardwareName: raid_card
+HardwareType: disk
+HardwareModel: ${raidModel}
+NagiosEnabled: TRUE
+EOT
+fi
+
# Swap
swap=$(free -h | grep Swap: | tr -s ' ' | cut -d ' ' -f2)
if [ -n "${swap}" ]; then
@@ -570,10 +598,27 @@ objectClass: EvoService
ServiceName: postgresql
ipServicePort: 5432
ServiceType: database
-ServiceVersion: PostgreSQL ${elasticsearch_version}
+ServiceVersion: PostgreSQL ${postgresql_version}
EOT
fi
+# mdadm
+if is_pkg_installed mdadm; then
+ mdadm_version=$(get_pkg_version mdadm)
+fi
+if [ -n "${mdadm_version}" ]; then
+ cat <> "${ldif_file}"
+
+dn: ServiceName=mdadm,${computer_dn}
+NagiosEnabled: TRUE
+objectClass: EvoService
+ServiceName: mdadm
+ServiceType: raid
+ServiceVersion: mdadm ${mdadm_version}
+EOT
+fi
+
+
# test if we have a stdout
if [ -t 1 ]; then
echo "Output is in ${ldif_file}"
diff --git a/java/tasks/oracle.yml b/java/tasks/oracle.yml
index c2ab5ebf..0b057695 100644
--- a/java/tasks/oracle.yml
+++ b/java/tasks/oracle.yml
@@ -14,9 +14,9 @@
state: directory
mode: "0777"
loop:
- - /srv/java-package
- - /srv/java-package/src
- - /srv/java-package/tmp
+ - /srv/java-package
+ - /srv/java-package/src
+ - /srv/java-package/tmp
tags:
- java
diff --git a/kvm-host/files/add-vm.sh b/kvm-host/files/add-vm.sh
index ec50763d..51b5c737 100755
--- a/kvm-host/files/add-vm.sh
+++ b/kvm-host/files/add-vm.sh
@@ -10,6 +10,8 @@
# Bash strict mode
set -euo pipefail
+VERSION="21.10"
+
isDryRun() {
test "${doDryRun}" = "true"
}
diff --git a/kvm-host/files/kvmstats.sh b/kvm-host/files/kvmstats.sh
index 5fa20ccb..0dcfb4e8 100755
--- a/kvm-host/files/kvmstats.sh
+++ b/kvm-host/files/kvmstats.sh
@@ -1,96 +1,202 @@
#!/bin/sh
+VERSION="21.10"
+
+PROGNAME=$(basename "$0")
+
+show_version() {
+ cat <,
+ Alexis Ben Miloud--Josselin ,
+ Jérémy Lecour
+ and others.
+
+${PROGNAME} 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 ${PROGNAME} --units
+END
+}
+
error () {
echo "$0": "$@" >&2
exit 1
}
-usage () {
- echo 'usage:' "$0" '[-a] [-u k|m|g] [-o human|html|csv]' >&2
- exit 1
+main() {
+ for VM in $(virsh list --name --all | sed '/^$/d' | sort)
+ do
+ echo "$VM"
+
+ # cpu
+ virsh vcpucount --current "$VM"
+
+ # 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 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
+ 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
+ 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 "%s | ", $i;print "
"}END{print "
\n"}'
+ ;;
+ 'csv')
+ tr ' ' ','
+ ;;
+ esac
}
+parse_units() {
+ case "$1" in
+ 'k')
+ POW="$(echo '1024 ^ 1' | bc)"
+ ;;
+ 'm')
+ POW="$(echo '1024 ^ 2' | bc)"
+ ;;
+ 'g')
+ POW="$(echo '1024 ^ 3' | bc)"
+ ;;
+ *)
+ printf 'ERROR: Unknown unit value: %s. Possible values: %s\n' "$1" "k, m, g" >&2
+ echo "" >&2
+ show_usage >&2
+ exit 1
+ ;;
+ esac
+}
+parse_output() {
+ case "$1" in
+ 'csv'|'html'|'human')
+ FMT="$1"
+ ;;
+ *)
+ printf 'ERROR: Unknown output value : %s. Possible values: %s\n' "$1" "csv, html, human" >&2
+ echo "" >&2
+ show_usage >&2
+ exit 1
+ ;;
+ esac
+}
+
+# Check dependencies
for DEP in bc virsh
do
command -v "$DEP" > /dev/null || error "$DEP" 'command not found'
done
+# default values
POW="$(echo '1024 ^ 3' | bc)"
FMT='human'
-while [ "$#" -ne 0 ]
-do
- case "$1" in
- '-a')
- SHOW_AVAIL='y'
- ;;
- '-o')
- case "$2" in
- 'csv'|'html'|'human')
- FMT="$2"
+
+# 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
+ ;;
+ -a|--all)
+ SHOW_AVAIL='y'
+ ;;
+ -u|--units)
+ # with value separated by space
+ if [ -n "$2" ]; then
+ parse_units "$2"
+ shift
+ else
+ printf 'ERROR: "-u|--units" requires a non-empty option argument.\n' >&2
+ exit 1
+ fi
+ ;;
+ --units=?*)
+ # with value speparated by =
+ parse_units ${1#*=}
+ ;;
+ --units=)
+ # without value
+ printf 'ERROR: "--units" requires a non-empty option argument.\n' >&2
+ exit 1
+ ;;
+
+ -o|--output)
+ # with value separated by space
+ if [ -n "$2" ]; then
+ parse_output "$2"
+ shift
+ else
+ printf 'ERROR: "-o|--output" requires a non-empty option argument.\n' >&2
+ exit 1
+ fi
+ ;;
+ --output=?*)
+ # with value speparated by =
+ parse_output ${1#*=}
+ ;;
+ --output=)
+ # without value
+ printf 'ERROR: "--output" 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
;;
*)
- usage
+ # Default case: If no more options then break out of the loop.
+ break
;;
- esac
- shift
- ;;
- '-u')
- case "$2" in
- 'k')
- POW="$(echo '1024 ^ 1' | bc)"
- ;;
- 'm')
- POW="$(echo '1024 ^ 2' | bc)"
- ;;
- 'g')
- POW="$(echo '1024 ^ 3' | bc)"
- ;;
- *)
- usage
- esac
- shift
- ;;
- *)
- usage
esac
+
shift
done
-for VM in $(virsh list --name --all)
-do
- echo "$VM"
-
- # cpu
- virsh vcpucount --current "$VM"
-
- # 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 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
- 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
- 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 "%s | ", $i;print "
"}END{print "
\n"}'
- ;;
-'csv')
- tr ' ' ','
- ;;
-esac
+main
diff --git a/kvm-host/tasks/main.yml b/kvm-host/tasks/main.yml
index 95cb7090..a2f6953c 100644
--- a/kvm-host/tasks/main.yml
+++ b/kvm-host/tasks/main.yml
@@ -5,7 +5,7 @@
when: kvm_install_drbd
## TODO: check why it's disabled
-#- include: ssh.yml
+- include: ssh.yml
- include: packages.yml
diff --git a/kvm-host/tasks/ssh.yml b/kvm-host/tasks/ssh.yml
index fe71c287..a36f7549 100644
--- a/kvm-host/tasks/ssh.yml
+++ b/kvm-host/tasks/ssh.yml
@@ -15,36 +15,34 @@
debug:
msg: "{{ ssh_keys.stdout }}"
-- name: Autorize other kvm ssh key
- authorized_key:
- user: root
- state: present
- key: "{{ item[0] }}"
- delegate_to: "{{ item[1] }}"
- loop: "{{ _keys | product(_servers) | list }}"
- vars:
- _keys: ssh_keys.stdout
- _servers: groups['hypervisors']
- when: item[1] != inventory_hostname
+#- name: Autorize other kvm ssh key
+# authorized_key:
+# user: root
+# state: present
+# key: "{{ item[0] }}"
+# delegate_to: "{{ item[1] }}"
+# 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
cron:
- name: "sync libvirt xml on {{ item }}"
+ name: "sync libvirt xml on {{ kvm_pair }}"
state: present
special_time: "hourly"
user: root
- job: "rsync -a --delete /etc/libvirt/qemu/ {{ hostvars[item]['ansible_hostname'] }}:/root/libvirt-{{ inventory_hostname }}/"
- loop:
- - "{{ groups['hypervisors'] }}"
- when: item != inventory_hostname
+ job: "rsync -a --delete /etc/libvirt/qemu/*xml {{ hostvars[kvm_pair]['lan.ip'] }}:/root/libvirt-{{ inventory_hostname }}/"
+ when: kvm_pair != inventory_hostname
+ tags: crontab
- name: Crontab for sync list of running vm
cron:
- name: "sync list of libvirt running vm on {{ item }}"
+ name: "sync list of libvirt running vm on {{ kvm_pair }}"
state: present
special_time: "daily"
user: root
- job: "virsh list --all | ssh {{ hostvars[item]['ansible_hostname'] }} 'cat >/root/libvirt-{{ inventory_hostname }}/virsh-list.txt'"
- loop:
- - "{{ groups['hypervisors'] }}"
- when: item != inventory_hostname
+ job: "virsh list --all | tee /root/virsh-list.txt | ssh {{ hostvars[kvm_pair]['lan.ip'] }} 'cat >/root/libvirt-{{ inventory_hostname }}/virsh-list.txt'"
+ when: kvm_pair != inventory_hostname
+ tags: crontab
diff --git a/listupgrade/files/old-kernel-autoremoval.sh b/listupgrade/files/old-kernel-autoremoval.sh
index ceed0b99..ce1c6002 100644
--- a/listupgrade/files/old-kernel-autoremoval.sh
+++ b/listupgrade/files/old-kernel-autoremoval.sh
@@ -4,13 +4,36 @@
# fork by reg from /etc/kernel/postinst.d/apt-auto-removal script
-VERSION="21.06.3"
+VERSION="21.10"
+readonly VERSION
-set -e
+PROGNAME=$(basename "$0")
-# shellcheck disable=SC2046
-eval $(apt-config shell DPKG Dir::bin::dpkg/f)
-DPKG="${DPKG:-/usr/bin/dpkg}"
+show_version() {
+ cat <,
+ Gregory Colpart ,
+ Romain Dessort ,
+ Ludovic Poujol ,
+ Jérémy Lecour
+ and others.
+
+${PROGNAME} 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 <&2
+ fi
+ ;;
+ *)
+ # Default case: If no more options then break out of the loop.
+ break
+ ;;
+ esac
+
+ shift
+done
+
+set -e
+
+
+main "${@}"
diff --git a/logstash/defaults/main.yml b/logstash/defaults/main.yml
index 456769cd..7cc40e49 100644
--- a/logstash/defaults/main.yml
+++ b/logstash/defaults/main.yml
@@ -1,8 +1,10 @@
---
-elastic_stack_version: "6.x"
+elastic_stack_version: "7.x"
logstash_jvm_xms: 256m
logstash_jvm_xmx: 512g
logstash_log_rotate_days: 365
logstash_custom_tmpdir: Null
logstash_default_tmpdir: /var/lib/logstash/tmp
+logstash_log_syslog_enabled: True
+logstash_config_force: True
\ No newline at end of file
diff --git a/logstash/handlers/main.yml b/logstash/handlers/main.yml
new file mode 100644
index 00000000..d21d4de3
--- /dev/null
+++ b/logstash/handlers/main.yml
@@ -0,0 +1,10 @@
+---
+
+- name: restart logstash
+ systemd:
+ name: logstash
+ state: restarted
+ daemon_reload: yes
+
+- name: reload systemd
+ command: systemctl daemon-reload
\ No newline at end of file
diff --git a/logstash/meta/main.yml b/logstash/meta/main.yml
index b2ef1210..bad2b6a5 100644
--- a/logstash/meta/main.yml
+++ b/logstash/meta/main.yml
@@ -24,5 +24,4 @@ galaxy_info:
# 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 }
+dependencies: []
diff --git a/logstash/tasks/logs.yml b/logstash/tasks/logs.yml
index 975cd8bc..b09ebaf2 100644
--- a/logstash/tasks/logs.yml
+++ b/logstash/tasks/logs.yml
@@ -16,3 +16,26 @@
group: root
mode: "0750"
when: is_cron_installed.rc == 0
+
+- name: "Create a system config directory for systemd overrides"
+ file:
+ path: /etc/systemd/system/logstash.service.d
+ state: directory
+
+- name: "disable syslog"
+ ini_file:
+ path: /etc/systemd/system/logstash.service.d/override.conf
+ section: Service
+ option: "{{ item.option }}"
+ value: "{{ item.value }}"
+ owner: root
+ group: root
+ mode: "0644"
+ create: yes
+ no_extra_spaces: yes
+ state: "{{ logstash_log_syslog_enabled | bool | ternary('absent','present') }}"
+ loop:
+ - { option: "StandardOutput", value: "null" }
+ - { option: "StandardError", value: "null" }
+ notify:
+ - restart logstash
\ No newline at end of file
diff --git a/logstash/tasks/main.yml b/logstash/tasks/main.yml
index 73bdab1d..856ceba1 100644
--- a/logstash/tasks/main.yml
+++ b/logstash/tasks/main.yml
@@ -88,7 +88,7 @@
owner: logstash
group: logstash
mode: "0640"
- force: yes
+ force: "{{ logstash_config_force | bool }}"
loop: "{{ query('first_found', templates) }}"
vars:
templates:
diff --git a/lxc-php/defaults/main.yml b/lxc-php/defaults/main.yml
index ce8a935d..9eb226f1 100644
--- a/lxc-php/defaults/main.yml
+++ b/lxc-php/defaults/main.yml
@@ -19,3 +19,4 @@ lxc_php_container_releases:
php70: "stretch"
php73: "buster"
php74: "bullseye"
+ php80: "bullseye"
diff --git a/lxc-php/handlers/main.yml b/lxc-php/handlers/main.yml
index 95882838..27ba8157 100644
--- a/lxc-php/handlers/main.yml
+++ b/lxc-php/handlers/main.yml
@@ -1,4 +1,9 @@
---
+- name: Reload php80-fpm
+ lxc_container:
+ name: "{{ lxc_php_version }}"
+ container_command: "systemctl reload php8.0-fpm"
+
- name: Reload php74-fpm
lxc_container:
name: "{{ lxc_php_version }}"
diff --git a/lxc-php/tasks/mail_opensmtpd.yml b/lxc-php/tasks/mail_opensmtpd.yml
index 1b4dbea0..25dec9ea 100644
--- a/lxc-php/tasks/mail_opensmtpd.yml
+++ b/lxc-php/tasks/mail_opensmtpd.yml
@@ -11,3 +11,13 @@
dest: "/var/lib/lxc/{{ lxc_php_version }}/rootfs/etc/smtpd.conf"
mode: "0644"
notify: "Restart opensmtpd"
+ when: lxc_php_container_releases[lxc_php_version] in ["jessie", "stretch", "buster"]
+
+
+- name: "{{ lxc_php_version }} - Configure opensmtpd (in the container)"
+ template:
+ src: smtpd.conf.bullseye.j2
+ dest: "/var/lib/lxc/{{ lxc_php_version }}/rootfs/etc/smtpd.conf"
+ mode: "0644"
+ notify: "Restart opensmtpd"
+ when: not lxc_php_container_releases[lxc_php_version] in ["jessie", "stretch", "buster"]
diff --git a/lxc-php/tasks/main.yml b/lxc-php/tasks/main.yml
index 25c0a978..0de38336 100644
--- a/lxc-php/tasks/main.yml
+++ b/lxc-php/tasks/main.yml
@@ -21,4 +21,7 @@
- include: "php74.yml"
when: lxc_php_version == "php74"
+- include: "php80.yml"
+ when: lxc_php_version == "php80"
+
- include: "misc.yml"
diff --git a/lxc-php/tasks/php74.yml b/lxc-php/tasks/php74.yml
index 9438dcc7..a3a7eb44 100644
--- a/lxc-php/tasks/php74.yml
+++ b/lxc-php/tasks/php74.yml
@@ -1,42 +1,5 @@
---
-- name: "{{ lxc_php_version }} - Install dependency packages"
- lxc_container:
- name: "{{ lxc_php_version }}"
- container_command: "DEBIAN_FRONTEND=noninteractive apt install -y wget apt-transport-https gnupg"
-
-- name: "{{ lxc_php_version }} - Add sury repo"
- lineinfile:
- dest: "/var/lib/lxc/{{ lxc_php_version }}/rootfs/etc/apt/sources.list.d/sury.list"
- line: "{{ item }}"
- state: present
- create: yes
- mode: "0644"
- loop:
- - "deb https://packages.sury.org/php/ bullseye main"
- - "deb http://pub.evolix.net/ bullseye-php74/"
-
-- 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"
- 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:
- 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-php/tasks/php80.yml b/lxc-php/tasks/php80.yml
new file mode 100644
index 00000000..390f7edf
--- /dev/null
+++ b/lxc-php/tasks/php80.yml
@@ -0,0 +1,57 @@
+---
+
+- name: "{{ lxc_php_version }} - Install dependency packages"
+ lxc_container:
+ name: "{{ lxc_php_version }}"
+ container_command: "DEBIAN_FRONTEND=noninteractive apt install -y wget apt-transport-https gnupg"
+
+- name: "{{ lxc_php_version }} - Add sury repo"
+ lineinfile:
+ dest: "/var/lib/lxc/{{ lxc_php_version }}/rootfs/etc/apt/sources.list.d/sury.list"
+ line: "{{ item }}"
+ state: present
+ create: yes
+ mode: "0644"
+ loop:
+ - "deb https://packages.sury.org/php/ bullseye main"
+ - "deb http://pub.evolix.net/ bullseye-php74/"
+
+- 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"
+ 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:
+ name: "{{ lxc_php_version }}"
+ container_command: "DEBIAN_FRONTEND=noninteractive apt update"
+
+- name: "{{ lxc_php_version }} - Install PHP packages"
+ lxc_container:
+ name: "{{ lxc_php_version }}"
+ container_command: "DEBIAN_FRONTEND=noninteractive apt install -y php-fpm php-cli php-gd php-intl php-imap php-ldap php-mysql php-pgsql php-sqlite3 php-curl php-zip php-mbstring php-zip composer libphp-phpmailer"
+
+- name: "{{ lxc_php_version }} - Copy evolinux PHP configuration"
+ template:
+ src: z-evolinux-defaults.ini.j2
+ dest: "{{ line_item }}"
+ mode: "0644"
+ notify: "Reload {{ lxc_php_version }}-fpm"
+ loop:
+ - "/var/lib/lxc/{{ lxc_php_version }}/rootfs/etc/php/8.0/fpm/conf.d/z-evolinux-defaults.ini"
+ - "/var/lib/lxc/{{ lxc_php_version }}/rootfs/etc/php/8.0/cli/conf.d/z-evolinux-defaults.ini"
+ loop_control:
+ loop_var: line_item
+
+- include: "mail_opensmtpd.yml"
diff --git a/lxc-php/templates/mailname.j2 b/lxc-php/templates/mailname.j2
new file mode 100644
index 00000000..e374dd45
--- /dev/null
+++ b/lxc-php/templates/mailname.j2
@@ -0,0 +1 @@
+{{ansible_fqdn}}
diff --git a/lxc-php/templates/smtpd.conf.bullseye.j2 b/lxc-php/templates/smtpd.conf.bullseye.j2
new file mode 100644
index 00000000..0a6d658f
--- /dev/null
+++ b/lxc-php/templates/smtpd.conf.bullseye.j2
@@ -0,0 +1,17 @@
+# This is the smtpd server system-wide configuration file.
+# See smtpd.conf(5) for more information.
+
+# To accept external mail, replace with: listen on all
+#listen on localhost
+
+# If you edit the file, you have to run "smtpctl update table aliases"
+table aliases file:/etc/aliases
+
+action "mbox" mbox alias
+action "relay" relay host "smtp://127.0.0.1"
+
+# Uncomment the following to accept external mail for domain "example.org"
+#match from any for domain "example.org" action "mbox"
+
+match for local action "mbox"
+match for any action "relay"
diff --git a/lxc-solr/tasks/main.yml b/lxc-solr/tasks/main.yml
index 3fad863f..d629bbf6 100644
--- a/lxc-solr/tasks/main.yml
+++ b/lxc-solr/tasks/main.yml
@@ -8,9 +8,7 @@
path: "/var/lib/lxc/{{ item.name }}/rootfs"
state: directory
mode: '0755'
- loop:
- - "{{ lxc_containers }}"
+ loop: "{{ lxc_containers }}"
- include: "solr.yml name={{item.name}} solr_version={{item.solr_version}} solr_port={{item.solr_port}}"
- loop:
- - "{{ lxc_containers }}"
+ loop: "{{ lxc_containers }}"
diff --git a/lxc/tasks/main.yml b/lxc/tasks/main.yml
index 74ba69ae..daf2885a 100644
--- a/lxc/tasks/main.yml
+++ b/lxc/tasks/main.yml
@@ -6,19 +6,19 @@
- debootstrap
- xz-utils
-- name: python-lxc is installed
+- name: python-lxc is installed (Debian <= 10)
apt:
name: python-lxc
state: present
- when: ansible_distribution_major_version is version('10', '<=')
+ when: ansible_python_version is version('3', '<')
-- name: python3-lxc is installed
+- name: python3-lxc is installed (Debian >= 10)
apt:
name: python3-lxc
state: present
- when: ansible_distribution_major_version is version('10', '>')
+ when: ansible_python_version is version('3', '>=')
-- name: Install additional packages on Buster
+- name: Install additional packages (Debian >= 10)
apt:
name:
- apparmor
@@ -43,6 +43,12 @@
- lxc_unprivilegied_containers | bool
- root_subuids.rc != 0
+- name: Check if /var has not mount options nodev or noexec
+ shell: findmnt | grep -E "/var[^/]" | grep -e nodev -e noexec
+ register: check_var
+ changed_when: false
+ failed_when: "check_var.rc == 0"
+
- name: Create containers
include: create-container.yml
vars:
diff --git a/metricbeat/defaults/main.yml b/metricbeat/defaults/main.yml
index 9529bef3..780a4ffd 100644
--- a/metricbeat/defaults/main.yml
+++ b/metricbeat/defaults/main.yml
@@ -1,5 +1,5 @@
---
-elastic_stack_version: "6.x"
+elastic_stack_version: "7.x"
metricbeat_elasticsearch_hosts:
- "localhost:9200"
diff --git a/mongodb/defaults/main.yml b/mongodb/defaults/main.yml
index ec255349..c118f588 100644
--- a/mongodb/defaults/main.yml
+++ b/mongodb/defaults/main.yml
@@ -6,3 +6,5 @@ mongodb_bind: 127.0.0.1
# Warning: config must not be overwritten by default
# otherwise it can disable important settings, like authorization :/
mongodb_force_config: False
+
+mongodb_version: 4.4
\ No newline at end of file
diff --git a/mongodb/files/server-5.0.asc b/mongodb/files/server-5.0.asc
new file mode 100644
index 00000000..44ea4919
--- /dev/null
+++ b/mongodb/files/server-5.0.asc
@@ -0,0 +1,29 @@
+-----BEGIN PGP PUBLIC KEY BLOCK-----
+
+mQINBGAsKNUBEAClMqPCvvqm6gFmbiorEN9qp00GI8oaECkwbxtGGbqX9sqMSrKe
+AB3sGI7kqG2Fl0K+xmmiq1QDjhNgFDA1jjXq+Bd66RNPtvu747IRxVs+9fX7bk67
+8Bruha7U3M5l4193x5oYLlbcZL9aC7RSJE2mggTyS6LarmF6vKQN9LMXDicnageV
+KCPpF2i3jkZaGnLPzAisW/pOjPQpWCbatTVqKOKvtOyP3Fz1spYd4obu6ELu1PXa
+gmhSfvWJYt1irpchOl29LWZfcmXuJszmb00bqm4gLcK12VrnK191iXv46A8h2hSO
+f3eQqrkc+pF/kw4RyG54EV7QtHXyTe9TVCbJUfgtliWIQt/bCoJYfPLHJaWIMs83
+bzA6ZvOjCKIfMS0CY5ZJyVaBfiI3wURSjgZIYFZAXVwbreQIfOKKuik7UVVn3xUO
+nWpmQ2zyI0W7cJMquxwLNjkI+RckPhIqxWFo5iNSV4v6pzrlHD1WmIfFGBKEn7m+
+edwVyHG53fNIFZjxyShO6Pf1vgb9Js/XmXB4lxYnNyx1tB+hQhXTjLlY6N5gPpw5
+Z/PWQc7vfYekUZGQMXhTyRxU0QTwmdEeKcb+fb9r23OH59bbAfzE10xTMzhqCd2L
+lgSozMBvMmkHb1xs1x6FFuv/U/X7LjHTrHIf4M//DNwdP4l4I1jhPlTAxwARAQAB
+tDdNb25nb0RCIDUuMCBSZWxlYXNlIFNpZ25pbmcgS2V5IDxwYWNrYWdpbmdAbW9u
+Z29kYi5jb20+iQI+BBMBAgAoBQJgLCjVAhsDBQkJZgGABgsJCAcDAgYVCAIJCgsE
+FgIDAQIeAQIXgAAKCRCwCgvR4sY8EawdD/0ewkyx3yE99K9n3y7gdvh5+2U8BsqU
+7SWEfup7kPpf+4pF5xWqMaciEV/wRAGt7TiKlfVyAv3Q9iNsaLFN+s3kMaIcKhwD
+8+q/iGfziIuOSTeo20dAxn9vF6YqrKGc7TbHdXf9AtYuJCfIU5j02uVZiupx+P9+
+rG39dEnjOXm3uY0Fv3pRGCpuGubDlWB1DYh0R5O481kDVGoMqBxmc3iTALu14L/u
+g+AKxFYfT4DmgdzPVMDhppgywfyd/IOWxoOCl4laEhVjUt5CygBa7w07qdKwWx2w
+gTd9U0KGHxnnSmvQYxrRrS5RX3ILPJShivTSZG+rMqnUe6RgCwBrKHCRU1L728Yv
+1B3ZFJLxB1TlVT2Hjr+oigp0RY9W1FCIdO2uhb9GImpaJ1Y0ZZqUkt/d9D8U2wcw
+SW6/6WYeO7wAi/zlJ25hrBwhxS2+88gM6wJ1yL9yrM9v8JUb7Kq0rCGsEO5kqscV
+AmX90wsF2cZ6gHR53eGIDbAJK0MO5RHR73aQ4bpTivPnoTx4HTj5fyhW9z8yCSOe
+BlQABoFFqFvOS7KBxoyIS3pxlDetWOSc6yQrvA1CwxnkB81OHNmJfWAbNbEtZkLm
+xs2c8CIh2R81yi6HUzAaxyDH7mrThbwX3hUe/wsaD1koV91G6bDD4Xx3zpa9DG/O
+HyB98+e983gslg==
+=IQQF
+-----END PGP PUBLIC KEY BLOCK-----
diff --git a/mongodb/tasks/main.yml b/mongodb/tasks/main.yml
index 1d238b00..3054ccfe 100644
--- a/mongodb/tasks/main.yml
+++ b/mongodb/tasks/main.yml
@@ -1,10 +1,5 @@
---
-# - fail:
-# msg: only compatible with Debian 8
-# when:
-# - ansible_distribution != "Debian" or ansible_distribution_release != "jessie"
-
- include: main_jessie.yml
when: ansible_distribution_release == "jessie"
diff --git a/mongodb/tasks/main_bullseye.yml b/mongodb/tasks/main_bullseye.yml
index d9e6e0eb..e31ffed3 100644
--- a/mongodb/tasks/main_bullseye.yml
+++ b/mongodb/tasks/main_bullseye.yml
@@ -1,9 +1,11 @@
---
-- name: Look for legacy apt keyring
- stat:
- path: /etc/apt/trusted.gpg
- register: _trusted_gpg_keyring
+- fail:
+ msg: Not compatible with Debian 11 (Bullseye)
+ when:
+ - ansible_distribution_release == "bullseye"
+ - mongodb_version is version_compare('5.0', '<=')
+
- name: MongoDB embedded GPG key is absent
apt_key:
@@ -14,8 +16,8 @@
- name: Add MongoDB GPG key
copy:
- src: server-4.4.asc
- dest: /etc/apt/trusted.gpg.d/mongodb-server-4.4.asc
+ src: "server-{{mongodb_version}}.asc"
+ dest: "/etc/apt/trusted.gpg.d/mongodb-server-{{mongodb_version}}.asc"
force: yes
mode: "0644"
owner: root
@@ -23,9 +25,9 @@
- name: enable APT sources list
apt_repository:
- repo: deb http://repo.mongodb.org/apt/debian buster/mongodb-org/4.4 main
+ repo: "deb http://repo.mongodb.org/apt/debian buster/mongodb-org/{{mongodb_version}} main"
state: present
- filename: mongodb-org-4.4
+ filename: "mongodb-org-{{mongodb_version}}"
update_cache: yes
- name: Install packages
@@ -40,30 +42,39 @@
name: mongod
enabled: yes
state: started
- when: _mongodb_install_package.changed
+ when: _mongodb_install_package is changed
- name: install dependency for monitoring
apt:
- name: python3-pymongo
+ name: python-pymongo
state: present
- name: Custom configuration
template:
- src: mongodb_bullseye.conf.j2
+ src: mongodb_buster.conf.j2
dest: "/etc/mongod.conf"
force: "{{ mongodb_force_config | bool | ternary('yes', 'no') }}"
notify: restart mongod
- name: Configure logrotate
template:
- src: logrotate_bullseye.j2
+ src: logrotate_buster.j2
dest: /etc/logrotate.d/mongodb
force: yes
backup: no
-- name: Munin plugins local directory exists
+- include_role:
+ name: evolix/remount-usr
+
+- name: Create plugin directory
file:
- dest: /usr/local/share/munin/plugins/
+ name: /usr/local/share/munin/
+ state: directory
+ mode: "0755"
+
+- name: Create plugin directory
+ file:
+ name: /usr/local/share/munin/plugins/
state: directory
mode: "0755"
@@ -72,7 +83,7 @@
src: "munin/{{ item }}"
dest: '/usr/local/share/munin/plugins/{{ item }}'
force: yes
- with_items:
+ loop:
- mongo_btree
- mongo_collections
- mongo_conn
@@ -88,7 +99,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/mongodb/tasks/main_buster.yml b/mongodb/tasks/main_buster.yml
index fc7ac7ed..cf5ce2ae 100644
--- a/mongodb/tasks/main_buster.yml
+++ b/mongodb/tasks/main_buster.yml
@@ -14,8 +14,8 @@
- name: Add MongoDB GPG key
copy:
- src: server-4.2.asc
- dest: /etc/apt/trusted.gpg.d/mongodb-server-4.2.asc
+ src: "server-{{mongodb_version}}.asc"
+ dest: "/etc/apt/trusted.gpg.d/mongodb-server-{{mongodb_version}}.asc"
force: yes
mode: "0644"
owner: root
@@ -23,9 +23,9 @@
- name: enable APT sources list
apt_repository:
- repo: deb http://repo.mongodb.org/apt/debian buster/mongodb-org/4.2 main
+ repo: "deb http://repo.mongodb.org/apt/debian buster/mongodb-org/{{mongodb_version}} main"
state: present
- filename: mongodb-org-4.2
+ filename: "mongodb-org-{{mongodb_version}}"
update_cache: yes
- name: Install packages
@@ -61,6 +61,9 @@
force: yes
backup: no
+- include_role:
+ name: evolix/remount-usr
+
- name: Create plugin directory
file:
name: /usr/local/share/munin/
diff --git a/munin/handlers/main.yml b/munin/handlers/main.yml
index a0d465a2..8654181d 100644
--- a/munin/handlers/main.yml
+++ b/munin/handlers/main.yml
@@ -1,4 +1,5 @@
---
+
- name: restart munin-node
service:
name: munin-node
@@ -8,3 +9,7 @@
service:
name: munin_node
state: restarted
+
+- name: systemd daemon-reload
+ systemd:
+ daemon_reload: yes
\ No newline at end of file
diff --git a/munin/tasks/main.yml b/munin/tasks/main.yml
index aab79f62..81769488 100644
--- a/munin/tasks/main.yml
+++ b/munin/tasks/main.yml
@@ -88,3 +88,20 @@
[swap]
user root
when: ansible_kernel is search("-grs-")
+
+- name: Create override directory for munin-node unit
+ file:
+ name: /etc/systemd/system/munin-node.service.d/
+ state: directory
+ mode: "0755"
+
+- name: Override is present for protected home
+ ini_file:
+ dest: "/etc/systemd/system/munin-node.service.d/override.conf"
+ section: "Service"
+ option: "ProtectHome"
+ value: "false"
+ state: present
+ notify:
+ - systemd daemon-reload
+ - restart munin-node
diff --git a/mysql-oracle/tasks/users.yml b/mysql-oracle/tasks/users.yml
index e5a7e3da..d0c444e5 100644
--- a/mysql-oracle/tasks/users.yml
+++ b/mysql-oracle/tasks/users.yml
@@ -1,22 +1,24 @@
---
-# dependency for mysql_user and mysql_db
-- name: python-mysqldb is installed (Ansible dependency)
+- name: Python2 dependencies for Ansible are installed
apt:
- name: python-mysqldb
+ name:
+ - python-mysqldb
+ - python-pymysql
state: present
- when: ansible_distribution_major_version is version('10', '<=')
tags:
- mysql
+ when: ansible_python_version is version('3', '<')
-# dependency for mysql_user and mysql_db
-- name: python3-mysqldb is installed (Ansible dependency)
+- name: Python3 dependencies for Ansible are installed
apt:
- name: python3-mysqldb
+ name:
+ - python3-mysqldb
+ - python3-pymysql
state: present
- when: ansible_distribution_major_version is version('10', '>')
tags:
- mysql
+ when: ansible_python_version is version('3', '>=')
- name: create a password for mysqladmin
command: "apg -n 1 -m 16 -M lcN"
diff --git a/mysql/files/evomariabackup.sh b/mysql/files/evomariabackup.sh
new file mode 100644
index 00000000..0e3de84b
--- /dev/null
+++ b/mysql/files/evomariabackup.sh
@@ -0,0 +1,554 @@
+#!/bin/sh
+
+VERSION="21.11"
+
+show_version() {
+ cat <,
+ Éric Morino ,
+ Jérémy Lecour
+ and others.
+
+evomariabackup comes with ABSOLUTELY NO WARRANTY. This is free software,
+and you are welcome to redistribute it under certain conditions.
+See the GNU Affero General Public License v3.0 for details.
+END
+}
+show_help() {
+ cat <> "${log_file}"
+ else
+ log_line "${level}" "${msg}" >&2
+ fi
+ fi
+}
+log_info() {
+ level="INFO"
+ msg=$1
+ if ! is_quiet; then
+ if is_log_file; then
+ log_line "${level}" "${msg}" >> "${log_file}"
+ else
+ log_line "${level}" "${msg}" >&2
+ fi
+ fi
+}
+log_warning() {
+ level="WARNING"
+ msg=$1
+ if ! is_quiet; then
+ if is_log_file; then
+ log_line "${level}" "${msg}" >> "${log_file}"
+ else
+ log_line "${level}" "${msg}" >&2
+ fi
+ fi
+}
+log_error() {
+ level="ERROR"
+ msg=$1
+ if ! is_quiet; then
+ if is_log_file; then
+ log_line "${level}" "${msg}" >> "${log_file}"
+ if tty -s; then
+ printf "%s\n" "${msg}" >&2
+ fi
+ else
+ log_line "${level}" "${msg}" >&2
+ fi
+ fi
+}
+log_fatal() {
+ level="FATAL"
+ msg=$1
+ if is_log_file; then
+ log_line "${level}" "${msg}" >> "${log_file}"
+ if tty -s; then
+ printf "%s\n" "${msg}" >&2
+ fi
+ else
+ log_line "${level}" "${msg}" >&2
+ fi
+}
+duration_in_seconds() {
+ if echo "${1}" | grep -E -q '^([0-9]+[wdhms])+$'; then
+ duration=$(echo "${1}" | sed 's/w/ * 604800 + /g; s/d/ * 86400 + /g; s/h/ * 3600 + /g; s/m/ * 60 + /g; s/s/ + /g; s/+ $//' | xargs expr)
+ elif echo "${1}" | grep -E -q '^[0-9]+$'; then
+ duration=$(echo "${1} * 3600" | xargs expr)
+ else
+ return 1
+ fi
+ log_debug "Duration \`${1}' translated to ${duration} seconds"
+
+ echo "${duration}"
+}
+lock_file_created_at() {
+ created_at=$(stat -c %Z "${lock_file}")
+ log_debug "Lock file ${lock_file} created at ${created_at}"
+
+ echo "${created_at}"
+}
+lock_file_age() {
+ last_change=$(lock_file_created_at)
+ now=$(date +"%s")
+
+ age=$(( now - last_change ))
+ log_debug "Lock file ${lock_file} is ${age} seconds old"
+
+ echo "${created_at}"
+}
+is_lock_file_too_old() {
+ test "$(lock_file_age)" -ge "${max_age}"
+}
+kill_or_clean_lockfile() {
+ lock_file=${1:-}
+
+ if [ -f "${lock_file}" ]; then
+ # Get Process ID from the lock file
+ pid=$(cat "${lock_file}")
+ if [ -n "${pid}" ]; then
+ log_debug "Found pid ${pid} in ${lock_file}"
+
+ if kill -0 "${pid}" 2> /dev/null; then
+ log_debug "Found process with pid ${pid}"
+
+ lock_file_created_at_human=$(date --date "@$(lock_file_created_at)" +"%Y-%m-%d %H:%M:%S")
+ if is_lock_file_too_old ; then
+ # Kill the children
+ pkill -9 --parent "${pid}"
+ # Kill the parent
+ kill -9 "${pid}"
+ # Only one process can run in parallel
+ log_warning "Process \`${pid}' (started at ${lock_file_created_at_human}) has been killed by \`$$'"
+ else
+ log_info "Process \`${pid}' (started at ${lock_file_created_at_human}) has precedence. Let's leave it work."
+ # make sure that this exit doesn't remove the existing lockfile !!
+ exit 0
+ fi
+ else
+ log_warning "Process not found at PID \`${pid}'. Ignoring lock file \`${lock_file}'."
+ fi
+ else
+ log_warning "Empty lockfile \`${lock_file}'. It should contain a PID."
+ fi
+ # Remove the lock file
+ rm -f "${lock_file}"
+ log_debug "Lock file ${lock_file} has been removed"
+ fi
+}
+new_lock_file() {
+ lock_file=${1:-}
+ lock_dir=$(dirname "${lock_file}")
+
+ if mkdir --parents "${lock_dir}"; then
+ echo $$ > "${lock_file}"
+ log_debug "Lock file '${lock_file}' has been created"
+ else
+ log_fatal "Failed to acquire lock file '${lock_file}'. Abort."
+ exit 1
+ fi
+}
+is_mariabackup_directory() {
+ directory=${1:-}
+ find "${directory}" -name 'ibdata*' -o -name 'ib_logfile*' -o -name 'xtrabackup_*' > /dev/null
+}
+check_backup_dir() {
+ if [ -d "${backup_dir:?}" ]; then
+ if [ "$(ls -A "${backup_dir:?}")" ]; then
+ if is_mariabackup_directory "${backup_dir:?}"; then
+ log_debug "The backup directory ${backup_dir:?} is not empty but looks like a mariabackup target. Let's clear it."
+ rm -rf "${backup_dir:?}"
+ else
+ log_fatal "The backup directory ${backup_dir:?} is not empty and doesn't look like a mariabackup target. Please verify and clear the directory if you are sure."
+ exit 1
+ fi
+ else
+ log_debug "The backup directory ${backup_dir:?} exists but is empty. Let's proceed."
+ fi
+ else
+ log_debug "The backup directory ${backup_dir:?} doesn't exist. Let's proceed."
+ fi
+ mkdir -p "${backup_dir:?}"
+}
+check_compress_dir() {
+ if [ -d "${compress_dir:?}" ]; then
+ log_debug "The compress_dir directory ${compress_dir:?} exists. Let's proceed."
+ else
+ log_debug "The compress_dir directory ${compress_dir:?} doesn't exist. Let's proceed."
+ fi
+ mkdir -p "${compress_dir:?}"
+}
+
+backup() {
+ if [ -z "${backup_dir}" ]; then
+ log_fatal "backup-dir option is empty"
+ else
+ check_backup_dir
+ fi
+
+ mariabackup_bin=$(command -v mariabackup)
+ if [ -z "${mariabackup_bin}" ]; then
+ log_fatal "Couldn't find mariabackup.\nUse 'apt install mariadb-backup'."
+ exit 1
+ fi
+
+ backup_command="${mariabackup_bin} --backup --slave-info --target-dir=${backup_dir:?}"
+
+
+ if ! is_quiet; then
+ log_debug "${backup_command}"
+ log_info "BEGIN mariabackup backup phase"
+ fi
+
+ if is_quiet || ! is_verbose ; then
+ ${backup_command} >/dev/null 2>&1
+ backup_rc=$?
+ elif ! is_quiet; then
+ if is_log_file; then
+ ${backup_command} >>"${log_file}" 2>&1
+ backup_rc=$?
+ else
+ ${backup_command}
+ backup_rc=$?
+ fi
+ fi
+
+ if [ ${backup_rc} -ne 0 ]; then
+ log_fatal "Error executing mariabackup --backup"
+ exit 1
+ elif ! is_quiet; then
+ log_info "END mariabackup backup phase"
+ fi
+
+ prepare_command="${mariabackup_bin} --prepare --target-dir=${backup_dir:?}"
+
+ if ! is_quiet; then
+ log_debug "${prepare_command}"
+ log_info "BEGIN mariabackup prepare phase"
+ fi
+
+ if is_quiet || ! is_verbose ; then
+ ${prepare_command} >/dev/null 2>&1
+ prepare_rc=$?
+ elif ! is_quiet; then
+ if is_log_file; then
+ ${prepare_command} >>"${log_file}" 2>&1
+ prepare_rc=$?
+ else
+ ${prepare_command}
+ prepare_rc=$?
+ fi
+ fi
+
+ if [ ${prepare_rc} -ne 0 ]; then
+ log_fatal "Error executing mariabackup --prepare"
+ exit 1
+ elif ! is_quiet; then
+ log_info "END mariabackup prepare phase"
+ fi
+}
+compress() {
+ compress_dir=$(dirname "${compress_file}")
+
+ if [ -z "${backup_dir}" ]; then
+ log_fatal "backup-dir option is empty"
+ exit 1
+ elif [ -e "${backup_dir}" ] && [ ! -d "${backup_dir}" ]; then
+ log_fatal "backup directory '${backup_dir}' exists but is not a directory"
+ exit 1
+ fi
+ if [ -z "${compress_file}" ]; then
+ log_fatal "compress-file option is empty"
+ exit 1
+ fi
+ if [ -n "${compress_dir}" ]; then
+ check_compress_dir
+ fi
+
+ pigz_bin=$(command -v pigz)
+ gzip_bin=$(command -v gzip)
+
+ if [ -n "${pigz_bin}" ]; then
+ compress_program="${pigz_bin} --keep -6"
+ elif [ -n "${gzip_bin}" ]; then
+ compress_program="${gzip_bin} -6"
+ else
+ log_fatal "Couldn't find pigz nor gzip.\nUse 'apt install pigz' or 'apt install gzip'."
+ exit 1
+ fi
+
+ if ! is_quiet; then
+ log_debug "Compression of ${backup_dir} to ${compress_file} using \`${compress_program}'"
+ log_info "BEGIN compression phase"
+ fi
+ if is_quiet || ! is_verbose ; then
+ tar --use-compress-program="${compress_program}" -cf "${compress_file}" "${backup_dir}" >/dev/null 2>&1
+ tar_rc=$?
+ elif ! is_quiet; then
+ if is_log_file; then
+ tar --use-compress-program="${compress_program}" -cf "${compress_file}" "${backup_dir}" >>"${log_file}" 2>&1
+ tar_rc=$?
+ else
+ tar --use-compress-program="${compress_program}" -cf "${compress_file}" "${backup_dir}"
+ tar_rc=$?
+ fi
+ fi
+
+ if [ ${tar_rc} -ne 0 ]; then
+ log_fatal "An error occured while compressing ${backup_dir} to ${compress_file}"
+ exit 1
+ elif ! is_quiet; then
+ log_info "END compression phase"
+ fi
+}
+main() {
+ kill_or_clean_lockfile "${lock_file}"
+ # shellcheck disable=SC2064
+ trap "rm -f ${lock_file};" 0
+ new_lock_file "${lock_file}"
+
+ if [ "${do_backup}" = "1" ] && [ -n "${backup_dir}" ]; then
+ backup "${backup_dir}"
+ fi
+
+ if [ "${do_compress}" = "1" ] && [ -n "${compress_file}" ]; then
+ compress "${backup_dir}" "${compress_file}"
+ fi
+}
+
+# Declare variables
+
+lock_file=""
+log_file=""
+verbose=""
+quiet=""
+max_age=""
+max_age=""
+do_backup=""
+backup_dir=""
+do_compress=""
+compress_file=""
+
+# 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
+ ;;
+
+ -m|--max-age)
+ # with value separated by space
+ if [ -n "$2" ]; then
+ max_age=$(duration_in_seconds "$2")
+ shift
+ else
+ log_fatal 'ERROR: "-m|--max-age" requires a non-empty option argument.'
+ fi
+ ;;
+ --max-age=?*)
+ # with value speparated by =
+ max_age=$(duration_in_seconds "${1#*=}")
+ ;;
+ --max-age=)
+ # without value
+ log_fatal 'ERROR: "--max-age" requires a non-empty option argument.'
+ ;;
+
+ --backup)
+ do_backup=1
+ ;;
+
+ --no-backup)
+ do_backup=0
+ ;;
+
+ --backup-dir)
+ # with value separated by space
+ if [ -n "$2" ]; then
+ backup_dir="$2"
+ shift
+ else
+ log_fatal 'ERROR: "--backup-dir" requires a non-empty option argument.'
+ fi
+ ;;
+ --backup-dir=?*)
+ # with value speparated by =
+ backup_dir=${1#*=}
+ ;;
+ --backup-dir=)
+ # without value
+ log_fatal '"--backup-dir" requires a non-empty option argument.'
+ ;;
+
+ --compress)
+ do_compress=1
+ ;;
+
+ --no-compress)
+ do_compress=0
+ ;;
+
+ --compress-file)
+ # with value separated by space
+ if [ -n "$2" ]; then
+ compress_file="$2"
+ if [ -z "${do_compress}" ]; then
+ do_compress=1
+ fi
+ shift
+ else
+ log_fatal '"--compress-file" requires a non-empty option argument.'
+ fi
+ ;;
+ --compress-file=?*)
+ # with value speparated by =
+ compress_file=${1#*=}
+ if [ -z "${do_compress}" ]; then
+ do_compress=1
+ fi
+ ;;
+ --compress-file=)
+ # without value
+ log_fatal '"--compress-file" requires a non-empty option argument.'
+ ;;
+
+ --lock-file)
+ # with value separated by space
+ if [ -n "$2" ]; then
+ lock_file="$2"
+ shift
+ else
+ log_fatal '"--lock-file" requires a non-empty option argument.'
+ fi
+ ;;
+ --lock-file=?*)
+ # with value speparated by =
+ lock_file=${1#*=}
+ ;;
+ --lock-file=)
+ # without value
+ log_fatal '"--lock-file" requires a non-empty option argument.'
+ ;;
+
+ --log-file)
+ # with value separated by space
+ if [ -n "$2" ]; then
+ log_file="$2"
+ shift
+ else
+ log_fatal '"--log-file" requires a non-empty option argument.'
+ fi
+ ;;
+ --log-file=?*)
+ # with value speparated by =
+ log_file=${1#*=}
+ ;;
+ --log-file=)
+ # without value
+ log_fatal '"--log-file" requires a non-empty option argument.'
+ ;;
+
+ -v|--verbose)
+ verbose=1
+ ;;
+
+ --quiet)
+ quiet=1
+ verbose=0
+ ;;
+
+ --)
+ # End of all options.
+ shift
+ break
+ ;;
+ -?*|[[:alnum:]]*)
+ # ignore unknown options
+ if tty -s; then
+ printf 'Unknown option : %s\n' "$1" >&2
+ echo "" >&2
+ show_usage >&2
+ exit 1
+ else
+ log_fatal 'Unknown option : %s\n' "$1" >&2
+ fi
+ ;;
+ *)
+ # Default case: If no more options then break out of the loop.
+ break
+ ;;
+ esac
+
+ shift
+done
+
+# Default values
+
+lock_file="${lock_file:-/run/lock/evomariabackup.lock}"
+verbose=${verbose:-0}
+quiet=${quiet:-0}
+max_age="${max_age:-86400}"
+do_backup="${do_backup:-1}"
+do_compress="${do_compress:-0}"
+
+main
\ No newline at end of file
diff --git a/mysql/files/mysql-queries-killer.sh b/mysql/files/mysql-queries-killer.sh
new file mode 100644
index 00000000..3ea6e00b
--- /dev/null
+++ b/mysql/files/mysql-queries-killer.sh
@@ -0,0 +1,197 @@
+#!/bin/sh
+
+VERSION="21.08"
+
+show_version() {
+ cat <,
+ Jérémy Lecour
+ and others.
+
+mysql-queries-killer 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 <] --list [--time