diff --git a/common.yaml.jinja b/common.yaml.jinja index 76bdc577..941ca012 100644 --- a/common.yaml.jinja +++ b/common.yaml.jinja @@ -1,4 +1,6 @@ {% import "_macros.jinja" as macros -%} +{%- import "_traefik2_labels.yml.jinja" as traefik2_labels -%} + version: "2.4" services: @@ -39,6 +41,7 @@ services: environment: POSTGRES_DB: *dbname POSTGRES_USER: *dbuser + PGHOST: "${DB_HOST:-db}" CONF_EXTRA: | work_mem = 512MB volumes: diff --git a/devel.yaml.jinja b/devel.yaml.jinja index a7ca099b..84d0da3a 100644 --- a/devel.yaml.jinja +++ b/devel.yaml.jinja @@ -1,4 +1,6 @@ {%- import "_macros.jinja" as macros -%} +{%- import "_traefik2_labels.yml.jinja" as traefik2_labels -%} +{%- set _key = traefik2_labels.key(project_name, odoo_version, "devel") -%} {% set whitelisted_hosts = ( "cdnjs.cloudflare.com", "fonts.googleapis.com", @@ -52,11 +54,12 @@ services: WDB_WEB_PORT: "{{ macros.version_major(odoo_version) }}984" # To avoid installing demo data export DOODBA_WITHOUT_DEMO=all WITHOUT_DEMO: "${DOODBA_WITHOUT_DEMO-false}" + PGHOST: {{ _key }}-db volumes: - ./odoo/custom:/opt/odoo/custom:ro,z - ./odoo/auto:/opt/odoo/auto:rw,z depends_on: - - db + - {{ _key }}-db {% for host in whitelisted_hosts -%} - proxy_{{ host|replace(".", "_") }} {% endfor -%} @@ -77,13 +80,14 @@ services: {%- endif %} {% if postgres_version -%} - db: + {{ _key }}-db: extends: file: common.yaml service: db environment: POSTGRES_DB: *dbname POSTGRES_PASSWORD: odoopassword + DB_HOST: {{ _key }}-db {%- endif %} pgweb: @@ -92,9 +96,10 @@ services: ports: - "127.0.0.1:{{ macros.version_major(odoo_version) }}081:8081" environment: - DATABASE_URL: postgres://{{ postgres_username }}:odoopassword@db:5432/devel?sslmode=disable + DATABASE_URL: postgres://{{ postgres_username }}:odoopassword@{{ _key }}-db:5432/devel?sslmode=disable + PGHOST: {{ _key }}-db depends_on: - - db + - {{ _key }}-db smtp: extends: diff --git a/prod.yaml.jinja b/prod.yaml.jinja index 2fea04ac..8b0ba58d 100644 --- a/prod.yaml.jinja +++ b/prod.yaml.jinja @@ -30,8 +30,9 @@ services: {%- if smtp_relay_host %} SMTP_SERVER: smtplocal {%- endif %} + PGHOST: {{ _key }}-db depends_on: - - db + - {{ _key }}-db {%- if smtp_relay_host %} - smtp {%- endif %} @@ -83,10 +84,12 @@ services: {%- endif %} {% if postgres_version -%} - db: + {{ _key }}-db: extends: file: common.yaml service: db + environment: + - DB_HOST={{ _key }}-db env_file: - .docker/db-creation.env restart: unless-stopped @@ -136,8 +139,10 @@ services: - .docker/backup.env - .docker/db-access.env restart: unless-stopped + environment: + PGHOST: {{ _key }}-db depends_on: - - db + - {{ _key }}-db {%- if smtp_relay_host %} - smtp {%- endif %} diff --git a/tasks_downstream.py b/tasks_downstream.py index 9befb697..3576ef43 100644 --- a/tasks_downstream.py +++ b/tasks_downstream.py @@ -26,10 +26,42 @@ PROJECT_ROOT = Path(__file__).parent.absolute() SRC_PATH = PROJECT_ROOT / "odoo" / "custom" / "src" + +# _key = os.environ.get("_key", "").strip() +# DB_SERVICE = os.environ.get("DB_HOST") or (_key + "-db" if _key else "db") + + +def get_db_service_name(): + """ + Return the database service name that ends with '-db'. If not found, + fall back to any service containing 'postgres' or 'db'. As a last + resort, return 'db'. + """ + for filename in ("devel.yaml", "devel.yml", "docker-compose.yml"): + compose_file = PROJECT_ROOT / filename + if compose_file.exists(): + with open(compose_file) as f: + try: + compose_data = yaml.safe_load(f) or {} + services = compose_data.get("services", {}) + for svc in services: + if svc.lower().endswith("-db"): + return svc + for svc in services: + if "postgres" in svc.lower() or "db" in svc.lower(): + return svc + except yaml.YAMLError: + pass + return "db" + + +DB_SERVICE = get_db_service_name() + UID_ENV = { "GID": os.environ.get("DOODBA_GID", str(os.getgid())), "UID": os.environ.get("DOODBA_UID", str(os.getuid())), "DOODBA_UMASK": os.environ.get("DOODBA_UMASK", "27"), + "PGHOST": DB_SERVICE, } UID_ENV.update( { @@ -982,7 +1014,9 @@ def snapshot( if not destination_db: destination_db = f"{source_db}-{datetime.now().strftime('%Y_%m_%d-%H_%M')}" with c.cd(str(PROJECT_ROOT)): - cur_state = c.run(f"{DOCKER_COMPOSE_CMD} stop odoo db", pty=True).stdout + cur_state = c.run( + f"{DOCKER_COMPOSE_CMD} stop odoo {DB_SERVICE}", pty=True + ).stdout _logger.info("Snapshoting current %s DB to %s", (source_db, destination_db)) _run = f"{DOCKER_COMPOSE_CMD} run --rm -l traefik.enable=false odoo" c.run( @@ -992,7 +1026,7 @@ def snapshot( ) if "Stopping" in cur_state: # Restart services if they were previously active - c.run(f"{DOCKER_COMPOSE_CMD} start odoo db", pty=True) + c.run(f"{DOCKER_COMPOSE_CMD} start odoo {DB_SERVICE}", pty=True) @task( @@ -1013,7 +1047,9 @@ def restore_snapshot( Uses click-odoo-copydb behind the scenes to restore a DB snapshot. """ with c.cd(str(PROJECT_ROOT)): - cur_state = c.run(f"{DOCKER_COMPOSE_CMD} stop odoo db", pty=True).stdout + cur_state = c.run( + f"{DOCKER_COMPOSE_CMD} stop odoo {DB_SERVICE}", pty=True + ).stdout if not snapshot_name: # List DBs res = c.run( @@ -1054,4 +1090,4 @@ def restore_snapshot( pty=True, ) if "Stopping" in cur_state: - c.run(f"{DOCKER_COMPOSE_CMD} start odoo db", pty=True) + c.run(f"{DOCKER_COMPOSE_CMD} start odoo {DB_SERVICE}", pty=True) diff --git a/test.yaml.jinja b/test.yaml.jinja index d9c28355..ff853c53 100644 --- a/test.yaml.jinja +++ b/test.yaml.jinja @@ -24,12 +24,13 @@ services: SMTP_SERVER: smtplocal # Just in case you use queue_job ODOO_QUEUE_JOB_CHANNELS: "root:1" + PGHOST: {{ _key }}-db restart: unless-stopped {%- if domains_test %} hostname: {{ macros.first_main_domain(domains_test)|tojson }} {%- endif %} depends_on: - - db + - {{ _key }}-db - smtp networks: default: @@ -57,12 +58,14 @@ services: - --max-cron-threads=1 {% if postgres_version -%} - db: + {{ _key }}-db: extends: file: common.yaml service: db env_file: - .docker/db-creation.env + environment: + - DB_HOST={{ _key }}-db restart: unless-stopped {%- endif %} diff --git a/tests/test_postgres.py b/tests/test_postgres.py index 3570422d..0bcbe4f1 100644 --- a/tests/test_postgres.py +++ b/tests/test_postgres.py @@ -8,6 +8,33 @@ from .conftest import DBVER_PER_ODOO +try: + from python_on_whales.components.compose.models import ComposeConfig +except ImportError: + ComposeConfig = None + + +def _get_db_service_name(dc: DockerClient) -> str: + config_data = dc.compose.config() + + # (1) In newer versions of python-on-whales: + # config_data is a ComposeConfig => config_data.services is a dict: + # { "service_name": ServiceConfig(...) } + # (2) In older versions: config_data is a "legacy" dict + # => config_data["services"] => { "service_name": {...} } + + if ComposeConfig and isinstance(config_data, ComposeConfig): + services_dict = config_data.services + else: + services_dict = config_data["services"] + for svc_name in services_dict: + if svc_name.lower().endswith("-db"): + return svc_name + for svc_name in services_dict: + if "postgres" in svc_name.lower() or "db" in svc_name.lower(): + return svc_name + return "db" + @pytest.mark.parametrize("dbver", ("oldest", "latest")) def test_postgresql_client_versions( @@ -17,18 +44,24 @@ def test_postgresql_client_versions( dbver: str, ): """Test multiple postgresql-client versions in odoo, db and duplicity services""" + unique_project_name = f"test_{uuid.uuid4().hex}" + dc_prod = DockerClient( + compose_files=["prod.yaml"], + compose_project_name=unique_project_name, + ) + dbver_raw = DBVER_PER_ODOO[supported_odoo_version][dbver] dbver_mver = dbver_raw.split(".")[0] - dc_prod = DockerClient(compose_files=["prod.yaml"]) + with local.cwd(tmp_path): print(str(cloned_template)) - assert True + run_copy( str(cloned_template), dst_path=".", data={ "odoo_version": supported_odoo_version, - "project_name": uuid.uuid4().hex, + "project_name": unique_project_name, "odoo_proxy": "", "postgres_version": dbver_raw, "backup_dst": "/tmp/dummy", @@ -40,6 +73,7 @@ def test_postgresql_client_versions( ) try: dc_prod.compose.build() + db_svc = _get_db_service_name(dc_prod) odoo_pgdump_stdout = dc_prod.compose.run( "odoo", command=["pg_dump", "--version"], @@ -50,7 +84,7 @@ def test_postgresql_client_versions( odoo_pgdump_stdout.splitlines()[-1].strip().split(" ")[2].split(".")[0] ) db_pgdump_stdout = dc_prod.compose.run( - "db", + db_svc, command=["pg_dump", "--version"], remove=True, tty=False,