mirror of
https://github.com/mag37/dockcheck.git
synced 2026-02-14 23:38:15 +01:00
Start/restart stacks once. Skip failed pulls. Final summary notification.
This commit is contained in:
parent
fc0b1a2505
commit
81d5ef65f6
4 changed files with 83 additions and 13 deletions
7
.gitignore
vendored
7
.gitignore
vendored
|
|
@ -8,4 +8,9 @@ regctl
|
|||
# ignore snooze file
|
||||
snooze.list
|
||||
# ignore updates file
|
||||
updates_available.txt
|
||||
updates_available.txt
|
||||
# ignore user compose files
|
||||
compose.yaml
|
||||
compose.yml
|
||||
docker-compose.yaml
|
||||
docker-compose.yml
|
||||
|
|
|
|||
|
|
@ -44,6 +44,8 @@
|
|||
# DISABLE_DOCKCHECK_NOTIFICATION=false
|
||||
## Uncomment and set to true to disable notifications when notify scripts themselves have updates.
|
||||
# DISABLE_NOTIFY_NOTIFICATION=false
|
||||
## Uncomment and set to true to enable a final action summary notification.
|
||||
# ENABLE_SUMMARY_NOTIFICATION=false
|
||||
#
|
||||
## Apprise configuration variables. Set APPRISE_PAYLOAD to make a CLI call or set APPRISE_URL to make an API request instead.
|
||||
# APPRISE_PAYLOAD='mailto://myemail:mypass@gmail.com
|
||||
|
|
|
|||
36
dockcheck.sh
36
dockcheck.sh
|
|
@ -1,6 +1,6 @@
|
|||
#!/usr/bin/env bash
|
||||
VERSION="v0.7.6"
|
||||
# ChangeNotes: Bugfixes and sanitation. Cleanup of default.config - migrate settings manually (optional).
|
||||
VERSION="v0.7.7"
|
||||
# ChangeNotes: Start/restart stacks once. Skip failed pulls. Final summary notification.
|
||||
Github="https://github.com/mag37/dockcheck"
|
||||
RawUrl="https://raw.githubusercontent.com/mag37/dockcheck/main/dockcheck.sh"
|
||||
|
||||
|
|
@ -94,6 +94,7 @@ GotUpdates=()
|
|||
NoUpdates=()
|
||||
GotErrors=()
|
||||
SelectedUpdates=()
|
||||
Actions=()
|
||||
CurlArgs="--retry ${CurlRetryCount:=3} --retry-delay ${CurlRetryDelay:=1} --connect-timeout ${CurlConnectTimeout:=5} -sf"
|
||||
regbin=""
|
||||
jqbin=""
|
||||
|
|
@ -159,6 +160,7 @@ fi
|
|||
if [[ "$DontUpdate" == true ]]; then AutoMode=true; fi
|
||||
if [[ "$MonoMode" == true ]]; then declare c_{red,green,yellow,blue,teal,reset}=""; fi
|
||||
if [[ "$Notify" == true ]]; then
|
||||
source "${ScriptWorkDir}/notify_templates/notify_v2.sh"
|
||||
source_if_exists_or_fail "${ScriptWorkDir}/notify.sh" || source_if_exists_or_fail "${ScriptWorkDir}/notify_templates/notify_v2.sh" || Notify=false
|
||||
fi
|
||||
if [[ -n "$Exclude" ]]; then
|
||||
|
|
@ -610,8 +612,10 @@ if [[ -n "${GotUpdates:-}" ]]; then
|
|||
if [[ "$DRunUp" == true ]]; then
|
||||
docker pull "$ContImage"
|
||||
printf "%s\n" "$i got a new image downloaded, rebuild manually with preferred 'docker run'-parameters"
|
||||
Actions+=("Pull $ContImage;Success;Manual rebuild with 'docker run'-parameters required")
|
||||
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"
|
||||
Actions+=("Pull $ContImage;Skipped;Started with docker run")
|
||||
fi
|
||||
continue
|
||||
fi
|
||||
|
|
@ -619,8 +623,12 @@ if [[ -n "${GotUpdates:-}" ]]; then
|
|||
if docker pull "$ContImage"; then
|
||||
# Removal of the <none>-tag image left behind from backup
|
||||
if [[ ! -z "${ContRepoDigests:-}" ]] && [[ -n "${BackupForDays:-}" ]]; then docker rmi "$ContRepoDigests"; fi
|
||||
SuccessfulUpdates+=("$i")
|
||||
Actions+=("Pull $ContImage;Success")
|
||||
else
|
||||
printf "\n%bDocker error, exiting!%b\n" "$c_red" "$c_reset" ; exit 1
|
||||
printf "\n%bError pulling update for %S. Skipping. %b\n" "$c_red" "$i" "$c_reset"
|
||||
FailedUpdates+=("$i")
|
||||
Actions+=("Pull $ContImage;Error")
|
||||
fi
|
||||
|
||||
done
|
||||
|
|
@ -630,8 +638,9 @@ if [[ -n "${GotUpdates:-}" ]]; then
|
|||
printf "%bSkipping container recreation due to -R.%b\n" "$c_yellow" "$c_reset"
|
||||
else
|
||||
printf "%bRecreating updated containers.%b\n" "$c_blue" "$c_reset"
|
||||
RestartedStacks=()
|
||||
CurrentQue=0
|
||||
for i in "${SelectedUpdates[@]}"; do
|
||||
for i in "${SuccessfulUpdates[@]}"; do
|
||||
((CurrentQue+=1))
|
||||
unset CompleteConfs
|
||||
# Extract labels and metadata
|
||||
|
|
@ -654,16 +663,18 @@ if [[ -n "${GotUpdates:-}" ]]; then
|
|||
|
||||
if [[ "$ContStateRunning" == "true" ]]; then
|
||||
printf "\n%bNow recreating (%s/%s): %b%s%b\n" "$c_teal" "$CurrentQue" "$NumberofUpdates" "$c_blue" "$i" "$c_reset"
|
||||
{ [[ "${RestartedStacks[@]}" == *"$ContPath"* ]] && { [[ $OnlySpecific != true ]] || [[ $ContOnlySpecific != true ]] } } && printf "%bStack already restarted. Skipping.%b\n" "$c_yellow" "$c_reset"
|
||||
else
|
||||
printf "\n%bSkipping recreation of %b%s%b as it's not running.%b\n" "$c_yellow" "$c_blue" "$i" "$c_yellow" "$c_reset"
|
||||
Actions+=("Recreate $i;Skipped;Not Running")
|
||||
continue
|
||||
fi
|
||||
|
||||
# Checking if compose-values are empty - hence started with docker run
|
||||
[[ -z "$ContPath" ]] && { echo "Not a compose container, skipping."; continue; }
|
||||
[[ -z "$ContPath" ]] && { echo "Not a compose container, skipping."; Actions+=("Recreate $i;Skipped;Not compose") ; continue; }
|
||||
|
||||
# cd to the compose-file directory to account for people who use relative volumes
|
||||
cd "$ContPath" || { printf "\n%bPath error - skipping%b %s" "$c_red" "$c_reset" "$i"; continue; }
|
||||
cd "$ContPath" || { printf "\n%bPath error - skipping%b %s" "$c_red" "$c_reset" "$i"; Actions+=("Recreate $i;Skipped;Path error") ; continue; }
|
||||
# Reformatting path + multi compose
|
||||
if [[ $ContConfigFile == '/'* ]]; then
|
||||
CompleteConfs=$(for conf in ${ContConfigFile//,/ }; do printf -- "-f %s " "$conf"; done)
|
||||
|
|
@ -678,9 +689,13 @@ if [[ -n "${GotUpdates:-}" ]]; then
|
|||
|
||||
# Check if the whole stack should be restarted
|
||||
if [[ "$ContRestartStack" == true ]] || [[ "$ForceRestartStacks" == true ]]; then
|
||||
${DockerBin} ${CompleteConfs} stop; ${DockerBin} ${CompleteConfs} ${ContEnvs} up -d || { printf "\n%bDocker error, exiting!%b\n" "$c_red" "$c_reset" ; exit 1; }
|
||||
[[ "${RestartedStacks[@]}" != *"$ContPath"* ]] && { ${DockerBin} ${CompleteConfs} stop; ${DockerBin} ${CompleteConfs} ${ContEnvs} up -d && Actions+=("Recreate $i;Success;Full stack restart") || { printf "\n%bFailed to recreate $i, skipping.%b\n" "$c_red" "$c_reset" ; Actions+=("Recreate $i;Error;Failed to start stack") ; } }
|
||||
RestartedStacks+=("$ContPath")
|
||||
else
|
||||
${DockerBin} ${CompleteConfs} ${ContEnvs} up -d ${SpecificContainer} || { printf "\n%bDocker error, exiting!%b\n" "$c_red" "$c_reset" ; exit 1; }
|
||||
{ [[ "${RestartedStacks[@]}" != *"$ContPath"* ]] || [[ -n "${SpecificContainer:-}" ]] } && { ${DockerBin} ${CompleteConfs} ${ContEnvs} up -d ${SpecificContainer} && Actions+=("Recreate $i;Success;${SpecificContainer:-Stack}") || { printf "\n%bFailed to recreate $i, skipping.%b\n" "$c_red" "$c_reset" ; Actions+=("Recreate $i;Error;Failed to start ${SpecificContainer:-Stack}") ; } }
|
||||
if [[ -z "${SpecificContainer:-}" ]]; then
|
||||
RestartedStacks+=("$ContPath")
|
||||
fi
|
||||
fi
|
||||
done
|
||||
fi
|
||||
|
|
@ -689,7 +704,7 @@ if [[ -n "${GotUpdates:-}" ]]; then
|
|||
# Trigger pruning only when backup-function is not used
|
||||
if [[ -z "${BackupForDays:-}" ]]; then
|
||||
if [[ "$AutoPrune" == false ]] && [[ "$AutoMode" == false ]]; then printf "\n"; read -rep "Would you like to prune all dangling images? y/[n]: " AutoPrune; fi
|
||||
if [[ "$AutoPrune" == true ]] || [[ "$AutoPrune" =~ [yY] ]]; then printf "\nAuto pruning.."; docker image prune -f; fi
|
||||
if [[ "$AutoPrune" == true ]] || [[ "$AutoPrune" =~ [yY] ]]; then printf "\nAuto pruning.."; docker image prune -f && Actions+=("Prune images;Success"); fi
|
||||
fi
|
||||
|
||||
else
|
||||
|
|
@ -702,4 +717,7 @@ fi
|
|||
# Clean up old backup image tags if -b is used
|
||||
[[ -n "${BackupForDays:-}" ]] && remove_backups
|
||||
|
||||
# Send final summary notification if enabled
|
||||
[[ "${Notify}" == true ]] && [[ "${ENABLE_SUMMARY_NOTIFICATION:-}" == true ]] && [[ "${#Actions[@]} -gt 0" ]] && { exec_if_exists_or_fail send_summary_notification || printf "Could not source summary notification function.\n"; }
|
||||
|
||||
exit 0
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
NOTIFY_V2_VERSION="v0.7"
|
||||
NOTIFY_V2_VERSION="v0.8"
|
||||
#
|
||||
# If migrating from an older notify template, remove your existing notify.sh file.
|
||||
# Leave (or place) this file in the "notify_templates" subdirectory within the same directory as the main dockcheck.sh script.
|
||||
|
|
@ -180,7 +180,9 @@ format_output() {
|
|||
local FormattedTextTemplate="$3"
|
||||
local tempcsv=""
|
||||
|
||||
if [[ ! "${UpdateType}" == "dockcheck_update" ]]; then
|
||||
if [[ "${UpdateType}" == "summary" ]]; then
|
||||
tempcsv="${UpdToString//;/,}"
|
||||
elif [[ ! "${UpdateType}" == "dockcheck_update" ]]; then
|
||||
tempcsv="${UpdToString// -> /,}"
|
||||
tempcsv="${tempcsv//.sh /.sh,}"
|
||||
else
|
||||
|
|
@ -194,12 +196,17 @@ format_output() {
|
|||
FormattedOutput="${tempcsv}"
|
||||
fi
|
||||
elif [[ "${OutputFormat}" == "json" ]]; then
|
||||
if [[ -z "${UpdToString}" ]]; then
|
||||
if [[ "${UpdateType}" == "summary" ]] && [[ -z "${UpdToString}" ]]; then
|
||||
FormattedOutput='{"actions": []}'
|
||||
elif [[ -z "${UpdToString}" ]]; then
|
||||
FormattedOutput='{"updates": []}'
|
||||
else
|
||||
if [[ "${UpdateType}" == "container_update" ]]; then
|
||||
# container updates case
|
||||
FormattedOutput=$(jq --compact-output --null-input --arg updates "${tempcsv}" '($updates | split("\\n")) | map(split(",")) | {"updates": map({"container_name": .[0], "release_notes": .[1]})} | del(..|nulls)')
|
||||
elif [[ "${UpdateType}" == "summary" ]]; then
|
||||
# final summary notification case
|
||||
FormattedOutput=$(jq --compact-output --null-input --arg actions "${tempcsv}" '($actions | split("\\n")) | map(split(",")) | {"actions": map({"action": .[0], "result": .[1], "description": .[2]})} | del(..|nulls)')
|
||||
elif [[ "${UpdateType}" == "notify_update" ]]; then
|
||||
# script updates case
|
||||
FormattedOutput=$(jq --compact-output --null-input --arg updates "${tempcsv}" '($updates | split("\\n")) | map(split(",")) | {"updates": map({"script_name": .[0], "installed_version": .[1], "latest_version": .[2]})}')
|
||||
|
|
@ -216,6 +223,8 @@ format_output() {
|
|||
else
|
||||
if [[ "${UpdateType}" == "container_update" ]]; then
|
||||
FormattedOutput="${FormattedTextTemplate/<insert_text_cu>/${UpdToString}}"
|
||||
elif [[ "${UpdateType}" == "summary" ]]; then
|
||||
FormattedOutput="${FormattedTextTemplate/<insert_text_sn>/${UpdToString}}"
|
||||
elif [[ "${UpdateType}" == "notify_update" ]]; then
|
||||
FormattedOutput="${FormattedTextTemplate/<insert_text_nu>/${UpdToString}}"
|
||||
elif [[ "${UpdateType}" == "dockcheck_update" ]]; then
|
||||
|
|
@ -301,6 +310,42 @@ send_notification() {
|
|||
return 0
|
||||
}
|
||||
|
||||
### Set ENABLE_SUMMARY_NOTIFICATION=true in dockcheck.config
|
||||
### to send a final action summary notification
|
||||
send_summary_notification() {
|
||||
Notified="false"
|
||||
|
||||
MessageTitle="$FromHost - Action summary"
|
||||
|
||||
UpdToString=$( printf '%s\\n' "${Actions[@]}" )
|
||||
UpdToString="${UpdToString%, }"
|
||||
UpdToString=${UpdToString%\\n}
|
||||
|
||||
for channel in "${enabled_notify_channels[@]}"; do
|
||||
local SkipNotification=$(skip_notification "${channel}" "1" "summary")
|
||||
if [[ "${SkipNotification}" == "false" ]]; then
|
||||
local template=$(get_channel_template "${channel}")
|
||||
|
||||
# Formats UpdToString variable per channel settings
|
||||
format_output "summary" "$(output_format "${channel}")" "🐋 Actions taken by $FromHost:\n<insert_text_sn>\n"
|
||||
|
||||
# Setting the MessageBody variable here.
|
||||
printf -v MessageBody "${FormattedOutput}"
|
||||
|
||||
printf "\nSending ${channel} summary notification"
|
||||
exec_if_exists_or_fail trigger_${template}_notification "${channel}" || \
|
||||
printf "\nAttempted to send summary notification to channel ${channel}, but the function was not found. Make sure notify_${template}.sh is available in the ${ScriptWorkDir} directory or notify_templates subdirectory."
|
||||
Notified="true"
|
||||
fi
|
||||
done
|
||||
|
||||
if [[ "${Notified}" == "true" ]]; then
|
||||
printf "\n"
|
||||
fi
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
### Set DISABLE_DOCKCHECK_NOTIFICATION=false in dockcheck.config
|
||||
### to not send notifications when dockcheck itself has updates.
|
||||
dockcheck_notification() {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue