bundles/apt: rework upgrade-and-reboot mechanics to be more robust
All checks were successful
bundlewrap/pipeline/head This commit looks good
All checks were successful
bundlewrap/pipeline/head This commit looks good
This commit is contained in:
parent
f33f638d88
commit
276bd6ae8d
4 changed files with 81 additions and 71 deletions
43
bundles/apt/files/do-unattended-upgrades
Normal file
43
bundles/apt/files/do-unattended-upgrades
Normal file
|
@ -0,0 +1,43 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
set -xeuo pipefail
|
||||||
|
|
||||||
|
apt-get update
|
||||||
|
|
||||||
|
DEBIAN_FRONTEND=noninteractive apt-get -y -q -o Dpkg::Options::=--force-confold -o Dpkg::Options::=--force-confdef dist-upgrade
|
||||||
|
|
||||||
|
DEBIAN_FRONTEND=noninteractive apt-get -y -q autoclean
|
||||||
|
|
||||||
|
DEBIAN_FRONTEND=noninteractive apt-get -y -q autoremove
|
||||||
|
|
||||||
|
% if clean_old_kernels:
|
||||||
|
existing=$(dpkg --get-selections | grep -E '^linux-(image|headers)-[0-9]' || true)
|
||||||
|
|
||||||
|
if [[ -z "$existing" ]]
|
||||||
|
then
|
||||||
|
echo "ERROR: No installed kernels found! Aborting!" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
current=$(uname -r | sed -r 's/-[a-zA-Z]+$//')
|
||||||
|
latest=$(echo "$existing" | sort --version-sort -t- -k 3,4 | tail -n 1 | sed -r 's/[^0-9]+([0-9]\.[^-]+-[0-9]+).*/\1/')
|
||||||
|
todelete=$(echo "$existing" | grep -v -E "($current|$latest)" | awk '{ print $1 }' || true)
|
||||||
|
|
||||||
|
if [[ -n "$todelete" ]]
|
||||||
|
then
|
||||||
|
DEBIAN_FRONTEND=noninteractive apt-get -qy purge $todelete
|
||||||
|
fi
|
||||||
|
% endif
|
||||||
|
|
||||||
|
% for affected, restarts in sorted(restart_triggers.items()):
|
||||||
|
up_since=$(systemctl show "${affected}" | sed -n 's/^ActiveEnterTimestamp=//p' || echo 0)
|
||||||
|
up_since_ts=$(date -d "$up_since" +%s || echo 0)
|
||||||
|
now=$(date +%s)
|
||||||
|
|
||||||
|
if [ $((now - up_since_ts)) -lt 3600 ]
|
||||||
|
then
|
||||||
|
% for restart in sorted(restarts):
|
||||||
|
systemctl restart "${restart}" || true
|
||||||
|
% endfor
|
||||||
|
fi
|
||||||
|
% endfor
|
|
@ -1,7 +1,5 @@
|
||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
|
||||||
set -euo pipefail
|
|
||||||
|
|
||||||
# With systemd, we can force logging to the journal. This is better than
|
# With systemd, we can force logging to the journal. This is better than
|
||||||
# spamming the world with cron mails. You can then view these logs using
|
# spamming the world with cron mails. You can then view these logs using
|
||||||
# "journalctl -rat upgrade-and-reboot".
|
# "journalctl -rat upgrade-and-reboot".
|
||||||
|
@ -13,7 +11,9 @@ then
|
||||||
exec 2> >(logger -t upgrade-and-reboot -p user.error)
|
exec 2> >(logger -t upgrade-and-reboot -p user.error)
|
||||||
fi
|
fi
|
||||||
|
|
||||||
set -x
|
. /etc/upgrade-and-reboot.conf
|
||||||
|
|
||||||
|
echo "Starting upgrade-and-reboot for node $nodename ..."
|
||||||
|
|
||||||
statusfile="/var/tmp/unattended_upgrades.status"
|
statusfile="/var/tmp/unattended_upgrades.status"
|
||||||
# Workaround, because /var/tmp is usually 1777
|
# Workaround, because /var/tmp is usually 1777
|
||||||
|
@ -27,7 +27,7 @@ then
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
softlockdir=/var/lib/bundlewrap/soft-${node.name}
|
softlockdir=/var/lib/bundlewrap/soft-$nodename
|
||||||
mkdir -p "$softlockdir"
|
mkdir -p "$softlockdir"
|
||||||
printf '{"comment": "UPDATE", "date": %s, "expiry": %s, "id": "UNATTENDED", "items": ["*"], "user": "root@localhost"}\n' \
|
printf '{"comment": "UPDATE", "date": %s, "expiry": %s, "id": "UNATTENDED", "items": ["*"], "user": "root@localhost"}\n' \
|
||||||
$(date +%s) \
|
$(date +%s) \
|
||||||
|
@ -35,62 +35,22 @@ printf '{"comment": "UPDATE", "date": %s, "expiry": %s, "id": "UNATTENDED", "ite
|
||||||
>"$softlockdir"/UNATTENDED
|
>"$softlockdir"/UNATTENDED
|
||||||
trap 'rm -f "$softlockdir"/UNATTENDED' EXIT
|
trap 'rm -f "$softlockdir"/UNATTENDED' EXIT
|
||||||
|
|
||||||
(
|
do-unattended-upgrades
|
||||||
apt-get update
|
|
||||||
DEBIAN_FRONTEND=noninteractive apt-get -y -q -o Dpkg::Options::=--force-confold -o Dpkg::Options::=--force-confdef dist-upgrade
|
|
||||||
)
|
|
||||||
ret=$?
|
ret=$?
|
||||||
|
|
||||||
echo "apt-get dist-upgrade exited $ret"
|
|
||||||
echo "$ret" > "$statusfile"
|
echo "$ret" > "$statusfile"
|
||||||
|
|
||||||
if (( $ret != 0 ))
|
if (( $ret != 0 ))
|
||||||
then
|
then
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
DEBIAN_FRONTEND=noninteractive apt-get -y -q autoclean
|
|
||||||
DEBIAN_FRONTEND=noninteractive apt-get -y -q autoremove
|
|
||||||
|
|
||||||
% if clean_old_kernels:
|
|
||||||
existing=$(dpkg --get-selections | grep -E '^linux-(image|headers)-[0-9]' || true)
|
|
||||||
|
|
||||||
if [[ -z "$existing" ]]
|
|
||||||
then
|
|
||||||
echo "ERROR: No installed kernels found! Aborting!" >&2
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
current=$(uname -r | sed -r 's/-[a-zA-Z]+$//')
|
|
||||||
latest=$(echo "$existing" | sort --version-sort -t- -k 3,4 | tail -n 1 | sed -r 's/[^0-9]+([0-9]\.[^-]+-[0-9]+).*/\1/')
|
|
||||||
todelete=$(echo "$existing" | grep -v -E "($current|$latest)" | awk '{ print $1 }' || true)
|
|
||||||
|
|
||||||
if [[ -n "$todelete" ]]
|
|
||||||
then
|
|
||||||
DEBIAN_FRONTEND=noninteractive apt-get -qy purge $todelete
|
|
||||||
fi
|
|
||||||
% endif
|
|
||||||
|
|
||||||
|
|
||||||
if [[ -f /var/run/reboot-required ]]
|
if [[ -f /var/run/reboot-required ]]
|
||||||
then
|
then
|
||||||
% if 'mail' in data:
|
if [[ -n "$reboot_mail_to" ]]
|
||||||
date | mail -s "SYSREBOOTNOW ${node.name}" ${data['mail']}
|
|
||||||
% endif
|
|
||||||
systemctl reboot
|
|
||||||
% if restart_triggers:
|
|
||||||
else
|
|
||||||
% for affected, restarts in sorted(restart_triggers.items()):
|
|
||||||
up_since=$(systemctl show "${affected}" | sed -n 's/^ActiveEnterTimestamp=//p' || echo 0)
|
|
||||||
up_since_ts=$(date -d "$up_since" +%s || echo 0)
|
|
||||||
now=$(date +%s)
|
|
||||||
|
|
||||||
if [ $((now - up_since_ts)) -lt 3600 ]
|
|
||||||
then
|
then
|
||||||
% for restart in sorted(restarts):
|
date | mail -s "SYSREBOOTNOW $nodename" "$reboot_mail_to"
|
||||||
systemctl restart "${restart}" || true
|
|
||||||
% endfor
|
|
||||||
fi
|
fi
|
||||||
% endfor
|
systemctl reboot
|
||||||
% endif
|
else
|
||||||
|
echo "upgrade-and-reboot for node $nodename is DONE"
|
||||||
fi
|
fi
|
||||||
|
|
2
bundles/apt/files/upgrade-and-reboot.conf
Normal file
2
bundles/apt/files/upgrade-and-reboot.conf
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
nodename="${node.name}"
|
||||||
|
reboot_mail_to="${node.metadata.get('apt/unattended-upgrades/reboot_mail_to', '')}"
|
|
@ -29,37 +29,42 @@ actions = {
|
||||||
}
|
}
|
||||||
|
|
||||||
files = {
|
files = {
|
||||||
'/usr/local/share/icinga/plugins/check_unattended_upgrades': {
|
|
||||||
'mode': '0755',
|
|
||||||
},
|
|
||||||
'/usr/local/sbin/upgrade-and-reboot': {
|
|
||||||
'content_type': 'mako',
|
|
||||||
'mode': '0700',
|
|
||||||
'context': {
|
|
||||||
'clean_old_kernels': node.metadata.get('apt/clean_old_kernels', True),
|
|
||||||
'data': node.metadata.get('apt/unattended-upgrades', {}),
|
|
||||||
'restart_triggers': node.metadata.get('apt/restart_triggers', {}),
|
|
||||||
}
|
|
||||||
},
|
|
||||||
'/etc/cloud': {
|
|
||||||
'delete': True,
|
|
||||||
},
|
|
||||||
'/etc/netplan': {
|
|
||||||
'delete': True,
|
|
||||||
},
|
|
||||||
'/var/lib/cloud': {
|
|
||||||
'delete': True,
|
|
||||||
},
|
|
||||||
'/etc/apt/sources.list': {
|
'/etc/apt/sources.list': {
|
||||||
'source': 'sources.list-{}-{}'.format(node.os, supported_os[node.os][node.os_version[0]]),
|
'source': 'sources.list-{}-{}'.format(node.os, supported_os[node.os][node.os_version[0]]),
|
||||||
'triggers': {
|
'triggers': {
|
||||||
'action:apt_update',
|
'action:apt_update',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
'/etc/cloud': {
|
||||||
|
'delete': True,
|
||||||
|
},
|
||||||
'/etc/kernel/postinst.d/unattended-upgrades': {
|
'/etc/kernel/postinst.d/unattended-upgrades': {
|
||||||
'source': 'kernel-postinst.d',
|
'source': 'kernel-postinst.d',
|
||||||
'mode': '0755',
|
'mode': '0755',
|
||||||
},
|
},
|
||||||
|
'/etc/netplan': {
|
||||||
|
'delete': True,
|
||||||
|
},
|
||||||
|
'/etc/upgrade-and-reboot.conf': {
|
||||||
|
'content_type': 'mako',
|
||||||
|
},
|
||||||
|
'/usr/local/sbin/upgrade-and-reboot': {
|
||||||
|
'mode': '0700',
|
||||||
|
},
|
||||||
|
'/usr/local/sbin/do-unattended-upgrades': {
|
||||||
|
'content_type': 'mako',
|
||||||
|
'mode': '0700',
|
||||||
|
'context': {
|
||||||
|
'clean_old_kernels': node.metadata.get('apt/clean_old_kernels', True),
|
||||||
|
'restart_triggers': node.metadata.get('apt/restart_triggers', {}),
|
||||||
|
}
|
||||||
|
},
|
||||||
|
'/usr/local/share/icinga/plugins/check_unattended_upgrades': {
|
||||||
|
'mode': '0755',
|
||||||
|
},
|
||||||
|
'/var/lib/cloud': {
|
||||||
|
'delete': True,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
directories = {
|
directories = {
|
||||||
|
|
Loading…
Add table
Reference in a new issue