--- # Досоздание баз в уже работающей СУБД. # # ЗАЧЕМ ЭТО ОТДЕЛЬНАЯ ЗАДАЧА. Базы описаны декларативно — 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]