mirror of
https://github.com/acedanger/shell.git
synced 2025-12-05 22:50:18 -08:00
feat: Add comprehensive Plex recovery validation script
- Introduced `validate-plex-recovery.sh` for validating Plex database recovery. - Implemented checks for service status, database integrity, web interface accessibility, API functionality, and recent logs. - Added detailed recovery summary and next steps for users. fix: Improve Debian patching script for compatibility - Enhanced `debian-patches.sh` to securely download and execute bootstrap scripts. - Updated package mapping logic and ensured proper permissions for patched files. fix: Update Docker test scripts for better permission handling - Modified `run-docker-tests.sh` to set appropriate permissions on logs directory. - Ensured log files have correct permissions after test runs. fix: Enhance setup scripts for secure installations - Updated `setup.sh` to securely download and execute installation scripts for zoxide and nvm. - Improved error handling for failed downloads. fix: Refine startup script for log directory permissions - Adjusted `startup.sh` to set proper permissions for log directories and files. chore: Revamp update-containers.sh for better error handling and logging - Rewrote `update-containers.sh` to include detailed logging and error handling. - Added validation for Docker image names and improved overall script robustness.
This commit is contained in:
@@ -1,49 +1,162 @@
|
||||
#!/bin/bash
|
||||
# go to "docker/media" folder
|
||||
cd ~/docker/media
|
||||
|
||||
# stop docker
|
||||
echo "Stopping docker"
|
||||
docker compose down
|
||||
#================================================================
|
||||
# HEADER
|
||||
#================================================================
|
||||
#% SYNOPSIS
|
||||
#+ update-containers.sh
|
||||
#%
|
||||
#% DESCRIPTION
|
||||
#+ Updates all Docker container images in the media stack by pulling
|
||||
#+ the latest versions and restarting the compose stack.
|
||||
#%
|
||||
#% OPTIONS
|
||||
#+ None
|
||||
#%
|
||||
#% EXAMPLES
|
||||
#+ ./update-containers.sh
|
||||
#%
|
||||
#% NOTES
|
||||
#+ - Requires Docker and Docker Compose to be installed
|
||||
#+ - Must be run from a directory containing docker-compose.yml
|
||||
#+ - Stops all containers before updating, then restarts them
|
||||
#+ - Handles missing images gracefully with warnings
|
||||
#%
|
||||
#% AUTHOR
|
||||
#+ AceDanger
|
||||
#%
|
||||
#% VERSION
|
||||
#+ 1.1.0
|
||||
#%
|
||||
#% SECURITY
|
||||
#+ - All variables are properly quoted to prevent command injection
|
||||
#+ - Input validation on Docker commands and image names
|
||||
#+ - Temporary files use secure locations with proper cleanup
|
||||
#+ - Error handling prevents script continuation on critical failures
|
||||
#%
|
||||
#================================================================
|
||||
|
||||
ERROR_FILE="/tmp/docker-images-update.error"
|
||||
# Enable strict error handling
|
||||
set -euo pipefail
|
||||
|
||||
# make sure that docker is running
|
||||
DOCKER_INFO_OUTPUT=$(docker info 2> /dev/null | grep "Containers:" | awk '{print $1}')
|
||||
# Constants
|
||||
readonly SCRIPT_NAME="$(basename "$0")"
|
||||
readonly DOCKER_MEDIA_DIR="$HOME/docker/media"
|
||||
readonly ERROR_FILE="/tmp/docker-images-update-$$.error"
|
||||
|
||||
if [ "$DOCKER_INFO_OUTPUT" == "Containers:" ]
|
||||
then
|
||||
echo "Docker is running, so we can continue"
|
||||
else
|
||||
echo "Docker is not running, exiting"
|
||||
# Cleanup function
|
||||
cleanup() {
|
||||
if [[ -f "$ERROR_FILE" ]]; then
|
||||
rm -f "$ERROR_FILE"
|
||||
fi
|
||||
}
|
||||
|
||||
# Set up cleanup trap
|
||||
trap cleanup EXIT ERR
|
||||
|
||||
# Function to log messages with timestamp
|
||||
log() {
|
||||
echo "[$(date '+%Y-%m-%d %H:%M:%S')] $*"
|
||||
}
|
||||
|
||||
# Function to validate Docker image name format
|
||||
validate_image_name() {
|
||||
local image="$1"
|
||||
# Basic validation for Docker image name format
|
||||
# Allow alphanumeric, hyphens, underscores, dots, slashes, and colons
|
||||
if [[ ! "$image" =~ ^[a-zA-Z0-9._/-]+:[a-zA-Z0-9._-]+$ ]]; then
|
||||
log "ERROR: Invalid Docker image name format: $image"
|
||||
return 1
|
||||
fi
|
||||
return 0
|
||||
}
|
||||
|
||||
# Change to docker media directory
|
||||
if [[ ! -d "$DOCKER_MEDIA_DIR" ]]; then
|
||||
log "ERROR: Docker media directory does not exist: $DOCKER_MEDIA_DIR"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# get a list of docker images that are currently installed
|
||||
IMAGES_WITH_TAGS=$(docker images | grep -v REPOSITORY | grep -v TAG | grep -v "<none>" | awk '{printf("%s:%s\n", $1, $2)}')
|
||||
cd "$DOCKER_MEDIA_DIR" || {
|
||||
log "ERROR: Failed to change to directory: $DOCKER_MEDIA_DIR"
|
||||
exit 1
|
||||
}
|
||||
|
||||
# run docker pull on all of the images
|
||||
for IMAGE in $IMAGES_WITH_TAGS; do
|
||||
echo "*****"
|
||||
echo "Updating $IMAGE"
|
||||
docker pull $IMAGE 2> $ERROR_FILE
|
||||
if [ $? != 0 ]; then
|
||||
ERROR=$(cat $ERROR_FILE | grep "not found")
|
||||
if [ "$ERROR" != "" ]; then
|
||||
echo "WARNING: Docker image $IMAGE not found in repository, skipping"
|
||||
else
|
||||
echo "ERROR: docker pull failed on image - $IMAGE"
|
||||
exit 2
|
||||
fi
|
||||
fi
|
||||
echo "*****"
|
||||
echo
|
||||
done
|
||||
# Stop docker compose
|
||||
log "Stopping Docker Compose stack"
|
||||
if ! docker compose down; then
|
||||
log "ERROR: Failed to stop Docker Compose stack"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# restart docker
|
||||
echo "Restarting Docker"
|
||||
docker compose up -d
|
||||
# Verify Docker is running
|
||||
log "Checking Docker daemon status"
|
||||
if ! docker info >/dev/null 2>&1; then
|
||||
log "ERROR: Docker daemon is not running or accessible"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# did everything finish correctly? Then we can exit
|
||||
echo "Docker images are now up to date"
|
||||
log "Docker is running, continuing with image updates"
|
||||
|
||||
# Get list of currently installed Docker images
|
||||
log "Retrieving list of installed Docker images"
|
||||
IMAGES_WITH_TAGS=$(docker images --format "{{.Repository}}:{{.Tag}}" | grep -v "<none>:" || true)
|
||||
|
||||
if [[ -z "$IMAGES_WITH_TAGS" ]]; then
|
||||
log "WARNING: No Docker images found to update"
|
||||
else
|
||||
log "Found $(echo "$IMAGES_WITH_TAGS" | wc -l) images to update"
|
||||
|
||||
# Process each image
|
||||
while IFS= read -r IMAGE; do
|
||||
[[ -z "$IMAGE" ]] && continue
|
||||
|
||||
log "Processing image: $IMAGE"
|
||||
|
||||
# Validate image name format
|
||||
if ! validate_image_name "$IMAGE"; then
|
||||
log "WARNING: Skipping invalid image name: $IMAGE"
|
||||
continue
|
||||
fi
|
||||
|
||||
log "Updating $IMAGE"
|
||||
|
||||
# Pull the image with error handling
|
||||
if docker pull "$IMAGE" 2>"$ERROR_FILE"; then
|
||||
log "Successfully updated: $IMAGE"
|
||||
else
|
||||
# Check if the error is due to image not found
|
||||
if grep -q "not found\|pull access denied\|repository does not exist" "$ERROR_FILE" 2>/dev/null; then
|
||||
log "WARNING: Docker image $IMAGE not found in repository, skipping"
|
||||
else
|
||||
log "ERROR: Failed to pull image $IMAGE"
|
||||
if [[ -f "$ERROR_FILE" ]]; then
|
||||
log "Error details: $(cat "$ERROR_FILE")"
|
||||
fi
|
||||
exit 2
|
||||
fi
|
||||
fi
|
||||
|
||||
log "Completed processing: $IMAGE"
|
||||
echo
|
||||
done <<< "$IMAGES_WITH_TAGS"
|
||||
fi
|
||||
|
||||
# Restart Docker Compose stack
|
||||
log "Restarting Docker Compose stack"
|
||||
if ! docker compose up -d; then
|
||||
log "ERROR: Failed to restart Docker Compose stack"
|
||||
exit 3
|
||||
fi
|
||||
|
||||
# Verify stack is running properly
|
||||
log "Verifying Docker Compose stack status"
|
||||
if docker compose ps --format "table {{.Name}}\t{{.Status}}" | grep -v "Up"; then
|
||||
log "WARNING: Some containers may not be running properly"
|
||||
docker compose ps
|
||||
else
|
||||
log "All containers are running successfully"
|
||||
fi
|
||||
|
||||
log "Docker images update completed successfully"
|
||||
exit 0
|
||||
|
||||
Reference in New Issue
Block a user