check_container_upgrade/check_container_upgrade
2024-03-03 17:26:48 +01:00

202 lines
4.1 KiB
Bash
Executable file

#!/bin/bash
# Monitoring plugin to check if running containers are upgradable
#
# Author: Benjamin Renard <brenard@zionetrix.net>
# Date: Sun, 03 Mar 2024 16:40:19 +0100
# Source: https://gitea.zionetrix.net/bn8/check_container_upgrade
#
ENGINE="auto"
POSSIBLE_ENGINES=( "auto" "docker" "podman" )
DEBUG=0
EXCLUDED_CONTAINERS=( buildx_buildkit_default )
declare -rA CHECK_PLUGINS=(
["/usr/lib/nagios/plugins/check_apt"]="/usr/lib/nagios/plugins/check_apt -u -U -t 60 -l"
["/usr/lib/nagios/plugins/check_apk"]="/usr/lib/nagios/plugins/check_apk"
)
function debug() {
if [ $DEBUG -eq 1 ]
then
>&2 echo -e "[DEBUG] $1"
fi
}
function is_empty() {
[ $# -gt 0 ] && return 1
return 0
}
function in_array() {
param=$1;
shift;
for elem in "$@";
do
[[ "$param" = "$elem" ]] && return 0;
done;
return 1
}
function usage() {
error="$1"
[ -n "$error" ] && echo "$error"
cat << EOF
Usage : $0 [-d] [-E /path/to/engine] [container1,...]
-E [path] Force a specific engine (possible values: ${POSSIBLE_ENGINES[@]}, default: $ENGINE)
-x [container] Exclude specified container (could be repeat)
-d Debug mode
-X Enable bash tracing (=set -x)
-h Show this message
EOF
[ -n "$error" ] && exit 1
exit 0
}
while getopts "hdXE:x:" OPTION
do
case $OPTION in
d)
DEBUG=1
;;
h)
usage
;;
E)
ENGINE=$OPTARG
if [ ! -x "$ENGINE" ]
then
in_array $ENGINE $POSSIBLE_ENGINES || usage "Invalid engine $ENGINE"
fi
;;
x)
EXCLUDED_CONTAINERS+=( $OPTARG )
;;
X)
set -x
;;
*)
usage "Unknown option $OPTION"
;;
esac
done
ONLY_CONTAINERS=( "${@:$OPTIND}" )
! is_empty $ONLY_CONTAINERS && debug "Only containers: ${ONLY_CONTAINERS[@]}"
if [ "$ENGINE" == "auto" ]
then
debug "Auto-detect engine..."
for engine in ${POSSIBLE_ENGINES[@]}
do
[ "$engine" == "auto" ] && continue
which "$engine" > /dev/null 2>&1
if [ $? -ne 0 ]
then
debug "$engine not found"
continue
fi
ENGINE="$engine"
break
done
if [ -z "$ENGINE" ]
then
echo "UNKNOWN - Fail to auto-detect engine"
exit 3
fi
debug "Auto-detected engine: $ENGINE"
fi
EXIT_CODE=0
declare -A UPTODATE
declare -A ERRORS
CHECKED_CONTAINERS=( )
debug "List running containers..."
RUNNING_CONTAINERS=$($ENGINE ps --format '{{.Names}}' | tr '\n' ' ')
debug "Running containers: $RUNNING_CONTAINERS"
for container in $RUNNING_CONTAINERS
do
if ! is_empty $ONLY_CONTAINERS && ! in_array $container $ONLY_CONTAINERS
then
debug "$container - Ignored"
continue
fi
if in_array $container $EXCLUDED_CONTAINERS
then
debug "$container - Excluded"
continue
fi
CHECKED_CONTAINERS+=( "$container" )
STATUS=""
for check_plugin in ${CHECK_PLUGINS[@]}
do
$ENGINE exec $container test -e $check_plugin > /dev/null 2>&1
if [ $? -ne 0 ]
then
debug "$container - Plugin $check_plugin not found"
continue
fi
debug "$container - Plugin $check_plugin found, use it"
STATUS="$($ENGINE exec $container ${CHECK_PLUGINS[${check_plugin}]} 2>&1)"
ex=$?
debug "$container - Plugin output: $STATUS"
debug "$container - Plugin exit code: $ex"
break
done
if [ -z "$STATUS" ]
then
debug "$container - No check plugin found"
STATUS="UNKNOWN - No check plugin available"
ex=3
fi
if [ $ex -eq 0 ]
then
UPTODATE+=( ["$container"]=$STATUS )
else
ERRORS+=( ["$container"]=$STATUS )
fi
[ $EXIT_CODE -ge $ex ] && continue
[ $ex -gt 3 ] && ex=3
EXIT_CODE=$ex
done
if ! is_empty $ONLY_CONTAINERS
then
for container in ${ONLY_CONTAINERS[@]}
do
if ! in_array $container $CHECKED_CONTAINERS
then
debug "$container - Not found"
ERRORS+=( ["$container"]="Not found" )
EXIT_CODE=3
fi
done
fi
debug "Final exit code: $EXIT_CODE"
case $EXIT_CODE in
0)
echo "OK - All containers are uptodate"
;;
1)
echo "WARNING - some containers need to be updated"
;;
2)
echo "CRITICAL - some containers need to be updated"
;;
*)
echo "UNKNOWN - fail to retrieve status of some containers"
;;
esac
for container in ${!ERRORS[@]}
do
echo ${container} - ${ERRORS[${container}]}
done
for container in ${!UPTODATE[@]}
do
echo ${container} - ${UPTODATE[${container}]}
done
exit $EXIT_CODE