Files

326 lines
7.6 KiB
Bash
Executable File
Raw Permalink Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/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
}
home_dir="/home/lucas"
green="\e[32m"
red="\e[31m"
norm="\e[0m"
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=""
fi
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
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
fi
echo "Finished Package Update"
###############################################################################
# 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
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"
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
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
)
;;
*"<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
for d in /docker/*; do
if [ -d $d ]; then
docker compose -f $d/docker-compose.yaml up -d
fi
done
docker container prune -f
docker network prune -f
docker image prune -a -f
docker builder prune -f
###############################################################################
# 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
write_out "Finished: $(date)"