352 lines
8.4 KiB
Bash
Executable File
352 lines
8.4 KiB
Bash
Executable File
#!/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"
|
||
venv_dir="${home_dir}/tools/spotdl_venv"
|
||
|
||
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 "${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..."
|
||
|
||
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
|
||
###############################################################################
|
||
|
||
if [[ ! -d "$venv_dir" ]] && [[ "$1" == "--create-venv" ]]; then
|
||
|
||
echo "Creating SpotDL virtual environment"
|
||
|
||
mkdir -p "${home_dir}/tools"
|
||
|
||
python3 -m venv "$venv_dir"
|
||
fi
|
||
if [[ -d "$venv_dir" ]]; then
|
||
if [[ ! -x "${venv_dir}/bin/pip3" ]]; then
|
||
|
||
echo "Installing pip"
|
||
|
||
"${venv_dir}/bin/python" -m ensurepip --upgrade
|
||
fi
|
||
|
||
echo "Updating venv tooling"
|
||
|
||
"${venv_dir}/bin/pip3" install --upgrade \
|
||
pip \
|
||
setuptools \
|
||
wheel
|
||
|
||
###############################################################################
|
||
# Ensure required packages exist
|
||
###############################################################################
|
||
|
||
mkdir -p "${home_dir}/.local/bin"
|
||
|
||
packages=(
|
||
spotdl
|
||
yt-dlp
|
||
youtube-dl
|
||
)
|
||
|
||
for package in "${packages[@]}"; do
|
||
|
||
echo "Checking package: ${package}"
|
||
|
||
if ! "${venv_dir}/bin/pip3" show "$package" >/dev/null 2>&1; then
|
||
|
||
echo "Installing ${package}"
|
||
|
||
"${venv_dir}/bin/pip3" install "$package"
|
||
|
||
else
|
||
|
||
echo "Updating ${package}"
|
||
|
||
"${venv_dir}/bin/pip3" install --upgrade "$package"
|
||
fi
|
||
|
||
if [[ -x "${venv_dir}/bin/${bin}" ]]; then
|
||
|
||
ln -sf "${venv_dir}/bin/${package}" "${home_dir}/.local/bin/${package}"
|
||
|
||
fi
|
||
if [[ $? -eq 0 ]]; then
|
||
write_out "${package} [${green}OK${norm}]"
|
||
else
|
||
write_out "${package} [${red}FAIL${norm}]"
|
||
fi
|
||
done
|
||
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)"
|