Compare commits

...

20 Commits

Author SHA1 Message Date
mag37
210c076968 Merge pull request #130 from mag37/osx_support
Some osx / bsd compatibility changes.
Rewritten the dependency (jq + regctl) install method.
Many thanks to @pshannon-git for testing!
2025-02-19 20:36:42 +01:00
mag37
65e875e860 fixed typo 2025-02-19 20:26:54 +01:00
mag37
3655f5ae8a version bump 2025-02-19 13:36:30 +01:00
mag37
78a7e1137f OSX appname return 2025-02-18 10:07:21 +01:00
mag37
76e6a5c38b Update dockcheck.sh
typo
2025-02-18 08:15:52 +01:00
mag37
41029f628d Update dockcheck.sh
indentation error.
2025-02-18 07:59:11 +01:00
mag37
b918844336 reformatting 2025-02-17 22:38:14 +01:00
mag37
27896c18ba squashed multiple dependency downloaders to one function 2025-02-17 22:23:10 +01:00
mag37
e68adb34d0 added info about macos osx 2025-02-15 13:23:42 +01:00
mag37
6bc896b193 typo 2025-02-14 13:01:23 +01:00
mag37
6cba140522 too tired.. forgot fi's 2025-02-13 22:21:53 +01:00
mag37
73050abf10 rewrote regctl download 2025-02-13 22:18:08 +01:00
mag37
d4d89c305c osx/bsd compatibility changes 2025-02-13 21:39:29 +01:00
mag37
bc6a3529c7 Update README.md 2025-02-07 19:34:24 +01:00
mag37
01b9b33751 Merge pull request #124 from mag37/prometheus_addon
Prometheus addon
2025-02-07 19:28:43 +01:00
mag37
9ed2a0bad0 finalized prometheus addon 2025-02-07 19:27:14 +01:00
mag37
43307350ca formatting of header 2025-01-31 23:58:05 +01:00
mag37
b3600f26ac restructure, moved to addon-subdir and split code to sourced snippet 2025-01-31 23:52:10 +01:00
mag37
79def47754 Merge pull request #121 from tdralle/main
Added an export for node_exporter's text file collector to provide metrics to Prometheus
2025-01-31 23:37:24 +01:00
Thorsten Dralle
58d53d3aaf Added a node collector to export statistics to prometheus 2025-01-27 20:57:19 +01:00
6 changed files with 553 additions and 62 deletions

View File

@@ -10,24 +10,20 @@
<a href="https://github.com/sponsors/mag37"><img src="https://img.shields.io/badge/-Sponsor-grey?style=flat-square&logo=github" alt="Github Sponsor"></a>
</p>
<h3 align="center">CLI tool to automate docker image updates. <br>No <b>pre-pull</b>, selective, optional notifications and prune when done.</h3>
<h2 align="center">Now with simple notification integrations!</h2>
<h4 align="center">With features like excluding specific containers, custom container labels, auto-prune when done and more.</h4>
<h4 align="center">Also see the fresh Podman fork <a href="https://github.com/sudo-kraken/podcheck">sudo-kraken/podcheck</a>!</h4>
<h2 align="center">CLI tool to automate docker image updates or notifying when updates are available.</h2>
<h3 align="center">Features:</h3>
<h3 align="center">selective updates, exclude containers, custom labels, notification plugins, prune when done and more.</h3>
<h4 align="center">For Podman - see the fork <a href="https://github.com/sudo-kraken/podcheck">sudo-kraken/podcheck</a>!</h4>
___
## :bell: Changelog
- **v0.5.3**: Local image check changed (use imageId instead of name) and Gotify-template fixed (whale icon removed).
- **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)
___
@@ -41,6 +37,7 @@ Example: dockcheck.sh -y -d 10 -e nextcloud,heimdall
Options:"
-a|y Automatic updates, without interaction.
-c D Exports metrics as prom file for the prometheus node_exporter. Provide the collector textfile directory.
-d N Only update to new images that are N+ days old. Lists too recent with +prefix and age. 2xSlower.
-e X Exclude containers, separated by comma.
-f Force stack restart after update. Caution: restarts once for every updated container within stack.
@@ -80,14 +77,15 @@ ___
## :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
- [jq](https://github.com/jqlang/jq)
- [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))
- User will be prompted to download `regctl` if not in `PATH` or `PWD`.
- 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
@@ -95,6 +93,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.
@@ -123,8 +124,8 @@ Further additions are welcome - suggestions or PR!
<sub><sup>Initiated and first contributed by [yoyoma2](https://github.com/yoyoma2).</sup></sub>
### :date: Release notes addon to Notifications
There's a function to use a lookup-file to add release note URL's to the notification message.
Copy the notify_templates/`urls.list` file to the script directory, it will be used automatically if it's there. Modify it as necessary, the names of interest in the left column needs to match your container names.
There's a function to use a lookup-file to add release note URL's to the notification message.
Copy the notify_templates/`urls.list` file to the script directory, it will be used automatically if it's there. Modify it as necessary, the names of interest in the left column needs to match your container names.
The output of the notification will look something like this:
```
Containers on hostname with updates available:
@@ -135,6 +136,17 @@ nginx -> https://github.com/docker-library/official-images/blob/master/library
```
The `urls.list` file is just an example and I'd gladly see that people contribute back when they add their preferred URLs to their lists.
## :chart_with_upwards_trend: Prometheus and node_exporter
Dockcheck can be used together with [Prometheus](https://github.com/prometheus/prometheus) and [node_exporter](https://github.com/prometheus/node_exporter) to export metrics via the file collector, scheduled with cron or likely.
This is done with the `-c` option, like this:
```
dockcheck.sh -c /path/to/exporter/directory
```
See the [README.md](./addons/prometheus/README.md) for more detailed information on how to set it up!
<sub><sup>Contributed by [tdralle](https://github.com/tdralle).</sup></sub>
## :bookmark: Labels
Optionally add labels to compose-files. Currently these are the usable labels:
```
@@ -186,7 +198,7 @@ function dchk {
Containers need to be manually stopped, removed and created again to run on the new image.
## :wrench: Debugging
If you hit issues, you could check the output of the `extras/errorCheck.sh` script for clues.
If you hit issues, you could check the output of the `extras/errorCheck.sh` script for clues.
Another option is to run the main script with debugging in a subshell `bash -x dockcheck.sh` - if there's a particular container/image that's causing issues you can filter for just that through `bash -x dockcheck.sh nginx`.
## :scroll: License
@@ -199,4 +211,3 @@ dockcheck is created and released under the [GNU GPL v3.0](https://www.gnu.org/l
___
### :floppy_disk: The [story](https://mag37.org/posts/project_dockcheck/) behind it. 1 year in retrospect.

View File

@@ -0,0 +1,61 @@
## [Prometheus](https://github.com/prometheus/prometheus) and [node_exporter](https://github.com/prometheus/node_exporter)
Dockcheck is capable to export metrics to prometheus via the text file collector provided by the node_exporter.
In order to do so the -c flag has to be specified followed by the file path that is configured in the text file collector of the node_exporter.
A simple cron job can be configured to export these metrics on a regular interval as shown in the sample below:
```
0 1 * * * /root/dockcheck.sh -n -c /var/lib/node_exporter/textfile_collector
```
The following metrics are exported to prometheus
```
# HELP dockcheck_images_analyzed Docker images that have been analyzed
# TYPE dockcheck_images_analyzed gauge
dockcheck_images_analyzed 22
# HELP dockcheck_images_outdated Docker images that are outdated
# TYPE dockcheck_images_outdated gauge
dockcheck_images_outdated 7
# HELP dockcheck_images_latest Docker images that are outdated
# TYPE dockcheck_images_latest gauge
dockcheck_images_latest 14
# HELP dockcheck_images_error Docker images with analysis errors
# TYPE dockcheck_images_error gauge
dockcheck_images_error 1
# HELP dockcheck_images_analyze_timestamp_seconds Last dockercheck run time
# TYPE dockcheck_images_analyze_timestamp_seconds gauge
dockcheck_images_analyze_timestamp_seconds 1737924029
```
Once those metrics are exported they can be used to define alarms as shown below
```
- alert: dockcheck_images_outdated
expr: sum by(instance) (dockcheck_images_outdated) > 0
for: 15s
labels:
severity: warning
annotations:
summary: "{{ $labels.instance }} has {{ $value }} outdated docker images."
description: "{{ $labels.instance }} has {{ $value }} outdated docker images."
- alert: dockcheck_images_error
expr: sum by(instance) (dockcheck_images_error) > 0
for: 15s
labels:
severity: warning
annotations:
summary: "{{ $labels.instance }} has {{ $value }} docker images having an error."
description: "{{ $labels.instance }} has {{ $value }} docker images having an error."
- alert: dockercheck_image_last_analyze
expr: (time() - dockcheck_images_analyze_timestamp_seconds) > (3600 * 24 * 3)
for: 15s
labels:
severity: warning
annotations:
summary: "{{ $labels.instance }} has not updated the dockcheck statistics for more than 3 days."
description: "{{ $labels.instance }} has not updated the dockcheck statistics for more than 3 days."
```
There is a reference Grafana dashboard in [grafana/grafana_dashboard.json](./grafana/grafana_dashboard.json).
![](./grafana/grafana_dashboard.png)

View File

@@ -0,0 +1,382 @@
{
"__inputs": [
{
"name": "DS_PROMETHEUS",
"label": "prometheus",
"description": "",
"type": "datasource",
"pluginId": "prometheus",
"pluginName": "Prometheus"
}
],
"__elements": {},
"__requires": [
{
"type": "grafana",
"id": "grafana",
"name": "Grafana",
"version": "11.4.0"
},
{
"type": "datasource",
"id": "prometheus",
"name": "Prometheus",
"version": "1.0.0"
},
{
"type": "panel",
"id": "table",
"name": "Table",
"version": ""
}
],
"annotations": {
"list": [
{
"builtIn": 1,
"datasource": {
"type": "grafana",
"uid": "-- Grafana --"
},
"enable": true,
"hide": true,
"iconColor": "rgba(0, 211, 255, 1)",
"name": "Annotations & Alerts",
"type": "dashboard"
}
]
},
"editable": true,
"fiscalYearStartMonth": 0,
"graphTooltip": 0,
"id": null,
"links": [],
"panels": [
{
"datasource": {
"type": "prometheus",
"uid": "${DS_PROMETHEUS}"
},
"fieldConfig": {
"defaults": {
"color": {
"mode": "thresholds"
},
"custom": {
"align": "auto",
"cellOptions": {
"type": "auto"
},
"inspect": false
},
"mappings": [],
"thresholds": {
"mode": "absolute",
"steps": [
{
"color": "green",
"value": null
},
{
"color": "red",
"value": 80
}
]
}
},
"overrides": [
{
"matcher": {
"id": "byName",
"options": "last_analyze_timestamp"
},
"properties": [
{
"id": "unit",
"value": "dateTimeAsIso"
}
]
},
{
"matcher": {
"id": "byName",
"options": "last_analyze_since"
},
"properties": [
{
"id": "unit",
"value": "s"
},
{
"id": "custom.cellOptions",
"value": {
"mode": "gradient",
"type": "color-background"
}
},
{
"id": "thresholds",
"value": {
"mode": "absolute",
"steps": [
{
"color": "green",
"value": null
},
{
"color": "red",
"value": 259200
}
]
}
}
]
},
{
"matcher": {
"id": "byName",
"options": "images_outdated"
},
"properties": [
{
"id": "custom.cellOptions",
"value": {
"mode": "gradient",
"type": "color-background"
}
},
{
"id": "thresholds",
"value": {
"mode": "absolute",
"steps": [
{
"color": "green",
"value": null
},
{
"color": "red",
"value": 1
}
]
}
}
]
},
{
"matcher": {
"id": "byName",
"options": "images_error"
},
"properties": [
{
"id": "custom.cellOptions",
"value": {
"mode": "gradient",
"type": "color-background"
}
},
{
"id": "thresholds",
"value": {
"mode": "absolute",
"steps": [
{
"color": "green",
"value": null
},
{
"color": "red",
"value": 1
}
]
}
}
]
}
]
},
"gridPos": {
"h": 14,
"w": 24,
"x": 0,
"y": 0
},
"id": 2,
"options": {
"cellHeight": "sm",
"footer": {
"countRows": false,
"fields": "",
"reducer": [
"sum"
],
"show": false
},
"frameIndex": 1,
"showHeader": true,
"sortBy": []
},
"pluginVersion": "11.4.0",
"targets": [
{
"disableTextWrap": false,
"editorMode": "code",
"exemplar": false,
"expr": "sum by(instance) (dockcheck_images_analyzed)",
"format": "table",
"fullMetaSearch": false,
"hide": false,
"includeNullMetadata": true,
"instant": true,
"interval": "",
"legendFormat": "{{instance}}",
"range": false,
"refId": "dockcheck_images_analyzed",
"useBackend": false,
"datasource": {
"type": "prometheus",
"uid": "${DS_PROMETHEUS}"
}
},
{
"datasource": {
"type": "prometheus",
"uid": "${DS_PROMETHEUS}"
},
"disableTextWrap": false,
"editorMode": "code",
"exemplar": false,
"expr": "sum by(instance) (dockcheck_images_outdated)",
"format": "table",
"fullMetaSearch": false,
"hide": false,
"includeNullMetadata": true,
"instant": true,
"legendFormat": "{{instance}}",
"range": false,
"refId": "dockcheck_images_outdated",
"useBackend": false
},
{
"datasource": {
"type": "prometheus",
"uid": "${DS_PROMETHEUS}"
},
"disableTextWrap": false,
"editorMode": "code",
"exemplar": false,
"expr": "sum by(instance) (dockcheck_images_latest)",
"format": "table",
"fullMetaSearch": false,
"hide": false,
"includeNullMetadata": true,
"instant": true,
"legendFormat": "{{instance}}",
"range": false,
"refId": "dockcheck_images_latest",
"useBackend": false
},
{
"datasource": {
"type": "prometheus",
"uid": "${DS_PROMETHEUS}"
},
"editorMode": "code",
"exemplar": false,
"expr": "sum by(instance) (dockcheck_images_error)",
"format": "table",
"hide": false,
"instant": true,
"legendFormat": "{{instance}}",
"range": false,
"refId": "dockcheck_images_error"
},
{
"datasource": {
"type": "prometheus",
"uid": "${DS_PROMETHEUS}"
},
"editorMode": "code",
"exemplar": false,
"expr": "dockcheck_images_analyze_timestamp_seconds * 1000",
"format": "table",
"hide": false,
"instant": true,
"legendFormat": "{{instance}}",
"range": false,
"refId": "dockcheck_images_analyze_timestamp_seconds"
},
{
"datasource": {
"type": "prometheus",
"uid": "${DS_PROMETHEUS}"
},
"editorMode": "code",
"exemplar": false,
"expr": "time() - dockcheck_images_analyze_timestamp_seconds",
"format": "table",
"hide": false,
"instant": true,
"legendFormat": "{{instance}}",
"range": false,
"refId": "dockcheck_images_last_analyze"
}
],
"title": "Dockcheck Status",
"transformations": [
{
"id": "merge",
"options": {}
},
{
"id": "organize",
"options": {
"excludeByName": {
"Time": true,
"__name__": true,
"job": true
},
"includeByName": {},
"indexByName": {
"Time": 0,
"Value #dockcheck_images_analyze_timestamp_seconds": 2,
"Value #dockcheck_images_analyzed": 4,
"Value #dockcheck_images_error": 7,
"Value #dockcheck_images_last_analyze": 3,
"Value #dockcheck_images_latest": 5,
"Value #dockcheck_images_outdated": 6,
"instance": 1,
"job": 8
},
"renameByName": {
"Value #A": "analyze_timestamp",
"Value #dockcheck_images_analyze_timestamp_seconds": "last_analyze_timestamp",
"Value #dockcheck_images_analyzed": "images_analyzed",
"Value #dockcheck_images_error": "images_error",
"Value #dockcheck_images_last_analyze": "last_analyze_since",
"Value #dockcheck_images_latest": "images_latest",
"Value #dockcheck_images_outdated": "images_outdated"
}
}
}
],
"type": "table"
}
],
"schemaVersion": 40,
"tags": [],
"templating": {
"list": []
},
"time": {
"from": "now-6h",
"to": "now"
},
"timepicker": {},
"timezone": "browser",
"title": "Dockcheck Status",
"uid": "feb4pv3kv1hxca",
"version": 17,
"weekStart": ""
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 50 KiB

View File

@@ -0,0 +1,28 @@
prometheus_exporter() {
checkedImages=$(($1 + $2 + $3))
checkTimestamp=$(date +%s)
promFileContent=()
promFileContent+=("# HELP dockcheck_images_analyzed Docker images that have been analyzed")
promFileContent+=("# TYPE dockcheck_images_analyzed gauge")
promFileContent+=("dockcheck_images_analyzed $checkedImages")
promFileContent+=("# HELP dockcheck_images_outdated Docker images that are outdated")
promFileContent+=("# TYPE dockcheck_images_outdated gauge")
promFileContent+=("dockcheck_images_outdated ${#GotUpdates[@]}")
promFileContent+=("# HELP dockcheck_images_latest Docker images that are outdated")
promFileContent+=("# TYPE dockcheck_images_latest gauge")
promFileContent+=("dockcheck_images_latest ${#NoUpdates[@]}")
promFileContent+=("# HELP dockcheck_images_error Docker images with analysis errors")
promFileContent+=("# TYPE dockcheck_images_error gauge")
promFileContent+=("dockcheck_images_error ${#GotErrors[@]}")
promFileContent+=("# HELP dockcheck_images_analyze_timestamp_seconds Last dockercheck run time")
promFileContent+=("# TYPE dockcheck_images_analyze_timestamp_seconds gauge")
promFileContent+=("dockcheck_images_analyze_timestamp_seconds $checkTimestamp")
printf "%s\n" "${promFileContent[@]}" > "$CollectorTextFileDirectory/dockcheck_info.prom\$\$"
mv -f "$CollectorTextFileDirectory/dockcheck_info.prom\$\$" "$CollectorTextFileDirectory/dockcheck_info.prom"
}

View File

@@ -1,6 +1,6 @@
#!/usr/bin/env bash
VERSION="v0.5.3.0"
### ChangeNotes: Bugfixes - local image check changed, Gotify-template fixed
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"
@@ -20,6 +20,7 @@ Help() {
echo
echo "Options:"
echo "-a|y Automatic updates, without interaction."
echo "-c Exports metrics as prom file for the prometheus node_exporter. Provide the collector textfile directory."
echo "-d N Only update to new images that are N+ days old. Lists too recent with +prefix and age. 2xSlower."
echo "-e X Exclude containers, separated by comma."
echo "-f Force stack restart after update. Caution: restarts once for every updated container within stack."
@@ -47,9 +48,11 @@ c_reset="\033[0m"
Timeout=10
Stopped=""
while getopts "aynpfrhlisvme:d:t:" options; do
while getopts "aynpfrhlisvmc:e:d:t:" options; do
case "${options}" in
a|y) AutoUp="yes" ;;
c) CollectorTextFileDirectory="${OPTARG}"
if ! [[ -d $CollectorTextFileDirectory ]] ; then { printf "The directory (%s) does not exist.\n" "${CollectorTextFileDirectory}" ; exit 2; } fi ;;
n) AutoUp="no" ;;
r) DRunUp="yes" ;;
p) AutoPrune="yes" ;;
@@ -128,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
@@ -149,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
@@ -177,14 +181,14 @@ 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;;
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"
@@ -192,49 +196,49 @@ 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
}
# 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
(sudo $PkgInstaller jq) ; PkgExitcode="$?"
[[ "$PkgExitcode" == 0 ]] && jqbin="jq" || printf "\n%bPackagemanager install failed%b, falling back to static binary.\n" "$c_yellow" "$c_reset"
# 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="$?" && 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
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
if [[ "$GetJq" =~ [nN] || "$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; }
# 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
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
# 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" ;
@@ -310,6 +314,11 @@ NoUpdates=($(sort <<<"${NoUpdates[*]}"))
GotUpdates=($(sort <<<"${GotUpdates[*]}"))
unset IFS
# Run the prometheus exporter function
if [ -n "$CollectorTextFileDirectory" ] ; then
source "$ScriptWorkDir"/addons/prometheus/prometheus_collector.sh && prometheus_exporter ${#NoUpdates[@]} ${#GotUpdates[@]} ${#GotErrors[@]}
fi
# Define how many updates are available
UpdCount="${#GotUpdates[@]}"