From d4d89c305c9c8c2de871db2775919b239851c388 Mon Sep 17 00:00:00 2001 From: mag37 Date: Thu, 13 Feb 2025 21:39:29 +0100 Subject: [PATCH 01/25] osx/bsd compatibility changes --- dockcheck.sh | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/dockcheck.sh b/dockcheck.sh index f42febf..100e466 100755 --- a/dockcheck.sh +++ b/dockcheck.sh @@ -131,7 +131,8 @@ choosecontainers() { datecheck() { ImageDate=$($regbin -v error image inspect "$RepoUrl" --format='{{.Created}}' | cut -d" " -f1 ) - ImageAge=$(( ( $(date +%s) - $(date -d "$ImageDate" +%s) )/86400 )) + ImageEpoch=$(date -d "$ImageDate" +%s 2>/dev/null) || ImageEpoch=$(date -f "%Y-%m-%d" -j "$ImageDate" +%s) + ImageAge=$(( ( $(date +%s) - $ImageEpoch )/86400 )) if [ "$ImageAge" -gt "$DaysOld" ] ; then return 0 else @@ -180,7 +181,7 @@ IFS=',' read -r -a Excludes <<< "$Exclude" ; unset IFS binary_downloader() { BinaryName="$1" BinaryUrl="$2" - case "$(uname --machine)" in + case "$(uname -m)" in x86_64|amd64) architecture="amd64" ;; arm64|aarch64) architecture="arm64";; *) printf "\n%bArchitecture not supported, exiting.%b\n" "$c_red" "$c_reset" ; exit 1;; From 73050abf10fbb880c5f6f184627b74e25e84f2bc Mon Sep 17 00:00:00 2001 From: mag37 Date: Thu, 13 Feb 2025 22:18:08 +0100 Subject: [PATCH 02/25] rewrote regctl download --- dockcheck.sh | 25 ++++++++++++++++++------- 1 file changed, 18 insertions(+), 7 deletions(-) diff --git a/dockcheck.sh b/dockcheck.sh index 100e466..400f64b 100755 --- a/dockcheck.sh +++ b/dockcheck.sh @@ -196,9 +196,10 @@ binary_downloader() { distro_checker() { if [[ -f /etc/arch-release ]] ; then PkgInstaller="pacman -S" - elif [[ -f /etc/redhat-release ]] ; then PkgInstaller="dnf install" - elif [[ -f /etc/SuSE-release ]] ; then PkgInstaller="zypper install" - elif [[ -f /etc/debian_version ]] ; then PkgInstaller="apt-get install" + elif [[ -f /etc/redhat-release ]] ; then PkgInstaller="sudo dnf install" + elif [[ -f /etc/SuSE-release ]] ; then PkgInstaller="sudo zypper install" + elif [[ -f /etc/debian_version ]] ; then PkgInstaller="sudo apt-get install" + elif [[ $(uname -s) == "Darwin" ]] ; then PkgInstaller="brew install" else PkgInstaller="ERROR" ; printf "\n%bNo distribution could be determined%b, falling back to static binary.\n" "$c_yellow" "$c_reset" fi } @@ -213,10 +214,10 @@ else if [[ "$GetJq" =~ [yYsS] ]] ; then [[ "$GetJq" =~ [yY] ]] && distro_checker if [[ -n "$PkgInstaller" && "$PkgInstaller" != "ERROR" ]] ; then - (sudo $PkgInstaller jq) ; PkgExitcode="$?" + ($PkgInstaller jq) ; PkgExitcode="$?" [[ "$PkgExitcode" == 0 ]] && jqbin="jq" || printf "\n%bPackagemanager install failed%b, falling back to static binary.\n" "$c_yellow" "$c_reset" fi - if [[ "$GetJq" =~ [nN] || "$PkgInstaller" == "ERROR" || "$PkgExitcode" != 0 ]] ; then + if [[ "$GetJq" =~ [sS] || "$PkgInstaller" == "ERROR" || "$PkgExitcode" != 0 ]] ; then binary_downloader "jq" "https://github.com/jqlang/jq/releases/latest/download/jq-linux-TEMP" [[ -f "$ScriptWorkDir/jq" ]] && jqbin="$ScriptWorkDir/jq" fi @@ -232,8 +233,18 @@ elif [[ -f "$ScriptWorkDir/regctl" ]]; then regbin="$ScriptWorkDir/regctl" ; else read -r -p "Required dependency 'regctl' missing, do you want it downloaded? y/[n] " GetRegctl if [[ "$GetRegctl" =~ [yY] ]] ; then - binary_downloader "regctl" "https://github.com/regclient/regclient/releases/latest/download/regctl-linux-TEMP" - [[ -f "$ScriptWorkDir/regctl" ]] && regbin="$ScriptWorkDir/regctl" + if [[ $(uname -s) == "Darwin" ]]; then + echo "Detected macOS, Installing regclient using Homebrew." + distro_checker + if [[ -n "$PkgInstaller" && "$PkgInstaller" != "ERROR" ]] ; then + ($PkgInstaller regclient) ; PkgExitcode="$?" + [[ "$PkgExitcode" == 0 ]] && regbin="regclient" || printf "\n%bPackagemanager install failed%b, falling back to static binary.\n" "$c_yellow" "$c_reset" + fi + else + GetRegctl="S" + if [[ "$GetRegct" =~ [Ss] || "$PkgInstaller" == "ERROR" || "$PkgExitcode" != 0 ]] ; then + binary_downloader "regctl" "https://github.com/regclient/regclient/releases/latest/download/regctl-linux-TEMP" + [[ -f "$ScriptWorkDir/regctl" ]] && regbin="$ScriptWorkDir/regctl" else printf "\n%bDependency missing, exiting.%b\n" "$c_red" "$c_reset" ; exit 1 ; fi fi From 6cba140522f39a4ea1aa8ffdd4ceda98913d7fad Mon Sep 17 00:00:00 2001 From: mag37 Date: Thu, 13 Feb 2025 22:21:53 +0100 Subject: [PATCH 03/25] too tired.. forgot fi's --- dockcheck.sh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/dockcheck.sh b/dockcheck.sh index 400f64b..5b998c9 100755 --- a/dockcheck.sh +++ b/dockcheck.sh @@ -242,9 +242,11 @@ else fi else GetRegctl="S" + fi if [[ "$GetRegct" =~ [Ss] || "$PkgInstaller" == "ERROR" || "$PkgExitcode" != 0 ]] ; then binary_downloader "regctl" "https://github.com/regclient/regclient/releases/latest/download/regctl-linux-TEMP" [[ -f "$ScriptWorkDir/regctl" ]] && regbin="$ScriptWorkDir/regctl" + fi else printf "\n%bDependency missing, exiting.%b\n" "$c_red" "$c_reset" ; exit 1 ; fi fi From 6bc896b1931ab326ed6a4b6a21a42edf4b67efb3 Mon Sep 17 00:00:00 2001 From: mag37 Date: Fri, 14 Feb 2025 13:01:23 +0100 Subject: [PATCH 04/25] typo --- dockcheck.sh | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/dockcheck.sh b/dockcheck.sh index 5b998c9..bd563b6 100755 --- a/dockcheck.sh +++ b/dockcheck.sh @@ -153,7 +153,7 @@ progress_bar() { } # Function to add user-provided urls to releasenotes -releasenotes() { +releasenotes() { for update in ${GotUpdates[@]}; do found=false while read -r container url; do @@ -187,8 +187,8 @@ binary_downloader() { *) printf "\n%bArchitecture not supported, exiting.%b\n" "$c_red" "$c_reset" ; exit 1;; esac GetUrl="${BinaryUrl/TEMP/"$architecture"}" - if [[ $(command -v curl) ]]; then curl -L $GetUrl > "$ScriptWorkDir/$BinaryName" ; - elif [[ $(command -v wget) ]]; then wget $GetUrl -O "$ScriptWorkDir/$BinaryName" ; + if [[ $(command -v curl) ]]; then curl -L $GetUrl > "$ScriptWorkDir/$BinaryName" ; + elif [[ $(command -v wget) ]]; then wget $GetUrl -O "$ScriptWorkDir/$BinaryName" ; else printf "%s\n" "curl/wget not available - get $BinaryName manually from the repo link, exiting."; exit 1; fi [[ -f "$ScriptWorkDir/$BinaryName" ]] && chmod +x "$ScriptWorkDir/$BinaryName" @@ -213,13 +213,13 @@ else GetJq=${GetJq:-no} # set default to no if nothing is given if [[ "$GetJq" =~ [yYsS] ]] ; then [[ "$GetJq" =~ [yY] ]] && distro_checker - if [[ -n "$PkgInstaller" && "$PkgInstaller" != "ERROR" ]] ; then + if [[ -n "$PkgInstaller" && "$PkgInstaller" != "ERROR" ]] ; then ($PkgInstaller jq) ; PkgExitcode="$?" [[ "$PkgExitcode" == 0 ]] && jqbin="jq" || printf "\n%bPackagemanager install failed%b, falling back to static binary.\n" "$c_yellow" "$c_reset" fi if [[ "$GetJq" =~ [sS] || "$PkgInstaller" == "ERROR" || "$PkgExitcode" != 0 ]] ; then binary_downloader "jq" "https://github.com/jqlang/jq/releases/latest/download/jq-linux-TEMP" - [[ -f "$ScriptWorkDir/jq" ]] && jqbin="$ScriptWorkDir/jq" + [[ -f "$ScriptWorkDir/jq" ]] && jqbin="$ScriptWorkDir/jq" fi else printf "\n%bDependency missing, exiting.%b\n" "$c_red" "$c_reset" ; exit 1 ; fi @@ -233,19 +233,19 @@ elif [[ -f "$ScriptWorkDir/regctl" ]]; then regbin="$ScriptWorkDir/regctl" ; else read -r -p "Required dependency 'regctl' missing, do you want it downloaded? y/[n] " GetRegctl if [[ "$GetRegctl" =~ [yY] ]] ; then - if [[ $(uname -s) == "Darwin" ]]; then + if [[ $(uname -s) == "Darwin" ]]; then echo "Detected macOS, Installing regclient using Homebrew." distro_checker - if [[ -n "$PkgInstaller" && "$PkgInstaller" != "ERROR" ]] ; then + if [[ -n "$PkgInstaller" && "$PkgInstaller" != "ERROR" ]] ; then ($PkgInstaller regclient) ; PkgExitcode="$?" [[ "$PkgExitcode" == 0 ]] && regbin="regclient" || printf "\n%bPackagemanager install failed%b, falling back to static binary.\n" "$c_yellow" "$c_reset" fi else GetRegctl="S" fi - if [[ "$GetRegct" =~ [Ss] || "$PkgInstaller" == "ERROR" || "$PkgExitcode" != 0 ]] ; then + if [[ "$GetRegctl" =~ [Ss] || "$PkgInstaller" == "ERROR" || "$PkgExitcode" != 0 ]] ; then binary_downloader "regctl" "https://github.com/regclient/regclient/releases/latest/download/regctl-linux-TEMP" - [[ -f "$ScriptWorkDir/regctl" ]] && regbin="$ScriptWorkDir/regctl" + [[ -f "$ScriptWorkDir/regctl" ]] && regbin="$ScriptWorkDir/regctl" fi else printf "\n%bDependency missing, exiting.%b\n" "$c_red" "$c_reset" ; exit 1 ; fi From e68adb34d0e177dac7771c1dd7ee9b7ae6fc84e5 Mon Sep 17 00:00:00 2001 From: mag37 Date: Sat, 15 Feb 2025 13:23:42 +0100 Subject: [PATCH 05/25] added info about macos osx --- README.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index a4360c0..63607aa 100644 --- a/README.md +++ b/README.md @@ -90,7 +90,8 @@ ___ - regctl requires `amd64/arm64` - see [workaround](#roller_coaster-workaround-for-non-amd64--arm64) if other architecture is used. ## :tent: Install Instructions -Download the script to a directory in **PATH**, I'd suggest using `~/.local/bin` as that's usually in **PATH**. +Download the script to a directory in **PATH**, I'd suggest using `~/.local/bin` as that's usually in **PATH**. +For OSX/macOS preferably use `/usr/local/bin`. ```sh # basic example with curl: curl -L https://raw.githubusercontent.com/mag37/dockcheck/main/dockcheck.sh -o ~/.local/bin/dockcheck.sh @@ -98,6 +99,9 @@ chmod +x ~/.local/bin/dockcheck.sh # or oneliner with wget: wget -O ~/.local/bin/dockcheck.sh "https://raw.githubusercontent.com/mag37/dockcheck/main/dockcheck.sh" && chmod +x ~/.local/bin/dockcheck.sh + +# OSX or macOS version with curl: + curl -L https://raw.githubusercontent.com/mag37/dockcheck/main/dockcheck.sh -o /usr/local/bin/dockcheck.sh && chmod +x /usr/local/bin/dockcheck.sh ``` Then call the script anywhere with just `dockcheck.sh`. Add preferred `notify.sh`-template to the same directory - this will not be touched by the scripts self-update function. From 27896c18ba7b8fdb1f1276390afe5746a377de97 Mon Sep 17 00:00:00 2001 From: mag37 Date: Mon, 17 Feb 2025 22:23:10 +0100 Subject: [PATCH 06/25] squashed multiple dependency downloaders to one function --- dockcheck.sh | 81 ++++++++++++++++++++++------------------------------ 1 file changed, 34 insertions(+), 47 deletions(-) diff --git a/dockcheck.sh b/dockcheck.sh index bd563b6..3ef134a 100755 --- a/dockcheck.sh +++ b/dockcheck.sh @@ -204,54 +204,41 @@ distro_checker() { fi } -# Dependency check for jq in PATH or directory -if [[ $(command -v jq) ]]; then jqbin="jq" ; -elif [[ -f "$ScriptWorkDir/jq" ]]; then jqbin="$ScriptWorkDir/jq" ; -else - printf "%s\n" "Required dependency 'jq' missing, do you want to install it?" - read -r -p "y: With packagemanager (sudo). / s: Download static binary. y/s/[n] " GetJq - GetJq=${GetJq:-no} # set default to no if nothing is given - if [[ "$GetJq" =~ [yYsS] ]] ; then - [[ "$GetJq" =~ [yY] ]] && distro_checker - if [[ -n "$PkgInstaller" && "$PkgInstaller" != "ERROR" ]] ; then - ($PkgInstaller jq) ; PkgExitcode="$?" - [[ "$PkgExitcode" == 0 ]] && jqbin="jq" || printf "\n%bPackagemanager install failed%b, falling back to static binary.\n" "$c_yellow" "$c_reset" - fi - if [[ "$GetJq" =~ [sS] || "$PkgInstaller" == "ERROR" || "$PkgExitcode" != 0 ]] ; then - binary_downloader "jq" "https://github.com/jqlang/jq/releases/latest/download/jq-linux-TEMP" - [[ -f "$ScriptWorkDir/jq" ]] && jqbin="$ScriptWorkDir/jq" - fi - else printf "\n%bDependency missing, exiting.%b\n" "$c_red" "$c_reset" ; exit 1 ; - fi -fi -# Final check if binary is correct -$jqbin --version &> /dev/null || { printf "%s\n" "jq is not working - try to remove it and re-download it, exiting."; exit 1; } +# Dependency check + installer function +dependency_check() { + AppName="$1" + AppVar="$2" + AppUrl="$3" + if [[ $(command -v $AppName) ]]; then export $AppVar="$AppName" ; + elif [[ -f "$ScriptWorkDir/$AppName" ]]; then export $AppVar="$ScriptWorkDir/$AppName" ; + else +   printf "%s\n" "Required dependency '$AppName' missing, do you want to install it?" +   read -r -p "y: With packagemanager (sudo). / s: Download static binary. y/s/[n] " GetBin +   GetBin=${GetBin:-no} # set default to no if nothing is given +   if [[ "$GetBin" =~ [yYsS] ]] ; then +     [[ "$GetBin" =~ [yY] ]] && distro_checker +     if [[ -n "$PkgInstaller" && "$PkgInstaller" != "ERROR" ]] ; then +       [[ $(uname -s) == "Darwin" && "$AppName" == "regctl" ]] && AppName=regclient +       ($PkgInstaller $AppName) ; PkgExitcode="$?" +       if [[ "$PkgExitcode" == 0 ]] ; then { export $AppVar="$AppName" && printf "\n%b$AppName installed.%b\n" "$c_green" "$c_reset"; }   +   else printf "\n%bPackagemanager install failed%b, falling back to static binary.\n" "$c_yellow" "$c_reset" +       fi +     fi +     if [[ "$GetBin" =~ [sS] || "$PkgInstaller" == "ERROR" || "$PkgExitcode" != 0 ]] ; then +         binary_downloader "$AppName" "$AppUrl" +         [[ -f "$ScriptWorkDir/$AppName" ]] && { export $AppVar="$ScriptWorkDir/$1" && printf "\n%b$AppName downloaded.%b\n" "$c_green" "$c_reset"; } +     fi +   else printf "\n%bDependency missing, exiting.%b\n" "$c_red" "$c_reset" ; exit 1 ; +   fi + fi + # Final check if binary is correct + [[ "$1" == "jq" ]] && VerFlag="--version" + [[ "$1" == "regctl" ]] && VerFlag="version" + ${!AppVar} $VerFlag &> /dev/null  || { printf "%s\n" "$AppName is not working - try to remove it and re-download it, exiting."; exit 1; } +} -# Dependency check for regctl in PATH or directory -if [[ $(command -v regctl) ]]; then regbin="regctl" ; -elif [[ -f "$ScriptWorkDir/regctl" ]]; then regbin="$ScriptWorkDir/regctl" ; -else - read -r -p "Required dependency 'regctl' missing, do you want it downloaded? y/[n] " GetRegctl - if [[ "$GetRegctl" =~ [yY] ]] ; then - if [[ $(uname -s) == "Darwin" ]]; then - echo "Detected macOS, Installing regclient using Homebrew." - distro_checker - if [[ -n "$PkgInstaller" && "$PkgInstaller" != "ERROR" ]] ; then - ($PkgInstaller regclient) ; PkgExitcode="$?" - [[ "$PkgExitcode" == 0 ]] && regbin="regclient" || printf "\n%bPackagemanager install failed%b, falling back to static binary.\n" "$c_yellow" "$c_reset" - fi - else - GetRegctl="S" - fi - if [[ "$GetRegctl" =~ [Ss] || "$PkgInstaller" == "ERROR" || "$PkgExitcode" != 0 ]] ; then - binary_downloader "regctl" "https://github.com/regclient/regclient/releases/latest/download/regctl-linux-TEMP" - [[ -f "$ScriptWorkDir/regctl" ]] && regbin="$ScriptWorkDir/regctl" - fi - else printf "\n%bDependency missing, exiting.%b\n" "$c_red" "$c_reset" ; exit 1 ; - fi -fi -# Final check if binary is correct -$regbin version &> /dev/null || { printf "%s\n" "regctl is not working - try to remove it and re-download it, exiting."; exit 1; } +dependency_check "regctl" "regbin" "https://github.com/regclient/regclient/releases/latest/download/regctl-linux-TEMP" +dependency_check "jq" "jqbin" "https://github.com/jqlang/jq/releases/latest/download/jq-linux-TEMP" # Check docker compose binary if docker compose version &> /dev/null ; then DockerBin="docker compose" ; From b9188443360b726ee5a29d6dd82f9d2831caaf5d Mon Sep 17 00:00:00 2001 From: mag37 Date: Mon, 17 Feb 2025 22:38:14 +0100 Subject: [PATCH 07/25] reformatting --- dockcheck.sh | 58 ++++++++++++++++++++++++++-------------------------- 1 file changed, 29 insertions(+), 29 deletions(-) diff --git a/dockcheck.sh b/dockcheck.sh index 3ef134a..0e199cd 100755 --- a/dockcheck.sh +++ b/dockcheck.sh @@ -206,35 +206,35 @@ distro_checker() { # Dependency check + installer function dependency_check() { - AppName="$1" - AppVar="$2" - AppUrl="$3" - if [[ $(command -v $AppName) ]]; then export $AppVar="$AppName" ; - elif [[ -f "$ScriptWorkDir/$AppName" ]]; then export $AppVar="$ScriptWorkDir/$AppName" ; - else -   printf "%s\n" "Required dependency '$AppName' missing, do you want to install it?" -   read -r -p "y: With packagemanager (sudo). / s: Download static binary. y/s/[n] " GetBin -   GetBin=${GetBin:-no} # set default to no if nothing is given -   if [[ "$GetBin" =~ [yYsS] ]] ; then -     [[ "$GetBin" =~ [yY] ]] && distro_checker -     if [[ -n "$PkgInstaller" && "$PkgInstaller" != "ERROR" ]] ; then -       [[ $(uname -s) == "Darwin" && "$AppName" == "regctl" ]] && AppName=regclient -       ($PkgInstaller $AppName) ; PkgExitcode="$?" -       if [[ "$PkgExitcode" == 0 ]] ; then { export $AppVar="$AppName" && printf "\n%b$AppName installed.%b\n" "$c_green" "$c_reset"; }   -   else printf "\n%bPackagemanager install failed%b, falling back to static binary.\n" "$c_yellow" "$c_reset" -       fi -     fi -     if [[ "$GetBin" =~ [sS] || "$PkgInstaller" == "ERROR" || "$PkgExitcode" != 0 ]] ; then -         binary_downloader "$AppName" "$AppUrl" -         [[ -f "$ScriptWorkDir/$AppName" ]] && { export $AppVar="$ScriptWorkDir/$1" && printf "\n%b$AppName downloaded.%b\n" "$c_green" "$c_reset"; } -     fi -   else printf "\n%bDependency missing, exiting.%b\n" "$c_red" "$c_reset" ; exit 1 ; -   fi - fi - # Final check if binary is correct - [[ "$1" == "jq" ]] && VerFlag="--version" - [[ "$1" == "regctl" ]] && VerFlag="version" - ${!AppVar} $VerFlag &> /dev/null  || { printf "%s\n" "$AppName is not working - try to remove it and re-download it, exiting."; exit 1; } + AppName="$1" + AppVar="$2" + AppUrl="$3" + if [[ $(command -v $AppName) ]]; then export $AppVar="$AppName" ; + elif [[ -f "$ScriptWorkDir/$AppName" ]]; then export $AppVar="$ScriptWorkDir/$AppName" ; + else + printf "%s\n" "Required dependency '$AppName' missing, do you want to install it?" + read -r -p "y: With packagemanager (sudo). / s: Download static binary. y/s/[n] " GetBin + GetBin=${GetBin:-no} # set default to no if nothing is given + if [[ "$GetBin" =~ [yYsS] ]] ; then + [[ "$GetBin" =~ [yY] ]] && distro_checker + if [[ -n "$PkgInstaller" && "$PkgInstaller" != "ERROR" ]] ; then + [[ $(uname -s) == "Darwin" && "$AppName" == "regctl" ]] && AppName=regclient + ($PkgInstaller $AppName) ; PkgExitcode="$?" + if [[ "$PkgExitcode" == 0 ]] ; then { export $AppVar="$AppName" && printf "\n%b$AppName installed.%b\n" "$c_green" "$c_reset"; } + else printf "\n%bPackagemanager install failed%b, falling back to static binary.\n" "$c_yellow" "$c_reset" + fi + fi + if [[ "$GetBin" =~ [sS] || "$PkgInstaller" == "ERROR" || "$PkgExitcode" != 0 ]] ; then + binary_downloader "$AppName" "$AppUrl" + [[ -f "$ScriptWorkDir/$AppName" ]] && { export $AppVar="$ScriptWorkDir/$1" && printf "\n%b$AppName downloaded.%b\n" "$c_green" "$c_reset"; } + fi + else printf "\n%bDependency missing, exiting.%b\n" "$c_red" "$c_reset" ; exit 1 ; + fi + fi + # Final check if binary is correct + [[ "$1" == "jq" ]] && VerFlag="--version" + [[ "$1" == "regctl" ]] && VerFlag="version" + ${!AppVar} $VerFlag &> /dev/null || { printf "%s\n" "$AppName is not working - try to remove it and re-download it, exiting."; exit 1; } } dependency_check "regctl" "regbin" "https://github.com/regclient/regclient/releases/latest/download/regctl-linux-TEMP" From 41029f628d5fd0e2c6315c613663e3dc9a6878f1 Mon Sep 17 00:00:00 2001 From: mag37 Date: Tue, 18 Feb 2025 07:59:11 +0100 Subject: [PATCH 08/25] Update dockcheck.sh indentation error. --- dockcheck.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dockcheck.sh b/dockcheck.sh index 0e199cd..6c4ad35 100755 --- a/dockcheck.sh +++ b/dockcheck.sh @@ -221,7 +221,7 @@ dependency_check() { [[ $(uname -s) == "Darwin" && "$AppName" == "regctl" ]] && AppName=regclient ($PkgInstaller $AppName) ; PkgExitcode="$?" if [[ "$PkgExitcode" == 0 ]] ; then { export $AppVar="$AppName" && printf "\n%b$AppName installed.%b\n" "$c_green" "$c_reset"; } - else printf "\n%bPackagemanager install failed%b, falling back to static binary.\n" "$c_yellow" "$c_reset" + else printf "\n%bPackagemanager install failed%b, falling back to static binary.\n" "$c_yellow" "$c_reset" fi fi if [[ "$GetBin" =~ [sS] || "$PkgInstaller" == "ERROR" || "$PkgExitcode" != 0 ]] ; then From 76e6a5c38b49c97479a72b449d41730b0e22a514 Mon Sep 17 00:00:00 2001 From: mag37 Date: Tue, 18 Feb 2025 08:15:52 +0100 Subject: [PATCH 09/25] Update dockcheck.sh typo --- dockcheck.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dockcheck.sh b/dockcheck.sh index 6c4ad35..8d7949e 100755 --- a/dockcheck.sh +++ b/dockcheck.sh @@ -218,7 +218,7 @@ dependency_check() { if [[ "$GetBin" =~ [yYsS] ]] ; then [[ "$GetBin" =~ [yY] ]] && distro_checker if [[ -n "$PkgInstaller" && "$PkgInstaller" != "ERROR" ]] ; then - [[ $(uname -s) == "Darwin" && "$AppName" == "regctl" ]] && AppName=regclient + [[ $(uname -s) == "Darwin" && "$AppName" == "regctl" ]] && AppName="regclient" ($PkgInstaller $AppName) ; PkgExitcode="$?" if [[ "$PkgExitcode" == 0 ]] ; then { export $AppVar="$AppName" && printf "\n%b$AppName installed.%b\n" "$c_green" "$c_reset"; } else printf "\n%bPackagemanager install failed%b, falling back to static binary.\n" "$c_yellow" "$c_reset" From 78a7e1137fd569b33c588a5c5e5c52bce6f2ec88 Mon Sep 17 00:00:00 2001 From: mag37 Date: Tue, 18 Feb 2025 10:07:21 +0100 Subject: [PATCH 10/25] OSX appname return --- dockcheck.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dockcheck.sh b/dockcheck.sh index 8d7949e..e27f12d 100755 --- a/dockcheck.sh +++ b/dockcheck.sh @@ -219,7 +219,7 @@ dependency_check() { [[ "$GetBin" =~ [yY] ]] && distro_checker if [[ -n "$PkgInstaller" && "$PkgInstaller" != "ERROR" ]] ; then [[ $(uname -s) == "Darwin" && "$AppName" == "regctl" ]] && AppName="regclient" - ($PkgInstaller $AppName) ; PkgExitcode="$?" + ($PkgInstaller $AppName) ; PkgExitcode="$?" && AppName="$1" if [[ "$PkgExitcode" == 0 ]] ; then { export $AppVar="$AppName" && printf "\n%b$AppName installed.%b\n" "$c_green" "$c_reset"; } else printf "\n%bPackagemanager install failed%b, falling back to static binary.\n" "$c_yellow" "$c_reset" fi From 3655f5ae8a002fd6068ebbe655f303e8c54dcd9a Mon Sep 17 00:00:00 2001 From: mag37 Date: Wed, 19 Feb 2025 13:36:30 +0100 Subject: [PATCH 11/25] version bump --- README.md | 8 +------- dockcheck.sh | 4 ++-- 2 files changed, 3 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index 63607aa..9a716f7 100644 --- a/README.md +++ b/README.md @@ -19,17 +19,11 @@ ___ ## :bell: Changelog +- **v0.5.5.0**: osx and bsd compatibility changes + rewrite of dependency installer - **v0.5.4.0**: Added support for a Prometheus+node_exporter metric collection through a file collector. - **v0.5.3.0**: Local image check changed (use imageId instead of name) and Gotify-template fixed (whale icon removed). - **v0.5.2.1**: Rewrite of dependency downloads, jq can be installed with package manager or static binary. - **v0.5.1**: DEPENDENCY WARNING: now requires **jq**. + Upstreaming changes from [sudo-kraken/podcheck](https://github.com/sudo-kraken/podcheck) -- **v0.5.0**: Rewritten notify logic - all templates are adjusted and should be migrated! - - Copy the custom settings from your current template to the new version of the same template. - - Look into, copy and customize the `urls.list` file if that's of interest. - - Other changes: - - Added Discord notify template. - - Verbosity changed of `regctl`. -- **v0.4.9**: Added a function to enrich the notify-message with release note URLs. See [Release notes addon](https://github.com/mag37/dockcheck#date-release-notes-addon-to-notifications) ___ diff --git a/dockcheck.sh b/dockcheck.sh index e27f12d..8f320aa 100755 --- a/dockcheck.sh +++ b/dockcheck.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash -VERSION="v0.5.4.0" -### ChangeNotes: Added support for a Prometheus+node_exporter metric collection through a file collector. +VERSION="v0.5.5.0" +### ChangeNotes: osx and bsd compatibility changes + rewrite of dependency installer Github="https://github.com/mag37/dockcheck" RawUrl="https://raw.githubusercontent.com/mag37/dockcheck/main/dockcheck.sh" From 65e875e8604ab9d46cefbb39620201b63bd5ee5c Mon Sep 17 00:00:00 2001 From: mag37 Date: Wed, 19 Feb 2025 20:26:54 +0100 Subject: [PATCH 12/25] fixed typo --- dockcheck.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dockcheck.sh b/dockcheck.sh index 8f320aa..365d7cb 100755 --- a/dockcheck.sh +++ b/dockcheck.sh @@ -316,7 +316,7 @@ unset IFS # Run the prometheus exporter function if [ -n "$CollectorTextFileDirectory" ] ; then - source "$ScriptWorkDir"/addons/prometheus/prometheus_collector.sh && prometheus_exporter ${#NoUpdates[@]} ${#GotUpdates[@]} ${#GotError[@]} + source "$ScriptWorkDir"/addons/prometheus/prometheus_collector.sh && prometheus_exporter ${#NoUpdates[@]} ${#GotUpdates[@]} ${#GotErrors[@]} fi # Define how many updates are available From 62a3d10b4f73e8c24347f3846365c658a0d7cd2f Mon Sep 17 00:00:00 2001 From: Thaurin Date: Wed, 19 Feb 2025 16:28:11 +0100 Subject: [PATCH 13/25] 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' From a2868ea50531d22a7d1ddbbbd1a4d4a8faa6c542 Mon Sep 17 00:00:00 2001 From: Thaurin Date: Thu, 20 Feb 2025 15:54:52 +0100 Subject: [PATCH 14/25] Add error message; increase number of subprocesses --- dockcheck.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dockcheck.sh b/dockcheck.sh index 5d0c38e..9e3da8b 100755 --- a/dockcheck.sh +++ b/dockcheck.sh @@ -361,11 +361,11 @@ else GotUpdates) GotUpdates+=("$item") ;; GotErrors) GotErrors+=("$item") ;; Skip) ;; - *) ;; + *) echo "Error: invalid result from subprocess! (${item})" ;; esac done < <( \ docker ps $Stopped --filter "name=$SearchName" --format '{{.Names}}' | \ - xargs -P 8 -I {} bash -c 'check_image "{}"' \ + xargs -P 32 -I {} bash -c 'check_image "{}"' \ ) fi From 408a8b14dd5a3f1ac3c7ac4beaf99f34108a5b7a Mon Sep 17 00:00:00 2001 From: Thaurin Date: Thu, 20 Feb 2025 18:39:27 +0100 Subject: [PATCH 15/25] Fix -d parameter not working anymore --- dockcheck.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dockcheck.sh b/dockcheck.sh index 9e3da8b..0327b27 100755 --- a/dockcheck.sh +++ b/dockcheck.sh @@ -346,7 +346,7 @@ else export -f check_image datecheck export Excludes_string="${Excludes[@]}" # Can only export scalar variables - export t_out regbin RepoUrl + export t_out regbin RepoUrl DaysOld # Asynchronously check the image-hash of every running container VS the registry while read -r line; do From 3aeee837f9bb426f9c65534b7bab2a29d8525aa4 Mon Sep 17 00:00:00 2001 From: Thaurin Date: Fri, 21 Feb 2025 17:54:19 +0100 Subject: [PATCH 16/25] Print entire line on error --- dockcheck.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dockcheck.sh b/dockcheck.sh index 0327b27..13bf6e2 100755 --- a/dockcheck.sh +++ b/dockcheck.sh @@ -361,7 +361,7 @@ else GotUpdates) GotUpdates+=("$item") ;; GotErrors) GotErrors+=("$item") ;; Skip) ;; - *) echo "Error: invalid result from subprocess! (${item})" ;; + *) echo "Error! Unexpected output from subprocess: ${line}" ;; esac done < <( \ docker ps $Stopped --filter "name=$SearchName" --format '{{.Names}}' | \ From b2d67c9f524520d13ce591c2e38073d8784f481a Mon Sep 17 00:00:00 2001 From: Thaurin Date: Fri, 21 Feb 2025 17:57:09 +0100 Subject: [PATCH 17/25] Removed experimental -z flag and old version check code --- dockcheck.sh | 129 ++++++++++++++++++++------------------------------- 1 file changed, 50 insertions(+), 79 deletions(-) diff --git a/dockcheck.sh b/dockcheck.sh index 13bf6e2..462e7e6 100755 --- a/dockcheck.sh +++ b/dockcheck.sh @@ -34,7 +34,6 @@ 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" } @@ -49,7 +48,7 @@ c_reset="\033[0m" Timeout=10 Stopped="" -while getopts "aynpfrhlisvmzc:e:d:t:" options; do +while getopts "aynpfrhlisvmc:e:d:t:" options; do case "${options}" in a|y) AutoUp="yes" ;; c) CollectorTextFileDirectory="${OPTARG}" @@ -65,7 +64,6 @@ while getopts "aynpfrhlisvmzc: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 ;; @@ -284,90 +282,63 @@ if [[ $t_out ]]; then else t_out="" fi -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 - if [[ -n "$DaysOld" ]] && ! datecheck ; then - NoUpdates+=("+$i ${ImageAge}d") - else - GotUpdates+=("$i") - fi - fi +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 - # Here the RegHash is the result of an error code - GotErrors+=("$i - ${RegHash}") - fi - 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" + if [[ -n "$DaysOld" ]] && ! datecheck ; then + echo NoUpdates "+$i ${ImageAge}d" else - if [[ -n "$DaysOld" ]] && ! datecheck ; then - echo NoUpdates "+$i ${ImageAge}d" - else - echo GotUpdates "$i" - fi + echo GotUpdates "$i" fi - else - # Here the RegHash is the result of an error code - echo GotErrors "$i - ${RegHash}" 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 DaysOld +# Make required functions and variables available to subprocesses +export -f check_image datecheck +export Excludes_string="${Excludes[@]}" # Can only export scalar variables +export t_out regbin RepoUrl DaysOld - # Asynchronously check the image-hash of every running container VS the registry - while read -r line; do - ((RegCheckQue+=1)) - progress_bar "$RegCheckQue" "$ContCount" +# 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#* } + Got=${line%% *} # Extracts the first word (NoUpdates, GotUpdates, GotErrors) + item=${line#* } - case "$Got" in - NoUpdates) NoUpdates+=("$item") ;; - GotUpdates) GotUpdates+=("$item") ;; - GotErrors) GotErrors+=("$item") ;; - Skip) ;; - *) echo "Error! Unexpected output from subprocess: ${line}" ;; - esac - done < <( \ - docker ps $Stopped --filter "name=$SearchName" --format '{{.Names}}' | \ - xargs -P 32 -I {} bash -c 'check_image "{}"' \ - ) -fi + case "$Got" in + NoUpdates) NoUpdates+=("$item") ;; + GotUpdates) GotUpdates+=("$item") ;; + GotErrors) GotErrors+=("$item") ;; + Skip) ;; + *) echo "Error! Unexpected output from subprocess: ${line}" ;; + esac +done < <( \ + docker ps $Stopped --filter "name=$SearchName" --format '{{.Names}}' | \ + xargs -P 32 -I {} bash -c 'check_image "{}"' \ +) # Sort arrays alphabetically IFS=$'\n' From 3e079e2ec51641d9d421e62ed77dc4944ca81f1c Mon Sep 17 00:00:00 2001 From: mag37 Date: Mon, 24 Feb 2025 21:49:19 +0100 Subject: [PATCH 18/25] Update dockcheck.sh Added MaxAsync variable. Added POSIX xargs check. Rewrote Excludes. --- dockcheck.sh | 24 ++++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/dockcheck.sh b/dockcheck.sh index 462e7e6..087138d 100755 --- a/dockcheck.sh +++ b/dockcheck.sh @@ -46,6 +46,7 @@ c_blue="\033[0;34m" c_teal="\033[0;36m" c_reset="\033[0m" +MaxAsync=32 Timeout=10 Stopped="" while getopts "aynpfrhlisvmc:e:d:t:" options; do @@ -285,13 +286,12 @@ fi 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 + for e in "${Excludes[@]}" ; do + if [[ "$i" == "$e" ]]; then + echo Skip $i + return + fi + done local NoUpdates GotUpdates GotErrors ImageId=$(docker inspect "$i" --format='{{.Image}}') @@ -320,6 +320,14 @@ export -f check_image datecheck export Excludes_string="${Excludes[@]}" # Can only export scalar variables export t_out regbin RepoUrl DaysOld +# Check for POSIX xargs with -P option, fallback without async +if (echo "test" | xargs -P 10 >/dev/null 2>&1) ; then + XargsAsync="-P $MaxAsync" +else + XargsAsync="" + printf "%bMissing POSIX xargs, consider installing 'findutils' for asynchronous lookups.%b\n" "$c_red" "$c_reset" +fi + # Asynchronously check the image-hash of every running container VS the registry while read -r line; do ((RegCheckQue+=1)) @@ -337,7 +345,7 @@ while read -r line; do esac done < <( \ docker ps $Stopped --filter "name=$SearchName" --format '{{.Names}}' | \ - xargs -P 32 -I {} bash -c 'check_image "{}"' \ + xargs ${XargsAsync} -I {} bash -c 'check_image "{}"' \ ) # Sort arrays alphabetically From 229cde0efb4c2a61ab769472d5a48d6c795693b0 Mon Sep 17 00:00:00 2001 From: mag37 Date: Mon, 24 Feb 2025 22:03:20 +0100 Subject: [PATCH 19/25] Updated README.md Added changelog. Added info about Docker Hub pull limit. --- README.md | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 9a716f7..d1dea1d 100644 --- a/README.md +++ b/README.md @@ -16,14 +16,16 @@

For Podman - see the fork sudo-kraken/podcheck!

+

:whale: Docker Hub pull limit :chart_with_downwards_trend: not an issue for checks but for actual pulls - read more

+ ___ ## :bell: Changelog +- **v0.5.6.0**: Heavily improved performance due to async checking for updates. - **v0.5.5.0**: osx and bsd compatibility changes + rewrite of dependency installer - **v0.5.4.0**: Added support for a Prometheus+node_exporter metric collection through a file collector. - **v0.5.3.0**: Local image check changed (use imageId instead of name) and Gotify-template fixed (whale icon removed). - **v0.5.2.1**: Rewrite of dependency downloads, jq can be installed with package manager or static binary. -- **v0.5.1**: DEPENDENCY WARNING: now requires **jq**. + Upstreaming changes from [sudo-kraken/podcheck](https://github.com/sudo-kraken/podcheck) ___ @@ -77,6 +79,7 @@ ___ ## :nut_and_bolt: Dependencies - Running docker (duh) and compose, either standalone or plugin. (see [Podman fork](https://github.com/sudo-kraken/podcheck) - Bash shell or compatible shell of at least v4.3 + - POSIX `xargs`, usually default but can be installed with the `findutils` package - to enable async. - [jq](https://github.com/jqlang/jq) - User will be prompted to install with package manager or download static binary. - [regclient/regctl](https://github.com/regclient/regclient) (Licensed under [Apache-2.0 License](http://www.apache.org/licenses/LICENSE-2.0)) @@ -177,7 +180,15 @@ chmod 755 regctl ``` Test it with `./regctl --help` and then either add the file to the same path as *dockcheck.sh* or in your path (eg. `~/.local/bin/regctl`). -## :guardsman: Function to auth with docker hub before running +## :whale: Docker Hub pull limit :chart_with_downwards_trend: not an issue for checks but for actual pulls +Due to recent changes in [Docker Hub usage and limits](https://docs.docker.com/docker-hub/usage/) +>Unauthenticated users: 10 pulls/hour +>Authenticated users with a free account: 100 pulls/hour + +This is not an issue for registry checks. But if you have a large stack and pull more than 10 updates at once consider updating more often or to create a free account. +You could use/modify the login-wrapper function in the example below to automate the login prior to running `dockcheck.sh`. + +### :guardsman: Function to auth with docker hub before running **Example** - Change names, paths, and remove cat+password flag if you rather get prompted: ```sh function dchk { From 61f90893ef27542e0124af198af742b15257a488 Mon Sep 17 00:00:00 2001 From: mag37 Date: Mon, 24 Feb 2025 22:12:11 +0100 Subject: [PATCH 20/25] async version bump --- dockcheck.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dockcheck.sh b/dockcheck.sh index 087138d..04fac69 100755 --- a/dockcheck.sh +++ b/dockcheck.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash -VERSION="v0.5.5.0" -### ChangeNotes: osx and bsd compatibility changes + rewrite of dependency installer +VERSION="v0.5.6.0" +### ChangeNotes: Heavily improved performance due to asynchronous update checks. Github="https://github.com/mag37/dockcheck" RawUrl="https://raw.githubusercontent.com/mag37/dockcheck/main/dockcheck.sh" From 502a16791917add8545bb2fb4d785d1b8141ef6b Mon Sep 17 00:00:00 2001 From: mag37 Date: Tue, 25 Feb 2025 21:30:20 +0100 Subject: [PATCH 21/25] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index d1dea1d..eb235fc 100644 --- a/README.md +++ b/README.md @@ -21,7 +21,7 @@ ___ ## :bell: Changelog -- **v0.5.6.0**: Heavily improved performance due to async checking for updates. +- **v0.5.6.0**: Heavily improved performance due to async checking for updates. Adjust the variable `MaxAsync=32` to something lower (or 1 ) if issues. - **v0.5.5.0**: osx and bsd compatibility changes + rewrite of dependency installer - **v0.5.4.0**: Added support for a Prometheus+node_exporter metric collection through a file collector. - **v0.5.3.0**: Local image check changed (use imageId instead of name) and Gotify-template fixed (whale icon removed). From 8110cd88927716c622b666a1cbcebd83aa230c3d Mon Sep 17 00:00:00 2001 From: mag37 Date: Tue, 25 Feb 2025 21:30:41 +0100 Subject: [PATCH 22/25] Update README.md --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index eb235fc..4cadd0c 100644 --- a/README.md +++ b/README.md @@ -21,7 +21,8 @@ ___ ## :bell: Changelog -- **v0.5.6.0**: Heavily improved performance due to async checking for updates. Adjust the variable `MaxAsync=32` to something lower (or 1 ) if issues. +- **v0.5.6.0**: Heavily improved performance due to async checking for updates. + - Adjust the variable `MaxAsync=32` to something lower (or 1 ) if issues. - **v0.5.5.0**: osx and bsd compatibility changes + rewrite of dependency installer - **v0.5.4.0**: Added support for a Prometheus+node_exporter metric collection through a file collector. - **v0.5.3.0**: Local image check changed (use imageId instead of name) and Gotify-template fixed (whale icon removed). From 8c3b899332ef56f5150925b80f34e8cf3e1beef5 Mon Sep 17 00:00:00 2001 From: mag37 Date: Wed, 26 Feb 2025 21:23:15 +0100 Subject: [PATCH 23/25] async hotfix, defaults to 1 subprocess, added -x option to set custom async value --- dockcheck.sh | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/dockcheck.sh b/dockcheck.sh index 04fac69..3ee7724 100755 --- a/dockcheck.sh +++ b/dockcheck.sh @@ -13,6 +13,10 @@ ScriptWorkDir="$(dirname "$ScriptPath")" LatestRelease="$(curl -s -r 0-50 $RawUrl | sed -n "/VERSION/s/VERSION=//p" | tr -d '"')" LatestChanges="$(curl -s -r 0-200 $RawUrl | sed -n "/ChangeNotes/s/# ChangeNotes: //p")" +# User customizable defaults +MaxAsync=1 +Timeout=10 + # Help Function Help() { echo "Syntax: dockcheck.sh [OPTION] [part of name to filter]" @@ -34,6 +38,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 "-x N Set max asynchronous subprocesses, 1 default, 0 to disable, 32+ tested." echo echo "Project source: $Github" } @@ -46,10 +51,8 @@ c_blue="\033[0;34m" c_teal="\033[0;36m" c_reset="\033[0m" -MaxAsync=32 -Timeout=10 Stopped="" -while getopts "aynpfrhlisvmc:e:d:t:" options; do +while getopts "aynpfrhlisvmc:e:d:t:x:" options; do case "${options}" in a|y) AutoUp="yes" ;; c) CollectorTextFileDirectory="${OPTARG}" @@ -65,6 +68,7 @@ while getopts "aynpfrhlisvmc:e:d:t:" options; do s) Stopped="-a" ;; t) Timeout="${OPTARG}" ;; v) printf "%s\n" "$VERSION" ; exit 0 ;; + x) MaxAsync=${OPTARG} ;; 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 ;; @@ -321,11 +325,11 @@ export Excludes_string="${Excludes[@]}" # Can only export scalar variables export t_out regbin RepoUrl DaysOld # Check for POSIX xargs with -P option, fallback without async -if (echo "test" | xargs -P 10 >/dev/null 2>&1) ; then +if (echo "test" | xargs -P 2 >/dev/null 2>&1) && [[ "$MaxAsync" != 0 ]]; then XargsAsync="-P $MaxAsync" else XargsAsync="" - printf "%bMissing POSIX xargs, consider installing 'findutils' for asynchronous lookups.%b\n" "$c_red" "$c_reset" + [[ "$MaxAsync" != 0 ]] && printf "%bMissing POSIX xargs, consider installing 'findutils' for asynchronous lookups.%b\n" "$c_red" "$c_reset" fi # Asynchronously check the image-hash of every running container VS the registry From 9ef2ea71356e32eb787f9a42223d5fb99653dadc Mon Sep 17 00:00:00 2001 From: mag37 Date: Wed, 26 Feb 2025 21:39:33 +0100 Subject: [PATCH 24/25] versionbump + changenotes --- dockcheck.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dockcheck.sh b/dockcheck.sh index 3ee7724..6bb9006 100755 --- a/dockcheck.sh +++ b/dockcheck.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash -VERSION="v0.5.6.0" -### ChangeNotes: Heavily improved performance due to asynchronous update checks. +VERSION="v0.5.6.1" +### ChangeNotes: Async hotfix, 1 subprocess default, modify MaxAsync variable or pass -x N option to increase. Github="https://github.com/mag37/dockcheck" RawUrl="https://raw.githubusercontent.com/mag37/dockcheck/main/dockcheck.sh" From bf1e78d2ff27364cb0267f3dfed2c9b31409e1eb Mon Sep 17 00:00:00 2001 From: mag37 Date: Wed, 26 Feb 2025 22:04:05 +0100 Subject: [PATCH 25/25] hotfix changelog --- README.md | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 4cadd0c..9e9ab79 100644 --- a/README.md +++ b/README.md @@ -21,8 +21,15 @@ ___ ## :bell: Changelog +Made MaxAsync=1 the default - edit to change. +Added -x option to pass a MaxAsync value on runtime. +Made it possible to disable xargs -P-flag by setting MaxAsync=0 or passing -x 0 option. + +- **v0.5.6.1**: Async xargs hotfix - due to errors `failed to request manifest head ... context canceled` + - Defaulted subprocess to 1 with `MaxAsync=1`, increase to find a stable value in your environment. + - Added `-x N` option to pass `MaxAsync` value at runtime. + - To disable xargs `-P` flag (max processes) all together, set `MaxAsync` to 0. - **v0.5.6.0**: Heavily improved performance due to async checking for updates. - - Adjust the variable `MaxAsync=32` to something lower (or 1 ) if issues. - **v0.5.5.0**: osx and bsd compatibility changes + rewrite of dependency installer - **v0.5.4.0**: Added support for a Prometheus+node_exporter metric collection through a file collector. - **v0.5.3.0**: Local image check changed (use imageId instead of name) and Gotify-template fixed (whale icon removed).