Files
auto-update-ubuntu/auto-upgrade-new

260 lines
5.5 KiB
Plaintext
Raw Normal View History

2026-01-30 09:35:27 +01:00
#!/usr/bin/env bash
# Author : Allan Christensen
# First Created : 23-06-2022 (DD-MM-YYYY)
# Description : OPS-controlled unattended-upgrades policy configuration for Ubuntu 24.04
# License : MIT License
#
# Are we root
#
if [[ $(id -u) -ne 0 ]]; then
echo ""
echo "Must be root or use sudo"
echo ""
exit 1
fi
#
# Variables
#
mode="${1:-}"
config1="/etc/apt/apt.conf.d/20auto-upgrades"
config1alt="/usr/share/unattended-upgrades/20auto-upgrades"
config2="/etc/apt/apt.conf.d/50unattended-upgrades"
config2alt="/usr/share/unattended-upgrades/50unattended-upgrades"
cronfile="/etc/cron.d/updatesystem"
#
# Functions
#
die () {
echo "Error: $*" >&2
exit 1
}
usage () {
cat <<EOF
Usage: $0 <mode>
Please select ONE of the following modes:
1 Security + software updates
Automatic reboot immediately after upgrades complete
2 Security + software updates
No automatic reboot
Users will be notified on next login if a reboot is required
3 Security updates only
Automatic reboot immediately after upgrades complete
4 Security updates only
No automatic reboot
Users will be notified on next login if a reboot is required
EOF
exit 1
}
chkcfg () {
if [[ ! -f "$1" ]]; then
[[ -f "$2" ]] || die "Missing source config: $2"
cp -Rp "$2" "$1" || die "Failed to copy $2 to $1"
fi
}
mkorig () {
if [[ ! -f "${1}.orig" ]]; then
cp -Rp "$1" "${1}.orig" || die "Failed to create backup: ${1}.orig"
fi
}
#
# Disable Ubuntu automatic timers (OPS owns scheduling)
#
disable_apt_timers () {
systemctl disable --now apt-daily.timer apt-daily-upgrade.timer >/dev/null 2>&1 || true
systemctl mask apt-daily.service apt-daily-upgrade.service >/dev/null 2>&1 || true
}
#
# Ensure periodic jobs are disabled (cron owns execution)
#
set_20auto () {
sed -i 's|^\s*APT::Periodic::Update-Package-Lists.*|APT::Periodic::Update-Package-Lists "0";|' "$config1"
sed -i 's|^\s*APT::Periodic::Unattended-Upgrade.*|APT::Periodic::Unattended-Upgrade "0";|' "$config1"
}
#
# Allowed origins explicit, Bash-native
#
set_allowed_origins () {
local allow_updates="$1"
#
# Always enable security updates
#
sed -i \
'/^\s*\/\/\s*"\${distro_id}:\${distro_codename}-security"/ s|^\s*//\s*||' \
"$config2"
#
# Enable or disable non-security updates
#
if [[ "$allow_updates" == "true" ]]; then
sed -i \
'/^\s*\/\/\s*"\${distro_id}:\${distro_codename}-updates"/ s|^\s*//\s*||' \
"$config2"
else
sed -i \
'/^\s*"\${distro_id}:\${distro_codename}-updates"/ s|^|// |' \
"$config2"
fi
}
#
# Reboot policy immediate reboot after upgrades
#
set_reboot_policy () {
local reboot="$1"
local reboot_with_users="$2"
#
# Automatic-Reboot (exact key only)
#
sed -i \
'/^\s*\/\/\s*Unattended-Upgrade::Automatic-Reboot\s/ s|^\s*//\s*||' \
"$config2"
sed -i \
's|^\s*Unattended-Upgrade::Automatic-Reboot\s*".*";|Unattended-Upgrade::Automatic-Reboot "'"$reboot"'";|' \
"$config2"
#
# Automatic-Reboot-WithUsers (exact key only)
#
sed -i \
'/^\s*\/\/\s*Unattended-Upgrade::Automatic-Reboot-WithUsers\s/ s|^\s*//\s*||' \
"$config2"
sed -i \
's|^\s*Unattended-Upgrade::Automatic-Reboot-WithUsers\s*".*";|Unattended-Upgrade::Automatic-Reboot-WithUsers "'"$reboot_with_users"'";|' \
"$config2"
#
# Ensure reboot-time stays commented (cron defines timing)
#
sed -i \
'/^\s*Unattended-Upgrade::Automatic-Reboot-Time/ s|^|// |' \
"$config2"
}
#
# Cron authoritative schedule
#
write_cron () {
cat > "$cronfile" <<EOF
#
# Managed by: auto-update-ubuntu
# Purpose : OPS-controlled unattended upgrades
# Schedule : Every Friday at 03:00
#
0 3 * * 5 root /usr/bin/apt update && /usr/bin/unattended-upgrade -v >/dev/null 2>&1
EOF
chmod 644 "$cronfile" || die "Failed chmod on $cronfile"
chown root:root "$cronfile" || die "Failed chown on $cronfile"
}
restart_services () {
systemctl restart unattended-upgrades.service >/dev/null 2>&1 || die "Failed to restart unattended-upgrades"
systemctl restart cron.service >/dev/null 2>&1 || die "Failed to restart cron"
}
#
# Validate mode
#
case "$mode" in
1|2|3|4) ;;
*) usage ;;
esac
#
# Informational output (configuration-time only)
#
echo "Applying unattended-upgrades policy:"
echo ""
case "$mode" in
1)
echo " Mode: 1"
echo " Updates: Security + software updates"
echo " Reboot: Immediate reboot after upgrades complete"
;;
2)
echo " Mode: 2"
echo " Updates: Security + software updates"
echo " Reboot: Disabled"
echo " User notification: On next login if a reboot is required"
;;
3)
echo " Mode: 3"
echo " Updates: Security updates only"
echo " Reboot: Immediate reboot after upgrades complete"
;;
4)
echo " Mode: 4"
echo " Updates: Security updates only"
echo " Reboot: Disabled"
echo " User notification: On next login if a reboot is required"
;;
esac
echo ""
#
# Packages (no implicit apt update)
#
apt-get -y -qq install unattended-upgrades update-notifier-common >/dev/null \
|| die "Package install failed"
#
# Ensure configs exist
#
chkcfg "$config1" "$config1alt"
chkcfg "$config2" "$config2alt"
#
# Backup originals (once)
#
mkorig "$config1"
mkorig "$config2"
#
# OPS-owned execution model
#
set_20auto
disable_apt_timers
#
# Apply policy
#
case "$mode" in
1|2) set_allowed_origins "true" ;;
3|4) set_allowed_origins "false" ;;
esac
case "$mode" in
1|3) set_reboot_policy "true" "true" ;;
2|4) set_reboot_policy "false" "false" ;;
esac
#
# Cron + services
#
write_cron
restart_services
exit 0