From 62a3d10b4f73e8c24347f3846365c658a0d7cd2f Mon Sep 17 00:00:00 2001 From: Thaurin Date: Wed, 19 Feb 2025 16:28:11 +0100 Subject: [PATCH] Add async checking for updates for improved performance --- dockcheck.sh | 107 ++++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 84 insertions(+), 23 deletions(-) diff --git a/dockcheck.sh b/dockcheck.sh index 365d7cb..5d0c38e 100755 --- a/dockcheck.sh +++ b/dockcheck.sh @@ -34,6 +34,7 @@ Help() { echo "-s Include stopped containers in the check. (Logic: docker ps -a)." echo "-t Set a timeout (in seconds) per container for registry checkups, 10 is default." echo "-v Prints current version." + echo "-z [Experimental] Check images asynchrously for increased performance." echo echo "Project source: $Github" } @@ -48,7 +49,7 @@ c_reset="\033[0m" Timeout=10 Stopped="" -while getopts "aynpfrhlisvmc:e:d:t:" options; do +while getopts "aynpfrhlisvmzc:e:d:t:" options; do case "${options}" in a|y) AutoUp="yes" ;; c) CollectorTextFileDirectory="${OPTARG}" @@ -64,6 +65,7 @@ while getopts "aynpfrhlisvmc:e:d:t:" options; do s) Stopped="-a" ;; t) Timeout="${OPTARG}" ;; v) printf "%s\n" "$VERSION" ; exit 0 ;; + z) ParallelCheck=1 ;; d) DaysOld=${OPTARG} if ! [[ $DaysOld =~ ^[0-9]+$ ]] ; then { printf "Days -d argument given (%s) is not a number.\n" "${DaysOld}" ; exit 2 ; } ; fi ;; h|*) Help ; exit 2 ;; @@ -282,31 +284,90 @@ if [[ $t_out ]]; then else t_out="" fi -# Check the image-hash of every running container VS the registry -for i in $(docker ps $Stopped --filter "name=$SearchName" --format '{{.Names}}') ; do - ((RegCheckQue+=1)) - progress_bar "$RegCheckQue" "$ContCount" - # Looping every item over the list of excluded names and skipping - for e in "${Excludes[@]}" ; do [[ "$i" == "$e" ]] && continue 2 ; done - ImageId=$(docker inspect "$i" --format='{{.Image}}') - RepoUrl=$(docker inspect "$i" --format='{{.Config.Image}}') - LocalHash=$(docker image inspect "$ImageId" --format '{{.RepoDigests}}') - # Checking for errors while setting the variable - if RegHash=$(${t_out} $regbin -v error image digest --list "$RepoUrl" 2>&1) ; then - if [[ "$LocalHash" = *"$RegHash"* ]] ; then - NoUpdates+=("$i") - else - if [[ -n "$DaysOld" ]] && ! datecheck ; then - NoUpdates+=("+$i ${ImageAge}d") +if [[ $ParallelCheck -ne 1 ]]; then + # Check the image-hash of every running container VS the registry + for i in $(docker ps $Stopped --filter "name=$SearchName" --format '{{.Names}}') ; do + ((RegCheckQue+=1)) + progress_bar "$RegCheckQue" "$ContCount" + # Looping every item over the list of excluded names and skipping + for e in "${Excludes[@]}" ; do [[ "$i" == "$e" ]] && continue 2 ; done + ImageId=$(docker inspect "$i" --format='{{.Image}}') + RepoUrl=$(docker inspect "$i" --format='{{.Config.Image}}') + LocalHash=$(docker image inspect "$ImageId" --format '{{.RepoDigests}}') + # Checking for errors while setting the variable + if RegHash=$(${t_out} $regbin -v error image digest --list "$RepoUrl" 2>&1) ; then + if [[ "$LocalHash" = *"$RegHash"* ]] ; then + NoUpdates+=("$i") else - GotUpdates+=("$i") + if [[ -n "$DaysOld" ]] && ! datecheck ; then + NoUpdates+=("+$i ${ImageAge}d") + else + GotUpdates+=("$i") + fi fi + else + # Here the RegHash is the result of an error code + GotErrors+=("$i - ${RegHash}") fi - else - # Here the RegHash is the result of an error code - GotErrors+=("$i - ${RegHash}") - fi -done + done +else + check_image() { + i="$1" + local Excludes=($Excludes_string) + local skip + for e in "${Excludes[@]}" ; do [[ "$i" == "$e" ]] && skip=1 ; done + + if [[ $skip -eq 1 ]]; then + echo Skip $i + return + fi + + local NoUpdates GotUpdates GotErrors + ImageId=$(docker inspect "$i" --format='{{.Image}}') + RepoUrl=$(docker inspect "$i" --format='{{.Config.Image}}') + LocalHash=$(docker image inspect "$ImageId" --format '{{.RepoDigests}}') + + # Checking for errors while setting the variable + if RegHash=$(${t_out} $regbin -v error image digest --list "$RepoUrl" 2>&1) ; then + if [[ "$LocalHash" = *"$RegHash"* ]] ; then + echo NoUpdates "$i" + else + if [[ -n "$DaysOld" ]] && ! datecheck ; then + echo NoUpdates "+$i ${ImageAge}d" + else + echo GotUpdates "$i" + fi + fi + else + # Here the RegHash is the result of an error code + echo GotErrors "$i - ${RegHash}" + fi + } + + export -f check_image datecheck + export Excludes_string="${Excludes[@]}" # Can only export scalar variables + export t_out regbin RepoUrl + + # Asynchronously check the image-hash of every running container VS the registry + while read -r line; do + ((RegCheckQue+=1)) + progress_bar "$RegCheckQue" "$ContCount" + + Got=${line%% *} # Extracts the first word (NoUpdates, GotUpdates, GotErrors) + item=${line#* } + + case "$Got" in + NoUpdates) NoUpdates+=("$item") ;; + GotUpdates) GotUpdates+=("$item") ;; + GotErrors) GotErrors+=("$item") ;; + Skip) ;; + *) ;; + esac + done < <( \ + docker ps $Stopped --filter "name=$SearchName" --format '{{.Names}}' | \ + xargs -P 8 -I {} bash -c 'check_image "{}"' \ + ) +fi # Sort arrays alphabetically IFS=$'\n'