listupgrade: upstream release 21.06
All checks were successful
continuous-integration/drone/push Build is passing
All checks were successful
continuous-integration/drone/push Build is passing
This commit is contained in:
parent
81730de78b
commit
dbc853a815
|
@ -29,6 +29,7 @@ The **patch** part changes incrementally at each release.
|
||||||
* evolinux-base: copy GPG key instead of using apt-key
|
* evolinux-base: copy GPG key instead of using apt-key
|
||||||
* evomaintenance: upstream release 0.6.4
|
* evomaintenance: upstream release 0.6.4
|
||||||
* kvm-host: replace the "kvm-tools" package with scripts deployed by Ansible
|
* kvm-host: replace the "kvm-tools" package with scripts deployed by Ansible
|
||||||
|
* listupgrade: upstream release 21.06
|
||||||
* nodejs: change GPG key name
|
* nodejs: change GPG key name
|
||||||
* ntpd: Add leapfile configuration setting to ntpd on debian 10+
|
* ntpd: Add leapfile configuration setting to ntpd on debian 10+
|
||||||
* packweb-apache: install phpMyAdmin from buster-backports
|
* packweb-apache: install phpMyAdmin from buster-backports
|
||||||
|
|
|
@ -7,31 +7,24 @@
|
||||||
# - 60 : current release is not in the $r_releases list
|
# - 60 : current release is not in the $r_releases list
|
||||||
# - 70 : at least an upgradable package is not in the $r_packages list
|
# - 70 : at least an upgradable package is not in the $r_packages list
|
||||||
|
|
||||||
set -e
|
VERSION="21.06"
|
||||||
|
|
||||||
configFile="/etc/evolinux/listupgrade.cnf"
|
show_version() {
|
||||||
|
cat <<END
|
||||||
|
listupgrade.sh version ${VERSION}
|
||||||
|
|
||||||
packages=$(mktemp --tmpdir=/tmp evoupdate.XXX)
|
Copyright 2018-2021 Evolix <info@evolix.fr>,
|
||||||
packagesHold=$(mktemp --tmpdir=/tmp evoupdate.XXX)
|
Gregory Colpart <reg@evolix.fr>,
|
||||||
servicesToRestart=$(mktemp --tmpdir=/tmp evoupdate.XXX)
|
Romain Dessort <rdessort@evolix.fr>,
|
||||||
template=$(mktemp --tmpdir=/tmp evoupdate.XXX)
|
Ludovic Poujol <lpoujol@evolix.fr>,
|
||||||
clientmail=$(grep EVOMAINTMAIL /etc/evomaintenance.cf | cut -d'=' -f2)
|
Jérémy Lecour <jlecour@evolix.fr>
|
||||||
mailto="${clientmail}"
|
and others.
|
||||||
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.
|
listupgrade.sh comes with ABSOLUTELY NO WARRANTY. This is free software,
|
||||||
if [[ "${hostname}" =~ "-" ]]; then
|
and you are welcome to redistribute it under certain conditions.
|
||||||
hostname=$(echo "${hostname}" | cut -d'-' -f2-)
|
See the GNU General Public Licence for details.
|
||||||
fi
|
END
|
||||||
# Edit $configFile to override some variables.
|
}
|
||||||
# shellcheck disable=SC1090,SC1091
|
|
||||||
[ -r "${configFile}" ] && . "${configFile}"
|
|
||||||
|
|
||||||
# Remove temporary files on exit.
|
|
||||||
# shellcheck disable=SC2064
|
|
||||||
trap "rm ${packages} ${packagesHold} ${servicesToRestart} ${template}" EXIT
|
|
||||||
|
|
||||||
# Parse line in retrieved upgrade file and ensure there is no malicious values.
|
# Parse line in retrieved upgrade file and ensure there is no malicious values.
|
||||||
get_value() {
|
get_value() {
|
||||||
|
@ -48,7 +41,7 @@ get_value() {
|
||||||
|
|
||||||
# Fetch which packages/releases will be upgraded.
|
# Fetch which packages/releases will be upgraded.
|
||||||
fetch_upgrade_info() {
|
fetch_upgrade_info() {
|
||||||
upgradeInfo=$(mktemp --tmpdir=/tmp evoupdate.XXX)
|
upgradeInfo=$(mktemp --tmpdir=/tmp listupgrade.XXX)
|
||||||
wget --no-check-certificate --quiet --output-document="${upgradeInfo}" https://upgrades.evolix.org/upgrade
|
wget --no-check-certificate --quiet --output-document="${upgradeInfo}" https://upgrades.evolix.org/upgrade
|
||||||
|
|
||||||
# shellcheck disable=SC2181
|
# shellcheck disable=SC2181
|
||||||
|
@ -78,43 +71,126 @@ is_in() {
|
||||||
return 1
|
return 1
|
||||||
}
|
}
|
||||||
|
|
||||||
if [[ "$1" != "--cron" ]]; then
|
render_mail_template() {
|
||||||
echo "À quel date/heure allez vous planifier l'envoi ?"
|
local template_file=$1
|
||||||
echo "Exemple : le jeudi 6 mars entre 18h00 et 23h00"
|
cat <<EOT >"${template_file}"
|
||||||
echo -n "> "
|
Content-Type: text/plain; charset="utf-8"
|
||||||
read -r date
|
Reply-To: equipe@evolix.fr
|
||||||
echo "À qui envoyer le mail ?"
|
From: equipe@evolix.net
|
||||||
echo -n "> "
|
To: ${clientmail}
|
||||||
read -r mailto
|
Subject: Prochain creneau pour mise a jour de votre serveur ${hostname}
|
||||||
fi
|
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 - Hébergement et Infogérance Open Source
|
||||||
|
http://evolix.com | Twitter: @Evolix @EvolixNOC | http://blog.evolix.com
|
||||||
|
EOT
|
||||||
|
}
|
||||||
|
# Files found in the directory passed as 1st argument
|
||||||
|
# are executed if they are executable
|
||||||
|
# and if their name doesn't contain a dot
|
||||||
|
exec_hooks_in_dir() {
|
||||||
|
hooks=$(find "${1}" -type f -executable -not -name '*.*')
|
||||||
|
for hook in ${hooks}; do
|
||||||
|
if ! cron_mode; then
|
||||||
|
printf "Running '%s\`\n" "${hook}"
|
||||||
|
fi
|
||||||
|
${hook}
|
||||||
|
done
|
||||||
|
}
|
||||||
|
pre_hooks() {
|
||||||
|
if [ -d "${hooksDir}/pre" ]; then
|
||||||
|
exec_hooks_in_dir "${hooksDir}/pre"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
post_hooks_and_exit() {
|
||||||
|
status=${1:-0}
|
||||||
|
if [ -d "${hooksDir}/post" ]; then
|
||||||
|
exec_hooks_in_dir "${hooksDir}/post"
|
||||||
|
fi
|
||||||
|
exit ${status}
|
||||||
|
}
|
||||||
|
|
||||||
|
cron_mode() {
|
||||||
|
test "${cron_mode}" = "1"
|
||||||
|
}
|
||||||
|
|
||||||
|
force_mode() {
|
||||||
|
test "${force_mode}" = "1"
|
||||||
|
}
|
||||||
|
|
||||||
|
main() {
|
||||||
# Update APT cache and get packages to upgrade and packages on hold.
|
# Update APT cache and get packages to upgrade and packages on hold.
|
||||||
aptUpdateOutput=$(apt update 2>&1 | (grep -E -ve '^(Listing|WARNING|$)' -e upgraded -e 'up to date' || true))
|
aptUpdateOutput=$(apt update 2>&1 | (grep -E -ve '^(Listing|WARNING|$)' -e upgraded -e 'up to date' || true))
|
||||||
|
|
||||||
if echo "${aptUpdateOutput}" | grep -E "^Err(:[0-9]+)? http"; then
|
if echo "${aptUpdateOutput}" | grep -E "^Err(:[0-9]+)? http"; then
|
||||||
echo "FATAL - Not able to fetch all sources (probably a pesky (mini)firewall). Please, fix me"
|
echo "FATAL - Not able to fetch all sources (probably a pesky (mini)firewall). Please, fix me"
|
||||||
exit 100
|
post_hooks_and_exit 100
|
||||||
fi
|
fi
|
||||||
|
|
||||||
apt-mark showhold > "${packagesHold}"
|
apt-mark showhold | sed -e 's/\(.\+\)/^\1\//' >"${packagesHold}"
|
||||||
apt list --upgradable 2>&1 | grep -v -f "${packagesHold}" | grep -Ev '^(Listing|WARNING|$)' > "${packages}"
|
apt list --upgradable 2>&1 | grep -v -f "${packagesHold}" | grep -v -E '^(Listing|WARNING|$)' >"${packages}"
|
||||||
packagesParsable=$(cut -f 1 -d / <"${packages}" | tr '\n' ' ')
|
packagesParsable=$(cut -f 1 -d / <"${packages}" | tr '\n' ' ')
|
||||||
|
|
||||||
# No updates? Exit!
|
# No updates? Exit!
|
||||||
test ! -s "${packages}" && exit 0
|
if [ ! -s "${packages}" ]; then
|
||||||
test ! -s "${packagesHold}" && echo 'Aucun' > "${packagesHold}"
|
if ! cron_mode; then
|
||||||
|
echo "There is nothing to upgrade. Bye."
|
||||||
|
fi
|
||||||
|
post_hooks_and_exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ ! -s "${packagesHold}" ]; then
|
||||||
|
echo 'Aucun' >"${packagesHold}"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if force_mode; then
|
||||||
|
if ! cron_mode; then
|
||||||
|
echo "Force mode is enabled, as if every release/package is available for upgrade."
|
||||||
|
fi
|
||||||
|
else
|
||||||
fetch_upgrade_info
|
fetch_upgrade_info
|
||||||
local_release=$(cut -f 1 -d . </etc/debian_version)
|
local_release=$(cut -f 1 -d . </etc/debian_version)
|
||||||
|
|
||||||
# Exit if skip_releases or skip_packages in upgrade info file are set to all.
|
# Exit if skip_releases or skip_packages in upgrade info file are set to all.
|
||||||
if [ "${r_skip_releases}" = "all" ] || [ "${r_skip_packages}" = "all" ]; then
|
if [ "${r_skip_releases}" = "all" ] || [ "${r_skip_packages}" = "all" ]; then
|
||||||
exit 30
|
post_hooks_and_exit 30
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Exit if the server's release is in skip_releases.
|
# Exit if the server's release is in skip_releases.
|
||||||
if [ -n "${r_skip_releases}" ] && is_in "${r_skip_releases}" "${local_release}"; then
|
if [ -n "${r_skip_releases}" ] && is_in "${r_skip_releases}" "${local_release}"; then
|
||||||
exit 40
|
post_hooks_and_exit 40
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Exit if all packages to upgrade are listed in skip_packages:
|
# Exit if all packages to upgrade are listed in skip_packages:
|
||||||
|
@ -125,24 +201,26 @@ if [ -n "${r_skip_packages}" ]; then
|
||||||
for pkg in ${r_skip_packages}; do
|
for pkg in ${r_skip_packages}; do
|
||||||
packageToUpgrade="${packageToUpgrade}/${pkg}"
|
packageToUpgrade="${packageToUpgrade}/${pkg}"
|
||||||
done
|
done
|
||||||
|
# shellcheck disable=SC2001
|
||||||
packageToUpgrade=$(echo "${packageToUpgrade}" | sed 's/ \+//g')
|
packageToUpgrade=$(echo "${packageToUpgrade}" | sed 's/ \+//g')
|
||||||
if [ -z "${packageToUpgrade}" ]; then
|
if [ -z "${packageToUpgrade}" ]; then
|
||||||
exit 50
|
post_hooks_and_exit 50
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Exit if the server's release is not in releases.
|
# Exit if the server's release is not in releases.
|
||||||
if [ -n "${r_releases}" ] && [ "${r_releases}" != "all" ]; then
|
if [ -n "${r_releases}" ] && [ "${r_releases}" != "all" ]; then
|
||||||
is_in "${r_releases}" "${local_release}" || exit 60
|
is_in "${r_releases}" "${local_release}" || post_hooks_and_exit 60
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Exit if there is packages to upgrades that are not in packages list:
|
# 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.
|
# we exit at the first package encountered that is not in packages list.
|
||||||
if [ -n "${r_packages}" ] && [ "${r_packages}" != "all" ]; then
|
if [ -n "${r_packages}" ] && [ "${r_packages}" != "all" ]; then
|
||||||
for pkg in ${packagesParsable}; do
|
for pkg in ${packagesParsable}; do
|
||||||
is_in "${r_packages}" "${pkg}" || exit 70
|
is_in "${r_packages}" "${pkg}" || post_hooks_and_exit 70
|
||||||
done
|
done
|
||||||
fi
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
# Guess which services will be restarted.
|
# Guess which services will be restarted.
|
||||||
for pkg in ${packagesParsable}; do
|
for pkg in ${packagesParsable}; do
|
||||||
|
@ -201,51 +279,8 @@ for pkg in ${packagesParsable}; do
|
||||||
done
|
done
|
||||||
test ! -s "${servicesToRestart}" && echo "Aucun" >"${servicesToRestart}"
|
test ! -s "${servicesToRestart}" && echo "Aucun" >"${servicesToRestart}"
|
||||||
|
|
||||||
cat << EOT > "${template}"
|
render_mail_template "${template}"
|
||||||
Content-Type: text/plain; charset="utf-8"
|
/usr/sbin/sendmail "${mailto}" <"${template}"
|
||||||
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 - Hébergement et Infogérance Open Source
|
|
||||||
http://evolix.com | Twitter: @Evolix @EvolixNOC | http://blog.evolix.com
|
|
||||||
EOT
|
|
||||||
|
|
||||||
< "${template}" /usr/sbin/sendmail "${mailto}"
|
|
||||||
|
|
||||||
# Now we try to fetch all the packages for the next update session
|
# Now we try to fetch all the packages for the next update session
|
||||||
downloadstatus=$(apt dist-upgrade --assume-yes --download-only -q2 2>&1)
|
downloadstatus=$(apt dist-upgrade --assume-yes --download-only -q2 2>&1)
|
||||||
|
@ -254,8 +289,7 @@ echo "${downloadstatus}" | grep -q 'Download complete and in download only mode'
|
||||||
# shellcheck disable=SC2181
|
# shellcheck disable=SC2181
|
||||||
if [ $? -ne 0 ]; then
|
if [ $? -ne 0 ]; then
|
||||||
echo "${downloadstatus}"
|
echo "${downloadstatus}"
|
||||||
fi;
|
fi
|
||||||
|
|
||||||
|
|
||||||
# Also, we try to update each container apt sources
|
# Also, we try to update each container apt sources
|
||||||
if which lxc-ls >/dev/null; then
|
if which lxc-ls >/dev/null; then
|
||||||
|
@ -265,16 +299,98 @@ if which lxc-ls > /dev/null; then
|
||||||
|
|
||||||
if (echo "${aptUpdateOutput}" | grep -E "^Err(:[0-9]+)? http"); then
|
if (echo "${aptUpdateOutput}" | grep -E "^Err(:[0-9]+)? http"); then
|
||||||
echo "FATAL CONTAINER - Not able to fetch all sources (probably a pesky (mini)firewall). Please, fix me"
|
echo "FATAL CONTAINER - Not able to fetch all sources (probably a pesky (mini)firewall). Please, fix me"
|
||||||
exit 150
|
post_hooks_and_exit 150
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Now we try to fetch all the packages for the next update session
|
# Now we try to fetch all the packages for the next update session
|
||||||
downloadstatus=$(lxc-attach -n "${container}" -- apt dist-upgrade --assume-yes --download-only -q2 2>&1)
|
downloadstatus=$(lxc-attach -n "${container}" -- apt dist-upgrade --assume-yes --download-only -q2 2>&1)
|
||||||
echo "${downloadstatus}" | grep -q 'Download complete and in download only mode'
|
|
||||||
|
|
||||||
if [ $? -ne 0 ]; then
|
if echo "${downloadstatus}" | grep -q 'Download complete and in download only mode'; then
|
||||||
echo "${downloadstatus}"
|
echo "${downloadstatus}"
|
||||||
fi;
|
fi
|
||||||
|
|
||||||
done
|
done
|
||||||
fi
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# Options parsing.
|
||||||
|
while :; do
|
||||||
|
case ${1} in
|
||||||
|
-V | --version)
|
||||||
|
show_version
|
||||||
|
exit 0
|
||||||
|
;;
|
||||||
|
--cron)
|
||||||
|
cron_mode=1
|
||||||
|
;;
|
||||||
|
-f | --force)
|
||||||
|
# Ignore exclusions from "upgrade info" and do as if all releases and packages are to be upgraded
|
||||||
|
force_mode=1
|
||||||
|
;;
|
||||||
|
-?* | [[:alnum:]]*)
|
||||||
|
# ignore unknown options
|
||||||
|
printf 'ERROR: Unknown option : %s\n' "$1" >&2
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
# Default case: If no more options then break out of the loop.
|
||||||
|
break
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
shift
|
||||||
|
done
|
||||||
|
|
||||||
|
## Do not stop on error. Instead we should catch them manually
|
||||||
|
# set -e
|
||||||
|
## Error on unassigned variables
|
||||||
|
set -u
|
||||||
|
|
||||||
|
export LC_ALL=C
|
||||||
|
|
||||||
|
configFile="/etc/evolinux/listupgrade.cnf"
|
||||||
|
|
||||||
|
cron_mode=${cron_mode:-0}
|
||||||
|
force_mode=${force_mode:-0}
|
||||||
|
clientmail=$(grep EVOMAINTMAIL /etc/evomaintenance.cf | cut -d'=' -f2)
|
||||||
|
mailto="${clientmail}"
|
||||||
|
date="Ce jeudi entre 18h00 et 23h00."
|
||||||
|
hostname=$(grep HOSTNAME /etc/evomaintenance.cf | cut -d'=' -f2)
|
||||||
|
hostname=${hostname%%.evolix.net}
|
||||||
|
hooksDir="/etc/evolinux/listupgrade-hooks"
|
||||||
|
|
||||||
|
# If hostname is composed with -, remove the first part.
|
||||||
|
if [[ "${hostname}" =~ "-" ]]; then
|
||||||
|
hostname=$(echo "${hostname}" | cut -d'-' -f2-)
|
||||||
|
fi
|
||||||
|
# Edit $configFile to override some variables.
|
||||||
|
# shellcheck disable=SC1090,SC1091
|
||||||
|
[ -r "${configFile}" ] && . "${configFile}"
|
||||||
|
|
||||||
|
# Create temporary files
|
||||||
|
packages=$(mktemp --tmpdir=/tmp listupgrade.XXX)
|
||||||
|
packagesHold=$(mktemp --tmpdir=/tmp listupgrade.XXX)
|
||||||
|
servicesToRestart=$(mktemp --tmpdir=/tmp listupgrade.XXX)
|
||||||
|
template=$(mktemp --tmpdir=/tmp listupgrade.XXX)
|
||||||
|
# Remove temporary files on exit.
|
||||||
|
# shellcheck disable=SC2064
|
||||||
|
trap "rm ${packages} ${packagesHold} ${servicesToRestart} ${template}" EXIT
|
||||||
|
|
||||||
|
if ! cron_mode; then
|
||||||
|
echo "À quelle date/heure allez vous planifier les mises à jour ?"
|
||||||
|
echo "Exemple : le jeudi 6 mars entre 18h00 et 23h00"
|
||||||
|
echo -n "> "
|
||||||
|
read -r date
|
||||||
|
echo "À qui envoyer le mail ?"
|
||||||
|
echo -n "> "
|
||||||
|
read -r mailto
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Execute pre hooks
|
||||||
|
pre_hooks
|
||||||
|
|
||||||
|
# call main function
|
||||||
|
main
|
||||||
|
|
||||||
|
# Execute post hooks and exit
|
||||||
|
post_hooks_and_exit 0
|
||||||
|
|
Loading…
Reference in a new issue