Files

329 lines
7.7 KiB
Bash
Raw Permalink Normal View History

2026-04-14 23:55:08 +02:00
#!/bin/bash
###############################################################################
# Script Name: system-update.sh
#
# Description:
# Performs automated system maintenance and package updates.
#
# Tasks:
# - apt update
# - apt upgrade
# - apt dist-upgrade
# - apt autoclean
# - apt autoremove
# - flatpak update
# - cleanup old log files
# - update Docker images
# - restart Docker service
# - maintain SpotDL Python virtual environment
# - install/update spotdl, yt-dlp and youtube-dl
# - optional email reporting
#
# Requirements:
# - apt
# - flatpak (optional)
# - python3-venv
# - docker (optional)
# - mail (optional, for -mail mode)
#
# Usage:
#
# Normal execution:
# ./system-update.sh
#
# Email report mode:
# ./system-update.sh -mail
#
# Logs:
# ~/.LOG/log_update_<timestamp>.log
#
###############################################################################
set -o pipefail
usage() {
cat <<EOF
Usage: ${0##*/} [OPTIONS]
Update apt pythoni flatpak and docker
Options:
-h, --help Show this help message and exit
--version Show script version
EOF
}
2026-04-14 23:55:08 +02:00
home_dir="/home/lucas"
2026-04-14 23:55:08 +02:00
green="\e[32m"
red="\e[31m"
norm="\e[0m"
2026-04-14 23:55:08 +02:00
MAIL=false
BUILD=false
die() {
echo "Error: $*" >&2
echo
usage >&2
exit 2
}
parse_args() {
while [[ $# -gt 0 ]]; do
case "$1" in
-h|--help)
usage
exit 0
;;
--version)
echo "${0##*/} 1.0"
exit 0
;;
--build)
BUILD=true
shift 1;
;;
--mail)
MAIL=true
shift 1;
;;
-*)
die "Unknown option: $1"
;;
*)
die "Unexpected argument: $1"
;;
esac
shift
done
}
write_out() {
if [[ "${MAIL}" == "true" ]]; then
printf "$@\n" >> /tmp/update.txt
else
printf "$@\n"
fi
}
echo "Start Update"
mkdir -p "${home_dir}/.LOG"
log_date="$(date +"%m%d%H")"
if [[ "$1" == "-mail" ]]; then
> /tmp/update.txt
exec 3>&1 4>&2 \
1>"${home_dir}/.LOG/log_update_${log_date}.log" \
2>&1
MAIL=true
green=""
red=""
norm=""
2026-04-14 23:55:08 +02:00
fi
2026-04-14 23:55:08 +02:00
write_out "Start: $(date)"
###############################################################################
# System Updates
###############################################################################
###############################################################################
# Standard updates
###############################################################################
CMD=(
"apt -y update"
"apt -y upgrade"
"apt -y dist-upgrade"
"apt -y autoclean"
"apt -y autoremove"
"find ${home_dir}/.LOG/ -name 'log_update_*' -mtime +6 -type f -delete"
)
MSG=(
"update"
"upgrade"
"dist-upgrade"
"autoclean"
"autoremove"
"log-cleanup"
)
for ((i=0; i<${#CMD[@]}; i++)); do
printf "Running: %s\n" "${CMD[$i]}"
if eval "sudo ${CMD[$i]}"; then
write_out "${MSG[$i]} [${green}OK${norm}]"
else
write_out "${MSG[$i]} [${red}FAIL${norm}]"
fi
2026-04-14 23:55:08 +02:00
done
###############################################################################
# Flatpak Update
###############################################################################
if command -v flatpak >/dev/null 2>&1; then
echo "Starting Flatpak Update..."
sudo flatpak update -y --noninteractive
ret=$?
echo "Flatpak returned: ${ret}"
if [[ $ret -eq 0 ]]; then
write_out "flatpak-update [${green}OK${norm}]"
else
write_out "flatpak-update [${red}FAIL${norm}]"
fi
2026-04-14 23:55:08 +02:00
fi
2026-08-19 11:24:15 +02:00
echo "Finished Package Update"
2026-08-19 11:24:15 +02:00
###############################################################################
# SpotDL Virtual Environment
###############################################################################
PACKAGES=(
yt-dlp
spotdl
)
# Install pipx if missing
if ! command -v pipx >/dev/null 2>&1; then
echo "Installing pipx..."
sudo apt update
sudo apt install -y pipx
pipx ensurepath
2026-04-14 23:55:08 +02:00
fi
# Check ffmpeg
if ! command -v ffmpeg >/dev/null 2>&1; then
echo "Installing ffmpeg..."
sudo apt install -y ffmpeg
fi
# Install or update packages
for pkg in "${PACKAGES[@]}"; do
if pipx list --short 2>/dev/null | grep -qx "$pkg"; then
echo "Updating $pkg..."
pipx upgrade "$pkg"
else
echo "Installing $pkg..."
pipx install "$pkg"
2026-09-26 13:18:01 +00:00
fi
done
# Install Deno for spotdl if missing
if ! command -v deno >/dev/null 2>&1; then
echo "Installing Deno..."
curl -fsSL https://deno.land/install.sh | sh
# Add to PATH for current shell
export PATH="$HOME/.deno/bin:$PATH"
fi
###############################################################################
# Docker Updates
###############################################################################
if command -v docker >/dev/null 2>&1; then
echo "Updating Docker images"
docker images --format "{{.Repository}}:{{.Tag}}" |
while read -r image; do
2026-10-04 19:42:37 +00:00
echo "####################################################"
echo "### $image"
echo "####################################################"
case "$image" in
qbittorrent-qbittorrent:*)
echo "Updating custom qBittorrent image..."
(
latest="$(curl -s https://api.github.com/repos/qbittorrent/qBittorrent/releases/latest | grep '"tag_name"' | cut -d '"' -f 4 | cut -d '-' -f2)"
current="$(docker exec -it qbittorrent /app/qbittorrent-nox -v | cut -d 'v' -f2)"
if [[ "$LATEST" != "$CURRENT" && "$BUILD" == "true" ]]; then
echo "New version available: $CURRENT -> $LATEST"
cd /docker/qbittorrent &&
docker compose build --pull &&
docker compose up -d
elif [[ "$LATEST" != "$CURRENT" ]]; then
echo "New version available: $CURRENT -> $LATEST"
echo "BUILD is turend off"
else
echo "No new version available: $CURRENT == $LATEST"
fi
)
;;
2026-10-13 17:50:11 +00:00
nextcloud:*)
docker pull "$image"
docker exec -it nextcloud php occ app:update --all
;;
*"<none>"*)
;;
*)
docker pull "$image"
;;
esac
done
systemctl restart docker
if [[ $? -eq 0 ]]; then
write_out "docker [${green}OK${norm}]"
else
write_out "docker [${red}FAIL${norm}]"
fi
fi
if [ -f /docker/qbittorrent/docker-compose.yml ]; then
cd /docker/qbittorrent || exit 1
 
if docker compose config >/dev/null 2>&1; then
echo "Updating custom qBittorrent image..."
docker compose build --pull
docker compose up -d
fi
fi
2026-10-04 19:42:37 +00:00
for d in /docker/*; do
if [ -d $d ]; then
docker compose -f $d/docker-compose.yaml up -d
fi
done
2026-10-02 10:59:01 +00:00
docker container prune -f
docker network prune -f
docker image prune -a -f
docker builder prune -f
2026-10-04 19:42:37 +00:00
###############################################################################
# Mail Report
###############################################################################
if [[ "${MAIL}" == "true" ]]; then
mail_str="$(cat /tmp/update.txt)"
echo "$mail_str" | mail \
-s "Automated Server Message - Upgrade" \
lucas-f@live.at
fi
2026-09-26 13:18:01 +00:00
write_out "Finished: $(date)"