From bbf76a26be7447e3b213266018307329aa96406b Mon Sep 17 00:00:00 2001 From: david Date: Tue, 31 Oct 2023 21:17:28 +0100 Subject: [PATCH] working on watch-containers.sh --- lib.sh | 1 + watch-containers.sh | 236 ++++++++++++++++++++++++++++++-------------- 2 files changed, 164 insertions(+), 73 deletions(-) diff --git a/lib.sh b/lib.sh index 1a8bb0a..b9ebd49 100644 --- a/lib.sh +++ b/lib.sh @@ -13,6 +13,7 @@ ## ## Information +## (don't touch unless you are me) ## LIB_NAME="lib.sh" diff --git a/watch-containers.sh b/watch-containers.sh index 56bf05c..f74c5ec 100755 --- a/watch-containers.sh +++ b/watch-containers.sh @@ -1,89 +1,179 @@ -#!/bin/bash +#!/usr/bin/env bash -# name: watch_containers.sh -# author: david@socialnerds.org -# version: 0.1 -# license: GPLv3 -# description: Checks if the running container count -# matches a number provided as $1 and optionally -# reports results to a healthchecks endpoint. -# usage: ./watch_containers.sh + ## ## ## ## ## ## ## ## ## ## ## ## ## ## + ## ## + ## watch-containers.sh ## + ## ## + ## Watch running containers and report ## + ## any changes to Healthchecks ## + ## ## + ## ## ## ## ## ## ## ## ## ## ## ## ## ## -# **** function definitions **** -function usage { - echo "usage: ./watch-containers.sh " + +## +## Information +## (don't touch unless you are me) +## + +NAME="watch-containers.sh" +DESCRIPTION="Watch running containers and report any changes to Healthchecks" +VERSION="0.2.0" +AUTHOR="david@socialnerds.org" +LICENSE="MIT" +WEBSITE="https://git.socialnerds.org/david/scripts" +CHANGELOG=("[2023-10-30][v0.2.0] Complete rewrite based on the new template.sh" + "[2022-01-22][v0.1.0] Initial version") + + +## +## Configuration +## + +EXECUTABLE="$(basename $0)" +LIBRARIES="lib.sh" +DEPENDENCIES="basename dirname readlink jq docker" +REQUIRE_ROOT=0 +#TODO: make the cache file configurable with an option flag +CACHE_FILE="/var/cache/watch-containers.json" + +ONLY_IN_CACHE=() +ONLY_IN_CURRENT=() + +## +## Functions +## + +# Print help information +function print_help() { + printf "%s\n\n%s\n%b\n\n%s\n %-15s %s\n %-15s %s\n %-15s %s\n %-15s %s\n %-15s %s\n" \ + "$DESCRIPTION" "Usage:" "$LIB_BOLD$EXECUTABLE $LIB_CLEAR" "Options:" \ + "-s, --state" "Save current state to file and exit" \ + "-h, --help" "Print help screen and exit" \ + "-i, --info" "Print script information and exit" \ + "-v, --verbose" "More verbose output" \ + "-q, --quiet" "No output except errors (overrides -v)" } -function get_container_count { - local CNT=$(docker ps --format {{.Names}} | wc -l) - if is_int "$CNT"; then - echo $CNT - fi -} -function is_int { - local INT_EXPR='^[0-9]+$' - if [[ $1 =~ $INT_EXPR ]]; then - return 0 +## +## Preflight +## + +# Load BASH libraries +SCRIPT_PATH=$(readlink -f "$0") +SCRIPT_DIR=$(dirname "$SCRIPT_PATH") +for LIBRARY in $LIBRARIES; do + if [[ -r "$SCRIPT_DIR/$LIBRARY" ]]; then + #echo "Loading library file [$SCRIPT_DIR/$LIBRARY]" + source "$SCRIPT_DIR/$LIBRARY" else - return 1 - fi -} - -function is_url { - local URL_EXPR='^https?://.+$' - if [[ $1 =~ $URL_EXPR ]]; then - return 0 - else - return 1 - fi -} - -# **** start **** - -#exit if no options -if [ -z "$1" ]; then - usage - exit 1 -fi - -#exit if $1 is no intager -if ! is_int "$1"; then - usage - exit 1 -fi - -#set expected running containers -NUM=$1 - -#get running container count -CNT=$(get_container_count) - -#set healthchecks url if not empty -URL="" -if [ -n "$2" ]; then - #exit if $2 is no valid url - if ! is_url "$2"; then - usage + echo "Error: Cannot load library file [$SCRIPT_DIR/$LIBRARY]" exit 1 fi - URL="$2" +done + +# Check for root privileges +if ! lib_amiroot && [[ $REQUIRE_ROOT -eq 1 ]]; then + lib_print "!You need to have root privileges" + exit 1 fi -MSG="Running containers: $CNT -Expected containers: $NUM" +# Check for dependencies +MISSING_COMMANDS=$(lib_missing_commands $DEPENDENCIES) +if [[ -n "$MISSING_COMMANDS" ]]; then + lib_print "!One or more commands missing [$MISSING_COMMANDS]" + lib_print "Try installing them with your package manager" + exit 1 +fi -echo "$MSG" -#report to healthchecks -if [ -n "$URL" ]; then - if [ $NUM -eq $CNT ]; then - curl -m 10 --retry 5 --data-raw "$MSG" "$URL" - else - curl -m 10 --retry 5 --data-raw "$MSG" "$URL/fail" +## +## Liftoff +## + +while [[ "$1" =~ ^- && ! "$1" == "--" ]]; do + case $1 in + -s|--state) + S=1 + ;; + -h|--help) + H=1 + ;; + -i|--info) + I=1 + ;; + -v|--verbose) + V=1 + ;; + -q|--quiet) + Q=1 + ;; + *) + lib_print "!Unknown option [$1]" + lib_print "Try --help or -h for available options" + exit 1 + ;; + esac + shift +done + +if [[ "$1" == '--' ]]; then + shift +fi + +if [[ $I -eq 1 ]]; then + lib_print_info + exit 0 +elif [[ $H -eq 1 ]]; then + print_help + exit 0 +elif [[ $S -eq 1 ]]; then + docker ps --no-trunc --format json > $CACHE_FILE + lib_print "Saving current state to cache file [$CACHE_FILE]" + exit 0 +fi + +# Get containers from cache file +if [[ -r "$CACHE_FILE" ]]; then + lib_print "?Reading cache from file [$CACHE_FILE]" + CACHE=($(cat $CACHE_FILE | jq -r .Names)) +else + lib_print "!No cache file found [$CACHE_FILE]" + exit 1 +fi + +# Get currently running containers +CURRENT=($(docker ps --no-trunc --format json | jq -r .Names)) + +# Iterate through the $CACHE array and check if each element is in the $CURRENT array +for I in "${CACHE[@]}"; do + if [[ " ${CURRENT[*]} " != *" $I "* ]]; then + ONLY_IN_CACHE+=("$I") fi -fi +done + +# Iterate through the $CURRENT array and check if each element is in the CACHE array +for I in "${CURRENT[@]}"; do + if [[ " ${CACHE[*]} " != *" $I "* ]]; then + ONLY_IN_CURRENT+=("$I") + fi +done + +# Print result +echo "Missing container(s): ${ONLY_IN_CACHE[@]}" +echo "New container(s): ${ONLY_IN_CURRENT[@]}" + +#if [[ -z "$1" ]]; then +# print_help +# exit 0 +#else + +#fi + + +## +## Here be dragons +## -# **** end **** exit 0