diff --git a/podman/deploy.py b/podman/deploy.py deleted file mode 100755 index aba6e9c..0000000 --- a/podman/deploy.py +++ /dev/null @@ -1,282 +0,0 @@ -#!/usr/bin/env python3 - -import subprocess # nosec 404 -import sys -from argparse import ArgumentParser -from pathlib import Path - -# Variables -# You might want to change some. - -# Volumes -VOLUMES_DIR = Path.home() / "volumes" -# AdvLabDB -ADVLABDB_REPO_LINK = "https://codeberg.org/Mo8it/AdvLabDB.git" -ADVLABDB_VOLUMES_DIR = VOLUMES_DIR / "advlabdb" -ADVLABDB_REPO_DIR = ADVLABDB_VOLUMES_DIR / "repo" -ADVLABDB_LOGS_DIR = ADVLABDB_VOLUMES_DIR / "logs" -ADVLABDB_DATA_DIR = ADVLABDB_VOLUMES_DIR / "data" -# Nginx -NGINX_CONF_D_DIR = ADVLABDB_VOLUMES_DIR / "nginx/conf.d" -# Traefik -TRAEFIK_VOLUMES_DIR = VOLUMES_DIR / "traefik" -TRAEFIK_ETC_DIR = TRAEFIK_VOLUMES_DIR / "etc" -TRAEFIK_LOGS_DIR = TRAEFIK_VOLUMES_DIR / "logs" -TRAEFIK_CERTS_DIR = TRAEFIK_VOLUMES_DIR / "certs" -# Systemd -SYSTEMD_USER_DIR = Path.home() / ".config/systemd/user" - - -# Parse script arguments - -parser = ArgumentParser( - description="Build the AdvLabDB image and deploy related containers.", -) -parser.add_argument( - "--skip-traefik", - action="store_true", - help="Do not deploy the Traefik container.", -) -parser.add_argument( - "-n", - "--network", - default="traefik", - help="Traefik's network. Default: traefik.", -) -parser.add_argument( - "-v", - "--verbose", - action="store_true", - help="Show more information while running.", -) - -args = parser.parse_args() - -# Functions - - -def run(command: str, **kwargs): - print("\n\nRunning command:") - print(f"\t{command}\n") - return subprocess.run(command, shell=True, **kwargs) # nosec B602 - - -# Needed for create_container -if args.verbose: - print(f"Making sure that the systemd directory for user services {SYSTEMD_USER_DIR} exists.") -SYSTEMD_USER_DIR.mkdir(parents=True, exist_ok=True) - - -def create_container(container_name: str, podman_args: str): - """ - Create a container with a systemd service. - """ - print(f"Creating container: {container_name}.") - run( - f"""podman create \ - --name {container_name} \ - --tz local \ - {podman_args}""", - check=True, - ) - - print(f"Generating a systemd service then enabling and starting it for the container {container_name}.") - print(f"The service is a user service named container-{container_name}.") - print("You can check its status with the following command:") - print(f"\tsystemctl --user status container-{container_name}") - run( - f"podman generate systemd --new --files --name {container_name}", - cwd=SYSTEMD_USER_DIR, - check=True, - ) - run( - f"systemctl --user enable --now container-{container_name}", - check=True, - ) - - -def pull_or_clone_repo(): - if ADVLABDB_REPO_DIR.is_dir(): - print("Pulling AdvLabDB repository.") - run( - "git pull --rebase origin main", - cwd=ADVLABDB_REPO_DIR, - check=True, - ) - else: - if args.verbose: - print(f"Making sure that the volumes directory {ADVLABDB_VOLUMES_DIR} exists.") - ADVLABDB_VOLUMES_DIR.mkdir(parents=True, exist_ok=True) - - print("Cloning AdvLabDB repository") - print(f"From:\t{ADVLABDB_REPO_LINK}") - print(f"Into:\t{ADVLABDB_REPO_DIR}") - run( - f"git clone {ADVLABDB_REPO_LINK} {ADVLABDB_REPO_DIR}", - check=True, - ) - - -def check_requirements(): - settings_file = ADVLABDB_DATA_DIR / "settings.ini" - if not settings_file.is_file(): - sys.exit(f"{settings_file} missing!") - - if not NGINX_CONF_D_DIR.is_dir(): - sys.exit(f"{NGINX_CONF_D_DIR} missing!") - - if not args.skip_traefik: - if not TRAEFIK_ETC_DIR.is_dir(): - sys.exit(f"{TRAEFIK_ETC_DIR} missing!") - - if run(f"podman network exists {args.network}").returncode != 0: - if args.skip_traefik: - sys.exit(f"Skipped Traefik's deployment although Traefik's network {args.network} does not exist!") - else: - print(f"Creating network {args.network}.") - run( - f"podman network create {args.network}", - # Commented out because old buildah versions do not support "network exists" - # check=True, - ) - - -def create_nginx_container(): - create_container( - "advlabdb-nginx", - f"""--network {args.network} \ - -v {NGINX_CONF_D_DIR}:/etc/nginx/conf.d:Z,ro \ - --label "io.containers.autoupdate=registry" \ - docker.io/library/nginx:alpine""", - ) - - -def create_traefik_container(): - if args.verbose: - print(f"Making sure that the logs directory {TRAEFIK_LOGS_DIR} exists.") - TRAEFIK_LOGS_DIR.mkdir(parents=True, exist_ok=True) - - if args.verbose: - print(f"Making sure that the certificates directory {TRAEFIK_CERTS_DIR} exists.") - TRAEFIK_CERTS_DIR.mkdir(parents=True, exist_ok=True) - - create_container( - "traefik", - f"""--network {args.network} \ - -p 80:80 \ - -p 443:443 \ - -v {TRAEFIK_ETC_DIR}:/etc/traefik:Z,ro \ - -v {TRAEFIK_LOGS_DIR}:/volumes/logs:Z \ - -v {TRAEFIK_CERTS_DIR}:/volumes/certs:Z \ - --label "io.containers.autoupdate=registry" \ - docker.io/library/traefik:latest""", - ) - - -# Needed for main and create_advlabdb_container -advlabdb_container_args = f"""--network {args.network} \ - -e ADVLABDB_DATA_DIR=/volumes/data \ - -v {ADVLABDB_REPO_DIR}:/volumes/repo:Z \ - -v {ADVLABDB_DATA_DIR}:/volumes/data:Z \ - -v {ADVLABDB_LOGS_DIR}:/volumes/logs:Z""" - - -def create_advlabdb_container(): - create_container( - "advlabdb", - f"{advlabdb_container_args} localhost/advlabdb:latest", - ) - - -def main(): - pull_or_clone_repo() - - # Checking requirements - - check_requirements() - - # Create/update the AdvLabDB image and container - - # Make sure that the builder container does not exist. - run( - "buildah rm builder", - stderr=subprocess.DEVNULL, - ) - - requirements_file = ADVLABDB_REPO_DIR / "requirements.txt" - container_cmd = ( - "\"gunicorn --bind 0.0.0.0:80 --workers 5 --log-file /volumes/logs/gunicorn.log 'run:create_app()'\"" - ) - - print("Creating AdvLabDB image.") - commands = ( - # Start building from a base image - "buildah from --pull --name builder docker.io/library/python:3.10-slim", - # Install Python requirements in the container - f"buildah copy builder {requirements_file} /root/requirements.txt", - "buildah run builder -- pip3 install -r /root/requirements.txt", - "buildah run builder -- rm /root/requirements.txt", - # Set the working directory of the container - "buildah config --workingdir /volumes/repo builder", - # Set the command that will run after starting the container - f"buildah config --cmd {container_cmd} builder", - ) - - for command in commands: - run(command, check=True) - - if run("systemctl --user is-enabled container-advlabdb").returncode == 0: - print("Disabling and deleting existing container advlabdb.") - run( - "systemctl --user disable --now container-advlabdb", - check=True, - ) - - if run("podman image exists localhost/advlabdb:latest").returncode == 0: - print("Deleting existing image advlabdb.") - run( - "podman rmi localhost/advlabdb:latest", - check=True, - ) - - # Save new image - run( - "buildah commit --rm builder advlabdb", - check=True, - ) - - if args.verbose: - print(f"Making sure that the logs directory {ADVLABDB_LOGS_DIR} exists.") - ADVLABDB_LOGS_DIR.mkdir(parents=True, exist_ok=True) - - # Running setup commands (if needed) - run_manage = f"podman run -it --rm {advlabdb_container_args} localhost/advlabdb:latest python3 manage.py" - commands = ( - # Generate secret keys if secrets.ini does not exist yet - f"{run_manage} setup generate-secrets", - # Initialize a database if none exists - f"{run_manage} setup init-db", - ) - - for command in commands: - run(command, check=True) - - create_advlabdb_container() - - # Create Traefik container if needed - - if not args.skip_traefik and run("systemctl --user is-enabled container-traefik").returncode != 0: - create_traefik_container() - - # Create Nginx container if needed - - if run("systemctl --user is-enabled container-advlabdb-nginx").returncode != 0: - create_nginx_container() - else: - run("systemctl --user restart container-advlabdb-nginx") - - print("\nDone!\n") - - -if __name__ == "__main__": - main()