218 lines
		
	
	
		
			5.5 KiB
		
	
	
	
		
			Bash
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			218 lines
		
	
	
		
			5.5 KiB
		
	
	
	
		
			Bash
		
	
	
		
			Executable File
		
	
	
	
	
| #!/bin/bash
 | |
| # 2023-08-26 Hyperling
 | |
| # Combine all programs which loop over Config into one which takes parameters.
 | |
| 
 | |
| ## Setup ##
 | |
| 
 | |
| DIR="$(dirname -- "${BASH_SOURCE[0]}")"
 | |
| PROG="$(basename -- "${BASH_SOURCE[0]}")"
 | |
| source $DIR/../source.env
 | |
| 
 | |
| ## Functions ##
 | |
| 
 | |
| function usage() {
 | |
| 	# Function to give the usage of the program.
 | |
| 	# Parameters:
 | |
| 	#   1) The exit code used when leaving.
 | |
| 	exit_code=$1
 | |
| 	echo ""
 | |
| 	echo -n "Usage: $PROG [-A ( -u | -d | -b | -p | -c | -s )] " 1>&2
 | |
| 	echo "[-i CONTAINER] [-l CONTAINER] [-h]" 1>&2
 | |
| 	cat <<- EOF
 | |
| 
 | |
| 		Manage all docker compose subprojects based on parameters. If no
 | |
| 		options are given then 'docker ps' is performed and the program exits.
 | |
| 
 | |
| 		Parameters - Standalone:
 | |
| 
 | |
| 		  (ALL)
 | |
| 		    -A : Equivalent of specifying '-udbpcs' for a full upgrade service.
 | |
| 
 | |
| 		  (UP)
 | |
| 		    -u : Start all containers with 'up -d'.
 | |
| 
 | |
| 		  (DOWN)
 | |
| 		    -d : Stop and take down all containers with 'down'.
 | |
| 
 | |
| 		  (BUILD)
 | |
| 		    -b : Do a 'build' for containers with a 'Dockerfile'.
 | |
| 
 | |
| 		  (PULL)
 | |
| 		    -p : Update all containers with 'pull'.
 | |
| 
 | |
| 		  (CLEAN)
 | |
| 		    -c : Remove any abandoned Docker objects using the 'prune' commands.
 | |
| 
 | |
| 		  (STATS)
 | |
| 		    -s : Tune in to the 'stats' of how each container is running.
 | |
| 
 | |
| 		Parameters - Specifying CONTAINER:
 | |
| 		  Variable can be either the container ID or container name. If (UP) is
 | |
| 		  also provided then the container does not need to be active, otherwise
 | |
| 		  the container must be running so that it can be accessed.
 | |
| 
 | |
| 		  (INTERACT)
 | |
| 		    -i CONTAINER : Remote into CONTAINER with 'exec -it CONTAINER sh'.
 | |
| 
 | |
| 		  (LOGS)
 | |
| 		    -l CONTAINER : Follow the logs of CONTAINER with 'logs -f CONTAINER'.
 | |
| 
 | |
| 		Parameters - Other:
 | |
| 
 | |
| 		  (HELP)
 | |
| 		    -h : Display this message.
 | |
| 
 | |
| 	EOF
 | |
| 	exit $exit_code
 | |
| }
 | |
| 
 | |
| function check_container() {
 | |
| 	# Ensure a container which will be accessed is either running or starting.
 | |
| 	# Parameters:
 | |
| 	#   1) CONTAINER, either as ID or Name.
 | |
| 	#   2) Why the container is being checked.
 | |
| 	container_to_check="$1"
 | |
| 	reason_to_check="$2"
 | |
| 
 | |
| 	exists=`docker ps | grep -c $container_to_check`
 | |
| 	if [[ ( $exists == 0 && -z $up ) || ( -n $down && -z $up ) ]]; then
 | |
| 		echo -n "ERROR: $container_to_check was requested for " 1>&2
 | |
| 		echo "$reason_to_check but it is not up or going to be up." 1>&2
 | |
| 		exit 2
 | |
| 	fi
 | |
| 
 | |
| 	return
 | |
| }
 | |
| 
 | |
| ## Parameters ##
 | |
| 
 | |
| while getopts ':Audbpcsi:l:h' opt; do
 | |
| 	case $opt in
 | |
| 		A) all="Y" ;;
 | |
| 		u) up="Y" ;;
 | |
| 		d) down="Y" ;;
 | |
| 		b) build="Y" ;;
 | |
| 		p) pull="Y" ;;
 | |
| 		c) clean="Y" ;;
 | |
| 		s) stats="Y" ;;
 | |
| 		i) interact="$OPTARG" ;;
 | |
| 		l) logs="$OPTARG" ;;
 | |
| 		h) usage 0 ;;
 | |
| 		*) echo "ERROR: Parameter '$OPTARG' not recognized." 1>&2 && usage 1 ;;
 | |
| 	esac
 | |
| done
 | |
| 
 | |
| # This is done outside the getopts for readability.
 | |
| if [[ -n $all ]]; then
 | |
| 	up="Y"; down="Y"; build="Y"; pull="Y"; clean="Y"; stats="Y"
 | |
| fi
 | |
| 
 | |
| ## Validations ##
 | |
| 
 | |
| # Script will behave poorly if not run with admin privileges.
 | |
| if [[ $LOGNAME != "root" ]]; then
 | |
| 	echo "*************************************************************"
 | |
| 	echo "WARNING: Script is intended for root. Please su or sudo/doas."
 | |
| 	echo "*************************************************************"
 | |
| fi
 | |
| 
 | |
| # Options which only work if the container exists or is going to be started.
 | |
| if [[ -n $interact ]]; then
 | |
| 	check_container $interact interaction
 | |
| fi
 | |
| if [[ -n $logs ]]; then
 | |
| 	check_container $logs logs
 | |
| fi
 | |
| 
 | |
| ## Main ##
 | |
| 
 | |
| # If no parameters are passed, list all the containers which are running.
 | |
| if [[ -z $up && -z $down && -z $build && -z $pull && -z $clean
 | |
| 	&& -z $interact && -z $logs && -z $stats
 | |
| ]]; then
 | |
| 	docker ps --size
 | |
| 	exit 0
 | |
| fi
 | |
| 
 | |
| # Otherwise, loop through all the subproject configurations.
 | |
| if [[ -n $up || -n $down || -n $build || -n $pull ]]; then
 | |
| 	cd $DOCKER_HOME/Config
 | |
| 	for dir in `ls`; do
 | |
| 		# If this is a directory, enter it, otherwise skip to the next listing.
 | |
| 		[ -d $dir ] && cd $dir || continue
 | |
| 		echo ""
 | |
| 		pwd
 | |
| 
 | |
| 		# Ensure .env files exist so that all compose variables are populated.
 | |
| 		if [[ -e ./env.standard && ! -e ./.env ]]; then
 | |
| 			echo "WARNING: .env file was not found, copying standard as placeholder."
 | |
| 			cp -v env.standard .env
 | |
| 		fi
 | |
| 
 | |
| 		# Ensure all configuration files have been created.
 | |
| 		if [[ -d ./config ]]; then
 | |
| 			ls ./config/*.example 2>/dev/null | while read example; do
 | |
| 				real=${example//.example/}
 | |
| 				if [[ ! -e $real ]]; then
 | |
| 					echo "WARNING: $real was not found, copying $example."
 | |
| 					cp -v $example $real
 | |
| 				fi
 | |
| 			done
 | |
| 		fi
 | |
| 
 | |
| 		# Shut off container.
 | |
| 		if [[ $down == "Y" ]]; then
 | |
| 			[ -e docker-compose.yml ] && docker compose down
 | |
| 		fi
 | |
| 
 | |
| 		# Update container from remote source such as Docker Hub.
 | |
| 		if [[ $pull == "Y" ]]; then
 | |
| 			[ -e docker-compose.yml ] && docker compose pull
 | |
| 		fi
 | |
| 
 | |
| 		# Execute commands within the container's Dockerfile.
 | |
| 		if [[ $build == "Y" ]]; then
 | |
| 			[ -e Dockerfile ] && docker compose build
 | |
| 		fi
 | |
| 
 | |
| 		# Run the container as a daemon.
 | |
| 		if [[ $up == "Y" ]]; then
 | |
| 			[ -e docker-compose.yml ] && docker compose up -d
 | |
| 		fi
 | |
| 
 | |
| 		cd ..
 | |
| 	done
 | |
| fi
 | |
| 
 | |
| # Dive into a container for running ad hoc commands.
 | |
| if [[ -n $interact ]]; then
 | |
| 	echo -e "\n*** Hopping into $interact ***"
 | |
| 	docker exec -it $interact sh
 | |
| fi
 | |
| 
 | |
| # Clean every type of Docker object which can be abandoined by Compose.
 | |
| if [[ -n $clean ]]; then
 | |
| 	echo -e "\n*** Cleaning Abandoned Objects ***"
 | |
| 	docker system df
 | |
| 	docker image prune -a
 | |
| 	docker container prune
 | |
| 	docker volume prune
 | |
| 	docker network prune
 | |
| 	docker builder prune -a
 | |
| 	docker system df
 | |
| fi
 | |
| 
 | |
| # Follow the logs of a container.
 | |
| if [[ -n $logs ]]; then
 | |
| 	echo -e "\n*** Following Logs of $logs ***"
 | |
| 	docker logs -f $logs
 | |
| fi
 | |
| 
 | |
| # Watch a top-level performance and resource monitor.
 | |
| if [[ -n $stats ]]; then
 | |
| 	echo -e "\n*** Tuning Into Stats ***"
 | |
| 	docker stats
 | |
| fi
 | |
| 
 | |
| exit 0
 |