From 588c22afc96136abd2a7acb51eeda8fbfc3071c5 Mon Sep 17 00:00:00 2001 From: Chris Funderburg Date: Sat, 17 Aug 2024 08:50:39 -0400 Subject: [PATCH] style: Add pre-commit checks and code cleanup This change adds an optional pre-commit configuration that can be used to keep the code style clean. I've also run it across all files and fixed numerous whitespaces issues. To use it, if wanted, just clone / pull the repo as normal, go into the folder and run: ``` pre-commit install ``` From that point on, when running `git commit`, it will run the checks on any changed files. Feel free to ignore this PR if you're not interested. --- .pre-commit-config.yaml | 11 +++++++++ README.md | 20 +++++++-------- dockcheck.sh | 47 ++++++++++++++++++------------------ extras/apprise_quickstart.md | 16 ++++++------ extras/dc_brief.sh | 4 +-- extras/errorCheck.sh | 4 +-- notify_DSM.sh | 2 +- notify_apprise.sh | 2 -- notify_gotify.sh | 10 ++++---- notify_matrix.sh | 8 +++--- notify_smtp.sh | 2 +- notify_telegram.sh | 10 ++++---- 12 files changed, 72 insertions(+), 64 deletions(-) create mode 100644 .pre-commit-config.yaml diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml new file mode 100644 index 0000000..04b74b8 --- /dev/null +++ b/.pre-commit-config.yaml @@ -0,0 +1,11 @@ +repos: +- repo: https://github.com/pre-commit/pre-commit-hooks + rev: v4.6.0 + hooks: + - id: check-yaml + - id: check-added-large-files + - id: trailing-whitespace + args: [--markdown-linebreak-ext=md] + - id: end-of-file-fixer + - id: mixed-line-ending + args: ['--fix=lf'] diff --git a/README.md b/README.md index 02b87b5..fb62329 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@

-

+

bash GPLv3 release @@ -72,16 +72,16 @@ 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 proceedes 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. - Bash shell or compatible shell of at least v4.3 -- [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`. +- [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 @@ -99,10 +99,10 @@ Add preferred `notify.sh`-template to the same directory - this will not be touc ## :loudspeaker: Notifications -Trigger with the `-i` flag. +Trigger with the `-i` flag. Run it scheduled with `-ni` to only get notified when there's updates available! -Use a `notify_X.sh` template file, copy it to `notify.sh`, modify it to your needs! (notify.sh is added to .gitignore) +Use a `notify_X.sh` template file, copy it to `notify.sh`, modify it to your needs! (notify.sh is added to .gitignore) **Current templates:** - Synology [DSM](https://www.synology.com/en-global/dsm) - Email with [mSMTP](https://wiki.debian.org/msmtp) (or deprecated alternative [sSMTP](https://wiki.debian.org/sSMTP)) @@ -115,7 +115,7 @@ Use a `notify_X.sh` template file, copy it to `notify.sh`, modify it to your nee - [Telegram](https://telegram.org/) - Telegram chat API. - [Matrix-Synapse](https://github.com/element-hq/synapse) - [Matrix](https://matrix.org/), open, secure, decentralised communication. -Further additions are welcome - suggestions or PR! +Further additions are welcome - suggestions or PR! Initiated and first contributed by [yoyoma2](https://github.com/yoyoma2). ## :bookmark: Labels @@ -163,7 +163,7 @@ function dchk { - Not working well with containers created by Portainer. ## :warning: `-r flag` disclaimer and warning -**Wont auto-update the containers, only their images. (compose is recommended)** +**Wont auto-update the containers, only their images. (compose is recommended)** `docker run` dont support using new images just by restarting a container. Containers need to be manually stopped, removed and created again to run on the new image. @@ -176,5 +176,5 @@ ___ ## Special Thanks -- :bison: [t0rnis](https://github.com/t0rnis) +- :bison: [t0rnis](https://github.com/t0rnis) - :leopard: [Palleri](https://github.com/Palleri) diff --git a/dockcheck.sh b/dockcheck.sh index 3a00518..0ea7c73 100755 --- a/dockcheck.sh +++ b/dockcheck.sh @@ -16,7 +16,7 @@ LatestChanges="$(curl -s -r 0-200 $RawUrl | sed -n "/ChangeNotes/s/### ChangeNot ### Help Function: Help() { - echo "Syntax: dockcheck.sh [OPTION] [part of name to filter]" + echo "Syntax: dockcheck.sh [OPTION] [part of name to filter]" echo "Example: dockcheck.sh -y -d 10 -e nextcloud,heimdall" echo echo "Options:" @@ -58,7 +58,7 @@ while getopts "aynpfrhlisvme:d:t:" options; do e) Exclude=${OPTARG} ;; m) declare c_{red,green,yellow,blue,teal,reset}="" ;; s) Stopped="-a" ;; - t) Timeout="${OPTARG}" ;; + 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 ;; @@ -69,12 +69,12 @@ shift "$((OPTIND-1))" self_update_curl() { cp "$ScriptPath" "$ScriptPath".bak - if [[ $(builtin type -P curl) ]]; then - curl -L $RawUrl > "$ScriptPath" ; chmod +x "$ScriptPath" + if [[ $(builtin type -P curl) ]]; 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 + elif [[ $(builtin type -P wget) ]]; 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 @@ -103,7 +103,7 @@ self_update() { choosecontainers() { 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 SelectedUpdates=( "${GotUpdates[@]}" ) @@ -147,9 +147,9 @@ progress_bar() { } ### Version check & initiate self update -if [[ "$VERSION" != "$LatestRelease" ]] ; then +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 [[ -z "$AutoUp" ]] ; then read -r -p "Would you like to update? y/[n]: " SelfUpdate [[ "$SelfUpdate" =~ [yY] ]] && self_update fi @@ -218,7 +218,7 @@ DocCount=$(docker ps $Stopped --filter "name=$SearchName" --format '{{.Names}}' RegCheckQue=0 ### Testing and setting timeout binary -t_out=$(type -P "timeout") +t_out=$(type -P "timeout") if [[ $t_out ]]; then t_out=$(realpath $t_out 2>/dev/null || readlink -f $t_out) if [[ $t_out =~ "busybox" ]]; then @@ -233,17 +233,17 @@ for i in $(docker ps $Stopped --filter "name=$SearchName" --format '{{.Names}}') ((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 + for e in "${Excludes[@]}" ; do [[ "$i" == "$e" ]] && continue 2 ; done 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") - else + if [[ "$LocalHash" = *"$RegHash"* ]] ; then + NoUpdates+=("$i") + else if [[ -n "$DaysOld" ]] && ! datecheck ; then - NoUpdates+=("+$i ${ImageAge}d") - else + NoUpdates+=("+$i ${ImageAge}d") + else GotUpdates+=("$i") fi fi @@ -273,13 +273,13 @@ if [[ -n ${GotErrors[*]} ]] ; then 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" ; } fi -### Optionally get updates if there's any +### 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" @@ -302,14 +302,14 @@ if [ -n "$GotUpdates" ] ; then 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 [ -z "$ContPath" ] ; then if [ "$DRunUp" == "yes" ] ; then docker pull "$ContImage" printf "%s\n" "$i got a new image downloaded, rebuild manually with preferred 'docker run'-parameters" else printf "\n%b%s%b has no compose labels, probably started with docker run - %bskipping%b\n\n" "$c_yellow" "$i" "$c_reset" "$c_yellow" "$c_reset" fi - continue + 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 ; } @@ -326,15 +326,15 @@ if [ -n "$GotUpdates" ] ; then ### 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 + 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" [[ -z "$AutoPrune" ]] && read -r -p "Would you like to prune dangling images? y/[n]: " AutoPrune - [[ "$AutoPrune" =~ [yY] ]] && docker image prune -f + [[ "$AutoPrune" =~ [yY] ]] && docker image prune -f else printf "\nNo updates installed, exiting.\n" fi @@ -343,4 +343,3 @@ else fi exit 0 - diff --git a/extras/apprise_quickstart.md b/extras/apprise_quickstart.md index 4ed8bfe..2d1ddd6 100644 --- a/extras/apprise_quickstart.md +++ b/extras/apprise_quickstart.md @@ -25,13 +25,13 @@ services: Then browse to the webui. ![](apprise-ex1.png) Here you'll click **Configuration Manager**, read the overview and then click on **Configuration**. -Under **Configuration** you'll craft/paste your notification config. +Under **Configuration** you'll craft/paste your notification config. ![](apprise-ex2.png) -The simplest way is just paste the url's as is (like in the example above). -There are many ways to customize with tags, groups, json and more. Read [caronc/apprise-api](https://github.com/caronc/apprise-api) for more info! +The simplest way is just paste the url's as is (like in the example above). +There are many ways to customize with tags, groups, json and more. Read [caronc/apprise-api](https://github.com/caronc/apprise-api) for more info! -Look at the [apprise wiki: Notification Services](https://github.com/caronc/apprise/wiki) for more info about how the url syntax for different services works. +Look at the [apprise wiki: Notification Services](https://github.com/caronc/apprise/wiki) for more info about how the url syntax for different services works. You can also use the [caronc/apprise-api](https://github.com/caronc/apprise-api) to host the api as a frontend to an already existing **Apprise**-setup on the host. @@ -40,7 +40,7 @@ You can also use the [caronc/apprise-api](https://github.com/caronc/apprise-api) ### Customize the **notify.sh** file. After you're done with the setup of the container and tried your notifications, you can copy the `notify_apprise.sh` file to `notify.sh` and start editing it. -Comment out/remove the bare metal apprise-command (starting with `apprise -vv -t...`). +Comment out/remove the bare metal apprise-command (starting with `apprise -vv -t...`). Uncomment and edit the `AppriseURL` variable and *curl* line It should look something like this when curling the API: ```bash @@ -72,11 +72,11 @@ ___ ## On host installed **Apprise** -Follow the official guide on [caronc/apprise](https://github.com/caronc/apprise)! +Follow the official guide on [caronc/apprise](https://github.com/caronc/apprise)! ### A brief, basic "get started" -- Install **apprise** +- Install **apprise** - python package `pip install apprise` - packaged in EPEL/Fedora `dnf install apprise` - packaged in AUR `[yay/pikaur/paru/other] apprise` @@ -92,7 +92,7 @@ Then either source the notifications with `-c=/path/to/config/apprise` or store - Test apprise with a single notification: - `apprise -vv -t 'test title' -b 'test notification body' 'mailto://myemail:mypass@gmail.com'` - Set up your notification URL's and test them. - - Look at the [apprise wiki: Notification Services](https://github.com/caronc/apprise/wiki) for more info about how the url syntax for different services works. + - Look at the [apprise wiki: Notification Services](https://github.com/caronc/apprise/wiki) for more info about how the url syntax for different services works. ### When done, customize the **notify.sh** file. After you're done with the setup of the container and tried your notifications, you can copy the `notify_apprise.sh` file to `notify.sh` and start editing it. diff --git a/extras/dc_brief.sh b/extras/dc_brief.sh index c188ae0..d496d06 100755 --- a/extras/dc_brief.sh +++ b/extras/dc_brief.sh @@ -29,7 +29,7 @@ for i in $(docker ps --filter "name=$SearchName" --format '{{.Names}}') ; do done ### Sort arrays alphabetically -IFS=$'\n' +IFS=$'\n' NoUpdates=($(sort <<<"${NoUpdates[*]}")) GotUpdates=($(sort <<<"${GotUpdates[*]}")) GotErrors=($(sort <<<"${GotErrors[*]}")) @@ -44,7 +44,7 @@ if [[ -n ${GotErrors[*]} ]] ; then printf "\n\033[0;31mContainers with errors, wont get updated:\033[0m\n" printf "%s\n" "${GotErrors[@]}" fi -if [[ -n ${GotUpdates[*]} ]] ; then +if [[ -n ${GotUpdates[*]} ]] ; then printf "\n\033[0;33mContainers with updates available:\033[0m\n" printf "%s\n" "${GotUpdates[@]}" fi diff --git a/extras/errorCheck.sh b/extras/errorCheck.sh index 30ebe52..327f454 100755 --- a/extras/errorCheck.sh +++ b/extras/errorCheck.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash SearchName="$1" -for i in $(docker ps --filter "name=$SearchName" --format '{{.Names}}') ; do +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 ; } @@ -8,7 +8,7 @@ for i in $(docker ps --filter "name=$SearchName" --format '{{.Names}}') ; do 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" }}') ContImage=$(docker inspect "$i" --format='{{.Config.Image}}') - + if [[ $ContConfigFile = '/'* ]] ; then ComposeFile="$ContConfigFile" else diff --git a/notify_DSM.sh b/notify_DSM.sh index b6e4df0..2affe30 100644 --- a/notify_DSM.sh +++ b/notify_DSM.sh @@ -9,7 +9,7 @@ MSMTP=$(which msmtp) SSMTP=$(which ssmtp) -if [ -n $MSMPT ] ; then +if [ -n $MSMPT ] ; then MAIL=$MSMTP elif [ -n $SSMTP ] && [ -z $MAIL ] ; then MAIL=$SSMTP diff --git a/notify_apprise.sh b/notify_apprise.sh index 9945524..9080cd8 100644 --- a/notify_apprise.sh +++ b/notify_apprise.sh @@ -33,5 +33,3 @@ apprise -vv -t "$MessageTitle" -b "$MessageBody" \ # curl -X POST -F "title=$MessageTitle" -F "body=$MessageBody" -F "tags=all" $AppriseURL } - - diff --git a/notify_gotify.sh b/notify_gotify.sh index 7a41a77..832b387 100644 --- a/notify_gotify.sh +++ b/notify_gotify.sh @@ -8,18 +8,18 @@ send_notification() { Updates=("$@") 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}" - + # Modify to fit your setup: GotifyToken="Your Gotify token here" - GotifyUrl="https://api.gotify/message?token=${GotifyToken}" - + GotifyUrl="https://api.gotify/message?token=${GotifyToken}" + curl \ -F "title=${MessageTitle}" \ -F "message=${MessageBody}" \ diff --git a/notify_matrix.sh b/notify_matrix.sh index 4c98456..998592a 100644 --- a/notify_matrix.sh +++ b/notify_matrix.sh @@ -8,13 +8,13 @@ send_notification() { Updates=("$@") 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" - + # Modify to fit your setup: AccessToken="Your Matrix token here" Room_id="Enter Room_id here" @@ -24,5 +24,5 @@ send_notification() { # 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" - + } diff --git a/notify_smtp.sh b/notify_smtp.sh index c62d3ed..9c81aa9 100644 --- a/notify_smtp.sh +++ b/notify_smtp.sh @@ -8,7 +8,7 @@ MSMTP=$(which msmtp) SSMTP=$(which ssmtp) -if [ -n $MSMPT ] ; then +if [ -n $MSMPT ] ; then MAIL=$MSMTP elif [ -n $SSMTP ] && [ -z $MAIL ] ; then MAIL=$SSMTP diff --git a/notify_telegram.sh b/notify_telegram.sh index e6da963..45584e6 100644 --- a/notify_telegram.sh +++ b/notify_telegram.sh @@ -8,20 +8,20 @@ send_notification() { Updates=("$@") 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" - + # Modify to fit your setup: TelegramToken="Your Telegram token here" TelegramChatId="Your Telegram ChatId here" TelegramUrl="https://api.telegram.org/bot$TelegramToken" TelegramTopicID=12345678 ## Set to 0 if not using specific topic within chat 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" - + }