Compare commits

...

109 Commits

Author SHA1 Message Date
mag37
3a8571c625 fixes for odd unbound variables 2025-03-31 11:23:21 +02:00
mag37
710cbc118f fix: Excludes unbound 2025-03-31 07:22:22 +02:00
mag37
68ec749c39 hotfixes 2025-03-30 22:58:47 +02:00
mag37
778df1de3c PkgInstaller bug, reformatted 2025-03-30 22:17:15 +02:00
mag37
8dd1bba75b Clean&refactor (#148)
* cleaning spaces and consistent formatting
* removed more subshells
* progress bar cleanup
* moved uservars to a .config file
* rewritten options from yes/no to true/false
* initialized default variables
* added bash options: -euo pipefail, shopt -s nullglob and failglob
* quoting variables, cleaning syntax, logic and order
* unquoted some variables due to breakage
* added exit on pull-fail
* added new sponsor
* added Slack template
2025-03-30 13:31:34 +02:00
mag37
b5c03a2caa Merge pull request #139 from devzwf/main
Update README.md
2025-03-18 05:38:59 +01:00
ZwF
9c4c79b885 Update README.md
Add the -x option to the readme...
2025-03-17 22:20:06 -04:00
mag37
d9fe113225 updated gif 2025-03-17 08:39:09 +01:00
mag37
0a9d60f4df Merge pull request #137 from mag37/notify_versioning
notify-template versioning
2025-03-16 20:56:11 +01:00
mag37
c57923f152 versionbump 2025-03-16 20:54:34 +01:00
mag37
fd1769c30f added versions + version checks to all templates 2025-03-16 20:47:46 +01:00
mag37
965f2dd825 first change to DSM 2025-03-14 20:36:07 +01:00
mag37
48057dfc66 notify and xargs info added
Added info about notifying on new dockcheck updates and a info block about async/xargs.
2025-03-09 10:19:22 +01:00
mag37
98e80854be Merge pull request #135 from mag37/dockcheck_upd_notify
rewrite of notify-templates
2025-03-09 10:00:57 +01:00
mag37
dcbdb5becd minor fixes 2025-03-09 09:57:45 +01:00
mag37
8fc4f41c49 version bump and change notes 2025-03-07 21:11:01 +01:00
mag37
9b0b6137a3 fixed typos 2025-03-07 21:05:58 +01:00
mag37
7ed4286fe7 merged updates from main 2025-03-07 20:47:43 +01:00
mag37
bf1e78d2ff hotfix changelog 2025-02-26 22:04:05 +01:00
mag37
9fa398e553 Merge pull request #132 from mag37/xargs_hotfix
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.
2025-02-26 21:42:58 +01:00
mag37
9ef2ea7135 versionbump + changenotes 2025-02-26 21:39:33 +01:00
mag37
8c3b899332 async hotfix, defaults to 1 subprocess, added -x option to set custom async value 2025-02-26 21:23:15 +01:00
mag37
8110cd8892 Update README.md 2025-02-25 21:30:41 +01:00
mag37
502a167919 Update README.md 2025-02-25 21:30:20 +01:00
mag37
61f90893ef async version bump 2025-02-24 22:12:11 +01:00
mag37
229cde0efb Updated README.md
Added changelog.
Added info about Docker Hub pull limit.
2025-02-24 22:03:20 +01:00
mag37
0c6674ac8e Merge pull request #128 from Thaurin/parallel_check
Add async checking for updates for improved performance
2025-02-24 21:59:30 +01:00
mag37
3e079e2ec5 Update dockcheck.sh
Added MaxAsync variable.
Added POSIX xargs check.
Rewrote Excludes.
2025-02-24 21:49:19 +01:00
Thaurin
b2d67c9f52 Removed experimental -z flag and old version check code 2025-02-21 17:57:09 +01:00
Thaurin
3aeee837f9 Print entire line on error 2025-02-21 17:54:19 +01:00
Thaurin
408a8b14dd Fix -d parameter not working anymore 2025-02-20 18:48:55 +01:00
Thaurin
a2868ea505 Add error message; increase number of subprocesses 2025-02-20 18:48:55 +01:00
Thaurin
62a3d10b4f Add async checking for updates for improved performance 2025-02-20 18:48:55 +01:00
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
06ea7fff6d newline and rephrasing 2025-02-15 13:35:47 +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
c436def448 typo 2025-02-13 21:34:03 +01:00
mag37
96ebe079a4 removed 'not source' message as its optional 2025-02-13 21:28:21 +01:00
mag37
111cb955b1 finalizing new notification structure 2025-02-10 19:46:23 +01:00
mag37
71967277aa new notification structure 2025-02-09 22:01:08 +01:00
mag37
1548b03a9e added else with inclusion of new function, rewrote 2 templates for testing 2025-02-07 20:47:01 +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
mag37
e6ff634394 versionbump 2025-01-28 21:55:35 +01:00
mag37
6444e18a4f Merge pull request #122 from mag37/5.3_fixes
local image check changed, Gotify-template fixed
2025-01-28 21:53:50 +01:00
mag37
14872b0471 local image check changed, Gotify-template fixed, version bump 2025-01-28 21:50:02 +01:00
mag37
07ad241e9f removed whale icon and changed redirection to still show errors 2025-01-28 21:08:20 +01:00
Thorsten Dralle
58d53d3aaf Added a node collector to export statistics to prometheus 2025-01-27 20:57:19 +01:00
mag37
15ce226a0a changed local image check to reference ID instead of image-name 2025-01-22 16:07:50 +01:00
mag37
cce5438aca Update notify_DSM.sh
Ensures DSM GUI refreshes its update-check.
TY @yoyoma2 for the fix.
2024-12-01 20:51:51 +01:00
mag37
be6f5edf52 Update README.md 2024-11-25 15:23:54 +01:00
mag37
99befd6938 hotfix to changenotes.
More important that it shows for older versions than being pretty.
2024-11-24 08:46:04 +01:00
mag37
8a63fd360c hotfix 2024-11-23 14:58:15 +01:00
mag37
d3786d6f75 hotfix 2024-11-23 14:57:39 +01:00
mag37
487cfb2822 typofix jq binary 2024-11-23 14:56:15 +01:00
mag37
b4943df46c Merge pull request #111 from mag37/dependency_download_rewrite
Dependency download rewrite + jq installer
2024-11-23 12:46:38 +01:00
mag37
8603c8d4b6 Merge branch 'main' into dependency_download_rewrite 2024-11-23 12:46:15 +01:00
mag37
ae66a6f0fd ChangeNote + finalizing fixes 2024-11-23 12:40:58 +01:00
mag37
3ac0521a9b Changenotes hotfix 2024-11-22 22:52:21 +01:00
mag37
00ae250511 versionbump + jq info 2024-11-22 15:11:49 +01:00
mag37
704387a7fe versionbump + jq info 2024-11-22 15:09:16 +01:00
mag37
1a6826e2ac versionbump + jq info 2024-11-22 15:08:44 +01:00
mag37
a28b9e555f Colorized error messages 2024-11-22 14:32:30 +01:00
mag37
8309b80dc2 cleaned old jq check + fixed some naming 2024-11-22 13:45:45 +01:00
mag37
bbe26a0ac2 changes to jq install logic
Will fall back to static binary if pkgmanager install fails
or no distribution matches.
2024-11-22 13:08:24 +01:00
mag37
d98d052af7 rewrote regctl-download to use new functions 2024-11-22 11:05:16 +01:00
mag37
fbba77dc1f jq downloading functions
Added distribution checker for packagemanager installs.
Added generic static binary downloader.
2024-11-22 11:00:45 +01:00
mag37
09c9faa008 Merge pull request #109 from mag37/feedback_podcheck
jq rewrite and formatting fixes
2024-11-20 08:39:30 +01:00
mag37
17ed46d157 Merge branch 'main' into feedback_podcheck 2024-11-20 08:38:49 +01:00
mag37
d744d51473 jq version bump 2024-11-18 21:13:44 +01:00
mag37
3821c22660 generalized variable name 2024-11-18 21:04:02 +01:00
mag37
5dd42b7336 changed to jq metadata check 2024-11-18 21:01:13 +01:00
mag37
8da2cbe611 Converted to jq metadata check.
Added jq binary check, fixed consistent command -v syntax.
2024-11-18 20:04:08 +01:00
mag37
9937d6bc3f minor readme updates 2024-11-17 20:43:22 +01:00
mag37
5517abb090 formatting to match improvements in podcheck fork 2024-11-17 14:54:28 +01:00
mag37
cb8c23e62d Update README.md
Added urls to podman fork
2024-11-16 20:39:51 +01:00
mag37
0009adc2cf Update urls.list
added vaultwarden-backup
2024-11-06 08:49:59 +01:00
mag37
8d39e1b66b new example-file 2024-10-21 20:51:23 +02:00
mag37
ec068dd19a Fixed typo. 2024-10-14 06:28:35 +02:00
mag37
119932aa19 Update README.md
added Discord to the notifications list.
2024-10-13 22:28:39 +02:00
mag37
a9f2433fab Merge pull request #104 from mag37/notify-rewrite
Complete rewrite of notify function, all templates adjusted + more.
2024-10-13 17:36:41 +02:00
mag37
18e467274e edited changenotes 2024-10-13 17:11:10 +02:00
mag37
6db92be627 getting ready for merge 2024-10-12 13:13:11 +02:00
mag37
fc47b1313b finalizing formatting and edits 2024-10-10 10:22:17 +02:00
mag37
76d2921719 fixed MSMTP-typo 2024-10-10 09:48:41 +02:00
mag37
2844e54fbd Merge pull request #102 from thomas-mc-work/patch-1
fix upgly typo which prevents email notifications
2024-10-08 22:05:53 +02:00
Thomas McWork
e0d66cc773 fix upgly typo which prevents email notifications 2024-10-08 21:57:23 +02:00
mag37
071fa4b245 changed regctl verbosity 2024-10-08 09:41:32 +02:00
mag37
cb73025a61 added discord template 2024-10-07 21:31:33 +02:00
mag37
87f1886d28 releasenotes rewritten to array 2024-10-07 21:29:49 +02:00
mag37
ac10a96cc8 all template rewritten, some guesswork 2024-10-07 21:28:31 +02:00
mag37
e5a7a715c6 Merge pull request #99 from lpukatch/release-note-urls
add release note urls
2024-10-05 21:26:31 +02:00
mag37
8a6a1fbec2 Update urls.list 2024-10-05 21:26:07 +02:00
lpukatch
04b0c46366 add release note urls for popular services 2024-10-05 09:36:06 -04:00
24 changed files with 1418 additions and 329 deletions

2
.gitignore vendored
View File

@@ -1,5 +1,7 @@
# ignore users custom notify.sh
/notify.sh
/urls.list
# ignore user config
/dockcheck.config
# ignore the auto-installed regctl
regctl

View File

@@ -10,19 +10,33 @@
<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>
<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>
<h4 align="center">:whale: Docker Hub pull limit :chart_with_downwards_trend: not an issue for checks but for actual pulls - <a href="#whale-docker-hub-pull-limit-chart_with_downwards_trend-not-an-issue-for-checks-but-for-actual-pulls">read more</a></h4>
___
## :bell: Changelog
- **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)
- **v0.4.8**: Rewrote prune logic to not prompt with options `-a|-y` or `-n`. Auto prune with `-p`.
- **v0.4.7**: Notification Template changes to gotify(new!), DSM(improved), SMTP(deprecation alternative).
- **v0.4.6**: Compatibility changes to timeout, due to busybox.
- **v0.4.5**: Bugfixes, compatibility changes to timeout and arrays.
- **v0.4.3**: Added timeout option to skip container if registry check takes too long (10s default).
- **v0.6.1**: Hotfixes: (try removing set+shopt+shopt if debugging more errors)
- xargs/pipefail, removed `-set -e` bash option for now.
- unbound variables fixed (hopefully)
- dependency installer from pkgmanager rewritten
- **v0.6.0**: Refactored a lot of code, cleaner logic and syntax, safer variables.
- Safer bash options with `set -euo pipefail`, `shopt -s nullglob` and `failglob`.
- Added a `default.conf` for user settings - persistent through updates.
- Added `notify_slack.sh` template for slack curl api.
- **v0.5.8**: Added version checks to all templates and a notification if a new template is released.
- **v0.5.7**: Rewritten templates - now with a function to notify when there's a new Dockcheck release.
- Manually migrate your current `notify.sh` settings to a new template for new functionality.
- **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.
___
@@ -34,8 +48,9 @@ $ ./dockcheck.sh -h
Syntax: dockcheck.sh [OPTION] [part of name to filter]
Example: dockcheck.sh -y -d 10 -e nextcloud,heimdall
Options:"
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.
@@ -47,11 +62,11 @@ Options:"
-p Auto-Prune dangling images after update.
-r Allow updating images for docker run, wont update the container.
-s Include stopped containers in the check. (Logic: docker ps -a).
-t Set a timeout (in seconds) per container for registry checkups, 10 is default.
-t N Set a timeout (in seconds) per container for registry checkups, 10 is default.
-v Prints current version.
-x N Set max asynchronous subprocesses, 1 default, 0 to disable, 32+ tested.
```
### Basic example:
```
$ ./dockcheck.sh
@@ -68,20 +83,24 @@ Containers with updates available:
Choose what containers to update:
Enter number(s) separated by comma, [a] for all - [q] to quit:
```
Then it proceedes to run `pull` and `up -d` on every container with updates.
Then it proceeds to run `pull` and `up -d` on every container with updates.
After the updates are complete, you'll get prompted if you'd like to prune dangling images.
___
## :nut_and_bolt: Dependencies
- Running docker (duh) and compose, either standalone or plugin.
- 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))
- 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**.
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
@@ -89,14 +108,22 @@ 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.
## :handbag: Configuration
To modify settings and have them persist through updates - copy the `default.config` to `dockcheck.config` alongside the script or in `~/.config/`.
Alternatively create an alias where specific flags and values are set.
Example `alias dc=dockcheck.sh -p -x 10 -t 3`.
## :loudspeaker: Notifications
Trigger with the `-i` flag.
Run it scheduled with `-ni` to only get notified when there's updates available!
Will also send a notification when `dockcheck.sh` itself has an update.
Use a `notify_X.sh` template file from the **notify_templates** directory, copy it to `notify.sh` alongside the script, modify it to your needs! (notify.sh is added to .gitignore)
**Current templates:**
@@ -111,13 +138,15 @@ Use a `notify_X.sh` template file from the **notify_templates** directory, copy
- [Telegram](https://telegram.org/) - Telegram chat API.
- [Matrix-Synapse](https://github.com/element-hq/synapse) - [Matrix](https://matrix.org/), open, secure, decentralised communication.
- [Pushover](https://pushover.net/) - Simple Notifications (to your phone, wearables, desktops)
- [Discord](https://support.discord.com/hc/en-us/articles/228383668-Intro-to-Webhooks) - Discord webhooks.
- [Slack](https://api.slack.com/tutorials/tracks/posting-messages-with-curl) - Slack curl api
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 and modify it as necessary, it will be used automatically if it's there.
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:
@@ -128,6 +157,22 @@ 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.
## :fast_forward: Asyncronous update checks with **xargs**; `-x N` option. (default=1)
Pass `-x N` where N is number of subprocesses allowed, experiment in your environment to find a suitable max!
Change the default value by editing the `MaxAsync=N` variable in `dockcheck.sh`. To disable the subprocess function set `MaxAsync=0`.
## :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:
```
@@ -158,7 +203,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 {
@@ -188,8 +241,8 @@ dockcheck is created and released under the [GNU GPL v3.0](https://www.gnu.org/l
## :heartpulse: Sponsorlist
- [avegy](https://github.com/avegy)
- [eichhorn](https://github.com/eichhorn)
___
### :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"
}

20
default.config Normal file
View File

@@ -0,0 +1,20 @@
### Custom user variables
# Copy this file to "dockcheck.config" to make it active
# Can be placed in ~/.config/ or alongside dockcheck.sh
#
# Uncomment and set your preferred configuration variables here
# This will not be replaced on updates
#Timeout=10 # Set a timeout (in seconds) per container for registry checkups.
#MaxAsync=1 # Set max asynchronous subprocesses, 1 default, 0 to disable.
#BarWidth=50 # The character width of the progress bar
#AutoMode=true # Automatic updates, without interaction.
#DontUpdate=true # No updates; only checking availability without interaction.
#AutoPrune=false # Auto-Prune dangling images after update.
#Notify=false # Inform - send a preconfigured notification.
#Exclude="one,two" # Exclude containers, separated by comma.
#DaysOld="5" # Only update to new images that are N+ days old. Lists too recent with +prefix and age. 2xSlower.
#Stopped="-a" # Include stopped containers in the check. (Logic: docker ps -a).
#OnlyLabel=false # Only update if label is set. See readme.
#ForceRestartStacks=false # Force stack restart after update. Caution.
#DRunUp=false # Allow updating images for docker run, wont update the container.

View File

@@ -1,43 +1,79 @@
#!/usr/bin/env bash
VERSION="v0.4.9"
### ChangeNotes: Added a function to enrich the notify-message with release note URLs. See README.
VERSION="v0.6.1"
### ChangeNotes: Hotfix - bug with xargs pipefail, pkgmanager logic, unbound variables
Github="https://github.com/mag37/dockcheck"
RawUrl="https://raw.githubusercontent.com/mag37/dockcheck/main/dockcheck.sh"
### Variables for self updating
set -uo pipefail
shopt -s nullglob
shopt -s failglob
# Variables for self updating
ScriptArgs=( "$@" )
ScriptPath="$(readlink -f "$0")"
ScriptWorkDir="$(dirname "$ScriptPath")"
### Check if there's a new release of the script:
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")"
# Check if there's a new release of the script
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")"
### Help Function:
# User customizable defaults
if [[ -s "${HOME}/.config/dockcheck.config" ]]; then
source "${HOME}/.config/dockcheck.config"
elif [[ -s "${ScriptWorkDir}/dockcheck.config" ]]; then
source "${ScriptWorkDir}/dockcheck.config"
fi
# Help Function
Help() {
echo "Syntax: dockcheck.sh [OPTION] [part of name to filter]"
echo "Example: dockcheck.sh -y -d 10 -e nextcloud,heimdall"
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."
echo "-h Print this Help."
echo "-i Inform - send a preconfigured notification."
echo "-l Only update if label is set. See readme."
echo "-m Monochrome mode, no printf color codes."
echo "-n No updates, only checking availability."
echo "-p Auto-Prune dangling images after update."
echo "-r Allow updating images for docker run, wont update the container."
echo "-m Monochrome mode, no printf colour codes."
echo "-n No updates; only checking availability without interaction."
echo "-p Auto-prune dangling images after update."
echo "-r Allow updating images for docker run; won't update the container."
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"
}
### Colors:
# Initialise variables
Timeout=${Timeout:=10}
MaxAsync=${MaxAsync:=1}
BarWidth=${BarWidth:=50}
AutoMode=${AutoMode:=false}
DontUpdate=${DontUpdate:=false}
AutoPrune=${AutoPrune:=false}
OnlyLabel=${OnlyLabel:=false}
Notify=${Notify:=false}
ForceRestartStacks=${ForceRestartStacks:=false}
DRunUp=${DRunUp:=false}
Stopped=${Stopped:=""}
CollectorTextFileDirectory=${CollectorTextFileDirectory:-}
Exclude=${Exclude:-}
DaysOld=${DaysOld:-}
Excludes=()
GotUpdates=()
NoUpdates=()
GotErrors=()
SelectedUpdates=()
regbin=""
jqbin=""
# Colours
c_red="\033[0;31m"
c_green="\033[0;32m"
c_yellow="\033[0;33m"
@@ -45,75 +81,103 @@ c_blue="\033[0;34m"
c_teal="\033[0;36m"
c_reset="\033[0m"
Timeout=10
Stopped=""
while getopts "aynpfrhlisvme:d:t:" options; do
while getopts "aynpfrhlisvmc:e:d:t:x:" options; do
case "${options}" in
a|y) AutoUp="yes" ;;
n) AutoUp="no" ;;
r) DRunUp="yes" ;;
p) AutoPrune="yes" ;;
a|y) AutoMode=true ;;
c) CollectorTextFileDirectory="${OPTARG}" ;;
n) DontUpdate=true; AutoMode=true;;
r) DRunUp=true ;;
p) AutoPrune=true ;;
l) OnlyLabel=true ;;
f) ForceRestartStacks=true ;;
i) [ -s "$ScriptWorkDir"/notify.sh ] && { source "$ScriptWorkDir"/notify.sh ; Notify="yes" ; } ;;
i) Notify=true ;;
e) Exclude=${OPTARG} ;;
m) declare c_{red,green,yellow,blue,teal,reset}="" ;;
s) Stopped="-a" ;;
t) Timeout="${OPTARG}" ;;
v) printf "%s\n" "$VERSION" ; exit 0 ;;
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 ;;
v) printf "%s\n" "$VERSION"; exit 0 ;;
x) MaxAsync=${OPTARG} ;;
d) DaysOld=${OPTARG} ;;
h|*) Help; exit 2 ;;
esac
done
shift "$((OPTIND-1))"
# Set $1 to a variable for name filtering later
SearchName="${1:-}"
# Setting up options and sourcing functions
if [[ "$DontUpdate" == true ]]; then AutoMode=true; fi
if [[ "$Notify" == true ]]; then
if [[ -s "${ScriptWorkDir}/notify.sh" ]]; then
source "${ScriptWorkDir}/notify.sh"
else Notify=false
fi
fi
if [[ -n "$Exclude" ]]; then
IFS=',' read -ra Excludes <<< "$Exclude"
unset IFS
fi
if [[ -n "$DaysOld" ]]; then
if ! [[ $DaysOld =~ ^[0-9]+$ ]]; then
printf "Days -d argument given (%s) is not a number.\n" "$DaysOld"
exit 2
fi
fi
if [[ -n "$CollectorTextFileDirectory" ]]; then
if ! [[ -d $CollectorTextFileDirectory ]]; then
printf "The directory (%s) does not exist.\n" "$CollectorTextFileDirectory"
exit 2
else
source "${ScriptWorkDir}/addons/prometheus/prometheus_collector.sh"
fi
fi
self_update_curl() {
cp "$ScriptPath" "$ScriptPath".bak
if [[ $(builtin type -P curl) ]]; then
curl -L $RawUrl > "$ScriptPath" ; chmod +x "$ScriptPath"
if command -v curl &>/dev/null; then
curl -L $RawUrl > "$ScriptPath"; chmod +x "$ScriptPath"
printf "\n%s\n" "--- starting over with the updated version ---"
exec "$ScriptPath" "${ScriptArgs[@]}" # run the new script with old arguments
exit 1 # exit the old instance
elif [[ $(builtin type -P wget) ]]; then
wget $RawUrl -O "$ScriptPath" ; chmod +x "$ScriptPath"
exit 1 # Exit the old instance
elif command -v wget &>/dev/null; then
wget $RawUrl -O "$ScriptPath"; chmod +x "$ScriptPath"
printf "\n%s\n" "--- starting over with the updated version ---"
exec "$ScriptPath" "${ScriptArgs[@]}" # run the new script with old arguments
exit 1 # exit the old instance
exit 0 # exit the old instance
else
printf "curl/wget not available - download the update manually: %s \n" "$Github"
fi
}
self_update() {
cd "$ScriptWorkDir" || { printf "Path error, skipping update.\n" ; return ; }
if [[ $(builtin type -P git) ]] && [[ "$(git ls-remote --get-url 2>/dev/null)" =~ .*"mag37/dockcheck".* ]] ; then
cd "$ScriptWorkDir" || { printf "Path error, skipping update.\n"; return; }
if command -v git &>/dev/null && [[ "$(git ls-remote --get-url 2>/dev/null)" =~ .*"mag37/dockcheck".* ]]; then
printf "\n%s\n" "Pulling the latest version."
git pull --force || { printf "Git error, manually pull/clone.\n" ; return ; }
git pull --force || { printf "Git error, manually pull/clone.\n"; return; }
printf "\n%s\n" "--- starting over with the updated version ---"
cd - || { printf "Path error.\n" ; return ; }
cd - || { printf "Path error.\n"; return; }
exec "$ScriptPath" "${ScriptArgs[@]}" # run the new script with old arguments
exit 1 # exit the old instance
exit 0 # exit the old instance
else
cd - || { printf "Path error.\n" ; return ; }
cd - || { printf "Path error.\n"; return; }
self_update_curl
fi
}
### Choose from list -function:
choosecontainers() {
while [[ -z "$ChoiceClean" ]]; do
while [[ -z "${ChoiceClean:-}" ]]; do
read -r -p "Enter number(s) separated by comma, [a] for all - [q] to quit: " Choice
if [[ "$Choice" =~ [qQnN] ]] ; then
if [[ "$Choice" =~ [qQnN] ]]; then
exit 0
elif [[ "$Choice" =~ [aAyY] ]] ; then
elif [[ "$Choice" =~ [aAyY] ]]; then
SelectedUpdates=( "${GotUpdates[@]}" )
ChoiceClean=${Choice//[,.:;]/ }
else
ChoiceClean=${Choice//[,.:;]/ }
for CC in $ChoiceClean ; do
if [[ "$CC" -lt 1 || "$CC" -gt $UpdCount ]] ; then # reset choice if out of bounds
echo "Number not in list: $CC" ; unset ChoiceClean ; break 1
for CC in $ChoiceClean; do
if [[ "$CC" -lt 1 || "$CC" -gt $UpdCount ]]; then # Reset choice if out of bounds
echo "Number not in list: $CC"; unset ChoiceClean; break 1
else
SelectedUpdates+=( "${GotUpdates[$CC-1]}" )
fi
@@ -126,9 +190,10 @@ choosecontainers() {
}
datecheck() {
ImageDate=$($regbin image inspect "$RepoUrl" --format='{{.Created}}' | cut -d" " -f1 )
ImageAge=$(( ( $(date +%s) - $(date -d "$ImageDate" +%s) )/86400 ))
if [ "$ImageAge" -gt "$DaysOld" ] ; then
ImageDate=$("$regbin" -v error image inspect "$RepoUrl" --format='{{.Created}}' | cut -d" " -f1)
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
return 1
@@ -138,70 +203,121 @@ datecheck() {
progress_bar() {
QueCurrent="$1"
QueTotal="$2"
BarWidth=${BarWidth:-50}
((Percent=100*QueCurrent/QueTotal))
((Complete=50*Percent/100)) # change first number for width (50)
((Left=50-Complete)) # change first number for width (50)
((Complete=BarWidth*Percent/100))
((Left=BarWidth-Complete)) || true # to not throw error when result is 0
BarComplete=$(printf "%${Complete}s" | tr " " "#")
BarLeft=$(printf "%${Left}s" | tr " " "-")
[[ "$QueTotal" == "$QueCurrent" ]] || printf "\r[%s%s] %s/%s " "$BarComplete" "$BarLeft" "$QueCurrent" "$QueTotal"
[[ "$QueTotal" == "$QueCurrent" ]] && printf "\r[%b%s%b] %s/%s \n" "$c_teal" "$BarComplete" "$c_reset" "$QueCurrent" "$QueTotal"
if [[ "$QueTotal" != "$QueCurrent" ]]; then
printf "\r[%s%s] %s/%s " "$BarComplete" "$BarLeft" "$QueCurrent" "$QueTotal"
else
printf "\r[%b%s%b] %s/%s \n" "$c_teal" "$BarComplete" "$c_reset" "$QueCurrent" "$QueTotal"
fi
}
### Function to add user-provided urls to releasenotes
# Function to add user-provided urls to releasenotes
releasenotes() {
for update in ${Updates[@]}; do
for update in "${GotUpdates[@]}"; do
found=false
while read -r container url; do
[[ $update == $container ]] && printf "%s -> %s\n" "$update" "$url" && found=true
done < "$ScriptWorkDir"/urls.list
[[ $found == false ]] && printf "%s -> url missing\n" "$update" || continue
if [[ "$update" == "$container" ]]; then Updates+=("$update -> $url"); found=true; fi
done < "${ScriptWorkDir}/urls.list"
if [[ "$found" == false ]]; then Updates+=("$update -> url missing"); else continue; fi
done
}
### Version check & initiate self update
if [[ "$VERSION" != "$LatestRelease" ]] ; then
# Static binary downloader for dependencies
binary_downloader() {
BinaryName="$1"
BinaryUrl="$2"
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 &>/dev/null; then curl -L "$GetUrl" > "$ScriptWorkDir/$BinaryName";
elif command -v wget &>/dev/null; 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"
}
distro_checker() {
if [[ -f /etc/arch-release ]]; then PkgInstaller="pacman -S"
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 + installer function
dependency_check() {
AppName="$1"
AppVar="$2"
AppUrl="$3"
if command -v "$AppName" &>/dev/null; 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"
if $PkgInstaller "$AppName"; then
AppName="$1"
export "$AppVar"="$AppName"
printf "\n%b%b installed.%b\n" "$c_green" "$AppName" "$c_reset"
else
PkgExitcode="ERROR"
printf "\n%bPackagemanager install failed%b, falling back to static binary.\n" "$c_yellow" "$c_reset"
fi
fi
if [[ "$GetBin" =~ [sS] || "$PkgInstaller" == "ERROR" ]]; then
binary_downloader "$AppName" "$AppUrl"
[[ -f "$ScriptWorkDir/$AppName" ]] && { export "$AppVar"="$ScriptWorkDir/$1" && printf "\n%b%b downloaded.%b\n" "$c_green" "$AppName" "$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; }
}
# Numbered List function
options() {
num=1
for i in "${GotUpdates[@]}"; do
echo "$num) $i"
((num++))
done
}
# Version check & initiate self update
if [[ "$VERSION" != "$LatestRelease" ]]; then
printf "New version available! %b%s%b ⇒ %b%s%b \n Change Notes: %s \n" "$c_yellow" "$VERSION" "$c_reset" "$c_green" "$LatestRelease" "$c_reset" "$LatestChanges"
if [[ -z "$AutoUp" ]] ; then
if [[ "$AutoMode" == false ]]; then
read -r -p "Would you like to update? y/[n]: " SelfUpdate
[[ "$SelfUpdate" =~ [yY] ]] && self_update
fi
fi
### Set $1 to a variable for name filtering later.
SearchName="$1"
### Create array of excludes
IFS=',' read -r -a Excludes <<< "$Exclude" ; unset IFS
### Check if required binary exists in PATH or directory:
if [[ $(builtin type -P "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] " GetDep
if [[ "$GetDep" =~ [yY] ]] ; then
### Check arch:
case "$(uname --machine)" in
x86_64|amd64) architecture="amd64" ;;
arm64|aarch64) architecture="arm64";;
*) echo "Architecture not supported, exiting." ; exit 1;;
esac
RegUrl="https://github.com/regclient/regclient/releases/latest/download/regctl-linux-$architecture"
if [[ $(builtin type -P curl) ]]; then curl -L $RegUrl > "$ScriptWorkDir/regctl" ; chmod +x "$ScriptWorkDir/regctl" ; regbin="$ScriptWorkDir/regctl" ;
elif [[ $(builtin type -P wget) ]]; then wget $RegUrl -O "$ScriptWorkDir/regctl" ; chmod +x "$ScriptWorkDir/regctl" ; regbin="$ScriptWorkDir/regctl" ;
else
printf "%s\n" "curl/wget not available - get regctl manually from the repo link, quitting."
fi
else
printf "%s\n" "Dependency missing, quitting."
exit 1
[[ "$Notify" == true ]] && { [[ $(type -t dockcheck_notification) == function ]] && dockcheck_notification "$VERSION" "$LatestRelease" "$LatestChanges" || printf "Could not source notification function.\n"; }
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; }
### Check docker compose binary:
if docker compose version &> /dev/null ; then DockerBin="docker compose" ;
elif docker-compose -v &> /dev/null; then DockerBin="docker-compose" ;
elif docker -v &> /dev/null; then
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" ;
elif docker-compose -v &>/dev/null; then DockerBin="docker-compose" ;
elif docker -v &>/dev/null; then
printf "%s\n" "No docker compose binary available, using plain docker (Not recommended!)"
printf "%s\n" "'docker run' will ONLY update images, not the container itself."
else
@@ -209,30 +325,21 @@ else
exit 1
fi
### Numbered List -function:
options() {
num=1
for i in "${GotUpdates[@]}"; do
echo "$num) $i"
((num++))
done
}
### Listing typed exclusions:
if [[ -n ${Excludes[*]} ]] ; then
# Listing typed exclusions
if [[ -n ${Excludes[*]:-} ]]; then
printf "\n%bExcluding these names:%b\n" "$c_blue" "$c_reset"
printf "%s\n" "${Excludes[@]}"
printf "\n"
fi
# Variables for progress_bar function
DocCount=$(docker ps $Stopped --filter "name=$SearchName" --format '{{.Names}}' | wc -l)
ContCount=$(docker ps $Stopped --filter "name=$SearchName" --format '{{.Names}}' | wc -l)
RegCheckQue=0
### Testing and setting timeout binary
t_out=$(type -P "timeout")
# Testing and setting timeout binary
t_out=$(command -v timeout || echo "")
if [[ $t_out ]]; then
t_out=$(realpath $t_out 2>/dev/null || readlink -f $t_out)
t_out=$(realpath "$t_out" 2>/dev/null || readlink -f "$t_out")
if [[ $t_out =~ "busybox" ]]; then
t_out="timeout ${Timeout}"
else t_out="timeout --foreground ${Timeout}"
@@ -240,81 +347,138 @@ 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" "$DocCount"
### Looping every item over the list of excluded names and skipping:
for e in "${Excludes[@]}" ; do [[ "$i" == "$e" ]] && continue 2 ; done
check_image() {
i="$1"
local Excludes=($Excludes_string)
for e in "${Excludes[@]}"; do
if [[ "$i" == "$e" ]]; then
printf "%s\n" "Skip $i"
return
fi
done
local NoUpdates GotUpdates GotErrors
ImageId=$(docker inspect "$i" --format='{{.Image}}')
RepoUrl=$(docker inspect "$i" --format='{{.Config.Image}}')
LocalHash=$(docker image inspect "$RepoUrl" --format '{{.RepoDigests}}')
# Checking for errors while setting the variable:
if RegHash=$(${t_out} $regbin image digest --list "$RepoUrl" 2>&1) ; then
if [[ "$LocalHash" = *"$RegHash"* ]] ; then
NoUpdates+=("$i")
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
printf "%s\n" "NoUpdates $i"
else
if [[ -n "$DaysOld" ]] && ! datecheck ; then
NoUpdates+=("+$i ${ImageAge}d")
if [[ -n "${DaysOld:-}" ]] && ! datecheck; then
printf "%s\n" "NoUpdates +$i ${ImageAge}d"
else
GotUpdates+=("$i")
printf "%s\n" "GotUpdates $i"
fi
fi
else
# Here the RegHash is the result of an error code.
GotErrors+=("$i - ${RegHash}")
printf "%s\n" "GotErrors $i - ${RegHash}" # Reghash contains an error code here
fi
done
}
### Sort arrays alphabetically
# 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
# Check for POSIX xargs with -P option, fallback without async
if (echo "test" | xargs -P 2 >/dev/null 2>&1) && [[ "$MaxAsync" != 0 ]]; then
XargsAsync="-P $MaxAsync"
else
XargsAsync=""
[[ "$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
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) ;;
*) echo "Error! Unexpected output from subprocess: ${line}" ;;
esac
done < <( \
docker ps $Stopped --filter "name=$SearchName" --format '{{.Names}}' | \
xargs $XargsAsync -I {} bash -c 'check_image "{}"' \
)
# Sort arrays alphabetically
IFS=$'\n'
NoUpdates=($(sort <<<"${NoUpdates[*]}"))
GotUpdates=($(sort <<<"${GotUpdates[*]}"))
NoUpdates=($(sort <<<"${NoUpdates[*]:-}"))
GotUpdates=($(sort <<<"${GotUpdates[*]:-}"))
unset IFS
### Define how many updates are available
# Run the prometheus exporter function
if [[ -n "${CollectorTextFileDirectory:-}" ]]; then
if type -t send_notification &>/dev/null; then
prometheus_exporter ${#NoUpdates[@]:-} ${#GotUpdates[@]:-} ${#GotErrors[@]:-}
else
printf "%s\n" "Could not source prometheus exporter function."
fi
fi
# Define how many updates are available
UpdCount="${#GotUpdates[@]}"
### List what containers got updates or not
if [[ -n ${NoUpdates[*]} ]] ; then
# List what containers got updates or not
if [[ -n ${NoUpdates[*]:-} ]]; then
printf "\n%bContainers on latest version:%b\n" "$c_green" "$c_reset"
printf "%s\n" "${NoUpdates[@]}"
fi
if [[ -n ${GotErrors[*]} ]] ; then
printf "\n%bContainers with errors, wont get updated:%b\n" "$c_red" "$c_reset"
if [[ -n ${GotErrors[*]:-} ]]; then
printf "\n%bContainers with errors, won't get updated:%b\n" "$c_red" "$c_reset"
printf "%s\n" "${GotErrors[@]}"
printf "%binfo:%b 'unauthorized' often means not found in a public registry.\n" "$c_blue" "$c_reset"
fi
if [[ -n ${GotUpdates[*]} ]] ; then
if [[ -n ${GotUpdates[*]:-} ]]; then
printf "\n%bContainers with updates available:%b\n" "$c_yellow" "$c_reset"
[[ -z "$AutoUp" ]] && options || printf "%s\n" "${GotUpdates[@]}"
[[ -n "$Notify" ]] && { [[ $(type -t send_notification) == function ]] && send_notification "${GotUpdates[@]}" || printf "Could not source notification function.\n" ; }
[[ "$AutoMode" == false ]] && options || printf "%s\n" "${GotUpdates[@]}"
[[ "$Notify" == true ]] && { type -t send_notification &>/dev/null && send_notification "${GotUpdates[@]}" || printf "Could not source notification function.\n"; }
fi
### Optionally get updates if there's any
if [ -n "$GotUpdates" ] ; then
if [ -z "$AutoUp" ] ; then
printf "\n%bChoose what containers to update.%b\n" "$c_teal" "$c_reset"
choosecontainers
# Optionally get updates if there's any
if [[ -n "${GotUpdates:-}" ]]; then
if [[ "$AutoMode" == false ]]; then
printf "\n%bChoose what containers to update.%b\n" "$c_teal" "$c_reset"
choosecontainers
else
SelectedUpdates=( "${GotUpdates[@]}" )
fi
if [ "$AutoUp" == "${AutoUp#[Nn]}" ] ; then
if [[ "$DontUpdate" == false ]]; then
NumberofUpdates="${#SelectedUpdates[@]}"
CurrentQue=0
for i in "${SelectedUpdates[@]}"
do
((CurrentQue+=1))
unset CompleteConfs
ContPath=$(docker inspect "$i" --format '{{ index .Config.Labels "com.docker.compose.project.working_dir" }}')
ContConfigFile=$(docker inspect "$i" --format '{{ index .Config.Labels "com.docker.compose.project.config_files" }}')
ContName=$(docker inspect "$i" --format '{{ index .Config.Labels "com.docker.compose.service" }}')
ContEnv=$(docker inspect "$i" --format '{{index .Config.Labels "com.docker.compose.project.environment_file" }}')
# Extract labels and metadata
ContLabels=$(docker inspect "$i" --format '{{json .Config.Labels}}')
ContImage=$(docker inspect "$i" --format='{{.Config.Image}}')
ContUpdateLabel=$(docker inspect "$i" --format '{{ index .Config.Labels "mag37.dockcheck.update" }}')
ContRestartStack=$(docker inspect "$i" --format '{{ index .Config.Labels "mag37.dockcheck.restart-stack" }}')
### Checking if compose-values are empty - hence started with docker run:
if [ -z "$ContPath" ] ; then
if [ "$DRunUp" == "yes" ] ; then
ContPath=$($jqbin -r '."com.docker.compose.project.working_dir"' <<< "$ContLabels")
[[ "$ContPath" == "null" ]] && ContPath=""
ContConfigFile=$($jqbin -r '."com.docker.compose.project.config_files"' <<< "$ContLabels")
[[ "$ContConfigFile" == "null" ]] && ContConfigFile=""
ContName=$($jqbin -r '."com.docker.compose.service"' <<< "$ContLabels")
[[ "$ContName" == "null" ]] && ContName=""
ContEnv=$($jqbin -r '."com.docker.compose.project.environment_file"' <<< "$ContLabels")
[[ "$ContEnv" == "null" ]] && ContEnv=""
ContUpdateLabel=$($jqbin -r '."mag37.dockcheck.update"' <<< "$ContLabels")
[[ "$ContUpdateLabel" == "null" ]] && ContUpdateLabel=""
ContRestartStack=$($jqbin -r '."mag37.dockcheck.restart-stack"' <<< "$ContLabels")
[[ "$ContRestartStack" == "null" ]] && ContRestartStack=""
# Checking if compose-values are empty - hence started with docker run
if [[ -z "$ContPath" ]]; then
if [[ "$DRunUp" == true ]]; then
docker pull "$ContImage"
printf "%s\n" "$i got a new image downloaded, rebuild manually with preferred 'docker run'-parameters"
else
@@ -322,30 +486,31 @@ if [ -n "$GotUpdates" ] ; then
fi
continue
fi
### cd to the compose-file directory to account for people who use relative volumes, eg - ${PWD}/data:data
cd "$ContPath" || { echo "Path error - skipping $i" ; continue ; }
# cd to the compose-file directory to account for people who use relative volumes
cd "$ContPath" || { echo "Path error - skipping $i"; continue; }
## Reformatting path + multi compose
if [[ $ContConfigFile = '/'* ]] ; then
CompleteConfs=$(for conf in ${ContConfigFile//,/ } ; do printf -- "-f %s " "$conf"; done)
if [[ $ContConfigFile = '/'* ]]; then
CompleteConfs=$(for conf in ${ContConfigFile//,/ }; do printf -- "-f %s " "$conf"; done)
else
CompleteConfs=$(for conf in ${ContConfigFile//,/ } ; do printf -- "-f %s/%s " "$ContPath" "$conf"; done)
CompleteConfs=$(for conf in ${ContConfigFile//,/ }; do printf -- "-f %s/%s " "$ContPath" "$conf"; done)
fi
printf "\n%bNow updating (%s/%s): %b%s%b\n" "$c_teal" "$CurrentQue" "$NumberofUpdates" "$c_blue" "$i" "$c_reset"
### Checking if Label Only -option is set, and if container got the label
[[ "$OnlyLabel" == true ]] && { [[ "$ContUpdateLabel" != true ]] && { echo "No update label, skipping." ; continue ; } }
docker pull "$ContImage"
### Check if the container got an environment file set and reformat it
if [ -n "$ContEnv" ]; then ContEnvs=$(for env in ${ContEnv//,/ } ; do printf -- "--env-file %s " "$env"; done) ; fi
### Check if the whole stack should be restarted
if [[ "$ContRestartStack" == true ]] || [[ "$ForceRestartStacks" == true ]] ; then
$DockerBin ${CompleteConfs} stop ; $DockerBin ${CompleteConfs} ${ContEnvs} up -d
# Checking if Label Only -option is set, and if container got the label
[[ "$OnlyLabel" == true ]] && { [[ "$ContUpdateLabel" != true ]] && { echo "No update label, skipping."; continue; } }
docker pull "$ContImage" || { printf "\n%bDocker error, exiting!%b\n" "$c_red" "$c_reset" ; exit 1; }
# Check if the container got an environment file set and reformat it
ContEnvs=""
if [[ -n "$ContEnv" ]]; then ContEnvs=$(for env in ${ContEnv//,/ }; do printf -- "--env-file %s " "$env"; done); fi
# Check if the whole stack should be restarted
if [[ "$ContRestartStack" == true ]] || [[ "$ForceRestartStacks" == true ]]; then
${DockerBin} ${CompleteConfs} stop; ${DockerBin} ${CompleteConfs} ${ContEnvs} up -d
else
$DockerBin ${CompleteConfs} ${ContEnvs} up -d ${ContName}
${DockerBin} ${CompleteConfs} ${ContEnvs} up -d ${ContName}
fi
done
printf "\n%bAll done!%b\n" "$c_green" "$c_reset"
if [[ -z "$AutoPrune" ]] && [[ -z "$AutoUp" ]]; then read -r -p "Would you like to prune dangling images? y/[n]: " AutoPrune ; fi
[[ "$AutoPrune" =~ [yY] ]] && docker image prune -f
if [[ "$AutoPrune" == false ]] && [[ "$AutoMode" == false ]]; then read -r -p "Would you like to prune dangling images? y/[n]: " AutoPrune; fi
if [[ "$AutoPrune" == true ]] || [[ "$AutoPrune" =~ [yY] ]]; then docker image prune -f; fi
else
printf "\nNo updates installed, exiting.\n"
fi

View File

@@ -2,12 +2,21 @@
SearchName="$1"
for i in $(docker ps --filter "name=$SearchName" --format '{{.Names}}') ; do
echo "------------ $i ------------"
ContPath=$(docker inspect "$i" --format '{{ index .Config.Labels "com.docker.compose.project.working_dir" }}')
[ -z "$ContPath" ] && { "$i has no compose labels - skipping" ; continue ; }
ContConfigFile=$(docker inspect "$i" --format '{{ index .Config.Labels "com.docker.compose.project.config_files" }}')
ContName=$(docker inspect "$i" --format '{{ index .Config.Labels "com.docker.compose.service" }}')
ContEnv=$(docker inspect "$i" --format '{{index .Config.Labels "com.docker.compose.project.environment_file" }}')
ContLabels=$(docker inspect "$i" --format '{{json .Config.Labels}}')
ContImage=$(docker inspect "$i" --format='{{.Config.Image}}')
ContPath=$(jq -r '."com.docker.compose.project.working_dir"' <<< "$ContLabels")
[ "$ContPath" == "null" ] && ContPath=""
[ -z "$ContPath" ] && { "$i has no compose labels - skipping" ; continue ; }
ContConfigFile=$(jq -r '."com.docker.compose.project.config_files"' <<< "$ContLabels")
[ "$ContConfigFile" == "null" ] && ContConfigFile=""
ContName=$(jq -r '."com.docker.compose.service"' <<< "$ContLabels")
[ "$ContName" == "null" ] && ContName=""
ContEnv=$(jq -r '."com.docker.compose.project.environment_file"' <<< "$ContLabels")
[ "$ContEnv" == "null" ] && ContEnv=""
ContUpdateLabel=$(jq -r '."mag37.dockcheck.update"' <<< "$ContLabels")
[ "$ContUpdateLabel" == "null" ] && ContUpdateLabel=""
ContRestartStack=$(jq -r '."mag37.dockcheck.restart-stack"' <<< "$ContLabels")
[ "$ContRestartStack" == "null" ] && ContRestartStack=""
if [[ $ContConfigFile = '/'* ]] ; then
ComposeFile="$ContConfigFile"
@@ -20,6 +29,8 @@ for i in $(docker ps --filter "name=$SearchName" --format '{{.Names}}') ; do
echo -e "Compose files:\t\t$ComposeFile"
echo -e "Environment files:\t$ContEnv"
echo -e "Container image:\t$ContImage"
echo -e "Update label:\t$ContUpdateLabel"
echo -e "Restart Stack label:\t$ContRestartStack"
echo
echo "Mounts:"
docker inspect -f '{{ range .Mounts }}{{ .Source }}:{{ .Destination }}{{ printf "\n" }}{{ end }}' "$i"

Binary file not shown.

Before

Width:  |  Height:  |  Size: 404 KiB

After

Width:  |  Height:  |  Size: 549 KiB

BIN
extras/example_old.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 472 KiB

View File

@@ -1,5 +1,6 @@
### DISCLAIMER: This is a third party addition to dockcheck - best effort testing.
# INFO: ssmtp is depcerated - consider to use msmtp instead.
NOTIFY_DSM_VERSION="v0.1"
# INFO: ssmtp is deprecated - consider to use msmtp instead.
#
# Copy/rename this file to notify.sh to enable the notification snipppet.
# mSMTP/sSMTP has to be installed and configured manually.
@@ -9,7 +10,7 @@
MSMTP=$(which msmtp)
SSMTP=$(which ssmtp)
if [ -n "$MSMPT" ] ; then
if [ -n "$MSMTP" ] ; then
MailPkg=$MSMTP
elif [ -n "$SSMTP" ] ; then
MailPkg=$SSMTP
@@ -17,10 +18,9 @@ else
echo "No msmtp or ssmtp binary found in PATH: $PATH" ; exit 1
fi
send_notification() {
Updates=("$@")
[ -s "$ScriptWorkDir"/urls.list ] && UpdToString=$( releasenotes ) || UpdToString=$( printf "%s\n" "${Updates[@]}" )
FromHost=$(hostname)
trigger_notification() {
CfgFile="/usr/syno/etc/synosmtp.conf"
# User variables:
@@ -34,20 +34,49 @@ SenderName=$(grep 'smtp_from_name' $CfgFile | sed -n 's/.*"\([^"]*\)".*/\1/p')
SenderMail=$(grep 'smtp_from_mail' $CfgFile | sed -n 's/.*"\([^"]*\)".*/\1/p')
SenderMail=${SenderMail:-$(grep 'eventmail1' $CfgFile | sed -n 's/.*"\([^"]*\)".*/\1/p')}
printf "\nSending email notification.\n"
$MailPkg $SendMailTo << __EOF
From: "$SenderName" <$SenderMail>
date:$(date -R)
To: <$SendMailTo>
Subject: $SubjectTag Updates available on $FromHost
Subject: $SubjectTag $MessageTitle $FromHost
Content-Type: text/plain; charset=UTF-8; format=flowed
Content-Transfer-Encoding: 7bit
The following containers on $FromHost have updates available:
$UpdToString
$MessageBody
From $SenderName
__EOF
# This ensures DSM's container manager will also see the update
/var/packages/ContainerManager/target/tool/image_upgradable_checker
}
send_notification() {
[ -s "$ScriptWorkDir"/urls.list ] && releasenotes || Updates=("$@")
UpdToString=$( printf '%s\\n' "${Updates[@]}" )
printf "\nSending email notification.\n"
MessageTitle="Updates available on"
# Setting the MessageBody variable here.
printf -v MessageBody "🐋 Containers on $FromHost with updates available:\n\n$UpdToString"
trigger_notification
}
### Rename (eg. disabled_dockcheck_notification), remove or comment out the following function
### to not send notifications when dockcheck itself has updates.
dockcheck_notification() {
printf "\nSending email dockcheck notification.\n"
MessageTitle="New version of dockcheck available on"
# Setting the MessageBody variable here.
printf -v MessageBody "Installed version: $1\nLatest version: $2\n\nChangenotes: $3\n"
RawNotifyUrl="https://raw.githubusercontent.com/mag37/dockcheck/main/notify_templates/notify_DSM.sh"
LatestNotifyRelease="$(curl -s -r 0-150 $RawNotifyUrl | sed -n "/NOTIFY_DSM_VERSION/s/NOTIFY_DSM_VERSION=//p" | tr -d '"')"
if [[ "$NOTIFY_DSM_VERSION" != "$LatestNotifyRelease" ]] ; then
printf -v NotifyUpdate "\n\nnotify_DSM.sh update avialable:\n $NOTIFY_DSM_VERSION -> $LatestNotifyRelease\n"
MessageBody="${MessageBody}${NotifyUpdate}"
fi
trigger_notification
}

View File

@@ -1,35 +1,55 @@
### DISCLAIMER: This is a third party addition to dockcheck - best effort testing.
NOTIFY_APPRISE_VERSION="v0.1"
#
# Copy/rename this file to notify.sh to enable the notification snippet.
# Required receiving services must already be set up.
# Modify to fit your setup - if API, set AppriseURL to your Apprise ip/domain.
send_notification() {
Updates=("$@")
[ -s "$ScriptWorkDir"/urls.list ] && UpdToString=$( releasenotes ) || UpdToString=$( printf "%s\n" "${Updates[@]}" )
FromHost=$(hostname)
printf "\nSending Apprise notification\n"
trigger_notification() {
MessageTitle="$FromHost - updates available."
# Setting the MessageBody variable here.
read -d '\n' MessageBody << __EOF
Containers on $FromHost with updates available:
$UpdToString
__EOF
# Modify to fit your setup:
apprise -vv -t "$MessageTitle" -b "$MessageBody" \
mailto://myemail:mypass@gmail.com \
mastodons://{token}@{host} \
pbul://o.gn5kj6nfhv736I7jC3cj3QLRiyhgl98b \
tgram://{bot_token}/{chat_id}/
### If you use the Apprise-API - Comment out the apprise command above.
### Uncomment the AppriseURL and the curl-line below:
# AppriseURL="http://apprise.mydomain.tld:1234/notify/apprise"
# curl -X POST -F "title=$MessageTitle" -F "body=$MessageBody" -F "tags=all" $AppriseURL
### Modify to fit your setup:
apprise -vv -t "$MessageTitle" -b "$MessageBody" \
mailto://myemail:mypass@gmail.com \
mastodons://{token}@{host} \
pbul://o.gn5kj6nfhv736I7jC3cj3QLRiyhgl98b \
tgram://{bot_token}/{chat_id}/
### If you use the Apprise-API - Comment out the apprise command above.
### Uncomment the AppriseURL and the curl-line below:
# AppriseURL="http://apprise.mydomain.tld:1234/notify/apprise"
# curl -X POST -F "title=$MessageTitle" -F "body=$MessageBody" -F "tags=all" $AppriseURL
}
send_notification() {
[ -s "$ScriptWorkDir"/urls.list ] && releasenotes || Updates=("$@")
UpdToString=$( printf '%s\\n' "${Updates[@]}" )
printf "\nSending Apprise notification\n"
MessageTitle="$FromHost - updates available."
# Setting the MessageBody variable here.
printf -v MessageBody "🐋 Containers on $FromHost with updates available:\n$UpdToString"
trigger_notification
}
### Rename (eg. disabled_dockcheck_notification), remove or comment out the following function
### to not send notifications when dockcheck itself has updates.
dockcheck_notification() {
printf "\nSending Apprise dockcheck notification\n"
MessageTitle="$FromHost - New version of dockcheck available."
# Setting the MessageBody variable here.
printf -v MessageBody "Installed version: $1 \nLatest version: $2 \n\nChangenotes: $3"
RawNotifyUrl="https://raw.githubusercontent.com/mag37/dockcheck/main/notify_templates/notify_apprise.sh"
LatestNotifyRelease="$(curl -s -r 0-150 $RawNotifyUrl | sed -n "/NOTIFY_APPRISE_VERSION/s/NOTIFY_APPRISE_VERSION=//p" | tr -d '"')"
if [[ "$NOTIFY_APPRISE_VERSION" != "$LatestNotifyRelease" ]] ; then
printf -v NotifyUpdate "\n\nnotify_apprise.sh update avialable:\n $NOTIFY_APPRISE_VERSION -> $LatestNotifyRelease\n"
MessageBody="${MessageBody}${NotifyUpdate}"
fi
trigger_notification
}

View File

@@ -0,0 +1,43 @@
### DISCLAIMER: This is a third party addition to dockcheck - best effort testing.
NOTIFY_DISCORD_VERSION="v0.1"
#
# Copy/rename this file to notify.sh to enable the notification snippet.
# Required receiving services must already be set up.
# Modify to fit your setup - set DiscordWebhookUrl
FromHost=$(hostname)
trigger_notification() {
# Modify to fit your setup:
DiscordWebhookUrl="PasteYourFullDiscordWebhookURL"
MsgBody="{\"username\":\"$FromHost\",\"content\":\"$MessageBody\"}"
curl -sS -o /dev/null --fail -X POST -H "Content-Type: application/json" -d "$MsgBody" "$DiscordWebhookUrl"
}
send_notification() {
[ -s "$ScriptWorkDir"/urls.list ] && releasenotes || Updates=("$@")
UpdToString=$( printf '%s\\n' "${Updates[@]}" )
printf "\nSending Discord notification\n"
# Setting the MessageBody variable here.
MessageBody="🐋 Containers on $FromHost with updates available: \n$UpdToString"
trigger_notification
}
### Rename (eg. disabled_dockcheck_notification), remove or comment out the following function
### to not send notifications when dockcheck itself has updates.
dockcheck_notification() {
printf "\nSending Discord dockcheck notification\n"
MessageBody="$FromHost - New version of dockcheck available: \n Installed version: $1 \nLatest version: $2 \n\nChangenotes: $3"
RawNotifyUrl="https://raw.githubusercontent.com/mag37/dockcheck/main/notify_templates/notify_discord.sh"
LatestNotifyRelease="$(curl -s -r 0-150 $RawNotifyUrl | sed -n "/NOTIFY_DISCORD_VERSION/s/NOTIFY_DISCORD_VERSION=//p" | tr -d '"')"
if [[ "$NOTIFY_DISCORD_VERSION" != "$LatestNotifyRelease" ]] ; then
printf -v NotifyUpdate "\n\nnotify_discord.sh update avialable:\n $NOTIFY_DISCORD_VERSION -> $LatestNotifyRelease\n"
MessageBody="${MessageBody}${NotifyUpdate}"
fi
trigger_notification
}

View File

@@ -1,14 +1,44 @@
### DISCLAIMER: This is a third party addition to dockcheck - best effort testing.
NOTIFY_GENERIC_VERSION="v0.1"
#
# Copy/rename this file to notify.sh to enable the notification snippet.
# generic sample, the "Hello World" of notification addons
send_notification() {
Updates=("$@")
[ -s "$ScriptWorkDir"/urls.list ] && UpdToString=$( releasenotes ) || UpdToString=$( printf "%s\n" "${Updates[@]}" )
FromHost=$(hostname)
FromHost=$(hostname)
# platform specific notification code would go here
printf "\n%bGeneric notification addon:%b" "$c_green" "$c_reset"
printf "\nThe following docker containers on %s need to be updated:\n%s\n" "$FromHost" "$UpdToString"
trigger_notification() {
# Modify to fit your setup:
printf "\n$MessageTitle\n"
printf "\n$MessageBody\n"
}
send_notification() {
[ -s "$ScriptWorkDir"/urls.list ] && releasenotes || Updates=("$@")
UpdToString=$( printf '%s\\n' "${Updates[@]}" )
# platform specific notification code would go here
printf "\n%bGeneric notification addon:%b" "$c_green" "$c_reset"
MessageTitle="$FromHost - updates available."
printf -v MessageBody "🐋 Containers on $FromHost with updates available:\n$UpdToString"
trigger_notification
}
### Rename (eg. disabled_dockcheck_notification), remove or comment out the following function
### to not send notifications when dockcheck itself has updates.
dockcheck_notification() {
printf "\nGeneric dockcheck notification\n"
MessageTitle="$FromHost - New version of dockcheck available."
# Setting the MessageBody variable here.
printf -v MessageBody "Installed version: $1 \nLatest version: $2 \n\nChangenotes: $3"
RawNotifyUrl="https://raw.githubusercontent.com/mag37/dockcheck/main/notify_templates/notify_generic.sh"
LatestNotifyRelease="$(curl -s -r 0-150 $RawNotifyUrl | sed -n "/NOTIFY_GENERIC_VERSION/s/NOTIFY_GENERIC_VERSION=//p" | tr -d '"')"
if [[ "$NOTIFY_GENERIC_VERSION" != "$LatestNotifyRelease" ]] ; then
printf -v NotifyUpdate "\n\nnotify_generic.sh update avialable:\n $NOTIFY_GENERIC_VERSION -> $LatestNotifyRelease\n"
MessageBody="${MessageBody}${NotifyUpdate}"
fi
trigger_notification
}

View File

@@ -1,21 +1,13 @@
### DISCLAIMER: This is a third party addition to dockcheck - best effort testing.
NOTIFY_GOTIFY_VERSION="v0.1"
#
# Copy/rename this file to notify.sh to enable the notification snippet.
# Required receiving services must already be set up.
# Modify to fit your setup - set GotifyUrl and GotifyToken.
send_notification() {
Updates=("$@")
[ -s "$ScriptWorkDir"/urls.list ] && UpdToString=$( releasenotes ) || UpdToString=$( printf "%s\n" "${Updates[@]}" )
FromHost=$(hostname)
# platform specific notification code would go here
printf "\nSending Gotify notification\n"
# Setting the MessageTitle and MessageBody variable here.
MessageTitle="${FromHost} - updates available."
MessageBody="Containers on ${FromHost} with updates available: ${UpdToString}"
FromHost=$(hostname)
trigger_notification() {
# Modify to fit your setup:
GotifyToken="Your Gotify token here"
GotifyUrl="https://api.gotify/message?token=${GotifyToken}"
@@ -24,6 +16,38 @@ send_notification() {
-F "title=${MessageTitle}" \
-F "message=${MessageBody}" \
-F "priority=5" \
-X POST "${GotifyUrl}" &> /dev/null
-X POST "${GotifyUrl}" 1> /dev/null
}
send_notification() {
[ -s "$ScriptWorkDir"/urls.list ] && releasenotes || Updates=("$@")
UpdToString=$( printf '%s\\n' "${Updates[@]}" )
# platform specific notification code would go here
printf "\nSending Gotify notification\n"
# Setting the MessageTitle and MessageBody variable here.
MessageTitle="${FromHost} - updates available."
printf -v MessageBody "Containers on $FromHost with updates available:\n$UpdToString"
trigger_notification
}
### Rename (eg. disabled_dockcheck_notification), remove or comment out the following function
### to not send notifications when dockcheck itself has updates.
dockcheck_notification() {
printf "\nSending Gotify dockcheck notification\n"
MessageTitle="$FromHost - New version of dockcheck available."
# Setting the MessageBody variable here.
printf -v MessageBody "Installed version: $1 \nLatest version: $2 \n\nChangenotes: $3"
RawNotifyUrl="https://raw.githubusercontent.com/mag37/dockcheck/main/notify_templates/notify_gotify.sh"
LatestNotifyRelease="$(curl -s -r 0-150 $RawNotifyUrl | sed -n "/NOTIFY_GOTIFY_VERSION/s/NOTIFY_GOTIFY_VERSION=//p" | tr -d '"')"
if [[ "$NOTIFY_GOTIFY_VERSION" != "$LatestNotifyRelease" ]] ; then
printf -v NotifyUpdate "\n\nnotify_gotify.sh update avialable:\n $NOTIFY_GOTIFY_VERSION -> $LatestNotifyRelease\n"
MessageBody="${MessageBody}${NotifyUpdate}"
fi
trigger_notification
}

View File

@@ -1,20 +1,13 @@
### DISCLAIMER: This is a third party addition to dockcheck - best effort testing.
NOTIFY_MATRIX_VERSION="v0.1"
#
# Copy/rename this file to notify.sh to enable the notification snippet.
# Required receiving services must already be set up.
# Modify to fit your setup - set MatrixServer, Room_id and AccessToken
send_notification() {
Updates=("$@")
[ -s "$ScriptWorkDir"/urls.list ] && UpdToString=$( releasenotes ) || UpdToString=$( printf "%s\n" "${Updates[@]}" )
FromHost=$(hostname)
# platform specific notification code would go here
printf "\nSending Matrix notification\n"
# Setting the MessageBody variable here.
MessageBody="🐋 Containers on $FromHost with updates available: \n$UpdToString"
FromHost=$(hostname)
trigger_notification() {
# Modify to fit your setup:
AccessToken="Your Matrix token here"
Room_id="Enter Room_id here"
@@ -22,7 +15,37 @@ send_notification() {
MsgBody="{\"msgtype\":\"m.text\",\"body\":\"$MessageBody\"}"
# URL Example: https://matrix.org/_matrix/client/r0/rooms/!xxxxxx:example.com/send/m.room.message?access_token=xxxxxxxx
curl -sS -o /dev/null --fail -X POST "$MatrixServer/_matrix/client/r0/rooms/$Room_id/send/m.room.message?access_token=$AccessToken" -H 'Content-Type: application/json' -d "$MsgBody"
}
send_notification() {
[ -s "$ScriptWorkDir"/urls.list ] && releasenotes || Updates=("$@")
UpdToString=$( printf '%s\\n' "${Updates[@]}" )
# platform specific notification code would go here
printf "\nSending Matrix notification\n"
# Setting the MessageBody variable here.
MessageBody="🐋 Containers on $FromHost with updates available: \n$UpdToString"
trigger_notification
}
### Rename (eg. disabled_dockcheck_notification), remove or comment out the following function
### to not send notifications when dockcheck itself has updates.
dockcheck_notification() {
printf "\nSending Matrix dockcheck notification\n"
MessageTitle="$FromHost - New version of dockcheck available."
# Setting the MessageBody variable here.
printf -v MessageBody "Installed version: $1 \nLatest version: $2 \n\nChangenotes: $3"
RawNotifyUrl="https://raw.githubusercontent.com/mag37/dockcheck/main/notify_templates/notify_matrix.sh"
LatestNotifyRelease="$(curl -s -r 0-150 $RawNotifyUrl | sed -n "/NOTIFY_MATRIX_VERSION/s/NOTIFY_MATRIX_VERSION=//p" | tr -d '"')"
if [[ "$NOTIFY_MATRIX_VERSION" != "$LatestNotifyRelease" ]] ; then
printf -v NotifyUpdate "\n\nnotify_matrix.sh update avialable:\n $NOTIFY_MATRIX_VERSION -> $LatestNotifyRelease\n"
MessageBody="${MessageBody}${NotifyUpdate}"
fi
trigger_notification
}

View File

@@ -1,31 +1,50 @@
### DISCLAIMER: This is a third party addition to dockcheck - best effort testing.
NOTIFY_NTFYSH_VERSION="v0.1"
#
# Copy/rename this file to notify.sh to enable the notification snippet.
# Setup app and subscription at https://ntfy.sh
# Use your unique Topic Name in the URL below.
send_notification() {
Updates=("$@")
[ -s "$ScriptWorkDir"/urls.list ] && UpdToString=$( releasenotes ) || UpdToString=$( printf "%s\n" "${Updates[@]}" )
FromHost=$(hostname)
printf "\nSending ntfy.sh notification\n"
MessageTitle="$FromHost - updates available."
# Setting the MessageBody variable here.
read -d '\n' MessageBody << __EOF
Containers on $FromHost with updates available:
$UpdToString
__EOF
# Modify to fit your setup:
NtfyUrl="ntfy.sh/YourUniqueTopicName"
curl -sS -o /dev/null --show-error --fail \
-H "Title: $MessageTitle" \
-d "$MessageBody" \
$NtfyUrl
trigger_notification() {
# Modify to fit your setup:
NtfyUrl="ntfy.sh/YourUniqueTopicName"
curl -sS -o /dev/null --show-error --fail \
-H "Title: $MessageTitle" \
-d "$MessageBody" \
$NtfyUrl
}
send_notification() {
[ -s "$ScriptWorkDir"/urls.list ] && releasenotes || Updates=("$@")
UpdToString=$( printf '%s\\n' "${Updates[@]}" )
printf "\nSending ntfy.sh notification\n"
MessageTitle="$FromHost - updates available."
# Setting the MessageBody variable here.
printf -v MessageBody "🐋 Containers on $FromHost with updates available:\n$UpdToString"
trigger_notification
}
### Rename (eg. disabled_dockcheck_notification), remove or comment out the following function
### to not send notifications when dockcheck itself has updates.
dockcheck_notification() {
printf "\nSending ntfy.sh dockcheck notification\n"
MessageTitle="$FromHost - New version of dockcheck available."
# Setting the MessageBody variable here.
printf -v MessageBody "Installed version: $1 \nLatest version: $2 \n\nChangenotes: $3"
RawNotifyUrl="https://raw.githubusercontent.com/mag37/dockcheck/main/notify_templates/notify_ntfy-sh.sh"
LatestNotifyRelease="$(curl -s -r 0-150 $RawNotifyUrl | sed -n "/NOTIFY_NTFYSH_VERSION/s/NOTIFY_NTFYSH_VERSION=//p" | tr -d '"')"
if [[ "$NOTIFY_NTFYSH_VERSION" != "$LatestNotifyRelease" ]] ; then
printf -v NotifyUpdate "\n\nnotify_ntfy-sh.sh update avialable:\n $NOTIFY_NTFYSH_VERSION -> $LatestNotifyRelease\n"
MessageBody="${MessageBody}${NotifyUpdate}"
fi
trigger_notification
}

View File

@@ -1,27 +1,51 @@
### DISCLAIMER: This is a third party addition to dockcheck - best effort testing.
NOTIFY_PUSHBULLET_VERSION="v0.1"
#
# Copy/rename this file to notify.sh to enable the notification snippet.
# Required receiving services must already be set up.
# Requires jq installed and in PATH.
# Modify to fit your setup - set Url and Token.
send_notification() {
Updates=("$@")
[ -s "$ScriptWorkDir"/urls.list ] && UpdToString=$( releasenotes ) || UpdToString=$( printf "%s\n" "${Updates[@]}" )
FromHost=$(hostname)
# platform specific notification code would go here
printf "\nSending pushbullet notification\n"
MessageTitle="$FromHost - updates available."
# Setting the MessageBody variable here.
MessageBody="Containers on $FromHost with updates available: $UpdToString"
# Modify to fit your setup:
PushUrl="https://api.pushbullet.com/v2/pushes"
PushToken="Your Pushbullet token here"
# Requires jq to process json data
jq -n --arg title "$MessageTitle" --arg body "$MessageBody" '{body: $body, title: $title, type: "note"}' | curl -sS -o /dev/null --show-error --fail -X POST -H "Access-Token: $PushToken" -H "Content-type: application/json" $PushUrl -d @-
trigger_notification() {
# Modify to fit your setup:
PushUrl="https://api.pushbullet.com/v2/pushes"
PushToken="Your Pushbullet token here"
# Requires jq to process json data
jq -n --arg title "$MessageTitle" --arg body "$MessageBody" '{body: $body, title: $title, type: "note"}' | curl -sS -o /dev/null --show-error --fail -X POST -H "Access-Token: $PushToken" -H "Content-type: application/json" $PushUrl -d @-
}
send_notification() {
[ -s "$ScriptWorkDir"/urls.list ] && releasenotes || Updates=("$@")
UpdToString=$( printf '%s\\n' "${Updates[@]}" )
# platform specific notification code would go here
printf "\nSending pushbullet notification\n"
MessageTitle="$FromHost - updates available."
# Setting the MessageBody variable here.
printf -v MessageBody "🐋 Containers on $FromHost with updates available:\n$UpdToString"
trigger_notification
}
### Rename (eg. disabled_dockcheck_notification), remove or comment out the following function
### to not send notifications when dockcheck itself has updates.
dockcheck_notification() {
printf "\nSending pushbullet dockcheck notification\n"
MessageTitle="$FromHost - New version of dockcheck available."
# Setting the MessageBody variable here.
printf -v MessageBody "Installed version: $1 \nLatest version: $2 \n\nChangenotes: $3"
RawNotifyUrl="https://raw.githubusercontent.com/mag37/dockcheck/main/notify_templates/notify_pushbullet.sh"
LatestNotifyRelease="$(curl -s -r 0-150 $RawNotifyUrl | sed -n "/NOTIFY_PUSHBULLET_VERSION/s/NOTIFY_PUSHBULLET_VERSION=//p" | tr -d '"')"
if [[ "$NOTIFY_PUSHBULLET_VERSION" != "$LatestNotifyRelease" ]] ; then
printf -v NotifyUpdate "\n\nnotify_pushbullet.sh update avialable:\n $NOTIFY_PUSHBULLET_VERSION -> $LatestNotifyRelease\n"
MessageBody="${MessageBody}${NotifyUpdate}"
fi
trigger_notification
}

View File

@@ -1,22 +1,14 @@
### DISCLAIMER: This is a third party addition to dockcheck - best effort testing.
NOTIFY_PUSHOVER_VERSION="v0.1"
#
# Copy/rename this file to notify.sh to enable the notification snippet.
# Required receiving services must already be set up.
# Requires jq installed and in PATH.
# Modify to fit your setup - set Url and Token.
send_notification() {
Updates=("$@")
[ -s "$ScriptWorkDir"/urls.list ] && UpdToString=$( releasenotes ) || UpdToString=$( printf "%s\n" "${Updates[@]}" )
FromHost=$(hostname)
# platform specific notification code would go here
printf "\nSending pushover notification\n"
MessageTitle="$FromHost - updates available."
# Setting the MessageBody variable here.
MessageBody="Containers on $FromHost with updates available: $UpdToString"
FromHost=$(hostname)
trigger_notification() {
# Modify to fit your setup:
PushoverUrl="https://api.pushover.net/1/messages.json"
PushoverUserKey="Your Pushover User Key Here"
@@ -30,3 +22,36 @@ send_notification() {
-F "message=$MessageBody" \
$PushoverUrl
}
send_notification() {
[ -s "$ScriptWorkDir"/urls.list ] && releasenotes || Updates=("$@")
UpdToString=$( printf '%s\\n' "${Updates[@]}" )
# platform specific notification code would go here
printf "\nSending pushover notification\n"
MessageTitle="$FromHost - updates available."
# Setting the MessageBody variable here.
printf -v MessageBody "🐋 Containers on $FromHost with updates available:\n$UpdToString"
trigger_notification
}
### Rename (eg. disabled_dockcheck_notification), remove or comment out the following function
### to not send notifications when dockcheck itself has updates.
dockcheck_notification() {
printf "\nSending pushover dockcheck notification\n"
MessageTitle="$FromHost - New version of dockcheck available."
# Setting the MessageBody variable here.
printf -v MessageBody "Installed version: $1 \nLatest version: $2 \n\nChangenotes: $3"
RawNotifyUrl="https://raw.githubusercontent.com/mag37/dockcheck/main/notify_templates/notify_pushover.sh"
LatestNotifyRelease="$(curl -s -r 0-150 $RawNotifyUrl | sed -n "/NOTIFY_PUSHOVER_VERSION/s/NOTIFY_PUSHOVER_VERSION=//p" | tr -d '"')"
if [[ "$NOTIFY_PUSHOVER_VERSION" != "$LatestNotifyRelease" ]] ; then
printf -v NotifyUpdate "\n\nnotify_pushover.sh update avialable:\n $NOTIFY_PUSHOVER_VERSION -> $LatestNotifyRelease\n"
MessageBody="${MessageBody}${NotifyUpdate}"
fi
trigger_notification
}

View File

@@ -0,0 +1,52 @@
### DISCLAIMER: This is a third party addition to dockcheck - best effort testing.
NOTIFY_SLACK_VERSION="v0.1"
#
# Copy/rename this file to notify.sh in the same directory as dockcheck.sh to enable the notification snippet.
# Setu app and token at https://api.slack.com/tutorials/tracks/posting-messages-with-curl
# Add your AccessToken and ChannelID below
FromHost=$(hostname)
trigger_notification() {
# Modify to fit your setup:
AccessToken="xoxb-not-a-real-token-this-will-not-work"
ChannelID="C123456"
SlackUrl="https://slack.com/api/chat.postMessage"
curl -sS -o /dev/null --show-error --fail \
-d "text=$MessageBody" -d "channel=$ChannelID" \
-H "Authorization: Bearer $AccessToken" \
-X POST $SlackUrl
}
send_notification() {
[ -s "$ScriptWorkDir"/urls.list ] && releasenotes || Updates=("$@")
UpdToString=$( printf '%s\\n' "${Updates[@]}" )
printf "\nSending Slack notification\n"
MessageTitle="$FromHost - updates available."
# Setting the MessageBody variable here.
printf -v MessageBody "🐋 Containers on $FromHost with updates available:\n$UpdToString"
trigger_notification
}
### Rename (eg. disabled_dockcheck_notification), remove or comment out the following function
### to not send notifications when dockcheck itself has updates.
dockcheck_notification() {
printf "\nSending Slack dockcheck notification\n"
MessageTitle="$FromHost - New version of dockcheck available."
# Setting the MessageBody variable here.
printf -v MessageBody "Installed version: $1 \nLatest version: $2 \n\nChangenotes: $3"
RawNotifyUrl="https://raw.githubusercontent.com/mag37/dockcheck/main/notify_templates/notify_slack.sh"
LatestNotifyRelease="$(curl -s -r 0-150 $RawNotifyUrl | sed -n "/NOTIFY_SLACK_VERSION/s/NOTIFY_SLACK_VERSION=//p" | tr -d '"')"
if [[ "$NOTIFY_SLACK_VERSION" != "$LatestNotifyRelease" ]] ; then
printf -v NotifyUpdate "\n\nnotify_slack.sh update avialable:\n $NOTIFY_SLACK_VERSION -> $LatestNotifyRelease\n"
MessageBody="${MessageBody}${NotifyUpdate}"
fi
trigger_notification
}

View File

@@ -1,4 +1,5 @@
### DISCLAIMER: This is a third party addition to dockcheck - best effort testing.
NOTIFY_SMTP_VERSION="v0.1"
# INFO: ssmtp is depcerated - consider to use msmtp instead.
#
# Copy/rename this file to notify.sh to enable the notification snipppet.
@@ -8,7 +9,7 @@
MSMTP=$(which msmtp)
SSMTP=$(which ssmtp)
if [ -n "$MSMPT" ] ; then
if [ -n "$MSMTP" ] ; then
MailPkg=$MSMTP
elif [ -n "$SSMTP" ] ; then
MailPkg=$SSMTP
@@ -16,29 +17,55 @@ else
echo "No msmtp or ssmtp binary found in PATH: $PATH" ; exit 1
fi
send_notification() {
Updates=("$@")
[ -s "$ScriptWorkDir"/urls.list ] && UpdToString=$( releasenotes ) || UpdToString=$( printf "%s\n" "${Updates[@]}" )
FromHost=$(hostname)
trigger_notification() {
# User variables:
SendMailFrom="me@mydomain.tld"
SendMailTo="me@mydomain.tld"
SubjectTag="dockcheck"
printf "\nSending email notification.\n"
$MailPkg $SendMailTo << __EOF
From: "$FromHost" <$SendMailFrom>
date:$(date -R)
To: <$SendMailTo>
Subject: [$SubjectTag] Updates available on $FromHost
Subject: [$SubjectTag] $MessageTitle $FromHost
Content-Type: text/plain; charset=UTF-8; format=flowed
Content-Transfer-Encoding: 7bit
The following containers on $FromHost have updates available:
$UpdToString
$MessageBody
__EOF
}
send_notification() {
[ -s "$ScriptWorkDir"/urls.list ] && releasenotes || Updates=("$@")
UpdToString=$( printf '%s\\n' "${Updates[@]}" )
printf "\nSending email notification.\n"
MessageTitle="Updates available on"
# Setting the MessageBody variable here.
printf -v MessageBody "🐋 Containers on $FromHost with updates available:\n\n$UpdToString"
trigger_notification
}
### Rename (eg. disabled_dockcheck_notification), remove or comment out the following function
### to not send notifications when dockcheck itself has updates.
dockcheck_notification() {
printf "\nSending email dockcheck notification.\n"
MessageTitle="New version of dockcheck available on"
# Setting the MessageBody variable here.
printf -v MessageBody "Installed version: $1 \nLatest version: $2 \n\nChangenotes: $3"
RawNotifyUrl="https://raw.githubusercontent.com/mag37/dockcheck/main/notify_templates/notify_smtp.sh"
LatestNotifyRelease="$(curl -s -r 0-150 $RawNotifyUrl | sed -n "/NOTIFY_SMTP_VERSION/s/NOTIFY_SMTP_VERSION=//p" | tr -d '"')"
if [[ "$NOTIFY_SMTP_VERSION" != "$LatestNotifyRelease" ]] ; then
printf -v NotifyUpdate "\n\nnotify_smtp.sh update avialable:\n $NOTIFY_SMTP_VERSION -> $LatestNotifyRelease\n"
MessageBody="${MessageBody}${NotifyUpdate}"
fi
trigger_notification
}

View File

@@ -1,20 +1,13 @@
### DISCLAIMER: This is a third party addition to dockcheck - best effort testing.
NOTIFY_TELEGRAM_VERSION="v0.1"
#
# Copy/rename this file to notify.sh to enable the notification snippet.
# Required receiving services must already be set up.
# Modify to fit your setup - set TelegramChatId and TelegramToken.
send_notification() {
Updates=("$@")
[ -s "$ScriptWorkDir"/urls.list ] && UpdToString=$( releasenotes ) || UpdToString=$( printf "%s\n" "${Updates[@]}" )
FromHost=$(hostname)
# platform specific notification code would go here
printf "\nSending Telegram notification\n"
# Setting the MessageBody variable here.
MessageBody="🐋 Containers on $FromHost with updates available: \n$UpdToString"
FromHost=$(hostname)
trigger_notification() {
# Modify to fit your setup:
TelegramToken="Your Telegram token here"
TelegramChatId="Your Telegram ChatId here"
@@ -23,5 +16,36 @@ send_notification() {
TelegramData="{\"chat_id\":\"$TelegramChatId\",\"text\":\"$MessageBody\",\"message_thread_id\":\"$TelegramTopicID\",\"disable_notification\": false}"
curl -sS -o /dev/null --fail -X POST "$TelegramUrl/sendMessage" -H 'Content-Type: application/json' -d "$TelegramData"
}
send_notification() {
[ -s "$ScriptWorkDir"/urls.list ] && releasenotes || Updates=("$@")
UpdToString=$( printf '%s\\n' "${Updates[@]}" )
# platform specific notification code would go here
printf "\nSending Telegram notification\n"
# Setting the MessageBody variable here.
MessageBody="🐋 Containers on $FromHost with updates available: \n$UpdToString"
trigger_notification
}
### Rename (eg. disabled_dockcheck_notification), remove or comment out the following function
### to not send notifications when dockcheck itself has updates.
dockcheck_notification() {
printf "\nSending Telegram dockcheck notification\n"
MessageTitle="$FromHost - New version of dockcheck available."
# Setting the MessageBody variable here.
printf -v MessageBody "$FromHost - New version of dockcheck available.\n\nInstalled version: $1 \nLatest version: $2 \n\nChangenotes: $3"
RawNotifyUrl="https://raw.githubusercontent.com/mag37/dockcheck/main/notify_templates/notify_telegram.sh"
LatestNotifyRelease="$(curl -s -r 0-150 $RawNotifyUrl | sed -n "/NOTIFY_TELEGRAM_VERSION/s/NOTIFY_TELEGRAM_VERSION=//p" | tr -d '"')"
if [[ "$NOTIFY_TELEGRAM_VERSION" != "$LatestNotifyRelease" ]] ; then
printf -v NotifyUpdate "\n\nnotify_telegram.sh update avialable:\n $NOTIFY_TELEGRAM_VERSION -> $LatestNotifyRelease\n"
MessageBody="${MessageBody}${NotifyUpdate}"
fi
trigger_notification
}

View File

@@ -6,3 +6,30 @@ apprise-api https://github.com/linuxserver/docker-apprise-api/releases
homer https://github.com/bastienwirtz/homer/releases
nginx https://github.com/docker-library/official-images/blob/master/library/nginx
vaultwarden-server https://github.com/dani-garcia/vaultwarden/releases
bruceforce-vaultwarden-backup https://github.com/Bruceforce/vaultwarden-backup/blob/main/CHANGELOG.md
actual_server https://actualbudget.org/blog
gotify https://github.com/gotify/server/releases
traefik https://github.com/traefik/traefik/releases
caddy https://github.com/caddyserver/caddy/releases
calibre https://github.com/linuxserver/docker-calibre/releases
calibre-web https://github.com/linuxserver/docker-calibre-web/releases
readarr https://github.com/Readarr/Readarr/releases
audiobookshelf https://github.com/advplyr/audiobookshelf/releases
gluetun https://github.com/qdm12/gluetun/releases
bazarr https://github.com/morpheus65535/bazarr/releases
bazarr-ls https://github.com/linuxserver/docker-bazarr/releases
prowlarr https://github.com/Prowlarr/Prowlarr/releases
prowlarr-ls https://github.com/linuxserver/docker-prowlarr/releases
recyclarr https://github.com/recyclarr/recyclarr/releases
sabnzbd https://github.com/linuxserver/docker-sabnzbd/releases
sonarr https://github.com/linuxserver/docker-sonarr/releases
radarr https://github.com/linuxserver/docker-radarr/releases
lidarr https://github.com/linuxserver/docker-lidarr/releases
jellyseerr https://github.com/Fallenbagel/jellyseerr/releases
jellyfin https://github.com/jellyfin/jellyfin/releases
home-assistant https://github.com/home-assistant/docker/releases
zigbee2mqtt https://github.com/Koenkk/zigbee2mqtt/releases
mqtt https://github.com/eclipse/mosquitto/tags