From 122057cc484c1d1e07f84c23a6f0387d5fb91929 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Th=C3=A9o=20LAGACHE?= Date: Mon, 20 Apr 2026 11:19:54 +0200 Subject: [PATCH] add: firebird --- commands/agent.py | 69 ++++++++++++++++++++++++++++++++++++++++++-- commands/db.py | 51 +++++++++++++++++++++++++++----- pyproject.toml | 3 +- templates/compose.py | 20 +++++++++++++ 4 files changed, 132 insertions(+), 11 deletions(-) diff --git a/commands/agent.py b/commands/agent.py index 1b0fd1f..dfc5912 100644 --- a/commands/agent.py +++ b/commands/agent.py @@ -21,6 +21,7 @@ validate_edge_key, ) from templates.compose import ( + AGENT_FIREBIRD_SNIPPET, AGENT_MARIADB_SNIPPET, AGENT_MONGODB_AUTH_SNIPPET, AGENT_MONGODB_SNIPPET, @@ -77,6 +78,22 @@ def agent( raw_template = fetch_template("agent.yml") + if "{{EXTRA_SERVICES}}" not in raw_template: + if "\nnetworks:" in raw_template: + raw_template = raw_template.replace( + "\nnetworks:", "\n\n{{EXTRA_SERVICES}}\n\nnetworks:" + ) + else: + raw_template += "\n\n{{EXTRA_SERVICES}}\n" + + if "{{EXTRA_VOLUMES}}" not in raw_template: + if "\nnetworks:" in raw_template: + raw_template = raw_template.replace( + "\nnetworks:", "\n\n{{EXTRA_VOLUMES}}\n\nnetworks:" + ) + else: + raw_template += "\n\n{{EXTRA_VOLUMES}}\n" + env_vars = { "EDGE_KEY": key, "PROJECT_NAME": project_name, @@ -114,7 +131,7 @@ def agent( if category == "SQL": db_type = Prompt.ask( "Type", - choices=["postgresql", "mysql", "mariadb", "sqlite"], + choices=["postgresql", "mysql", "mariadb", "sqlite", "firebird"], default="postgresql", ) else: @@ -150,7 +167,11 @@ def agent( "Port", default=5432 if db_type == "postgresql" - else (3306 if db_type in ["mysql", "mariadb"] else 27017), + else ( + 3050 + if db_type == "firebird" + else (3306 if db_type in ["mysql", "mariadb"] else 27017) + ), ) user = Prompt.ask("Username") password = Prompt.ask("Password", password=True) @@ -177,7 +198,7 @@ def agent( if category == "SQL": db_engine = Prompt.ask( "Engine", - choices=["postgresql", "mysql", "mariadb", "sqlite"], + choices=["postgresql", "mysql", "mariadb", "sqlite", "firebird"], default="postgresql", ) db_variant = "standard" @@ -372,6 +393,48 @@ def agent( f"[success]✔ Added MongoDB container (Port {mongo_port})[/success]" ) + elif db_engine == "firebird": + fb_port = get_free_port() + db_user = "alice" + db_pass = secrets.token_hex(8) + db_name = "mirror.fdb" + service_name = f"db-firebird-{secrets.token_hex(2)}" + + var_prefix = service_name.upper().replace("-", "_") + env_vars[f"{var_prefix}_PORT"] = str(fb_port) + env_vars[f"{var_prefix}_DB"] = db_name + env_vars[f"{var_prefix}_USER"] = db_user + env_vars[f"{var_prefix}_PASS"] = db_pass + + snippet = ( + AGENT_FIREBIRD_SNIPPET.replace("${SERVICE_NAME}", service_name) + .replace("${PORT}", f"${{{var_prefix}_PORT}}") + .replace("${VOL_NAME}", f"{service_name}-data") + .replace("${DB_NAME}", f"${{{var_prefix}_DB}}") + .replace("${USER}", f"${{{var_prefix}_USER}}") + .replace("${PASSWORD}", f"${{{var_prefix}_PASS}}") + ) + + extra_services += snippet + volumes_list.append(f"{service_name}-data") + + add_db_to_json( + path, + { + "name": db_name, + "database": db_name, + "type": "firebird", + "username": db_user, + "password": db_pass, + "port": fb_port, + "host": "localhost", + "generated_id": str(uuid.uuid4()), + }, + ) + console.print( + f"[success]✔ Added Firebird container (Port {fb_port})[/success]" + ) + if volumes_list: for vol in volumes_list: extra_volumes += f" {vol}:\n" diff --git a/commands/db.py b/commands/db.py index 3ef9b8e..a01f9e8 100644 --- a/commands/db.py +++ b/commands/db.py @@ -10,6 +10,7 @@ from core.config import add_db_to_json, load_db_config, save_db_config, write_env_file from core.utils import console, get_free_port, validate_work_dir from templates.compose import ( + AGENT_FIREBIRD_SNIPPET, AGENT_MARIADB_SNIPPET, AGENT_MONGODB_AUTH_SNIPPET, AGENT_MONGODB_SNIPPET, @@ -75,7 +76,7 @@ def add_db(name: str = typer.Argument(..., help="Name of the agent")): if category == "SQL": db_type = Prompt.ask( "Type", - choices=["postgresql", "mysql", "mariadb", "sqlite"], + choices=["postgresql", "mysql", "mariadb", "sqlite", "firebird"], default="postgresql", ) else: @@ -98,7 +99,11 @@ def add_db(name: str = typer.Argument(..., help="Name of the agent")): "Port", default=5432 if db_type == "postgresql" - else (3306 if db_type in ["mysql", "mariadb"] else 27017), + else ( + 3050 + if db_type == "firebird" + else (3306 if db_type in ["mysql", "mariadb"] else 27017) + ), ) user = Prompt.ask("Username") password = Prompt.ask("Password", password=True) @@ -119,7 +124,7 @@ def add_db(name: str = typer.Argument(..., help="Name of the agent")): if category == "SQL": db_engine = Prompt.ask( "Engine", - choices=["postgresql", "mysql", "mariadb", "sqlite"], + choices=["postgresql", "mysql", "mariadb", "sqlite", "firebird"], default="postgresql", ) else: @@ -246,23 +251,55 @@ def add_db(name: str = typer.Argument(..., help="Name of the agent")): .replace("${DB_NAME}", f"${{{var_prefix}_DB}}") ) + elif db_engine == "firebird": + db_port = get_free_port() + db_user = "alice" + db_pass = secrets.token_hex(8) + db_name = "mirror.fdb" + service_name = f"db-firebird-{secrets.token_hex(2)}" + var_prefix = service_name.upper().replace("-", "_") + env_vars[f"{var_prefix}_PORT"] = str(db_port) + env_vars[f"{var_prefix}_DB"] = db_name + env_vars[f"{var_prefix}_USER"] = db_user + env_vars[f"{var_prefix}_PASS"] = db_pass + snippet = ( + AGENT_FIREBIRD_SNIPPET.replace("${SERVICE_NAME}", service_name) + .replace("${PORT}", f"${{{var_prefix}_PORT}}") + .replace("${VOL_NAME}", f"{service_name}-data") + .replace("${DB_NAME}", f"${{{var_prefix}_DB}}") + .replace("${USER}", f"${{{var_prefix}_USER}}") + .replace("${PASSWORD}", f"${{{var_prefix}_PASS}}") + ) + compose_path = path / "docker-compose.yml" if compose_path.exists(): with open(compose_path, "r") as f: content = f.read() - insert_pos = content.find("networks:") - if insert_pos == -1: + if "\nnetworks:" in content: + insert_pos = content.find("\nnetworks:") + 1 + elif content.startswith("networks:"): + insert_pos = 0 + else: insert_pos = len(content) new_content = content[:insert_pos] + snippet + "\n" + content[insert_pos:] vol_snippet = f" {service_name}-data:\n" - vol_pos = new_content.find("volumes:") + + vol_pos = -1 + if "\nvolumes:" in new_content: + vol_pos = new_content.find("\nvolumes:") + 1 + elif new_content.startswith("volumes:"): + vol_pos = 0 + if vol_pos != -1: - end_of_volumes = new_content.find("networks:", vol_pos) + end_of_volumes = new_content.find("\nnetworks:", vol_pos) if end_of_volumes == -1: end_of_volumes = len(new_content) + else: + end_of_volumes += 1 + new_content = ( new_content[:end_of_volumes] + vol_snippet diff --git a/pyproject.toml b/pyproject.toml index 9b8d350..4c81167 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -8,5 +8,6 @@ dependencies = [ "rich>=14.2.0", "typer>=0.20.0", "pyinstaller>=6.17.0", - "requests>=2.32.5" + "requests>=2.32.5", + "pyyaml >=6.0.0", ] diff --git a/templates/compose.py b/templates/compose.py index 03eaa43..83bbfe7 100644 --- a/templates/compose.py +++ b/templates/compose.py @@ -57,5 +57,25 @@ - ${VOL_NAME}:/data/db """ +AGENT_FIREBIRD_SNIPPET = """ + ${SERVICE_NAME}: + container_name: ${PROJECT_NAME}-${SERVICE_NAME} + image: firebirdsql/firebird + restart: always + networks: + - portabase + - default + ports: + - "${PORT}:3050" + volumes: + - ${VOL_NAME}:/var/lib/firebird/data + environment: + - FIREBIRD_DATABASE=${DB_NAME} + - FIREBIRD_USER=${USER} + - FIREBIRD_PASSWORD=${PASSWORD} + - FIREBIRD_ROOT_PASSWORD=${PASSWORD} + - FIREBIRD_DATABASE_DEFAULT_CHARSET=UTF8 +""" +