| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144 | #!/usr/bin/env bashset -eBACKUP_PATH="/backup"# Make sure that required directories existmkdir -p "${BACKUP_PATH}"mkdir -p "/etc/crontabs"chown git:git /backupchmod 2770 /backup# [string] BACKUP_INTERVAL   Period expression# [string] BACKUP_RETENTION  Period expressionif [ -z "${BACKUP_INTERVAL}" ]; then	echo "Backup disabled: BACKUP_INTERVAL has not been found" 1>&2	exit 1fiif [ -z "${BACKUP_RETENTION}" ]; then	echo "Backup retention period is not defined, default to 7 days" 1>&2	BACKUP_RETENTION='7d'fi# Parse BACKUP_INTERVAL environment variable and generate appropriate cron expression. Backup cron task will be run as scheduled.# Expected format: nu (n - number, u - unit) (eg. 3d means 3 days)# Supported units: h - hours, d - days, M - monthsparse_generate_cron_expression() {	CRON_EXPR_MINUTES="*"	CRON_EXPR_HOURS="*"	CRON_EXPR_DAYS="*"	CRON_EXPR_MONTHS="*"    # shellcheck disable=SC2001	TIME_INTERVAL=$(echo "${BACKUP_INTERVAL}" | sed -e 's/[hdM]$//')    # shellcheck disable=SC2001	TIME_UNIT=$(echo "${BACKUP_INTERVAL}" | sed -e 's/^[0-9]\+//')	if [ "${TIME_UNIT}" = "h" ]; then		if [ ! "${TIME_INTERVAL}" -le 23 ]; then			echo "Parse error: Time unit 'h' (hour) cannot be greater than 23" 1>&2			exit 1		fi		CRON_EXPR_MINUTES=0		CRON_EXPR_HOURS="*/${TIME_INTERVAL}"	elif [ "${TIME_UNIT}" = "d" ]; then		if [ ! "${TIME_INTERVAL}" -le 30 ]; then			echo "Parse error: Time unit 'd' (day) cannot be greater than 30" 1>&2			exit 1		fi		CRON_EXPR_MINUTES=0		CRON_EXPR_HOURS=0		CRON_EXPR_DAYS="*/${TIME_INTERVAL}"	elif [ "${TIME_UNIT}" = "M" ]; then		if [ ! "${TIME_INTERVAL}" -le 12 ]; then			echo "Parse error: Time unit 'M' (month) cannot be greater than 12" 1>&2			exit 1		fi		CRON_EXPR_MINUTES=0		CRON_EXPR_HOURS=0		CRON_EXPR_DAYS="1"		CRON_EXPR_MONTHS="*/${TIME_INTERVAL}"	else		echo "Parse error: BACKUP_INTERVAL expression is invalid" 1>&2		exit 1	fi	echo "${CRON_EXPR_MINUTES} ${CRON_EXPR_HOURS} ${CRON_EXPR_DAYS} ${CRON_EXPR_MONTHS} *"}# Parse BACKUP_RETENTION environment variable and generate appropriate find command expression.# Expected format: nu (n - number, u - unit) (eg. 3d means 3 days)# Supported units: m - minutes, d - daysparse_generate_retention_expression() {	FIND_TIME_EXPR='mtime'	# shellcheck disable=SC2001	TIME_INTERVAL=$(echo "${BACKUP_RETENTION}" | sed -e 's/[mhdM]$//')	# shellcheck disable=SC2001	TIME_UNIT=$(echo "${BACKUP_RETENTION}" | sed -e 's/^[0-9]\+//')	if [ "${TIME_UNIT}" = "m" ]; then		if [ "${TIME_INTERVAL}" -le 59 ]; then			echo "Warning: Minimal retention is 60m. Value set to 60m" 1>&2			TIME_INTERVAL=60		fi		FIND_TIME_EXPR="mmin"	elif [ "${TIME_UNIT}" = "h" ]; then		echo "Error: Unsupported expression - Try: eg. 120m for 2 hours." 1>&2		exit 1	elif [ "${TIME_UNIT}" = "d" ]; then		FIND_TIME_EXPR="mtime"	elif [ "${TIME_UNIT}" = "M" ]; then		echo "Error: Unsupported expression - Try: eg. 60d for 2 months." 1>&2		exit 1	else		echo "Parse error: BACKUP_RETENTION expression is invalid" 1>&2		exit 1	fi	echo "${FIND_TIME_EXPR} +${TIME_INTERVAL:-7}"}add_backup_cronjob() {	CRONTAB_USER="${1:-git}"	CRONTAB_FILE="/etc/crontabs/${CRONTAB_USER}"	CRONJOB_EXPRESSION="${2:-}"	CRONJOB_EXECUTOR="${3:-}"	CRONJOB_EXECUTOR_ARGUMENTS="${4:-}"  CRONJOB_TASK="${CRONJOB_EXPRESSION} /bin/sh ${CRONJOB_EXECUTOR} ${CRONJOB_EXECUTOR_ARGUMENTS}"	if [ -f "${CRONTAB_FILE}" ]; then		CRONJOB_EXECUTOR_COUNT=$(grep -c "${CRONJOB_EXECUTOR}" "${CRONTAB_FILE}" || exit 0)		if [ "${CRONJOB_EXECUTOR_COUNT}" != "0" ]; then			echo "Cron job already exists for ${CRONJOB_EXECUTOR}. Updating existing." 1>&2			CRONJOB_TASK=$(echo "{CRONJOB_TASK}" | sed 's/\//\\\//g' )			CRONJOB_EXECUTOR=$(echo "{CRONJOB_EXECUTOR}" | sed 's/\//\\\//g' )			sed -i "/${CRONJOB_EXECUTOR}/c\\${CRONJOB_TASK}" "${CRONTAB_FILE}"			return 0		fi	fi	# Finally append new line with cron task expression	echo "${CRONJOB_TASK}" >>"${CRONTAB_FILE}"}CRONTAB_USER=$(awk -v val="${PUID}" -F ":" '$3==val{print $1}' /etc/passwd)# Up to this point, it was desirable that interpreter handles the command errors and halts execution upon any error.# From now, we handle the errors our self.set +eRETENTION_EXPRESSION="$(parse_generate_retention_expression)"if [ -z "${RETENTION_EXPRESSION}" ]; then	echo "Couldn't generate backup retention expression. Aborting backup setup" 1>&2	exit 1fi# Backup rotator cron will run every 5 minutesadd_backup_cronjob "${CRONTAB_USER}" "*/5 * * * *" "/app/gogs/docker/runtime/backup-rotator.sh" "'${BACKUP_PATH}' '${RETENTION_EXPRESSION}'"add_backup_cronjob "${CRONTAB_USER}" "$(parse_generate_cron_expression)" "/app/gogs/docker/runtime/backup-job.sh" "'${BACKUP_PATH}'"
 |