#!/bin/bash # ====================================================================== # # Check DOCKER INFOS # # requirements: # - docker # - sudo permissions on docker command # - jq # # ---------------------------------------------------------------------- # Cli docs: # https://docs.docker.com/engine/reference/commandline/docker/ # ---------------------------------------------------------------------- # 2024-01-18 v1.0 <axel.hahn@unibe.ch> init # 2024-01-22 v1.1 <axel.hahn@unibe.ch> detect DOCKER; use sudo; add debug # 2024-01-23 v1.2 <axel.hahn@unibe.ch> Show a list of docker containers; add path # 2024-01-24 v1.3 <axel.hahn@unibe.ch> remove emoji icons; handle "null" in license info; show rootless or not # 2024-01-29 v1.4 <axel.hahn@unibe.ch> add --target option # 2024-02-13 v1.5 <axel.hahn@unibe.ch> update docker ps --format # 2025-02-10 v1.6 <axel.hahn@unibe.ch> harden sourcing files # 2025-06-23 v1.7 <axel.hahn@unibe.ch> check status output "(healthy)"; speedup output of containers # ====================================================================== # shellcheck source=/dev/null . "$( dirname "$0" )/inc_pluginfunctions" || exit 1 . "$( dirname "$0" )/inc_dockerfunctions.sh" || exit 1 self_APPVERSION=1.7 # ---------------------------------------------------------------------- # FUNCTIONS # ---------------------------------------------------------------------- # show help function _showHelp(){ local _self; _self="$( basename "$0" )" cat <<EOH $( ph.showImlHelpHeader ) Show docker version and count of containers total and by its status. It returns CRITICAL if a created container is not running. OK if no container was created yet or all conmtainers are running. UNKNOWM if - docker or jq were not found - docker data were not fetched - docker cannot be connected This check provides performance data. USAGE: $_self [OPTIONS] OPTIONS: General: -h, --help this help -d, --debug Debug; Flag: show all docker system infos Connect to docker: -p, --path Custom directory for docker binary -t, --target Custom docker target; value for DOCKER_HOST Needed only if Docker does not run on a unix socket or multiple users run a rootless docker daemon. Flags: -c, --containers Flag: Show containers -e, --errors Flag: Show containers on error only EXAMPLES: $_self Show Status of all containers $_self -c Show Status of all containers and a list of container names with its status. $_self -e Show Status of all containers. If not all containers are running you get a list of container names with its status. $_self -p /usr/bin Show Status of all containers. The docker binary will be searched in given path first - then in all other dirs of \$PATH $_self -d Show Status of all containers and json with all docker system infos. EOH } # ---------------------------------------------------------------------- # MAIN # ---------------------------------------------------------------------- bOptContainers=0 bOptContOnErrors=0 bOptDebug=0 while [[ "$#" -gt 0 ]]; do case $1 in -h|--help) _showHelp; exit 0;; -c|--containers) bOptContainers=1; shift;; -d|--debug) bOptDebug=1; shift;; -e|--errors) bOptContOnErrors=1; shift;; -p|--path) if ! grep ":{$2}:" <<< ":{$PATH}:" >/dev/null; then PATH="$2:$PATH"; fi shift; shift;; -t|--target) export DOCKER_HOST="$2"; shift; shift;; *) echo "ERROR: Unknown parameter: $1"; _showHelp; exit 1; esac; done ph.require "docker" ph.require "jq" _detectDockerenv # --- get data data=$( sudo -n --preserve-env docker system info --format '{{ json . }}' ) _detectDockererror "$data" 1 typeset -i iCTotal; iCTotal=$( _getString "$data" ".Containers" ) iCRunning=$(_getString "$data" ".ContainersRunning" ) iCPaused=$( _getString "$data" ".ContainersPaused" ) iCStopped=$(_getString "$data" ".ContainersStopped" ) iImages=$( _getString "$data" ".Images" ) sVersion=$( _getString "$data" ".ServerVersion") sLicense=$( _getString "$data" ".ProductLicense" ) # --- generate result if [ "$iCTotal" -eq "0" ]; then out+="Welcome to Docker! No container was created yet." else if [ "$iCRunning" -eq "0" ]; then ph.setStatus critical out+="No container is running" # if -e was given: enable to show containers test $bOptContOnErrors -eq 1 && bOptContainers=1 else if [ "$iCRunning" -ne "$iCTotal" ]; then ph.setStatus critical out+="Not all containers are running" # if -e was given: enable to show containers test $bOptContOnErrors -eq 1 && bOptContainers=1 else out+="All containers are running" fi fi fi ph.perfadd "containers-running" "$iCRunning" "" "" 0 "$iCTotal" ph.perfadd "containers-paused" "$iCPaused" "" "" 0 "$iCTotal" ph.perfadd "containers-stopped" "$iCStopped" "" "" 0 "$iCTotal" ph.perfadd "images" "$iImages" # --- output sStatus="Docker $sVersion (" test -n "$sLicense" && sStatus+="$sLicense, " test "$_is_docker_rootless" -eq "0" && sStatus+="as root" test "$_is_docker_rootless" -eq "1" && sStatus+="rootless" sStatus+=") .. " sStatus+="containers: $iCTotal running: $iCRunning paused: $iCPaused stopped: $iCStopped .. " sStatus+="images: $iImages" if [ $bOptContainers -eq 1 ] && [ "$iCTotal" -gt "0" ]; then out+="$( echo echo "Containers:" # containers=$( sudo -n --preserve-env docker ps --all --format '{"Names": "{{.Names}}", "State": "{{.State}}", "Status": "{{.Status}}" }' 2>/dev/null ) containers=$( sudo -n --preserve-env docker ps --format "table {{.Names}} | {{.State}} | {{.Status}}" --all 2>/dev/null | sed -n 2,\$p ) echo "$containers" | while read -r line; do contStatus="OK" if grep -q "(" <<< "$line"; then if grep -Fv "(healthy)" <<< "$line" | grep -q "("; then contStatus="??" # commented because within a while loop I am in a subshell # ph.setStatus critical fi else if ! grep -q "| running |" <<< "$line"; then contStatus="??" fi fi echo "$contStatus $line" done echo )" fi if grep -q "^??" <<< "$out"; then ph.setStatus critical fi ph.status "$sStatus" echo "$out" # if -d was given then show debug infos too test $bOptDebug -eq 1 && ( echo; echo "DEBUG: full docker system infos as json"; echo "$data" | jq ; _debugInfos) ph.exit # ----------------------------------------------------------------------