WIP: newkernel script #80

Closed
benpro wants to merge 12 commits from newkernel into unstable
10 changed files with 418 additions and 0 deletions
Showing only changes of commit 59995ca92e - Show all commits

28
newkernel/.kitchen.yml Normal file
View file

@ -0,0 +1,28 @@
---
driver:
name: docker
privileged: true
use_sudo: false
provisioner:
name: ansible_playbook
hosts: test-kitchen
roles_path: ../
ansible_verbose: true
require_ansible_source: false
require_chef_for_busser: false
idempotency_test: true
platforms:
- name: debian
driver_config:
image: evolix/ansible:2.2.1
suites:
- name: default
provisioner:
name: ansible_playbook
playbook: ./tests/test.yml
transport:
max_ssh_sessions: 6

7
newkernel/README.md Normal file
View file

@ -0,0 +1,7 @@
# listupgrade
Install and configure a script not help manage Debian package updates.
## Tasks
Installation and configuration are performed via `tasks/main.yml`.

View file

@ -0,0 +1,3 @@
---
general_alert_email: "root@localhost"
listupgrade_alert_email: Null

View file

@ -0,0 +1,67 @@
#!/bin/bash
set -e
configFile="/etc/evolinux/newkernel.cnf"
template=$(mktemp --tmpdir=/tmp evoupdate.XXX)
clientmail=$(grep EVOMAINTMAIL /etc/evomaintenance.cf | cut -d'=' -f2)
mailto=$clientmail
date="Ce jeudi entre 18h00 et 23h00."
hostname=$(grep HOSTNAME /etc/evomaintenance.cf | cut -d'=' -f2)
hostname=${hostname%%.evolix.net}
# If hostname is composed with -, remove the first part.
if [[ $hostname =~ "-" ]]; then
hostname=$(echo $hostname | cut -d'-' -f2-)
fi
# Edit $configFile to override some variables.
[ -r $configFile ] && . $configFile
# Remove temporary files on exit.
trap "rm $template" EXIT
# No updates? Exit!
nextKernel=$(grep -m1 -aEo "#1 SMP Debian .* \([0-9]{4}-[0-9]{2}-[0-9]{2}\)" /vmlinuz)
currentKernel=$(uname -v)
if [ "$nextKernel" = "$currentKernel" ]; then
exit 0
fi
#To: ${clientmail}
cat << EOT > $template
Content-Type: text/plain; charset="utf-8"
Reply-To: equipe@evolix.fr
From: equipe@evolix.net
To: bserie@evolix.fr
Subject: Prochain creneau pour mise a jour de votre serveur $hostname
X-Date: $date
Bonjour,
Le noyau de votre serveur doit être mis à jour. Pour cela nous devons
redémarrer votre machine ${hostname}.
Sauf indication contraire de votre part,
le prochain créneau prévu pour
intervenir manuellement pour réaliser ces mises-à-jour est :
${date}
Si nous intervenons, un redémarrage complet du serveur sera réalisé, entraînant
plusieurs minutes de coupures. Nous nous assurerons de vérifier le bon
démarrage de la machin ainsi que de ses services. Si nous ne sommes pas
intervenus sur ce créneau, vous recevrez une nouvelle notification le mois
prochain.
Votre version actuelle du noyau : $currentKernel
Après redémarrage votre version sera : $nextKernel
N'hésitez pas à nous faire toute remarque sur ce créneau d'intervention le plus
tôt possible.
Cordialement,
--
Équipe Evolix <equipe@evolix.fr>
Evolix - Hébergement et Infogérance Open Source http://www.evolix.fr/
EOT
<$template /usr/sbin/sendmail $mailto

28
newkernel/meta/main.yml Normal file
View file

@ -0,0 +1,28 @@
galaxy_info:
author: Evolix
description: Installation and configuration of the listupgrade script
issue_tracker_url: https://gitea.evolix.org/evolix/ansible-roles/issues
license: GPLv2
min_ansible_version: 2.2
platforms:
- name: Debian
versions:
- jessie
galaxy_tags: []
# List tags for your role here, one per line. A tag is
# a keyword that describes and categorizes the role.
# Users find roles by searching for tags. Be sure to
# remove the '[]' above if you add tags to this list.
#
# NOTE: A tag is limited to a single word comprised of
# alphanumeric characters. Maximum 20 tags per role.
dependencies: []
# List your role dependencies here, one per line.
# Be sure to remove the '[]' above if you add dependencies
# to this list.

54
newkernel/tasks/main.yml Normal file
View file

@ -0,0 +1,54 @@
---
- include_role:
name: remount-usr
- name: Scripts dir is present
file:
path: "/usr/share/scripts"
state: directory
owner: root
group: root
mode: "0700"
- name: Copy listupgrade script
template:
src: listupgrade.sh.j2
dest: "/usr/share/scripts/listupgrade.sh"
mode: "0700"
owner: root
group: root
force: yes
- name: Create /etc/evolinux
file:
path: /etc/evolinux
state: directory
owner: root
group: root
mode: "0700"
- name: Copy listupgrade config
template:
src: listupgrade.cnf.j2
dest: /etc/evolinux/listupgrade.cnf
mode: "0600"
owner: root
group: root
force: no
- name: Cron.d is present
file:
path: "/etc/cron.d"
state: directory
mode: "0755"
owner: root
group: root
- name: Enable listupgrade cron
template:
src: listupgrade_cron.j2
dest: /etc/cron.d/listupgrade
mode: "0600"
owner: root
group: root

View file

@ -0,0 +1,4 @@
#date="Ce jeudi entre 18h00 et 23h00."
#clientmail="client@evolix.net"
#mailto="{{ listupgrade_alert_email or general_alert_email | mandatory }}"
#hostname=""

View file

@ -0,0 +1,222 @@
#!/bin/bash
# Exit codes :
# - 30 : $skip_releases or $skip_packages is set to "all"
# - 40 : current release is in $skip_releases list
# - 50 : all upgradable packages are in the $skip_packages list
# - 60 : current release is not in the $r_releases list
# - 70 : at least an upgradable package is not in the $r_packages list
set -e
configFile="/etc/evolinux/listupgrade.cnf"
packages=$(mktemp --tmpdir=/tmp evoupdate.XXX)
packagesHold=$(mktemp --tmpdir=/tmp evoupdate.XXX)
servicesToRestart=$(mktemp --tmpdir=/tmp evoupdate.XXX)
template=$(mktemp --tmpdir=/tmp evoupdate.XXX)
clientmail=$(grep EVOMAINTMAIL /etc/evomaintenance.cf | cut -d'=' -f2)
mailto=$clientmail
date="Ce jeudi entre 18h00 et 23h00."
hostname=$(grep HOSTNAME /etc/evomaintenance.cf | cut -d'=' -f2)
hostname=${hostname%%.evolix.net}
# If hostname is composed with -, remove the first part.
if [[ $hostname =~ "-" ]]; then
hostname=$(echo $hostname | cut -d'-' -f2-)
fi
# Edit $configFile to override some variables.
[ -r $configFile ] && . $configFile
# Remove temporary files on exit.
trap "rm $packages $packagesHold $servicesToRestart $template" EXIT
# Parse line in retrieved upgrade file and ensure there is no malicious values.
get_value() {
file="$1"
variable="$2"
value="$(grep "^$2:" $1 |head -n 1 |cut -d ':' -f 2 |sed 's/^ //')"
if echo "$value" |grep -q -E '^[-.: [:alnum:]]*$'; then
echo $value
else
printf >&2 "Error parsing value \"$value\" for variable $variables.\n"
fi
}
# Fetch which packages/releases will be upgraded.
fetch_upgrade_info() {
upgradeInfo=$(mktemp --tmpdir=/tmp evoupdate.XXX)
wget -q -O $upgradeInfo https://upgrades.evolix.org/upgrade
r_releases="$(get_value $upgradeInfo "releases")"
r_skip_releases="$(get_value $upgradeInfo "skip_releases")"
r_packages="$(get_value $upgradeInfo "packages")"
r_skip_packages="$(get_value $upgradeInfo "skip_packages")"
rm $upgradeInfo
}
# Check if element $element is in (space separated) list $list.
is_in() {
list="$1"
element="$2"
for i in $list; do
if [ "$element" = "$i" ]; then
return 0
fi
done
return 1
}
if [[ "$1" != "--cron" ]]; then
echo "À quel date/heure allez vous planifier l'envoi ?"
echo "Exemple : le jeudi 6 mars entre 18h00 et 23h00"
echo -n ">"
read date
echo "À qui envoyer le mail ?"
echo -n ">"
read mailto
fi
# Update APT cache and get packages to upgrade and packages on hold.
apt -q2 update 2>&1 | (egrep -ve '^(Listing|WARNING|$)' -e upgraded -e 'up to date' || true )
apt-mark showhold > $packagesHold
apt list --upgradable 2>&1 | grep -v -f $packagesHold | egrep -v '^(Listing|WARNING|$)' > $packages
packagesParsable=$(cut -f 1 -d / <$packages |tr '\n' ' ')
# No updates? Exit!
test ! -s $packages && exit 0
test ! -s $packagesHold && echo 'Aucun' > $packagesHold
fetch_upgrade_info
local_release=$(cut -f 1 -d . </etc/debian_version)
# Exit if skip_releases or skip_packages in upgrade info file are set to all.
([ "$r_skip_releases" = "all" ] || [ "$r_skip_packages" = "all" ]) && exit 30
# Exit if the server's release is in skip_releases.
[ -n "$r_skip_releases" ] && is_in "$r_skip_releases" "$local_release" && exit 40
# Exit if all packages to upgrade are listed in skip_packages:
# we remove each package to skip from the $packageToUpgrade list. At the end,
# if there is no additional packages to upgrade, we can exit.
if [ -n "$r_skip_packages" ]; then
packageToUpgrade="$packagesParsable"
for pkg in $r_skip_packages; do
packageToUpgrade="${packageToUpgrade/$pkg}"
done
packageToUpgrade=$(echo $packageToUpgrade |sed 's/ \+//g')
if [ -z "$packageToUpgrade" ]; then
exit 50
fi
fi
# Exit if the server's release is not in releases.
if [ -n "$r_releases" ] && [ "$r_releases" != "all" ]; then
is_in "$r_releases" "$local_release" || exit 60
fi
# Exit if there is packages to upgrades that are not in packages list:
# we exit at the first package encountered that is not in packages list.
if [ -n "$r_packages" ] && [ "$r_packages" != "all" ]; then
for pkg in $packagesParsable; do
is_in "$r_packages" "$pkg" || exit 70
done
fi
# Guess which services will be restarted.
for pkg in $packagesParsable; do
if echo "$pkg" |grep -qE "^(lib)?apache2"; then
echo "Apache2" >>$servicesToRestart
elif echo "$pkg" |grep -q "^nginx"; then
echo "Nginx" >>$servicesToRestart
elif echo "$pkg" |grep -q "^php5-fpm"; then
echo "PHP FPM" >>$servicesToRestart
elif echo "$pkg" |grep -q "^mysql-server"; then
echo "MySQL" >>$servicesToRestart
elif echo "$pkg" |grep -q "^mariadb-server"; then
echo "MariaDB" >>$servicesToRestart
elif echo "$pkg" |grep -qE "^postgresql-[[:digit:]]+\.[[:digit:]]+$"; then
echo "PostgreSQL" >>$servicesToRestart
elif echo "$pkg" |grep -qE "^tomcat[[:digit:]]+$"; then
echo "Tomcat" >>$servicesToRestart
elif [ "$pkg" = "redis-server" ]; then
echo "redis-server" >>$servicesToRestart
elif [ "$pkg" = "mongodb-server" ]; then
echo "redis-server" >>$servicesToRestart
elif echo "$pkg" |grep -qE "^courier-(pop|imap)"; then
echo "Courier POP/IMAP" >>$servicesToRestart
elif echo "$pkg" |grep -qE "^dovecot-(pop|imap)d"; then
echo "Dovecot POP/IMAP" >>$servicesToRestart
elif [ "$pkg" = "samba" ]; then
echo "Samba" >>$servicesToRestart
elif [ "$pkg" = "slapd" ]; then
echo "OpenLDAP" >>$servicesToRestart
elif [ "$pkg" = "bind9" ]; then
echo "Bind9" >>$servicesToRestart
elif [ "$pkg" = "postfix" ]; then
echo "Postfix" >>$servicesToRestart
elif [ "$pkg" = "haproxy" ]; then
echo "HAProxy" >>$servicesToRestart
elif [ "$pkg" = "varnish" ]; then
echo "Varnish" >>$servicesToRestart
elif [ "$pkg" = "squid" ]; then
echo "Squid" >>$servicesToRestart
elif [ "$pkg" = "libc6" ]; then
echo "Tous les services (mise à jour de libc6)." >$servicesToRestart
break
elif [ "$pkg" = "libstdc++6" ]; then
echo "Tous les services (mise à jour de libstdc++6)." >$servicesToRestart
break
elif echo "$pkg" |grep -q "^libssl"; then
echo "Tous les services (mise à jour de libssl)." >$servicesToRestart
break
fi
done
test ! -s $servicesToRestart && echo "Aucun" >$servicesToRestart
cat << EOT > $template
Content-Type: text/plain; charset="utf-8"
Reply-To: equipe@evolix.fr
From: equipe@evolix.net
To: ${clientmail}
Subject: Prochain creneau pour mise a jour de votre serveur $hostname
X-Debian-Release: $local_release
X-Packages: $packagesParsable
X-Date: $date
Bonjour,
Des mises-à-jour de sécurité ou mineures sont à réaliser sur votre serveur
${hostname}.
Sauf indication contraire de votre part, le prochain créneau prévu pour
intervenir manuellement pour réaliser ces mises-à-jour est :
${date}
Si nous intervenons, un redémarrage des éventuels services concernés sera
réalisé, entraînant a priori quelques secondes de coupure. Si nous ne sommes
pas intervenus sur ce créneau, vous recevrez une nouvelle notification la
semaine prochaine.
Voici la listes de packages qui seront mis à jour :
$(cat $packages)
Liste des packages dont la mise-à-jour a été manuellement suspendue :
$(cat $packagesHold)
Liste des services qui seront redémarrés :
$(cat $servicesToRestart)
N'hésitez pas à nous faire toute remarque sur ce créneau d'intervention le plus
tôt possible.
Cordialement,
--
Équipe Evolix <equipe@evolix.fr>
Evolix - Hébergement et Infogérance Open Source http://www.evolix.fr/
EOT
<$template /usr/sbin/sendmail $mailto

View file

@ -0,0 +1 @@
42 9 * * 2 root /usr/share/scripts/listupgrade.sh --cron

4
newkernel/tests/test.yml Normal file
View file

@ -0,0 +1,4 @@
---
- hosts: test-kitchen
roles:
- role: listupgrade