Skip to content

Commit

Permalink
fix: enhance logging in backup; fix cron scheduling
Browse files Browse the repository at this point in the history
  • Loading branch information
jmaddington committed Nov 26, 2024
1 parent c3cfc30 commit 568e0fc
Show file tree
Hide file tree
Showing 2 changed files with 107 additions and 20 deletions.
28 changes: 26 additions & 2 deletions app/backup.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,25 @@
from datetime import datetime

logger = logging.getLogger(__name__)
logger.setLevel(logging.INFO)

# Create handlers
console_handler = logging.StreamHandler()

# Ensure the log directory exists
log_dir = os.path.dirname('/var/log/pgbackup.log')
if not os.path.exists(log_dir):
os.makedirs(log_dir)
file_handler = logging.FileHandler('/var/log/pgbackup.log')

# Create formatters and add them to handlers
formatter = logging.Formatter('[PGBACKUP] %(asctime)s - %(name)s - %(levelname)s - %(message)s')
console_handler.setFormatter(formatter)
file_handler.setFormatter(formatter)

# Add handlers to the logger
logger.addHandler(console_handler)
logger.addHandler(file_handler)

def main():
parser = argparse.ArgumentParser(description="Backup script with optional GPG encryption and post-backup script.")
Expand All @@ -19,9 +38,14 @@ def main():
parser.add_argument("--gid", type=int, help="GID for the backup file")
args = parser.parse_args()

# Get the current datetime and format it
# # Get the current datetime and format it
current_datetime = datetime.now().strftime("%Y-%m-%d-%H-%M-%S")
output_path = f"{current_datetime}-{args.output}"
# output_path = f"{args.output}-{current_datetime}"

# Prefix the filename with the current date by splitting the output path and inserting the current datetime
split_path = args.output.split("/")
split_path[-1] = f"{current_datetime}-{split_path[-1]}"
output_path = "/".join(split_path)

try:
if args.encrypt:
Expand Down
99 changes: 81 additions & 18 deletions app/entrypoint.py
Original file line number Diff line number Diff line change
@@ -1,27 +1,59 @@
import os
import subprocess
import logging
from datetime import datetime
import argparse
import time

print("Welcome to the entrypoint script!")

logger = logging.getLogger(__name__)
logger.setLevel(logging.INFO)

# Create handlers
console_handler = logging.StreamHandler()

# Ensure the log directory exists
log_dir = os.path.dirname('/var/log/pgbackup.log')
if not os.path.exists(log_dir):
os.makedirs(log_dir)
file_handler = logging.FileHandler('/var/log/pgbackup.log')

# Create formatters and add them to handlers
formatter = logging.Formatter('[PGBACKUP] %(asctime)s - %(name)s - %(levelname)s - %(message)s')
console_handler.setFormatter(formatter)
file_handler.setFormatter(formatter)

# Add handlers to the logger
logger.addHandler(console_handler)
logger.addHandler(file_handler)

logger.info("The date of this host is: %s", subprocess.run(["date"], stdout=subprocess.PIPE).stdout.decode().strip())

PG_VERSION = os.getenv("PG_VERSION", "16")

# If /scripts exists chmod +xr-w all files in it
if os.path.exists("/scripts"):
for file in os.listdir("/scripts"):
os.chmod(f"/scripts/{file}", 0o555)
parser = argparse.ArgumentParser(description="Entrypoint script and cron job target")
parser.add_argument("--cron", required=False, type=bool, default=False, help="Run the cron job")
args = parser.parse_args()

try:
subprocess.run(["apt", "install", "-y", f"postgresql-client-{PG_VERSION}"], check=True)
except subprocess.CalledProcessError as e:
logger.error(f"Failed to install PostgreSQL client: {e}")
exit(1)
except Exception as e:
logger.error(f"An unexpected error occurred during PostgreSQL client installation: {e}")
exit(1)
if args.cron:
logger.info("Running in cron mode.")

# Housekeeping if running for the first time
if args.cron == False:
# If /scripts exists chmod +xr-w all files in it
if os.path.exists("/scripts"):
for file in os.listdir("/scripts"):
os.chmod(f"/scripts/{file}", 0o555)

try:
logger.info("Installing PostgreSQL client...")
subprocess.run(["apt", "install", "-y", f"postgresql-client-{PG_VERSION}"], check=True)
except subprocess.CalledProcessError as e:
logger.error(f"Failed to install PostgreSQL client: {e}")
exit(1)
except Exception as e:
logger.error(f"An unexpected error occurred during PostgreSQL client installation: {e}")
exit(1)

try:
cron_schedule = os.getenv("CRON_SCHEDULE")
Expand Down Expand Up @@ -61,20 +93,36 @@
with open("/app/key", "w") as key_file:
key_file.write(os.getenv("KEY"))
os.chmod("/app/key", 0o600)


if args.cron == True:
logger.info("Running the cron job backup.")
try:
subprocess.run(backup_command, check=True)
logger.info("Cron backup complete.")
exit(0)
except subprocess.CalledProcessError as e:
logger.error(f"Failed to run cron backup: {e}")
exit(1)
except Exception as e:
logger.error(f"An unexpected error occurred during cron backup: {e}")
exit(1)

# Set up cron job if CRON_SCHEDULE is set and start cron service
if cron_schedule:
logger.info(f"Setting up cron job with schedule: {cron_schedule}")
try:
cron_job = f"{cron_schedule} {' '.join(backup_command)} >> /var/log/cron.log 2>&1"
cron_job = f"{cron_schedule} touch /app/run"
with open("/etc/cron.d/backup-cron", "w") as cron_file:
cron_file.write(cron_job + "\n")
os.chmod("/etc/cron.d/backup-cron", 0o644)
subprocess.run(["crontab", "/etc/cron.d/backup-cron"], check=True)
open("/var/log/cron.log", "a").close()
subprocess.run(["cron"], check=True)

except subprocess.CalledProcessError as e:
logger.error(f"Failed to set up cron job or start cron service: {e}")
exit(1)

except Exception as e:
logger.error(f"An unexpected error occurred while setting up cron job: {e}")
exit(1)
Expand All @@ -92,17 +140,32 @@
logger.error(f"An unexpected error occurred during initial backup: {e}")
exit(1)

# If CRON_SCHEDULE is set, tail the cron log to keep the container running
# If CRON_SCHEDULE is set watch for the /app/run file and run the backup
# It is set up this way because cron can't access the environment variables
if cron_schedule:
subprocess.run(["tail", "-f", "/var/log/cron.log"], check=True)


while True:
# Check to see if /app/run exists
if os.path.exists("/app/run"):
os.remove("/app/run")
try:
subprocess.run(backup_command, check=True)
except subprocess.CalledProcessError as e:
logger.error(f"Failed to run backup: {e}")
exit(1)
else:
logger.debug("No /app/run file found.")
time.sleep(60)

elif not enable_initial_backup:
logger.info("No CRON_SCHEDULE set. Running one-time backup...")
subprocess.run(backup_command, check=True)
logger.info("Backup complete. Exiting.")

except subprocess.CalledProcessError as e:
logger.error(f"Failed to run backup or set up cron job: {e}")
exit(1)

except Exception as e:
logger.error(f"An unexpected error occurred: {e}")
exit(1)

0 comments on commit 568e0fc

Please sign in to comment.