Продолжение разбора: после появления bimapidb оба пода упали на psycopg2.ProgrammingError: ltree type not found in the database а миграция api — на type "ltree" does not exist LINE 2: ALTER TABLE bimelement ADD hierarchy ltree null; models/database.py при инициализации зовёт register_ltree(conn), без расширения приложение не стартует. Роль bim не суперпользователь и CREATE EXTENSION сама не сделает — расширение обязан завести бутстрап, как у sarex_db и workflow_db. Добавлено в contour.databases. --- Почему понадобилась отдельная задача ansible --- Базы и расширения описаны декларативно, но заводит их скрипт бутстрапа ТОЛЬКО при старте пода postgresql. На живом кластере правка списка доезжает до Kubernetes и не делает ничего: спецификация пода не меняется, пересоздания нет. Flux при этом полностью зелёный, а приложение падает с "database does not exist" — связь между причиной и симптомом неочевидна. Альтернатива — перезапуск postgresql-0, но это обрыв коннектов django, processing и workspaces ради одной базы. Добавлены tasks/databases.yml, список sarex_databases в defaults и задача `uv run poe dbsync`. Делает ровно то же, что бутстрап, но без простоя, и идемпотентно: существующие базы пропускаются, расширения создаются через IF NOT EXISTS. Расширения обрабатываются отдельным шагом и всегда, а не только для новых баз, — расширение может появиться в списке позже самой базы, ровно так и вышло с ltree. Проверено на живом контуре: bim-api 2/2 (uWSGI поднял воркеров), bim-worker 2/2 (celery подключился к брокеру, 8 задач зарегистрировано).
83 lines
4.3 KiB
YAML
83 lines
4.3 KiB
YAML
---
|
||
# Досоздание баз в уже работающей СУБД.
|
||
#
|
||
# ЗАЧЕМ ЭТО ОТДЕЛЬНАЯ ЗАДАЧА. Базы описаны декларативно — contour.databases в
|
||
# infrastructure/postgresql/aero. Но заводит их скрипт бутстрапа, который
|
||
# выполняется ТОЛЬКО при старте пода postgresql. На живом кластере правка
|
||
# списка доезжает до Kubernetes (HelmRelease обновляется, Flux рапортует
|
||
# успех) и не делает ничего: под не пересоздаётся, потому что его
|
||
# спецификация не изменилась.
|
||
#
|
||
# Выглядит это так: приложение падает с
|
||
# psycopg2.OperationalError: FATAL: database "bimapidb" does not exist
|
||
# при полностью зелёном Flux. Так и случилось с bim.
|
||
#
|
||
# Альтернатива — перезапуск postgresql-0, но это обрыв коннектов у django,
|
||
# processing и workspaces ради одной новой базы. Здесь мы делаем ровно то же,
|
||
# что сделал бы бутстрап, но без простоя.
|
||
#
|
||
# ИДЕМПОТЕНТНО: существующие базы пропускаются, повторный прогон ничего не
|
||
# меняет. Ничего не удаляет и не пересоздаёт — только добавляет недостающее.
|
||
#
|
||
# Пароли ролям здесь НЕ задаются: роли и их пароли остаются за бутстрапом и
|
||
# Vault (secrets/postgresql/users). Если роли-владельца ещё нет, создание
|
||
# базы упадёт явно — это правильнее, чем завести её от postgres.
|
||
#
|
||
# Запуск: uv run poe dbsync
|
||
|
||
- name: Получить список существующих баз
|
||
ansible.builtin.shell:
|
||
cmd: >-
|
||
{{ compose_cmd }} exec -T k3s-server
|
||
kubectl -n postgresql exec postgresql-0 -c postgresql --
|
||
sh -ec 'PGPASSWORD=$POSTGRES_POSTGRES_PASSWORD psql -U postgres -tAc
|
||
"select datname from pg_database"'
|
||
chdir: "{{ deploy_dir }}"
|
||
register: existing_databases
|
||
changed_when: false
|
||
tags: [dbsync]
|
||
|
||
- name: Создать недостающие базы
|
||
ansible.builtin.shell:
|
||
cmd: >-
|
||
{{ compose_cmd }} exec -T k3s-server
|
||
kubectl -n postgresql exec postgresql-0 -c postgresql --
|
||
sh -ec 'PGPASSWORD=$POSTGRES_POSTGRES_PASSWORD psql -U postgres -c
|
||
"CREATE DATABASE \"{{ item.name }}\" OWNER \"{{ item.owner }}\""'
|
||
chdir: "{{ deploy_dir }}"
|
||
loop: "{{ sarex_databases }}"
|
||
loop_control:
|
||
label: "{{ item.name }} (владелец {{ item.owner }})"
|
||
when: item.name not in existing_databases.stdout_lines
|
||
changed_when: true
|
||
tags: [dbsync]
|
||
|
||
# Расширения создаются ОТДЕЛЬНЫМ шагом и всегда, а не только для новых баз:
|
||
# расширение могло появиться в списке позже самой базы — ровно так и вышло с
|
||
# ltree у bimapidb. CREATE EXTENSION IF NOT EXISTS идемпотентен.
|
||
#
|
||
# Выполняется от postgres, а не от владельца базы: роли приложений не
|
||
# суперпользователи и создать расширение не могут.
|
||
- name: Создать расширения в базах
|
||
ansible.builtin.shell:
|
||
cmd: >-
|
||
{{ compose_cmd }} exec -T k3s-server
|
||
kubectl -n postgresql exec postgresql-0 -c postgresql --
|
||
sh -ec 'PGPASSWORD=$POSTGRES_POSTGRES_PASSWORD psql -U postgres
|
||
-d "{{ item.0.name }}" -c
|
||
"CREATE EXTENSION IF NOT EXISTS \"{{ item.1 }}\""'
|
||
chdir: "{{ deploy_dir }}"
|
||
loop: "{{ sarex_databases | subelements('extensions', skip_missing=True) }}"
|
||
loop_control:
|
||
label: "{{ item.0.name }}: {{ item.1 }}"
|
||
changed_when: true
|
||
tags: [dbsync]
|
||
|
||
- name: Итог
|
||
ansible.builtin.debug:
|
||
msg: >-
|
||
Базы: {{ sarex_databases | map(attribute='name') | join(', ') }}.
|
||
Уже существовали: {{ sarex_databases | map(attribute='name')
|
||
| select('in', existing_databases.stdout_lines) | join(', ') | default('нет', true) }}
|
||
tags: [dbsync]
|