From 28120175f2c20257d1b14ecb15a5d8cccf139784 Mon Sep 17 00:00:00 2001 From: Pavel Astakhov Date: Fri, 25 Oct 2024 13:38:34 +0500 Subject: [PATCH 1/9] Test jobs before adding them to the crontab file * move timestamp() function to the functions.sh file --- functions.sh | 4 ++++ update_cron.sh | 40 +++++++++++++++++++++++++++++----------- 2 files changed, 33 insertions(+), 11 deletions(-) diff --git a/functions.sh b/functions.sh index dbcab36..73eeba2 100644 --- a/functions.sh +++ b/functions.sh @@ -1,3 +1,7 @@ +timestamp() { + date -u "+%Y-%m-%d %H:%M:%S %Z" +} + isTrue() { case $1 in "True" | "TRUE" | "true" | 1) diff --git a/update_cron.sh b/update_cron.sh index 566124f..e380ecb 100644 --- a/update_cron.sh +++ b/update_cron.sh @@ -4,16 +4,13 @@ DIR=$(dirname "$0") . "$DIR/functions.sh" # Temp cron file paths +CRON_FILE_TEST="/tmp/cron_test" CRON_FILE_NEW="/root/crontab.new" CRON_FILE="/root/crontab" CRON_LOG_DIR=${CRON_LOG_DIR:-/var/log/cron} mkdir -p "$CRON_LOG_DIR" -timestamp() { - date -u "+%Y-%m-%d %H:%M:%S %Z" -} - # Function to extract specific cron job labels from a container extract_cron_jobs() { _container_id=$1 @@ -47,10 +44,11 @@ touch $CRON_FILE_NEW # Process each container for container in $containers; do cron_jobs=$(extract_cron_jobs "$container") + target_container=$(docker inspect -f '{{.Name}}' "$container" | cut -c2-) # Remove leading / if [ -z "$cron_jobs" ]; then - log "No cron jobs found for container: $container" + log "No cron jobs found for container: $target_container ($container)" else - log "Processing container: $container" + log "Processing container: $target_container ($container)" echo "$cron_jobs" | while IFS= read -r job; do decoded_job=$(decode_cron_job "$job") @@ -64,10 +62,19 @@ for container in $containers; do # Check if both schedule and command labels are set if [ -n "$job_schedule" ] && [ -n "$job_command" ]; then - target_container=$(docker inspect -f '{{.Name}}' "$container" | cut -c2-) # Remove leading / cron_entry="$job_schedule docker exec $target_container sh -c '$job_command' 2>&1 | tee -a $CRON_LOG_DIR/\$(date -u +\%Y-\%m-\%d_\%H-\%M-\%S_\%Z)_$job_key.log" - echo "$cron_entry" >> $CRON_FILE_NEW # Write in one line to the cron file - log "Scheduled task for $target_container: $cron_entry" + # Run the supercronic test + echo "$cron_entry" >> $CRON_FILE_TEST + if ! supercronic -test $CRON_FILE_TEST > /dev/null 2>&1; then + printf "\n\n%s ========================================================\n" "$(timestamp)" + echo "ERROR: BAD CRON JOB '$cron_entry'" + supercronic -debug -test $CRON_FILE_TEST + printf "\n================================================================================\n\n" + # TODO make the cron container unhealthy + else + echo "$cron_entry" >> $CRON_FILE_NEW # Write in one line to the cron file + log "Scheduled task for $target_container: $cron_entry" + fi else echo "$(timestamp) Error: job_schedule or job_command is missing." fi @@ -86,8 +93,19 @@ if ! diff -u "$CRON_FILE" "$CRON_FILE_NEW" > /dev/null; then cat "$CRON_FILE_NEW" printf "=========================================\n\n" - # Update the crontab file - cat "$CRON_FILE_NEW" > "$CRON_FILE" + # Update the crontab file if it looks good for supercronic (we tested it one by one line above, but to make sure) + if ! supercronic -test $CRON_FILE_NEW > /dev/null 2>&1; then + printf "\n\n%s ########################################################\n" "$(timestamp)" + echo "ERROR: SOMETHING IS WRONG IN THE CRONTAB FILE" + supercronic -debug -test $CRON_FILE_NEW + echo "ERROR: CHANGES ARE NOT APPLIED." + echo "CURRENT CRONTAB FILE IS:" + cat "$CRON_FILE" + printf "\n################################################################################\n\n" + # TODO make the cron container unhealthy + else + cat "$CRON_FILE_NEW" > "$CRON_FILE" + fi else echo "$(timestamp) No changes detected in crontab file." fi From 05f866f67ebd59883fefd30d51d6d7e1f5a3c761 Mon Sep 17 00:00:00 2001 From: Pavel Astakhov Date: Fri, 25 Oct 2024 14:01:26 +0500 Subject: [PATCH 2/9] improve output messages --- functions.sh | 2 +- update_cron.sh | 18 +++++++++--------- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/functions.sh b/functions.sh index 73eeba2..7890793 100644 --- a/functions.sh +++ b/functions.sh @@ -15,6 +15,6 @@ isTrue() { log() { if isTrue "$DEBUG"; then - echo "$(timestamp)" "$@" + echo "$(timestamp) | " "$@" fi } diff --git a/update_cron.sh b/update_cron.sh index e380ecb..edefae4 100644 --- a/update_cron.sh +++ b/update_cron.sh @@ -31,14 +31,14 @@ extract_cron_command() { # Get the project name if [ -z "$COMPOSE_PROJECT_NAME" ]; then - echo "$(timestamp) COMPOSE_PROJECT_NAME is not set. The service cron will run tasks for all Docker containers." + echo "$(timestamp) | The COMPOSE_PROJECT_NAME variable isn't set. The cron service handles jobs for all docker containers (all docker-compose stacks) on the server." containers=$(docker ps -q) else - echo "$(timestamp) The service cron will run tasks for Docker containers defined in the COMPOSE_PROJECT_NAME: $COMPOSE_PROJECT_NAME" + echo "$(timestamp) | The cron service handles jobs for the docker-compose stack defined in the COMPOSE_PROJECT_NAME variable: $COMPOSE_PROJECT_NAME" containers=$(docker ps --filter "label=com.docker.compose.project=$COMPOSE_PROJECT_NAME" -q) fi -echo "$(timestamp) Updating cron jobs..." +echo "$(timestamp) | Updating cron jobs..." touch $CRON_FILE_NEW # Process each container @@ -66,7 +66,7 @@ for container in $containers; do # Run the supercronic test echo "$cron_entry" >> $CRON_FILE_TEST if ! supercronic -test $CRON_FILE_TEST > /dev/null 2>&1; then - printf "\n\n%s ========================================================\n" "$(timestamp)" + printf "\n\n%s | ========================================================\n" "$(timestamp)" echo "ERROR: BAD CRON JOB '$cron_entry'" supercronic -debug -test $CRON_FILE_TEST printf "\n================================================================================\n\n" @@ -76,7 +76,7 @@ for container in $containers; do log "Scheduled task for $target_container: $cron_entry" fi else - echo "$(timestamp) Error: job_schedule or job_command is missing." + echo "$(timestamp) | Error: job_schedule or job_command is missing." fi done fi @@ -85,17 +85,17 @@ done # Check if there are changes if ! diff -u "$CRON_FILE" "$CRON_FILE_NEW" > /dev/null; then # Print the changes in the crontab: - printf "\n\n%s Changes in the crontab file:\n" "$(timestamp)" + printf "\n\n%s | Changes in the crontab file:\n" "$(timestamp)" diff -u "$CRON_FILE" "$CRON_FILE_NEW" | tail -n +3 # Remove the first two lines containing file names # Print the updated crontab file - printf "\n%s Updated crontab file:\n=========================================\n" "$(timestamp)" + printf "\n%s | Updated crontab file:\n=========================================\n" "$(timestamp)" cat "$CRON_FILE_NEW" printf "=========================================\n\n" # Update the crontab file if it looks good for supercronic (we tested it one by one line above, but to make sure) if ! supercronic -test $CRON_FILE_NEW > /dev/null 2>&1; then - printf "\n\n%s ########################################################\n" "$(timestamp)" + printf "\n\n%s | ########################################################\n" "$(timestamp)" echo "ERROR: SOMETHING IS WRONG IN THE CRONTAB FILE" supercronic -debug -test $CRON_FILE_NEW echo "ERROR: CHANGES ARE NOT APPLIED." @@ -107,7 +107,7 @@ if ! diff -u "$CRON_FILE" "$CRON_FILE_NEW" > /dev/null; then cat "$CRON_FILE_NEW" > "$CRON_FILE" fi else - echo "$(timestamp) No changes detected in crontab file." + echo "$(timestamp) | No changes detected in crontab file." fi rm "$CRON_FILE_NEW" From 011713ec834ccb12a8e2a0e6652dbc4f7e4d52ff Mon Sep 17 00:00:00 2001 From: Pavel Astakhov Date: Fri, 25 Oct 2024 14:11:30 +0500 Subject: [PATCH 3/9] Create empty crontab file --- startup.sh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/startup.sh b/startup.sh index 5916f0d..52cc91d 100644 --- a/startup.sh +++ b/startup.sh @@ -2,7 +2,8 @@ DIR=$(dirname "$0") . "$DIR/functions.sh" -touch /root/crontab +# Create empty crontab file +true > /root/crontab if isTrue "$DEBUG"; then supercronic -debug -inotify /root/crontab & From e77f6f0dc46a94d995acf8b9bd981f910add6d1b Mon Sep 17 00:00:00 2001 From: Pavel Astakhov Date: Fri, 25 Oct 2024 14:14:51 +0500 Subject: [PATCH 4/9] echo "$(timestamp) |" "$@" on log() --- functions.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/functions.sh b/functions.sh index 7890793..52705b6 100644 --- a/functions.sh +++ b/functions.sh @@ -15,6 +15,6 @@ isTrue() { log() { if isTrue "$DEBUG"; then - echo "$(timestamp) | " "$@" + echo "$(timestamp) |" "$@" fi } From e931c60e82f736f3d8c75d499749ec9c721a3eab Mon Sep 17 00:00:00 2001 From: Pavel Astakhov Date: Fri, 25 Oct 2024 14:22:30 +0500 Subject: [PATCH 5/9] printf "\nERROR ERROR ERROR... --- update_cron.sh | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/update_cron.sh b/update_cron.sh index edefae4..2c42333 100644 --- a/update_cron.sh +++ b/update_cron.sh @@ -66,8 +66,9 @@ for container in $containers; do # Run the supercronic test echo "$cron_entry" >> $CRON_FILE_TEST if ! supercronic -test $CRON_FILE_TEST > /dev/null 2>&1; then - printf "\n\n%s | ========================================================\n" "$(timestamp)" - echo "ERROR: BAD CRON JOB '$cron_entry'" + printf "\n%s | ========================================================\n" "$(timestamp)" + printf "\nERROR ERROR ERROR ERROR ERROR ERROR ERROR ERROR ERROR ERROR ERROR ERROR ERROR ERROR ERROR ERROR ERROR\n\n" + echo "BAD CRON JOB: '$cron_entry'" supercronic -debug -test $CRON_FILE_TEST printf "\n================================================================================\n\n" # TODO make the cron container unhealthy @@ -95,8 +96,9 @@ if ! diff -u "$CRON_FILE" "$CRON_FILE_NEW" > /dev/null; then # Update the crontab file if it looks good for supercronic (we tested it one by one line above, but to make sure) if ! supercronic -test $CRON_FILE_NEW > /dev/null 2>&1; then - printf "\n\n%s | ########################################################\n" "$(timestamp)" - echo "ERROR: SOMETHING IS WRONG IN THE CRONTAB FILE" + printf "\n%s | ########################################################\n" "$(timestamp)" + printf "\nERROR ERROR ERROR ERROR ERROR ERROR ERROR ERROR ERROR ERROR ERROR ERROR ERROR ERROR ERROR ERROR ERROR\n\n" + echo "SOMETHING IS WRONG IN THE CRONTAB FILE" supercronic -debug -test $CRON_FILE_NEW echo "ERROR: CHANGES ARE NOT APPLIED." echo "CURRENT CRONTAB FILE IS:" From d39db87091f768cbd5f76239798f2e2e7aadfd17 Mon Sep 17 00:00:00 2001 From: Pavel Astakhov Date: Fri, 25 Oct 2024 21:10:15 +0500 Subject: [PATCH 6/9] remove some emty lines in output --- update_cron.sh | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/update_cron.sh b/update_cron.sh index 2c42333..9dfa30e 100644 --- a/update_cron.sh +++ b/update_cron.sh @@ -66,11 +66,11 @@ for container in $containers; do # Run the supercronic test echo "$cron_entry" >> $CRON_FILE_TEST if ! supercronic -test $CRON_FILE_TEST > /dev/null 2>&1; then - printf "\n%s | ========================================================\n" "$(timestamp)" + echo "$(timestamp) | ========================================================" printf "\nERROR ERROR ERROR ERROR ERROR ERROR ERROR ERROR ERROR ERROR ERROR ERROR ERROR ERROR ERROR ERROR ERROR\n\n" echo "BAD CRON JOB: '$cron_entry'" supercronic -debug -test $CRON_FILE_TEST - printf "\n================================================================================\n\n" + printf "==================================================================================\n\n" # TODO make the cron container unhealthy else echo "$cron_entry" >> $CRON_FILE_NEW # Write in one line to the cron file @@ -86,7 +86,7 @@ done # Check if there are changes if ! diff -u "$CRON_FILE" "$CRON_FILE_NEW" > /dev/null; then # Print the changes in the crontab: - printf "\n\n%s | Changes in the crontab file:\n" "$(timestamp)" + printf "\n%s | Changes in the crontab file:\n" "$(timestamp)" diff -u "$CRON_FILE" "$CRON_FILE_NEW" | tail -n +3 # Remove the first two lines containing file names # Print the updated crontab file @@ -96,14 +96,14 @@ if ! diff -u "$CRON_FILE" "$CRON_FILE_NEW" > /dev/null; then # Update the crontab file if it looks good for supercronic (we tested it one by one line above, but to make sure) if ! supercronic -test $CRON_FILE_NEW > /dev/null 2>&1; then - printf "\n%s | ########################################################\n" "$(timestamp)" + echo "$(timestamp) | ########################################################" printf "\nERROR ERROR ERROR ERROR ERROR ERROR ERROR ERROR ERROR ERROR ERROR ERROR ERROR ERROR ERROR ERROR ERROR\n\n" echo "SOMETHING IS WRONG IN THE CRONTAB FILE" supercronic -debug -test $CRON_FILE_NEW echo "ERROR: CHANGES ARE NOT APPLIED." echo "CURRENT CRONTAB FILE IS:" cat "$CRON_FILE" - printf "\n################################################################################\n\n" + printf "##################################################################################\n\n" # TODO make the cron container unhealthy else cat "$CRON_FILE_NEW" > "$CRON_FILE" From ea54d6d8571d2142b06db44acabd62f56d1aa54e Mon Sep 17 00:00:00 2001 From: Pavel Astakhov Date: Fri, 25 Oct 2024 21:16:31 +0500 Subject: [PATCH 7/9] fix echo "$cron_entry" > $CRON_FILE_TEST --- update_cron.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/update_cron.sh b/update_cron.sh index 9dfa30e..581f632 100644 --- a/update_cron.sh +++ b/update_cron.sh @@ -64,7 +64,7 @@ for container in $containers; do if [ -n "$job_schedule" ] && [ -n "$job_command" ]; then cron_entry="$job_schedule docker exec $target_container sh -c '$job_command' 2>&1 | tee -a $CRON_LOG_DIR/\$(date -u +\%Y-\%m-\%d_\%H-\%M-\%S_\%Z)_$job_key.log" # Run the supercronic test - echo "$cron_entry" >> $CRON_FILE_TEST + echo "$cron_entry" > $CRON_FILE_TEST if ! supercronic -test $CRON_FILE_TEST > /dev/null 2>&1; then echo "$(timestamp) | ========================================================" printf "\nERROR ERROR ERROR ERROR ERROR ERROR ERROR ERROR ERROR ERROR ERROR ERROR ERROR ERROR ERROR ERROR ERROR\n\n" From 26fa24608b723cf3b7287a80190258699a69677c Mon Sep 17 00:00:00 2001 From: Pavel Astakhov Date: Fri, 25 Oct 2024 21:25:29 +0500 Subject: [PATCH 8/9] printf "\n%s | NO JOBS IN CRONTAB FILE\n\n" "$(timestamp)" --- update_cron.sh | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/update_cron.sh b/update_cron.sh index 581f632..aab4742 100644 --- a/update_cron.sh +++ b/update_cron.sh @@ -89,10 +89,14 @@ if ! diff -u "$CRON_FILE" "$CRON_FILE_NEW" > /dev/null; then printf "\n%s | Changes in the crontab file:\n" "$(timestamp)" diff -u "$CRON_FILE" "$CRON_FILE_NEW" | tail -n +3 # Remove the first two lines containing file names - # Print the updated crontab file - printf "\n%s | Updated crontab file:\n=========================================\n" "$(timestamp)" - cat "$CRON_FILE_NEW" - printf "=========================================\n\n" + if [ -z "$(cat filename)" ]; then + printf "\n%s | NO JOBS IN CRONTAB FILE\n\n" "$(timestamp)" + else + # Print the updated crontab file + printf "\n%s | Updated crontab file:\n=========================================\n" "$(timestamp)" + cat "$CRON_FILE_NEW" + printf "=========================================\n\n" + fi # Update the crontab file if it looks good for supercronic (we tested it one by one line above, but to make sure) if ! supercronic -test $CRON_FILE_NEW > /dev/null 2>&1; then From 122c1fec0a56a0058be6296365b17c8c897f1b5a Mon Sep 17 00:00:00 2001 From: Pavel Astakhov Date: Fri, 25 Oct 2024 21:29:19 +0500 Subject: [PATCH 9/9] fix if [ ! -s "$CRON_FILE_NEW" ]; then --- update_cron.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/update_cron.sh b/update_cron.sh index aab4742..39182c0 100644 --- a/update_cron.sh +++ b/update_cron.sh @@ -89,7 +89,7 @@ if ! diff -u "$CRON_FILE" "$CRON_FILE_NEW" > /dev/null; then printf "\n%s | Changes in the crontab file:\n" "$(timestamp)" diff -u "$CRON_FILE" "$CRON_FILE_NEW" | tail -n +3 # Remove the first two lines containing file names - if [ -z "$(cat filename)" ]; then + if [ ! -s "$CRON_FILE_NEW" ]; then printf "\n%s | NO JOBS IN CRONTAB FILE\n\n" "$(timestamp)" else # Print the updated crontab file