Skip to content
Snippets Groups Projects
check_docker_info 6.35 KiB
#!/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
# ======================================================================


. $(dirname $0)/inc_pluginfunctions
. $(dirname $0)/inc_dockerfunctions.sh

self_APPVERSION=1.5

# ----------------------------------------------------------------------
# FUNCTIONS
# ----------------------------------------------------------------------


# show help
function _showHelp(){
    local _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 (slow)
  -e, --errors      Flag: Show containers on error only (slow)

EXAMPLES:
  $_self
    Show Status of all containers

  $_self -c
    Show Status of all containers and a list of container names with its
    status. Warning: this feature uses docker ps --all and can be slow.

  $_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"

ph.status "$sStatus"
echo "$out"

if [ $bOptContainers -eq 1 ] && [ "$iCTotal" -gt "0" ]; then
    echo
    echo "Containers:"
    # containers=$( sudo -n --preserve-env docker ps --all --format "{{ json . }}" --all 2>/dev/null )
    containers=$( sudo -n --preserve-env docker ps --all --format '{"Names": "{{.Names}}", "State": "{{.State}}", "Status": "{{.Status}}" }' 2>/dev/null )
   
    echo "$containers" | while read -r line; do    
      sName=$(   _getString "$line" ".Names" )
      sState=$(  _getString "$line" ".State" )
      sStatus=$( _getString "$line" ".Status" )
      sIco=
      # Icinga ui does not show these characters
      # sIco="🔶"
      # grep "exited"  <<< "${sState}" >/dev/null && sIco="❌"
      # grep "running" <<< "${sState}" >/dev/null && sIco="✅"

      printf "  %-14s %-40s %-20s\n" "$sIco $sState" "$sName" "$sStatus" 

    done 
    echo

fi

# 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

# ----------------------------------------------------------------------