Refactor YAMS script

This commit is contained in:
Roger Gonzalez 2024-12-26 09:26:21 -03:00
parent 6c63d02746
commit 9f1cbc00b6
Signed by: rogs
GPG Key ID: C7ECE9C6C36EC2E6

316
yams
View File

@ -1,145 +1,231 @@
#!/bin/bash #!/bin/bash
set -euo pipefail set -euo pipefail
dc="docker compose -f <filename> -f <custom_file_filename>" # Constants
install_directory="<install_directory>" readonly DC="docker compose -f <filename> -f <custom_file_filename>"
readonly INSTALL_DIRECTORY="<install_directory>"
option=${1:-"--help"} readonly TIMEOUT_SECONDS=60
destination=${2:-"."} readonly IP_ENDPOINTS=(
destination=$(realpath "$destination")
help() {
echo "yams - Yet Another Media Server"
echo
echo "Usage: yams [--help|restart|stop|start|destroy|check-vpn|backup [destination]|update (deprecated)]"
echo "options:"
echo "--help displays this help message"
echo "restart restarts yams services"
echo "stop stops all yams services"
echo "start starts yams services"
echo "destroy destroy yams services so you can start from scratch"
echo "check-vpn checks if the VPN is working as expected"
echo "backup [destination] backs up yams to the destination location"
echo "update updates YAMS (deprecated)"
}
send_success_message() {
echo -e "$(printf "\e[32m$1\e[0m")"
}
send_error_message() {
echo -e "$(printf "\e[31m$1\e[0m")"
exit 255
}
find_available_ip_endpoint() {
ip_endpoints=(
"https://ipinfo.io/ip" "https://ipinfo.io/ip"
"https://api.ipify.org" "https://api.ipify.org"
"https://checkip.amazonaws.com" "https://checkip.amazonaws.com"
"https://tnedi.me" "https://tnedi.me"
"https://api.myip.la" "https://api.myip.la"
"https://wtfismyip.com/text" "https://wtfismyip.com/text"
) )
for ip in ${ip_endpoints[@]}; do # Color codes for better readability
endpoint=$(curl -s "$ip") readonly RED='\033[0;31m'
if [ "$endpoint" != "" ]; then readonly GREEN='\033[0;32m'
echo $ip readonly YELLOW='\033[1;33m'
break readonly NC='\033[0m' # No Color
fi
done # Available commands
declare -A COMMANDS=(
["--help"]="displays this help message"
["restart"]="restarts yams services"
["stop"]="stops all yams services"
["start"]="starts yams services"
["destroy"]="destroy yams services so you can start from scratch"
["check-vpn"]="checks if the VPN is working as expected"
["backup"]="backs up yams to the destination location"
)
# Functions
log_success() {
echo -e "${GREEN}$1${NC}"
} }
if [ "$option" == "--help" ]; then log_error() {
help echo -e "${RED}$1${NC}" >&2
exit 0 exit 1
fi }
if [ "$option" == "restart" ]; then log_warning() {
$dc stop && $dc up -d echo -e "${YELLOW}$1${NC}"
echo "YAMS is starting. Wait 1 min until all the services are up and running..." }
exit 0
fi
if [ "$option" == "stop" ]; then show_help() {
$dc stop echo "yams - Yet Another Media Server"
exit 0 echo
fi echo "Usage: yams [command] [options]"
echo
echo "Commands:"
for cmd in "${!COMMANDS[@]}"; do
printf "%-25s %s\n" "$cmd" "${COMMANDS[$cmd]}"
done
echo
echo "Examples:"
echo " yams start # Start all YAMS services"
echo " yams backup /path/to/backup # Backup YAMS to specified directory"
}
if [ "$option" == "start" ]; then wait_for_services() {
$dc up -d local wait_time=0
echo "YAMS is starting. Wait 1 min until all the services are up and running..." echo -n "Waiting for services to start"
exit 0
fi
if [ "$option" == "check-vpn" ]; then while [ $wait_time -lt $TIMEOUT_SECONDS ]; do
# Get the total number of services and number of running services
local total_services
local running_services
total_services=$($DC ps --format '{{.Name}}' | wc -l)
running_services=$($DC ps --format '{{.Status}}' | grep -c "Up")
if [ "$total_services" -eq "$running_services" ]; then
echo
log_success "All $total_services services are up and running!"
return 0
fi
# Show progress with count
echo -n "."
sleep 1
((wait_time++))
# Every 10 seconds, show status
if [ $((wait_time % 10)) -eq 0 ]; then
echo
echo -n "$running_services/$total_services services running"
fi
done
echo
log_error "Not all services started within ${TIMEOUT_SECONDS} seconds ($running_services/$total_services running)"
}
find_available_ip_endpoint() {
for endpoint in "${IP_ENDPOINTS[@]}"; do
if curl -s --connect-timeout 5 "$endpoint" > /dev/null; then
echo "$endpoint"
return 0
fi
done
return 1
}
get_ip_with_retries() {
local context=$1 # "local" or "qbittorrent"
local cmd_prefix=""
if [ "$context" = "qbittorrent" ]; then
cmd_prefix="docker exec qbittorrent"
fi
for endpoint in "${IP_ENDPOINTS[@]}"; do
local ip
if [ "$context" = "local" ]; then
ip=$(curl -s --connect-timeout 5 "$endpoint")
else
ip=$($cmd_prefix curl -s --connect-timeout 5 "$endpoint")
fi
if [ -n "$ip" ] && [[ "$ip" =~ ^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
echo "$ip"
return 0
fi
done
return 1
}
check_vpn() {
echo "Getting your IP..." echo "Getting your IP..."
ip_endpoint=$(find_available_ip_endpoint) local your_ip
if [ "$ip_endpoint" == "" ]; then your_ip=$(get_ip_with_retries "local") || log_error "Failed to get your IP address from any endpoint"
send_error_message "No available endpoint to get IP address!" echo "Your IP: $your_ip"
fi
your_ip=$(curl -s $ip_endpoint)
echo "$your_ip"
echo "Your local IP country is $(curl -s https://am.i.mullvad.net/country)"
echo
echo
echo "Getting your qBittorrent IP..."
qbittorrent_ip=$(docker exec qbittorrent sh -c "curl -s $ip_endpoint"); local country
if [ -n "$qbittorrent_ip" ]; then country=$(curl -s --connect-timeout 5 "https://am.i.mullvad.net/country") || log_warning "Couldn't determine your country"
echo "$qbittorrent_ip" [ -n "$country" ] && echo "Your local IP country is $country"
echo "Your country in qBittorrent is $(docker exec -it qbittorrent sh -c 'curl -s https://am.i.mullvad.net/country')"
if [ "$qbittorrent_ip" == "$your_ip" ]; then echo -e "\nGetting your qBittorrent IP..."
send_error_message "Your IPs are the same! qBittorrent is exposing your IP! ⚠️" local qbit_ip
qbit_ip=$(get_ip_with_retries "qbittorrent") || log_error "Failed to get qBittorrent IP from any endpoint"
echo "qBittorrent IP: $qbit_ip"
local qbit_country
qbit_country=$(docker exec qbittorrent curl -s --connect-timeout 5 "https://am.i.mullvad.net/country") || log_warning "Couldn't determine qBittorrent country"
[ -n "$qbit_country" ] && echo "qBittorrent country is $qbit_country"
if [ "$qbit_ip" == "$your_ip" ]; then
log_error "⚠️ WARNING: Your IPs are the same! qBittorrent is exposing your IP!"
else else
send_success_message "Your IPs are different. qBittorrent is masking your IP! ✅ " log_success "✅ Success: Your IPs are different. qBittorrent is masking your IP!"
fi fi
else }
send_error_message "Failed to retrieve qBittorrent IP. Please check your setup. ⚠️"
fi
fi
if [ "$option" == "destroy" ]; then backup_yams() {
echo local destination=$1
echo local backup_date
read -p "Are you sure you want to destroy all your yams services? THIS IS NOT RECOVERABLE! ⚠️ ️🚨 [y/N]: " destroy_now backup_date=$(date '+%Y-%m-%d-%s')
destroy_now=${destroy_now:-"n"} local backup_file="$destination/yams-backup-$backup_date.tar.gz"
if [ "$destroy_now" == "y" ]; then
$dc down
echo
echo
echo "yams services were destroyed. To restart, run: "
echo "\$ yams start"
fi
fi
if [ "$option" == "update" ]; then
echo "This command is deprecated. Please update YAMS manually."
fi
if [ "$option" == "backup" ]; then
echo "Stopping YAMS services..." echo "Stopping YAMS services..."
$dc stop > /dev/null 2>&1 $DC stop > /dev/null 2>&1 || log_error "Failed to stop services"
echo
echo "Backing up YAMS to $destination..." echo -e "\nBacking up YAMS to $destination..."
echo "This may take a while depending on the size of your installation." echo "This may take a while depending on the size of your installation."
echo "Please wait... ⌛" echo "Please wait... ⌛"
backup_date=$(date '+%Y-%m-%d-%s') # Copy current yams script and create backup
backup_file="$destination/yams-backup-$backup_date.tar.gz" cp "$(which yams)" "$INSTALL_DIRECTORY" || log_warning "Failed to backup yams script"
tar --exclude='transcoding-temp' -czf "$backup_file" -C "$INSTALL_DIRECTORY" . ||
log_error "Failed to create backup archive"
cp $(which yams) $install_directory echo -e "\nStarting YAMS services..."
tar --exclude='transcoding-temp' -caf "$backup_file" -C "$install_directory" . $DC start > /dev/null 2>&1 || log_warning "Failed to restart services"
echo log_success "Backup completed successfully! 🎉"
echo "Backup completed! 🎉"
echo "Starting YAMS services..."
$dc start > /dev/null 2>&1
echo
send_success_message "Backup completed successfully! 🎉"
echo "Backup file: $backup_file" echo "Backup file: $backup_file"
fi }
destroy_yams() {
echo -e "\nWARNING: This will destroy all your YAMS services!"
read -p "Are you sure you want to continue? This is not recoverable! ⚠️ 🚨 [y/N]: " -r
if [[ ${REPLY,,} =~ ^y$ ]]; then
$DC down || log_error "Failed to destroy services"
echo -e "\nYAMS services were destroyed. To restart, run: yams start"
fi
}
main() {
local command=${1:-"--help"}
local destination=${2:-.}
# Validate and normalize destination path if provided
if [ "$command" = "backup" ]; then
destination=$(realpath "$destination") || log_error "Invalid backup destination path"
fi
case "$command" in
--help)
show_help
;;
restart)
$DC stop && $DC up -d
wait_for_services
;;
stop)
$DC stop || log_error "Failed to stop services"
log_success "Services stopped successfully"
;;
start)
$DC up -d || log_error "Failed to start services"
wait_for_services
;;
check-vpn)
check_vpn
;;
destroy)
destroy_yams
;;
backup)
backup_yams "$destination"
;;
*)
log_error "Unknown command: $command\nRun 'yams --help' for usage information"
;;
esac
}
main "$@"