Skip to content

Commit

Permalink
Using unique service db names (#515)
Browse files Browse the repository at this point in the history
[IMP] Use unique db service name for project, version and environment

- Setting environment variable PGHOST to current service name
- Adapt test
- Adapt tasks_downstream
  • Loading branch information
josep-tecnativa authored Feb 13, 2025
1 parent 772d808 commit cb3e32a
Show file tree
Hide file tree
Showing 6 changed files with 103 additions and 17 deletions.
3 changes: 3 additions & 0 deletions common.yaml.jinja
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
{% import "_macros.jinja" as macros -%}
{%- import "_traefik2_labels.yml.jinja" as traefik2_labels -%}

version: "2.4"

services:
Expand Down Expand Up @@ -39,6 +41,7 @@ services:
environment:
POSTGRES_DB: *dbname
POSTGRES_USER: *dbuser
PGHOST: "${DB_HOST:-db}"
CONF_EXTRA: |
work_mem = 512MB
volumes:
Expand Down
13 changes: 9 additions & 4 deletions devel.yaml.jinja
Original file line number Diff line number Diff line change
@@ -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",
Expand Down Expand Up @@ -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 -%}
Expand All @@ -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:
Expand All @@ -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:
Expand Down
11 changes: 8 additions & 3 deletions prod.yaml.jinja
Original file line number Diff line number Diff line change
Expand Up @@ -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 %}
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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 %}
Expand Down
44 changes: 40 additions & 4 deletions tasks_downstream.py
Original file line number Diff line number Diff line change
Expand Up @@ -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(
{
Expand Down Expand Up @@ -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(
Expand All @@ -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(
Expand All @@ -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(
Expand Down Expand Up @@ -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)
7 changes: 5 additions & 2 deletions test.yaml.jinja
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down Expand Up @@ -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 %}

Expand Down
42 changes: 38 additions & 4 deletions tests/test_postgres.py
Original file line number Diff line number Diff line change
Expand Up @@ -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(
Expand All @@ -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",
Expand All @@ -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"],
Expand All @@ -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,
Expand Down

0 comments on commit cb3e32a

Please sign in to comment.