From f5ce8af04caf099ae1f78adb94a9e0cb0318e888 Mon Sep 17 00:00:00 2001 From: samrose Date: Mon, 24 Jun 2024 13:38:04 -0400 Subject: [PATCH 01/45] feat: nix-ami-changes --- .github/workflows/ami-release-nix.yml | 121 +++ .github/workflows/nix-build.yml | 6 +- .github/workflows/text-nix.yml | 117 +++ .github/workflows/textinfra-nix.yml | 145 ++++ amazon-arm64-nix.pkr.hcl | 277 +++++++ .../files/admin_api_scripts/grow_fs.sh | 23 + .../admin_api_scripts/manage_readonly_mode.sh | 45 + .../admin_api_scripts/pg_egress_collect.pl | 132 +++ .../pg_upgrade_scripts/check.sh | 16 + .../pg_upgrade_scripts/common.sh | 63 ++ .../pg_upgrade_scripts/complete.sh | 153 ++++ .../pg_upgrade_scripts/initiate.sh | 333 ++++++++ .../pg_upgrade_scripts/pgsodium_getkey.sh | 12 + .../pg_upgrade_scripts/prepare.sh | 15 + ansible-nix/files/adminapi.service.j2 | 13 + ansible-nix/files/adminapi.sudoers.conf | 28 + ansible-nix/files/ansible-pull.service | 20 + ansible-nix/files/ansible-pull.timer | 11 + ansible-nix/files/apt_periodic | 4 + ansible-nix/files/cron.deny | 2 + .../files/database-optimizations.service.j2 | 12 + ansible-nix/files/default.sysstat | 9 + ansible-nix/files/envoy.service | 31 + ansible-nix/files/envoy_config/cds.yaml | 46 ++ ansible-nix/files/envoy_config/envoy.yaml | 23 + ansible-nix/files/envoy_config/lds.yaml | 315 +++++++ .../remove_apikey_query_parameter.lua | 8 + .../fail2ban_config/fail2ban.service.conf | 6 + .../fail2ban_config/filter-pgbouncer.conf.j2 | 3 + .../fail2ban_config/filter-postgresql.conf.j2 | 3 + .../fail2ban_config/jail-pgbouncer.conf.j2 | 7 + .../fail2ban_config/jail-postgresql.conf.j2 | 8 + .../files/fail2ban_config/jail-ssh.conf | 4 + ansible-nix/files/fail2ban_config/jail.local | 4 + ansible-nix/files/gotrue.service.j2 | 21 + ansible-nix/files/journald.conf | 6 + ansible-nix/files/kong_config/kong.conf.j2 | 7 + ansible-nix/files/kong_config/kong.env.j2 | 8 + ansible-nix/files/kong_config/kong.service.j2 | 28 + ansible-nix/files/logind.conf | 2 + .../logrotate-postgres-auth.conf | 8 + .../logrotate-postgres-csv.conf | 11 + .../logrotate_config/logrotate-postgres.conf | 9 + .../logrotate_config/logrotate-walg.conf | 9 + ansible-nix/files/manifest.json | 1 + ansible-nix/files/nginx.service.j2 | 22 + ansible-nix/files/permission_check.py | 204 +++++ .../files/pg_egress_collect.service.j2 | 13 + .../files/pgbouncer_config/pgbouncer.ini.j2 | 364 ++++++++ .../pgbouncer_config/pgbouncer.service.j2 | 20 + .../pgbouncer_auth_schema.sql | 20 + .../tmpfiles.d-pgbouncer.conf.j2 | 2 + .../files/pgsodium_getkey_readonly.sh.j2 | 14 + .../files/pgsodium_getkey_urandom.sh.j2 | 10 + .../files/postgres_exporter.service.j2 | 14 + .../custom_read_replica.conf.j2 | 5 + .../postgresql_config/custom_walg.conf.j2 | 21 + .../files/postgresql_config/pg_hba.conf.j2 | 94 +++ .../files/postgresql_config/pg_ident.conf.j2 | 50 ++ .../postgresql_config/postgresql-csvlog.conf | 33 + .../postgresql-stdout-log.conf | 4 + .../postgresql_config/postgresql.conf.j2 | 776 ++++++++++++++++++ .../postgresql_config/postgresql.service.j2 | 24 + .../files/postgresql_config/supautils.conf.j2 | 12 + .../tmpfiles.postgresql.conf | 5 + .../before-create.sql | 84 ++ .../dblink/after-create.sql | 14 + .../pg_cron/after-create.sql | 13 + .../pg_tle/after-create.sql | 1 + .../pgsodium/after-create.sql | 3 + .../postgis_tiger_geocoder/after-create.sql | 10 + .../postgres_fdw/after-create.sql | 21 + .../files/postgrest-optimizations.service.j2 | 11 + ansible-nix/files/postgrest.service.j2 | 18 + ansible-nix/files/services.slice.j2 | 6 + ansible-nix/files/sodium_extension.sql | 6 + ansible-nix/files/start-envoy.sh | 12 + ansible-nix/files/stat_extension.sql | 2 + ansible-nix/files/supabase_facts.ini | 2 + ansible-nix/files/sysstat.sysstat | 36 + ansible-nix/files/systemd-resolved.conf | 8 + ansible-nix/files/ufw.service.conf | 4 + ansible-nix/files/vector.service.j2 | 20 + .../wal_change_ownership.sh | 42 + .../files/walg_helper_scripts/wal_fetch.sh | 12 + ansible-nix/manifest-playbook.yml | 91 ++ ansible-nix/playbook.yml | 120 +++ .../tasks/clean-build-dependencies.yml | 21 + ansible-nix/tasks/finalize-ami.yml | 72 ++ ansible-nix/tasks/internal/admin-api.yml | 92 +++ ansible-nix/tasks/internal/admin-mgr.yml | 22 + .../tasks/internal/pg_egress_collect.yml | 15 + .../tasks/internal/postgres-exporter.yml | 48 ++ .../tasks/internal/setup-ansible-pull.yml | 29 + ansible-nix/tasks/internal/setup-nftables.yml | 34 + ansible-nix/tasks/internal/supautils.yml | 77 ++ ansible-nix/tasks/setup-envoy.yml | 60 ++ ansible-nix/tasks/setup-extensions.yml | 94 +++ ansible-nix/tasks/setup-fail2ban.yml | 70 ++ ansible-nix/tasks/setup-gotrue.yml | 54 ++ ansible-nix/tasks/setup-kong.yml | 62 ++ ansible-nix/tasks/setup-migrations.yml | 13 + ansible-nix/tasks/setup-nginx.yml | 82 ++ ansible-nix/tasks/setup-pgbouncer.yml | 135 +++ ansible-nix/tasks/setup-postgres.yml | 132 +++ ansible-nix/tasks/setup-postgrest.yml | 84 ++ ansible-nix/tasks/setup-supabase-internal.yml | 108 +++ ansible-nix/tasks/setup-system.yml | 154 ++++ ansible-nix/tasks/setup-wal-g.yml | 130 +++ ansible-nix/tasks/stage2/optimizations.yml | 27 + ansible-nix/tasks/stage2/playbook.yml | 79 ++ ansible-nix/tasks/stage2/setup-extensions.yml | 70 ++ ansible-nix/tasks/stage2/setup-migrations.yml | 13 + .../tasks/stage2/stage2-setup-postgres.yml | 279 +++++++ ansible-nix/tasks/stage2/test-image.yml | 104 +++ common-nix.vars.pkr.hcl | 1 + ebssurrogate/scripts/chroot-bootstrap-nix.sh | 219 +++++ .../scripts/surrogate-bootstrap-nix.sh | 324 ++++++++ flake.nix | 23 +- nix/ext/postgis.nix | 8 +- nix/ext/sfcgal/sfcgal.nix | 31 + nix/overlays/postgis.nix | 7 - nix/tests/postgresql.conf.in | 1 - nix/tests/prime.sql | 1 - scripts/nix-provision.sh | 43 + stage2-nix-psql.pkr.hcl | 134 +++ 126 files changed, 7298 insertions(+), 22 deletions(-) create mode 100644 .github/workflows/ami-release-nix.yml create mode 100644 .github/workflows/text-nix.yml create mode 100644 .github/workflows/textinfra-nix.yml create mode 100644 amazon-arm64-nix.pkr.hcl create mode 100644 ansible-nix/files/admin_api_scripts/grow_fs.sh create mode 100644 ansible-nix/files/admin_api_scripts/manage_readonly_mode.sh create mode 100644 ansible-nix/files/admin_api_scripts/pg_egress_collect.pl create mode 100755 ansible-nix/files/admin_api_scripts/pg_upgrade_scripts/check.sh create mode 100755 ansible-nix/files/admin_api_scripts/pg_upgrade_scripts/common.sh create mode 100755 ansible-nix/files/admin_api_scripts/pg_upgrade_scripts/complete.sh create mode 100755 ansible-nix/files/admin_api_scripts/pg_upgrade_scripts/initiate.sh create mode 100755 ansible-nix/files/admin_api_scripts/pg_upgrade_scripts/pgsodium_getkey.sh create mode 100755 ansible-nix/files/admin_api_scripts/pg_upgrade_scripts/prepare.sh create mode 100644 ansible-nix/files/adminapi.service.j2 create mode 100644 ansible-nix/files/adminapi.sudoers.conf create mode 100644 ansible-nix/files/ansible-pull.service create mode 100644 ansible-nix/files/ansible-pull.timer create mode 100644 ansible-nix/files/apt_periodic create mode 100644 ansible-nix/files/cron.deny create mode 100644 ansible-nix/files/database-optimizations.service.j2 create mode 100644 ansible-nix/files/default.sysstat create mode 100644 ansible-nix/files/envoy.service create mode 100644 ansible-nix/files/envoy_config/cds.yaml create mode 100644 ansible-nix/files/envoy_config/envoy.yaml create mode 100644 ansible-nix/files/envoy_config/lds.yaml create mode 100644 ansible-nix/files/envoy_config/remove_apikey_query_parameter.lua create mode 100644 ansible-nix/files/fail2ban_config/fail2ban.service.conf create mode 100644 ansible-nix/files/fail2ban_config/filter-pgbouncer.conf.j2 create mode 100644 ansible-nix/files/fail2ban_config/filter-postgresql.conf.j2 create mode 100644 ansible-nix/files/fail2ban_config/jail-pgbouncer.conf.j2 create mode 100644 ansible-nix/files/fail2ban_config/jail-postgresql.conf.j2 create mode 100644 ansible-nix/files/fail2ban_config/jail-ssh.conf create mode 100644 ansible-nix/files/fail2ban_config/jail.local create mode 100644 ansible-nix/files/gotrue.service.j2 create mode 100644 ansible-nix/files/journald.conf create mode 100644 ansible-nix/files/kong_config/kong.conf.j2 create mode 100644 ansible-nix/files/kong_config/kong.env.j2 create mode 100644 ansible-nix/files/kong_config/kong.service.j2 create mode 100644 ansible-nix/files/logind.conf create mode 100644 ansible-nix/files/logrotate_config/logrotate-postgres-auth.conf create mode 100644 ansible-nix/files/logrotate_config/logrotate-postgres-csv.conf create mode 100644 ansible-nix/files/logrotate_config/logrotate-postgres.conf create mode 100644 ansible-nix/files/logrotate_config/logrotate-walg.conf create mode 100644 ansible-nix/files/manifest.json create mode 100644 ansible-nix/files/nginx.service.j2 create mode 100644 ansible-nix/files/permission_check.py create mode 100644 ansible-nix/files/pg_egress_collect.service.j2 create mode 100644 ansible-nix/files/pgbouncer_config/pgbouncer.ini.j2 create mode 100644 ansible-nix/files/pgbouncer_config/pgbouncer.service.j2 create mode 100644 ansible-nix/files/pgbouncer_config/pgbouncer_auth_schema.sql create mode 100644 ansible-nix/files/pgbouncer_config/tmpfiles.d-pgbouncer.conf.j2 create mode 100644 ansible-nix/files/pgsodium_getkey_readonly.sh.j2 create mode 100755 ansible-nix/files/pgsodium_getkey_urandom.sh.j2 create mode 100644 ansible-nix/files/postgres_exporter.service.j2 create mode 100644 ansible-nix/files/postgresql_config/custom_read_replica.conf.j2 create mode 100644 ansible-nix/files/postgresql_config/custom_walg.conf.j2 create mode 100755 ansible-nix/files/postgresql_config/pg_hba.conf.j2 create mode 100755 ansible-nix/files/postgresql_config/pg_ident.conf.j2 create mode 100644 ansible-nix/files/postgresql_config/postgresql-csvlog.conf create mode 100644 ansible-nix/files/postgresql_config/postgresql-stdout-log.conf create mode 100644 ansible-nix/files/postgresql_config/postgresql.conf.j2 create mode 100644 ansible-nix/files/postgresql_config/postgresql.service.j2 create mode 100644 ansible-nix/files/postgresql_config/supautils.conf.j2 create mode 100644 ansible-nix/files/postgresql_config/tmpfiles.postgresql.conf create mode 100644 ansible-nix/files/postgresql_extension_custom_scripts/before-create.sql create mode 100644 ansible-nix/files/postgresql_extension_custom_scripts/dblink/after-create.sql create mode 100644 ansible-nix/files/postgresql_extension_custom_scripts/pg_cron/after-create.sql create mode 100644 ansible-nix/files/postgresql_extension_custom_scripts/pg_tle/after-create.sql create mode 100644 ansible-nix/files/postgresql_extension_custom_scripts/pgsodium/after-create.sql create mode 100644 ansible-nix/files/postgresql_extension_custom_scripts/postgis_tiger_geocoder/after-create.sql create mode 100644 ansible-nix/files/postgresql_extension_custom_scripts/postgres_fdw/after-create.sql create mode 100644 ansible-nix/files/postgrest-optimizations.service.j2 create mode 100644 ansible-nix/files/postgrest.service.j2 create mode 100644 ansible-nix/files/services.slice.j2 create mode 100644 ansible-nix/files/sodium_extension.sql create mode 100644 ansible-nix/files/start-envoy.sh create mode 100644 ansible-nix/files/stat_extension.sql create mode 100644 ansible-nix/files/supabase_facts.ini create mode 100644 ansible-nix/files/sysstat.sysstat create mode 100644 ansible-nix/files/systemd-resolved.conf create mode 100644 ansible-nix/files/ufw.service.conf create mode 100644 ansible-nix/files/vector.service.j2 create mode 100644 ansible-nix/files/walg_helper_scripts/wal_change_ownership.sh create mode 100644 ansible-nix/files/walg_helper_scripts/wal_fetch.sh create mode 100644 ansible-nix/manifest-playbook.yml create mode 100644 ansible-nix/playbook.yml create mode 100644 ansible-nix/tasks/clean-build-dependencies.yml create mode 100644 ansible-nix/tasks/finalize-ami.yml create mode 100644 ansible-nix/tasks/internal/admin-api.yml create mode 100644 ansible-nix/tasks/internal/admin-mgr.yml create mode 100644 ansible-nix/tasks/internal/pg_egress_collect.yml create mode 100644 ansible-nix/tasks/internal/postgres-exporter.yml create mode 100644 ansible-nix/tasks/internal/setup-ansible-pull.yml create mode 100644 ansible-nix/tasks/internal/setup-nftables.yml create mode 100644 ansible-nix/tasks/internal/supautils.yml create mode 100644 ansible-nix/tasks/setup-envoy.yml create mode 100644 ansible-nix/tasks/setup-extensions.yml create mode 100644 ansible-nix/tasks/setup-fail2ban.yml create mode 100644 ansible-nix/tasks/setup-gotrue.yml create mode 100644 ansible-nix/tasks/setup-kong.yml create mode 100644 ansible-nix/tasks/setup-migrations.yml create mode 100644 ansible-nix/tasks/setup-nginx.yml create mode 100644 ansible-nix/tasks/setup-pgbouncer.yml create mode 100644 ansible-nix/tasks/setup-postgres.yml create mode 100644 ansible-nix/tasks/setup-postgrest.yml create mode 100644 ansible-nix/tasks/setup-supabase-internal.yml create mode 100644 ansible-nix/tasks/setup-system.yml create mode 100644 ansible-nix/tasks/setup-wal-g.yml create mode 100644 ansible-nix/tasks/stage2/optimizations.yml create mode 100644 ansible-nix/tasks/stage2/playbook.yml create mode 100644 ansible-nix/tasks/stage2/setup-extensions.yml create mode 100644 ansible-nix/tasks/stage2/setup-migrations.yml create mode 100644 ansible-nix/tasks/stage2/stage2-setup-postgres.yml create mode 100644 ansible-nix/tasks/stage2/test-image.yml create mode 100644 common-nix.vars.pkr.hcl create mode 100755 ebssurrogate/scripts/chroot-bootstrap-nix.sh create mode 100755 ebssurrogate/scripts/surrogate-bootstrap-nix.sh create mode 100644 nix/ext/sfcgal/sfcgal.nix delete mode 100644 nix/overlays/postgis.nix create mode 100644 scripts/nix-provision.sh create mode 100644 stage2-nix-psql.pkr.hcl diff --git a/.github/workflows/ami-release-nix.yml b/.github/workflows/ami-release-nix.yml new file mode 100644 index 000000000..abc119bbc --- /dev/null +++ b/.github/workflows/ami-release-nix.yml @@ -0,0 +1,121 @@ +name: Release AMI Nix + +on: + push: + branches: + - sam/2-stage-ami-nix + paths: + - '.github/workflows/ami-release-nix.yml' + - 'common-nix.vars.pkr.hcl' + workflow_dispatch: + +jobs: + build: + strategy: + matrix: + include: + - runner: arm-runner + arch: arm64 + ubuntu_release: focal + ubuntu_version: 20.04 + mcpu: neoverse-n1 + runs-on: ${{ matrix.runner }} + timeout-minutes: 150 + permissions: + contents: write + packages: write + id-token: write + + steps: + - name: Checkout Repo + uses: actions/checkout@v3 + + - name: Run checks if triggered manually + if: ${{ github.event_name == 'workflow_dispatch' }} + # Update `ci.yaml` too if changing constraints. + run: | + SUFFIX=$(sed -E 's/postgres-version = "[0-9\.]+(.*)"/\1/g' common-nix.vars.pkr.hcl) + if [[ -z $SUFFIX ]] ; then + echo "Version must include non-numeric characters if built manually." + exit 1 + fi + + # extensions are build in nix prior to this step + # so we can just use the binaries from the nix store + # for postgres, extensions and wrappers + + - name: Build AMI stage 1 + run: | + packer init amazon-arm64-nix.pkr.hcl + GIT_SHA=${{github.sha}} + packer build -var "git-head-version=${GIT_SHA}" -var "packer-execution-id=${GITHUB_RUN_ID}" -var-file="development-arm.vars.pkr.hcl" -var-file="common-nix.vars.pkr.hcl" -var "ansible_arguments=" amazon-arm64-nix.pkr.hcl + + - name: Build AMI stage 2 + run: | + packer init stage2-nix-psql.pkr.hcl + GIT_SHA=${{github.sha}} + packer build -var "git-head-version=${GIT_SHA}" -var "packer-execution-id=${GITHUB_RUN_ID}" -var-file="development-arm.vars.pkr.hcl" -var-file="common-nix.vars.pkr.hcl" stage2-nix-psql.pkr.hcl + + - name: Grab release version + id: process_release_version + run: | + VERSION=$(sed -e 's/postgres-version = "\(.*\)"/\1/g' common-nix.vars.pkr.hcl) + echo "version=$VERSION" >> "$GITHUB_OUTPUT" + + - name: configure aws credentials - staging + uses: aws-actions/configure-aws-credentials@v4 + with: + role-to-assume: ${{ secrets.DEV_AWS_ROLE }} + aws-region: "us-east-1" + + - name: Upload software manifest to s3 staging + run: | + cd ansible + ansible-playbook -i localhost \ + -e "ami_release_version=${{ steps.process_release_version.outputs.version }}" \ + -e "internal_artifacts_bucket=${{ secrets.ARTIFACTS_BUCKET }}" \ + manifest-playbook.yml + + + #Our self hosted github runner already has permissions to publish images + #but they're limited to only that; + #so if we want s3 access we'll need to config credentials with the below steps + # (which overwrites existing perms) after the ami build + + - name: configure aws credentials - prod + uses: aws-actions/configure-aws-credentials@v4 + with: + role-to-assume: ${{ secrets.PROD_AWS_ROLE }} + aws-region: "us-east-1" + + - name: Upload software manifest to s3 prod + run: | + cd ansible + ansible-playbook -i localhost \ + -e "ami_release_version=${{ steps.process_release_version.outputs.version }}" \ + -e "internal_artifacts_bucket=${{ secrets.PROD_ARTIFACTS_BUCKET }}" \ + manifest-playbook.yml + + + + - name: Create release + uses: softprops/action-gh-release@v1 + with: + name: ${{ steps.process_release_version.outputs.version }} + tag_name: ${{ steps.process_release_version.outputs.version }} + target_commitish: ${{github.sha}} + + - name: Slack Notification on Failure + if: ${{ failure() }} + uses: rtCamp/action-slack-notify@v2 + env: + SLACK_WEBHOOK: ${{ secrets.SLACK_NOTIFICATIONS_WEBHOOK }} + SLACK_USERNAME: 'gha-failures-notifier' + SLACK_COLOR: 'danger' + SLACK_MESSAGE: 'Building Postgres AMI failed' + SLACK_FOOTER: '' + + - name: Cleanup resources on build cancellation + if: ${{ cancelled() }} + run: | + aws ec2 describe-instances --filters "Name=tag:packerExecutionId,Values=${GITHUB_RUN_ID}" --query "Reservations[].Instances[].InstanceId" --output text | xargs -n 1 -I {} aws ec2 terminate-instances --instance-ids {} diff --git a/.github/workflows/nix-build.yml b/.github/workflows/nix-build.yml index 93f6549e7..0d6336cd0 100644 --- a/.github/workflows/nix-build.yml +++ b/.github/workflows/nix-build.yml @@ -25,7 +25,11 @@ jobs: steps: - name: Check out code - uses: actions/checkout@v3 + uses: actions/checkout@v4 + with: + ref: ${{ github.event.pull_request.head.ref || github.ref }} + fetch-depth: 0 + fetch-tags: true - name: aws-creds uses: aws-actions/configure-aws-credentials@v4 with: diff --git a/.github/workflows/text-nix.yml b/.github/workflows/text-nix.yml new file mode 100644 index 000000000..6c5778c7f --- /dev/null +++ b/.github/workflows/text-nix.yml @@ -0,0 +1,117 @@ +name: Test Database + +on: + # push: + # branches: + # - develop + # pull_request: + workflow_dispatch: + +jobs: + build: + strategy: + matrix: + include: + - runner: [self-hosted, X64] + arch: amd64 + - runner: arm-runner + arch: arm64 + runs-on: ${{ matrix.runner }} + timeout-minutes: 180 + env: + POSTGRES_PORT: 5478 + POSTGRES_PASSWORD: password + steps: + - uses: actions/checkout@v3 + - id: args + uses: mikefarah/yq@master + with: + cmd: yq 'to_entries | map(select(.value|type == "!!str")) | map(.key + "=" + .value) | join("\n")' 'ansible/vars.yml' + + - run: docker context create builders + - uses: docker/setup-buildx-action@v3 + with: + endpoint: builders + - uses: docker/build-push-action@v5 + with: + load: true + context: . + target: production + build-args: | + ${{ steps.args.outputs.result }} + tags: samrose/nix-experimental-postgresql-15-aarch64-linux:latest + cache-from: | + type=gha,scope=${{ github.ref_name }}-latest-${{ matrix.arch }} + type=gha,scope=${{ github.base_ref }}-latest-${{ matrix.arch }} + cache-to: type=gha,mode=max,scope=${{ github.ref_name }}-latest-${{ matrix.arch }} + + - name: Start Postgres + run: | + docker run --rm --pull=never \ + -e POSTGRES_PASSWORD=${{ env.POSTGRES_PASSWORD }} \ + -p ${{ env.POSTGRES_PORT }}:5432 \ + --name supabase_postgres \ + -d supabase/postgres:latest + + - name: Install psql + run: | + sudo apt update + sudo apt install -y --no-install-recommends postgresql-client + + - name: Install pg_prove + run: sudo cpan -T TAP::Parser::SourceHandler::pgTAP + env: + SHELL: /bin/bash + + - name: Wait for healthy database + run: | + count=0 + until [ "$(docker inspect -f '{{.State.Health.Status}}' "$container")" == "healthy" ]; do + exit=$? + count=$((count + 1)) + if [ $count -ge "$retries" ]; then + echo "Retry $count/$retries exited $exit, no more retries left." + docker stop -t 2 "$container" + return $exit + fi + sleep 1; + done; + echo "$container container is healthy" + env: + retries: 20 + container: supabase_postgres + + - name: Run tests + run: pg_prove migrations/tests/test.sql + env: + PGHOST: localhost + PGPORT: ${{ env.POSTGRES_PORT }} + PGDATABASE: postgres + PGUSER: supabase_admin + PGPASSWORD: ${{ env.POSTGRES_PASSWORD }} + + - name: Check migrations are idempotent + run: | + for sql in ./migrations/db/migrations/*.sql; do + echo "$0: running $sql" + psql -v ON_ERROR_STOP=1 --no-password --no-psqlrc -f "$sql" + done + env: + PGHOST: localhost + PGPORT: ${{ env.POSTGRES_PORT }} + PGDATABASE: postgres + PGUSER: supabase_admin + PGPASSWORD: ${{ env.POSTGRES_PASSWORD }} + + schema: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - name: verify schema.sql is committed + run: | + docker compose -f migrations/docker-compose.yaml up db dbmate --abort-on-container-exit + if ! git diff --ignore-space-at-eol --exit-code --quiet migrations/schema.sql; then + echo "Detected uncommitted changes after build. See status below:" + git diff + exit 1 + fi diff --git a/.github/workflows/textinfra-nix.yml b/.github/workflows/textinfra-nix.yml new file mode 100644 index 000000000..f88cc6077 --- /dev/null +++ b/.github/workflows/textinfra-nix.yml @@ -0,0 +1,145 @@ +name: Testinfra Integration Tests + +on: + #pull_request: + workflow_dispatch: + +jobs: + # test-all-in-one: + # strategy: + # matrix: + # include: + # - runner: [self-hosted, X64] + # arch: amd64 + # - runner: arm-runner + # arch: arm64 + # runs-on: ${{ matrix.runner }} + # timeout-minutes: 30 + # steps: + # - uses: actions/checkout@v3 + + # - run: docker context create builders + # - uses: docker/setup-buildx-action@v3 + # with: + # endpoint: builders + + # - name: Run aio integration tests + # run: | + # # TODO: use poetry for pkg mgmt + # pip3 install boto3 boto3-stubs[essential] docker ec2instanceconnectcli pytest pytest-testinfra[paramiko,docker] requests + + + # if ! pytest -vv testinfra/test_all_in_one.py; then + # # display container logs if the test fails + + # if [ -f testinfra-aio-container-logs.log ]; then + # echo "AIO container logs:" + # cat testinfra-aio-container-logs.log + # fi + # exit 1 + # fi + + test-ami: + strategy: + matrix: + include: + - runner: arm-runner + arch: arm64 + ubuntu_release: focal + ubuntu_version: 20.04 + mcpu: neoverse-n1 + runs-on: ${{ matrix.runner }} + timeout-minutes: 150 + permissions: + contents: write + packages: write + id-token: write + + steps: + - name: Checkout Repo + uses: actions/checkout@v4 + + - id: args + uses: mikefarah/yq@master + with: + cmd: yq 'to_entries | map(select(.value|type == "!!str")) | map(.key + "=" + .value) | join("\n")' 'ansible/vars.yml' + + - run: docker context create builders + + - uses: docker/setup-buildx-action@v3 + with: + endpoint: builders + + - uses: docker/build-push-action@v5 + with: + build-args: | + ${{ steps.args.outputs.result }} + target: extensions + tags: supabase/postgres:extensions + platforms: linux/${{ matrix.arch }} + outputs: type=tar,dest=/tmp/extensions.tar + cache-from: | + type=gha,scope=${{ github.ref_name }}-extensions + type=gha,scope=${{ github.base_ref }}-extensions + type=gha,scope=develop-extensions + cache-to: type=gha,mode=max,scope=${{ github.ref_name }}-extensions + + - name: Extract built packages + run: | + mkdir -p ansible/files/extensions + tar xvf /tmp/extensions.tar -C ansible/files/extensions --strip-components 1 + + - id: version + run: echo "${{ steps.args.outputs.result }}" | grep "postgresql" >> "$GITHUB_OUTPUT" + + - name: Build Postgres deb + uses: docker/build-push-action@v5 + with: + file: docker/Dockerfile + target: pg-deb + build-args: | + ubuntu_release=${{ matrix.ubuntu_release }} + ubuntu_release_no=${{ matrix.ubuntu_version }} + postgresql_major=${{ steps.version.outputs.postgresql_major }} + postgresql_release=${{ steps.version.outputs.postgresql_release }} + CPPFLAGS=-mcpu=${{ matrix.mcpu }} + tags: supabase/postgres:deb + platforms: linux/${{ matrix.arch }} + outputs: type=tar,dest=/tmp/pg-deb.tar + cache-from: | + type=gha,scope=${{ github.ref_name }}-deb + type=gha,scope=${{ github.base_ref }}-deb + type=gha,scope=develop-deb + cache-to: type=gha,mode=max,scope=${{ github.ref_name }}-deb + + - name: Extract Postgres deb + run: | + mkdir -p ansible/files/postgres + tar xvf /tmp/pg-deb.tar -C ansible/files/postgres --strip-components 1 + + # Packer doesn't support skipping registering the AMI for the ebssurrogate + # builder, so we register an AMI with a fixed name and run tests on an + # instance launched from that + # https://github.com/hashicorp/packer/issues/4899 + - name: Build AMI + run: | + packer init amazon-arm64.pkr.hcl + GIT_SHA=${{github.sha}} + packer build -var "git-head-version=${GIT_SHA}" -var "packer-execution-id=${GITHUB_RUN_ID}" -var-file="development-arm.vars.pkr.hcl" -var-file="common.vars.pkr.hcl" -var "ansible_arguments=" -var "postgres-version=ci-ami-test" -var "region=ap-southeast-1" -var 'ami_regions=["ap-southeast-1"]' -var "force-deregister=true" amazon-arm64.pkr.hcl + + - name: Run tests + timeout-minutes: 10 + run: | + # TODO: use poetry for pkg mgmt + pip3 install boto3 boto3-stubs[essential] docker ec2instanceconnectcli pytest pytest-testinfra[paramiko,docker] requests + pytest -vv -s testinfra/test_ami.py + + - name: Cleanup resources on build cancellation + if: ${{ cancelled() }} + run: | + aws ec2 --region ap-southeast-1 describe-instances --filters "Name=tag:packerExecutionId,Values=${GITHUB_RUN_ID}" --query "Reservations[].Instances[].InstanceId" --output text | xargs -n 1 -I {} aws ec2 terminate-instances --region ap-southeast-1 --instance-ids {} + + - name: Cleanup resources on build cancellation + if: ${{ always() }} + run: | + aws ec2 --region ap-southeast-1 describe-instances --filters "Name=tag:testinfra-run-id,Values=${GITHUB_RUN_ID}" --query "Reservations[].Instances[].InstanceId" --output text | xargs -n 1 -I {} aws ec2 terminate-instances --region ap-southeast-1 --instance-ids {} || true diff --git a/amazon-arm64-nix.pkr.hcl b/amazon-arm64-nix.pkr.hcl new file mode 100644 index 000000000..0fcf6a4ac --- /dev/null +++ b/amazon-arm64-nix.pkr.hcl @@ -0,0 +1,277 @@ +variable "ami" { + type = string + default = "ubuntu/images/hvm-ssd/ubuntu-focal-20.04-arm64-server-*" +} + +variable "profile" { + type = string + default = "${env("AWS_PROFILE")}" +} + +variable "ami_name" { + type = string + default = "supabase-postgres" +} + +variable "ami_regions" { + type = list(string) + default = ["ap-southeast-2"] +} + +variable "ansible_arguments" { + type = string + default = "--skip-tags install-postgrest,install-pgbouncer,install-supabase-internal" +} + +variable "aws_access_key" { + type = string + default = "" +} + +variable "aws_secret_key" { + type = string + default = "" +} + +variable "environment" { + type = string + default = "prod" +} + +variable "region" { + type = string +} + +variable "build-vol" { + type = string + default = "xvdc" +} + +# ccache docker image details +variable "docker_user" { + type = string + default = "" +} + +variable "docker_passwd" { + type = string + default = "" +} + +variable "docker_image" { + type = string + default = "" +} + +variable "docker_image_tag" { + type = string + default = "latest" +} + +locals { + creator = "packer" +} + +variable "postgres-version" { + type = string + default = "" +} + +variable "git-head-version" { + type = string + default = "unknown" +} + +variable "packer-execution-id" { + type = string + default = "unknown" +} + +variable "force-deregister" { + type = bool + default = false +} + +packer { + required_plugins { + amazon = { + source = "github.com/hashicorp/amazon" + version = "~> 1" + } + } +} + +# source block +source "amazon-ebssurrogate" "source" { + profile = "${var.profile}" + #access_key = "${var.aws_access_key}" + #ami_name = "${var.ami_name}-arm64-${formatdate("YYYY-MM-DD-hhmm", timestamp())}" + ami_name = "${var.ami_name}-${var.postgres-version}-stage-1" + ami_virtualization_type = "hvm" + ami_architecture = "arm64" + ami_regions = "${var.ami_regions}" + instance_type = "c6g.4xlarge" + region = "${var.region}" + #secret_key = "${var.aws_secret_key}" + force_deregister = var.force-deregister + + # Use latest official ubuntu focal ami owned by Canonical. + source_ami_filter { + filters = { + virtualization-type = "hvm" + name = "${var.ami}" + root-device-type = "ebs" + } + owners = [ "099720109477" ] + most_recent = true + } + ena_support = true + launch_block_device_mappings { + device_name = "/dev/xvdf" + delete_on_termination = true + volume_size = 10 + volume_type = "gp3" + } + + launch_block_device_mappings { + device_name = "/dev/xvdh" + delete_on_termination = true + volume_size = 8 + volume_type = "gp3" + } + + launch_block_device_mappings { + device_name = "/dev/${var.build-vol}" + delete_on_termination = true + volume_size = 16 + volume_type = "gp2" + omit_from_artifact = true + } + + run_tags = { + creator = "packer" + appType = "postgres" + packerExecutionId = "${var.packer-execution-id}" + } + run_volume_tags = { + creator = "packer" + appType = "postgres" + } + snapshot_tags = { + creator = "packer" + appType = "postgres" + } + tags = { + creator = "packer" + appType = "postgres" + postgresVersion = "${var.postgres-version}-stage1" + sourceSha = "${var.git-head-version}" + } + + communicator = "ssh" + ssh_pty = true + ssh_username = "ubuntu" + ssh_timeout = "5m" + + ami_root_device { + source_device_name = "/dev/xvdf" + device_name = "/dev/xvda" + delete_on_termination = true + volume_size = 10 + volume_type = "gp2" + } + + associate_public_ip_address = true +} + +# a build block invokes sources and runs provisioning steps on them. +build { + sources = ["source.amazon-ebssurrogate.source"] + + provisioner "file" { + source = "ebssurrogate/files/sources-arm64.cfg" + destination = "/tmp/sources.list" + } + + provisioner "file" { + source = "ebssurrogate/files/ebsnvme-id" + destination = "/tmp/ebsnvme-id" + } + + provisioner "file" { + source = "ebssurrogate/files/70-ec2-nvme-devices.rules" + destination = "/tmp/70-ec2-nvme-devices.rules" + } + + provisioner "file" { + source = "ebssurrogate/scripts/chroot-bootstrap-nix.sh" + destination = "/tmp/chroot-bootstrap-nix.sh" + } + + provisioner "file" { + source = "ebssurrogate/files/cloud.cfg" + destination = "/tmp/cloud.cfg" + } + + provisioner "file" { + source = "ebssurrogate/files/vector.timer" + destination = "/tmp/vector.timer" + } + + provisioner "file" { + source = "ebssurrogate/files/apparmor_profiles" + destination = "/tmp" + } + + provisioner "file" { + source = "migrations" + destination = "/tmp" + } + + provisioner "file" { + source = "ebssurrogate/files/unit-tests" + destination = "/tmp" + } + + # Copy ansible playbook + provisioner "shell" { + inline = ["mkdir /tmp/ansible-playbook"] + } + + provisioner "file" { + source = "ansible-nix" + destination = "/tmp/ansible-playbook" + } + + provisioner "file" { + source = "scripts" + destination = "/tmp/ansible-playbook" + } + + provisioner "file" { + source = "ansible/vars.yml" + destination = "/tmp/ansible-playbook/vars.yml" + } + + provisioner "shell" { + environment_vars = [ + "ARGS=${var.ansible_arguments}", + "DOCKER_USER=${var.docker_user}", + "DOCKER_PASSWD=${var.docker_passwd}", + "DOCKER_IMAGE=${var.docker_image}", + "DOCKER_IMAGE_TAG=${var.docker_image_tag}", + "POSTGRES_SUPABASE_VERSION=${var.postgres-version}" + ] + use_env_var_file = true + script = "ebssurrogate/scripts/surrogate-bootstrap-nix.sh" + execute_command = "sudo -S sh -c '. {{.EnvVarFile}} && {{.Path}}'" + start_retry_timeout = "5m" + skip_clean = true + } + + provisioner "file" { + source = "/tmp/ansible.log" + destination = "/tmp/ansible.log" + direction = "download" + } +} diff --git a/ansible-nix/files/admin_api_scripts/grow_fs.sh b/ansible-nix/files/admin_api_scripts/grow_fs.sh new file mode 100644 index 000000000..6d2a4e5e4 --- /dev/null +++ b/ansible-nix/files/admin_api_scripts/grow_fs.sh @@ -0,0 +1,23 @@ +#! /usr/bin/env bash + +set -euo pipefail + +VOLUME_TYPE=${1:-data} + +if [ -b /dev/nvme1n1 ] ; then + if [[ "${VOLUME_TYPE}" == "data" ]]; then + resize2fs /dev/nvme1n1 + + elif [[ "${VOLUME_TYPE}" == "root" ]] ; then + growpart /dev/nvme0n1 2 + resize2fs /dev/nvme0n1p2 + + else + echo "Invalid disk specified: ${VOLUME_TYPE}" + exit 1 + fi +else + growpart /dev/nvme0n1 2 + resize2fs /dev/nvme0n1p2 +fi +echo "Done resizing disk" diff --git a/ansible-nix/files/admin_api_scripts/manage_readonly_mode.sh b/ansible-nix/files/admin_api_scripts/manage_readonly_mode.sh new file mode 100644 index 000000000..41c9f5a1e --- /dev/null +++ b/ansible-nix/files/admin_api_scripts/manage_readonly_mode.sh @@ -0,0 +1,45 @@ +#! /usr/bin/env bash + +set -euo pipefail + +SUBCOMMAND=$1 + +function set_mode { + MODE=$1 + psql -h localhost -U supabase_admin -d postgres -c "ALTER SYSTEM SET default_transaction_read_only to ${MODE};" + psql -h localhost -U supabase_admin -d postgres -c "SELECT pg_reload_conf();" +} + +function check_override { + COMMAND=$(cat < 220.235.16.223.62599: Flags [S.], cksum 0x5de3 (incorrect -> 0x63da), seq 2314200657, ack 2071735457, win 62643, options [mss 8961,sackOK,TS val 3358598837 ecr 1277499190,nop,wscale 7], length 0 +# 1674013833.989257 IP (tos 0x0, ttl 64, id 24975, offset 0, flags [DF], proto TCP (6), length 52) +# 10.112.101.122.5432 > 220.235.16.223.62599: Flags [.], cksum 0x5ddb (incorrect -> 0xa25b), seq 1, ack 9, win 490, options [nop,nop,TS val 3358598885 ecr 1277499232], length 0 +# +# Sample IPv6 input lines: +# +# 1706483718.836526 IP6 (flowlabel 0x0bf27, hlim 64, next-header TCP (6) payload length: 125) 2406:da18:4fd:9b00:959:c52:ce68:10c8.5432 > 2406:da12:d78:f501:1273:296c:2482:c7a7.50530: Flags [P.], seq 25:118, ack 125, win 488, options [nop,nop,TS val 1026340732 ecr 1935666426], length 93 +# 1706483718.912083 IP6 (flowlabel 0x0bf27, hlim 64, next-header TCP (6) payload length: 501) 2406:da18:4fd:9b00:959:c52:ce68:10c8.5432 > 2406:da12:d78:f501:1273:296c:2482:c7a7.50530: Flags [P.], seq 118:587, ack 234, win 488, options [nop,nop,TS val 1026340807 ecr 1935666497], length 469 +# 1706483718.984001 IP6 (flowlabel 0x0bf27, hlim 64, next-header TCP (6) payload length: 151) 2406:da18:4fd:9b00:959:c52:ce68:10c8.5432 > 2406:da12:d78:f501:1273:296c:2482:c7a7.50530: Flags [P.], seq 587:706, ack 448, win 487, options [nop,nop,TS val 1026340879 ecr 1935666569], length 119 +sub extract_packet_length { + my ($line) = @_; + + #print("debug: >> " . $line); + + if ($line =~ /^.*, length (\d+)$/) { + # extract tcp packet length and add it up + my $len = $1; + $captured_len += $len; + } +} + +# write total length to file +sub write_file { + my ($output) = @_; + + my $now = strftime "%F %T", localtime time; + print "[$now] write captured len $captured_len to $output\n"; + + open(my $fh, "+>", $output) or die "Could not open file '$output' $!"; + print $fh "$captured_len"; + close($fh) or die "Could not write file '$output' $!"; +} + +# main +sub main { + # get arguments + GetOptions( + "interval:i" => \(my $interval = 60), + "output:s" => \(my $output = "/tmp/pg_egress_collect.txt"), + "help" => sub { HelpMessage(0) }, + ) or HelpMessage(1); + + my $loop = IO::Async::Loop->new; + + # tcpdump extractor + my $extractor = IO::Async::Stream->new_for_stdin( + on_read => sub { + my ($self, $buffref, $eof) = @_; + + while($$buffref =~ s/^(.*\n)//) { + my $line = $1; + extract_packet_length($line); + } + + return 0; + }, + ); + + # schedule file writer per minute + my $writer = IO::Async::Timer::Periodic->new( + interval => $interval, + on_tick => sub { + write_file($output); + + # reset total captured length + $captured_len = 0; + }, + ); + $writer->start; + + print "pg_egress_collect started, egress data will be saved to $output at interval $interval seconds.\n"; + + $loop->add($extractor); + $loop->add($writer); + $loop->run; +} + +main(); + +__END__ + +=head1 NAME + +pg_egress_collect.pl - collect egress from tcpdump output, extract TCP packet length, aggregate in specified interval and write to output file. + +=head1 SYNOPSIS + +pg_egress_collect.pl [-i interval] [-o output] + +Options: + + -i, --interval interval + output file write interval, in seconds, default is 60 seconds + + -o, --output output + output file path, default is /tmp/pg_egress_collect.txt + + -h, --help + print this help message + +=cut diff --git a/ansible-nix/files/admin_api_scripts/pg_upgrade_scripts/check.sh b/ansible-nix/files/admin_api_scripts/pg_upgrade_scripts/check.sh new file mode 100755 index 000000000..f85e9571b --- /dev/null +++ b/ansible-nix/files/admin_api_scripts/pg_upgrade_scripts/check.sh @@ -0,0 +1,16 @@ +#! /usr/bin/env bash +## This script provides a method to check the status of the database upgrade +## process, which is updated in /tmp/pg-upgrade-status by initiate.sh +## This runs on the old (source) instance. + +set -euo pipefail + +STATUS_FILE="/tmp/pg-upgrade-status" + +if [ -f "${STATUS_FILE}" ]; then + STATUS=$(cat "${STATUS_FILE}") + echo -n "${STATUS}" +else + echo -n "unknown" +fi + diff --git a/ansible-nix/files/admin_api_scripts/pg_upgrade_scripts/common.sh b/ansible-nix/files/admin_api_scripts/pg_upgrade_scripts/common.sh new file mode 100755 index 000000000..bf549b212 --- /dev/null +++ b/ansible-nix/files/admin_api_scripts/pg_upgrade_scripts/common.sh @@ -0,0 +1,63 @@ +#! /usr/bin/env bash + +# Common functions and variables used by initiate.sh and complete.sh + +REPORTING_PROJECT_REF="ihmaxnjpcccasmrbkpvo" +REPORTING_CREDENTIALS_FILE="/root/upgrade-reporting-credentials" + +REPORTING_ANON_KEY="" +if [ -f "$REPORTING_CREDENTIALS_FILE" ]; then + REPORTING_ANON_KEY=$(cat "$REPORTING_CREDENTIALS_FILE") +fi + +function run_sql { + psql -h localhost -U supabase_admin -d postgres "$@" +} + +function ship_logs { + LOG_FILE=$1 + + if [ -z "$REPORTING_ANON_KEY" ]; then + echo "No reporting key found. Skipping log upload." + return 0 + fi + + if [ ! -f "$LOG_FILE" ]; then + echo "No log file found. Skipping log upload." + return 0 + fi + + if [ ! -s "$LOG_FILE" ]; then + echo "Log file is empty. Skipping log upload." + return 0 + fi + + HOSTNAME=$(hostname) + DERIVED_REF="${HOSTNAME##*-}" + + printf -v BODY '{ "ref": "%s", "step": "%s", "content": %s }' "$DERIVED_REF" "completion" "$(cat "$LOG_FILE" | jq -Rs '.')" + curl -sf -X POST "https://$REPORTING_PROJECT_REF.supabase.co/rest/v1/error_logs" \ + -H "apikey: ${REPORTING_ANON_KEY}" \ + -H 'Content-type: application/json' \ + -d "$BODY" +} + +function retry { + local retries=$1 + shift + + local count=0 + until "$@"; do + exit=$? + wait=$((2 ** (count + 1))) + count=$((count + 1)) + if [ $count -lt "$retries" ]; then + echo "Command $* exited with code $exit, retrying..." + sleep $wait + else + echo "Command $* exited with code $exit, no more retries left." + return $exit + fi + done + return 0 +} diff --git a/ansible-nix/files/admin_api_scripts/pg_upgrade_scripts/complete.sh b/ansible-nix/files/admin_api_scripts/pg_upgrade_scripts/complete.sh new file mode 100755 index 000000000..b139091ed --- /dev/null +++ b/ansible-nix/files/admin_api_scripts/pg_upgrade_scripts/complete.sh @@ -0,0 +1,153 @@ +#! /usr/bin/env bash + +## This script is run on the newly launched instance which is to be promoted to +## become the primary database instance once the upgrade successfully completes. +## The following commands copy custom PG configs and enable previously disabled +## extensions, containing regtypes referencing system OIDs. + +set -eEuo pipefail + +SCRIPT_DIR=$(dirname -- "$0";) +# shellcheck disable=SC1091 +source "$SCRIPT_DIR/common.sh" + +LOG_FILE="/var/log/pg-upgrade-complete.log" + +function cleanup { + UPGRADE_STATUS=${1:-"failed"} + EXIT_CODE=${?:-0} + + echo "$UPGRADE_STATUS" > /tmp/pg-upgrade-status + + ship_logs "$LOG_FILE" || true + + exit "$EXIT_CODE" +} + +function execute_patches { + # Patch pg_net grants + PG_NET_ENABLED=$(run_sql -A -t -c "select count(*) > 0 from pg_extension where extname = 'pg_net';") + + if [ "$PG_NET_ENABLED" = "t" ]; then + PG_NET_GRANT_QUERY=$(cat < 0 from pg_extension where extname = 'pg_cron' and extowner::regrole::text = 'postgres';") + + if [ "$HAS_PG_CRON_OWNED_BY_POSTGRES" = "t" ]; then + RECREATE_PG_CRON_QUERY=$(cat < /tmp/pg-upgrade-status + + echo "1. Mounting data disk" + retry 3 mount -a -v + + # copying custom configurations + echo "2. Copying custom configurations" + retry 3 copy_configs + + echo "3. Starting postgresql" + retry 3 service postgresql start + + echo "4. Running generated SQL files" + retry 3 run_generated_sql + + echo "4.1. Applying patches" + execute_patches || true + + run_sql -c "ALTER USER postgres WITH NOSUPERUSER;" + + echo "4.2. Applying authentication scheme updates" + retry 3 apply_auth_scheme_updates + + sleep 5 + + echo "5. Restarting postgresql" + retry 3 service postgresql restart + + echo "5.1. Restarting gotrue and postgrest" + retry 3 service gotrue restart + retry 3 service postgrest restart + + echo "6. Starting vacuum analyze" + retry 3 start_vacuum_analyze +} + +function copy_configs { + cp -R /data/conf/* /etc/postgresql-custom/ + chown -R postgres:postgres /var/lib/postgresql/data + chown -R postgres:postgres /data/pgdata +} + +function run_generated_sql { + if [ -d /data/sql ]; then + for FILE in /data/sql/*.sql; do + if [ -f "$FILE" ]; then + run_sql -f "$FILE" + fi + done + fi +} + +# Projects which had their passwords hashed using md5 need to have their passwords reset +# Passwords for managed roles are already present in /etc/postgresql.schema.sql +function apply_auth_scheme_updates { + PASSWORD_ENCRYPTION_SETTING=$(run_sql -A -t -c "SHOW password_encryption;") + if [ "$PASSWORD_ENCRYPTION_SETTING" = "md5" ]; then + run_sql -c "ALTER SYSTEM SET password_encryption TO 'scram-sha-256';" + run_sql -c "SELECT pg_reload_conf();" + run_sql -f /etc/postgresql.schema.sql + fi +} + +function start_vacuum_analyze { + echo "complete" > /tmp/pg-upgrade-status + su -c 'vacuumdb --all --analyze-in-stages' -s "$SHELL" postgres + echo "Upgrade job completed" +} + +trap cleanup ERR + + +complete_pg_upgrade >> $LOG_FILE 2>&1 & diff --git a/ansible-nix/files/admin_api_scripts/pg_upgrade_scripts/initiate.sh b/ansible-nix/files/admin_api_scripts/pg_upgrade_scripts/initiate.sh new file mode 100755 index 000000000..492890a1e --- /dev/null +++ b/ansible-nix/files/admin_api_scripts/pg_upgrade_scripts/initiate.sh @@ -0,0 +1,333 @@ +#! /usr/bin/env bash + +## This script is run on the old (source) instance, mounting the data disk +## of the newly launched instance, disabling extensions containing regtypes, +## and running pg_upgrade. +## It reports the current status of the upgrade process to /tmp/pg-upgrade-status, +## which can then be subsequently checked through check.sh. + +# Extensions to disable before running pg_upgrade. +# Running an upgrade with these extensions enabled will result in errors due to +# them depending on regtypes referencing system OIDs or outdated library files. +EXTENSIONS_TO_DISABLE=( + "pg_graphql" +) + +PG14_EXTENSIONS_TO_DISABLE=( + "wrappers" + "pgrouting" +) + +PG13_EXTENSIONS_TO_DISABLE=( + "pgrouting" +) + +set -eEuo pipefail + +SCRIPT_DIR=$(dirname -- "$0";) +# shellcheck disable=SC1091 +source "$SCRIPT_DIR/common.sh" + +LOG_FILE="/var/log/pg-upgrade-initiate.log" + +PGVERSION=$1 +IS_DRY_RUN=${2:-false} +if [ "$IS_DRY_RUN" != false ]; then + IS_DRY_RUN=true +fi + +MOUNT_POINT="/data_migration" + +POST_UPGRADE_EXTENSION_SCRIPT="/tmp/pg_upgrade/pg_upgrade_extensions.sql" +OLD_PGVERSION=$(run_sql -A -t -c "SHOW server_version;") + +POSTGRES_CONFIG_PATH="/etc/postgresql/postgresql.conf" +PGBINOLD="/usr/lib/postgresql/bin" +PGLIBOLD="/usr/lib/postgresql/lib" + +# If upgrading from older major PG versions, disable specific extensions +if [[ "$OLD_PGVERSION" =~ ^14.* ]]; then + EXTENSIONS_TO_DISABLE+=("${PG14_EXTENSIONS_TO_DISABLE[@]}") +elif [[ "$OLD_PGVERSION" =~ ^13.* ]]; then + EXTENSIONS_TO_DISABLE+=("${PG13_EXTENSIONS_TO_DISABLE[@]}") +elif [[ "$OLD_PGVERSION" =~ ^12.* ]]; then + POSTGRES_CONFIG_PATH="/etc/postgresql/12/main/postgresql.conf" + PGBINOLD="/usr/lib/postgresql/12/bin" +fi + +echo "Detected PG version: $PGVERSION" + +cleanup() { + UPGRADE_STATUS=${1:-"failed"} + EXIT_CODE=${?:-0} + + if [ "$UPGRADE_STATUS" = "failed" ]; then + echo "Upgrade job failed. Cleaning up and exiting." + fi + + if [ -d "${MOUNT_POINT}/pgdata/pg_upgrade_output.d/" ]; then + echo "Copying pg_upgrade output to /var/log" + cp -R "${MOUNT_POINT}/pgdata/pg_upgrade_output.d/" /var/log/ || true + ship_logs "$LOG_FILE" || true + tail -n +1 /var/log/pg_upgrade_output.d/*/* > /var/log/pg_upgrade_output.d/pg_upgrade.log || true + ship_logs "/var/log/pg_upgrade_output.d/pg_upgrade.log" || true + fi + + if [ -L "/usr/share/postgresql/${PGVERSION}" ]; then + rm "/usr/share/postgresql/${PGVERSION}" + + if [ -f "/usr/share/postgresql/${PGVERSION}.bak" ]; then + mv "/usr/share/postgresql/${PGVERSION}.bak" "/usr/share/postgresql/${PGVERSION}" + fi + + if [ -d "/usr/share/postgresql/${PGVERSION}.bak" ]; then + mv "/usr/share/postgresql/${PGVERSION}.bak" "/usr/share/postgresql/${PGVERSION}" + fi + fi + + if [ "$IS_DRY_RUN" = false ]; then + echo "Restarting postgresql" + systemctl enable postgresql + retry 5 systemctl restart postgresql + fi + + echo "Re-enabling extensions" + if [ -f $POST_UPGRADE_EXTENSION_SCRIPT ]; then + run_sql -f $POST_UPGRADE_EXTENSION_SCRIPT + fi + + echo "Removing SUPERUSER grant from postgres" + run_sql -c "ALTER USER postgres WITH NOSUPERUSER;" + + if [ "$IS_DRY_RUN" = false ]; then + echo "Unmounting data disk from ${MOUNT_POINT}" + umount $MOUNT_POINT + fi + echo "$UPGRADE_STATUS" > /tmp/pg-upgrade-status + + exit "$EXIT_CODE" +} + +function handle_extensions { + rm -f $POST_UPGRADE_EXTENSION_SCRIPT + touch $POST_UPGRADE_EXTENSION_SCRIPT + + PASSWORD_ENCRYPTION_SETTING=$(run_sql -A -t -c "SHOW password_encryption;") + if [ "$PASSWORD_ENCRYPTION_SETTING" = "md5" ]; then + echo "ALTER SYSTEM SET password_encryption = 'md5';" >> $POST_UPGRADE_EXTENSION_SCRIPT + fi + + cat << EOF >> $POST_UPGRADE_EXTENSION_SCRIPT +ALTER SYSTEM SET jit = off; +SELECT pg_reload_conf(); +EOF + + # Disable extensions if they're enabled + # Generate SQL script to re-enable them after upgrade + for EXTENSION in "${EXTENSIONS_TO_DISABLE[@]}"; do + EXTENSION_ENABLED=$(run_sql -A -t -c "SELECT EXISTS(SELECT 1 FROM pg_extension WHERE extname = '${EXTENSION}');") + if [ "$EXTENSION_ENABLED" = "t" ]; then + echo "Disabling extension ${EXTENSION}" + run_sql -c "DROP EXTENSION IF EXISTS ${EXTENSION} CASCADE;" + cat << EOF >> $POST_UPGRADE_EXTENSION_SCRIPT +DO \$\$ +BEGIN + IF EXISTS (SELECT 1 FROM pg_available_extensions WHERE name = '${EXTENSION}') THEN + CREATE EXTENSION IF NOT EXISTS ${EXTENSION} CASCADE; + END IF; +END; +\$\$; +EOF + fi + done +} + +function initiate_upgrade { + mkdir -p "$MOUNT_POINT" + SHARED_PRELOAD_LIBRARIES=$(cat "$POSTGRES_CONFIG_PATH" | grep shared_preload_libraries | sed "s/shared_preload_libraries =\s\{0,1\}'\(.*\)'.*/\1/") + + # Wrappers officially launched in PG15; PG14 version is incompatible + if [[ "$OLD_PGVERSION" =~ 14* ]]; then + SHARED_PRELOAD_LIBRARIES=$(echo "$SHARED_PRELOAD_LIBRARIES" | sed "s/wrappers,//" | xargs) + fi + SHARED_PRELOAD_LIBRARIES=$(echo "$SHARED_PRELOAD_LIBRARIES" | sed "s/pg_cron,//" | xargs) + SHARED_PRELOAD_LIBRARIES=$(echo "$SHARED_PRELOAD_LIBRARIES" | sed "s/check_role_membership,//" | xargs) + + PGDATAOLD=$(cat "$POSTGRES_CONFIG_PATH" | grep data_directory | sed "s/data_directory = '\(.*\)'.*/\1/") + + PGDATANEW="$MOUNT_POINT/pgdata" + PG_UPGRADE_BIN_DIR="/tmp/pg_upgrade_bin/$PGVERSION" + PGBINNEW="$PG_UPGRADE_BIN_DIR/bin" + PGLIBNEW="$PG_UPGRADE_BIN_DIR/lib" + PGSHARENEW="$PG_UPGRADE_BIN_DIR/share" + + # running upgrade using at least 1 cpu core + WORKERS=$(nproc | awk '{ print ($1 == 1 ? 1 : $1 - 1) }') + + echo "1. Extracting pg_upgrade binaries" + mkdir -p "/tmp/pg_upgrade_bin" + tar zxf "/tmp/persistent/pg_upgrade_bin.tar.gz" -C "/tmp/pg_upgrade_bin" + + # copy upgrade-specific pgsodium_getkey script into the share dir + chmod +x "$SCRIPT_DIR/pgsodium_getkey.sh" + cp "$SCRIPT_DIR/pgsodium_getkey.sh" "$PGSHARENEW/extension/pgsodium_getkey" + if [ -d "/var/lib/postgresql/extension/" ]; then + cp "$SCRIPT_DIR/pgsodium_getkey.sh" "/var/lib/postgresql/extension/pgsodium_getkey" + chown postgres:postgres "/var/lib/postgresql/extension/pgsodium_getkey" + fi + + chown -R postgres:postgres "/tmp/pg_upgrade_bin/$PGVERSION" + + # upgrade job outputs a log in the cwd; needs write permissions + mkdir -p /tmp/pg_upgrade/ + chown -R postgres:postgres /tmp/pg_upgrade/ + cd /tmp/pg_upgrade/ + + # Fixing erros generated by previous dpkg executions (package upgrades et co) + echo "2. Fixing potential errors generated by dpkg" + DEBIAN_FRONTEND=noninteractive dpkg --configure -a --force-confold || true # handle errors generated by dpkg + + # Needed for PostGIS, since it's compiled with Protobuf-C support now + echo "3. Installing libprotobuf-c1 if missing" + if [[ ! "$(apt list --installed libprotobuf-c1 | grep "installed")" ]]; then + apt-get update && apt --fix-broken install -y libprotobuf-c1 + fi + + echo "4. Setup locale if required" + if ! grep -q "^en_US.UTF-8" /etc/locale.gen ; then + echo "en_US.UTF-8 UTF-8" >> /etc/locale.gen + locale-gen + fi + + if [ "$IS_DRY_RUN" = false ]; then + # awk NF==3 prints lines with exactly 3 fields, which are the block devices currently not mounted anywhere + # excluding nvme0 since it is the root disk + echo "5. Determining block device to mount" + BLOCK_DEVICE=$(lsblk -dprno name,size,mountpoint,type | grep "disk" | grep -v "nvme0" | awk 'NF==3 { print $1; }') + echo "Block device found: $BLOCK_DEVICE" + + mkdir -p "$MOUNT_POINT" + echo "6. Mounting block device" + + sleep 5 + e2fsck -pf "$BLOCK_DEVICE" + + sleep 1 + mount "$BLOCK_DEVICE" "$MOUNT_POINT" + + sleep 1 + resize2fs "$BLOCK_DEVICE" + fi + + if [ -f "$MOUNT_POINT/pgsodium_root.key" ]; then + cp "$MOUNT_POINT/pgsodium_root.key" /etc/postgresql-custom/pgsodium_root.key + chown postgres:postgres /etc/postgresql-custom/pgsodium_root.key + chmod 600 /etc/postgresql-custom/pgsodium_root.key + fi + + echo "7. Disabling extensions and generating post-upgrade script" + handle_extensions + + echo "8. Granting SUPERUSER to postgres user" + run_sql -c "ALTER USER postgres WITH SUPERUSER;" + + if [ -d "/usr/share/postgresql/${PGVERSION}" ]; then + mv "/usr/share/postgresql/${PGVERSION}" "/usr/share/postgresql/${PGVERSION}.bak" + fi + ln -s "$PGSHARENEW" "/usr/share/postgresql/${PGVERSION}" + + cp --remove-destination "$PGLIBNEW"/*.control "$PGSHARENEW/extension/" + cp --remove-destination "$PGLIBNEW"/*.sql "$PGSHARENEW/extension/" + + # This is a workaround for older versions of wrappers which don't have the expected + # naming scheme, containing the version in their library's file name + # e.g. wrappers-0.1.16.so, rather than wrappers.so + # pg_upgrade errors out when it doesn't find an equivalent file in the new PG version's + # library directory, so we're making sure the new version has the expected (old version's) + # file name. + # After the upgrade completes, the new version's library file is used. + # i.e. + # - old version: wrappers-0.1.16.so + # - new version: wrappers-0.1.18.so + # - workaround to make pg_upgrade happy: copy wrappers-0.1.18.so to wrappers-0.1.16.so + if [ -d "$PGLIBOLD" ]; then + WRAPPERS_LIB_PATH=$(find "$PGLIBNEW" -name "wrappers*so" -print -quit) + if [ -f "$WRAPPERS_LIB_PATH" ]; then + OLD_WRAPPER_LIB_PATH=$(find "$PGLIBOLD" -name "wrappers*so" -print -quit) + if [ -f "$OLD_WRAPPER_LIB_PATH" ]; then + LIB_FILE_NAME=$(basename "$OLD_WRAPPER_LIB_PATH") + if [ "$WRAPPERS_LIB_PATH" != "$PGLIBNEW/${LIB_FILE_NAME}" ]; then + echo "Copying $OLD_WRAPPER_LIB_PATH to $WRAPPERS_LIB_PATH" + cp "$WRAPPERS_LIB_PATH" "$PGLIBNEW/${LIB_FILE_NAME}" + fi + fi + fi + fi + + export LD_LIBRARY_PATH="${PGLIBNEW}" + + echo "9. Creating new data directory, initializing database" + chown -R postgres:postgres "$MOUNT_POINT/" + rm -rf "${PGDATANEW:?}/" + su -c "$PGBINNEW/initdb -L $PGSHARENEW -D $PGDATANEW/" -s "$SHELL" postgres + + UPGRADE_COMMAND=$(cat < /tmp/pg-upgrade-status +if [ "$IS_DRY_RUN" = true ]; then + initiate_upgrade +else + initiate_upgrade >> "$LOG_FILE" 2>&1 & + echo "Upgrade initiate job completed" +fi diff --git a/ansible-nix/files/admin_api_scripts/pg_upgrade_scripts/pgsodium_getkey.sh b/ansible-nix/files/admin_api_scripts/pg_upgrade_scripts/pgsodium_getkey.sh new file mode 100755 index 000000000..5a5a90e44 --- /dev/null +++ b/ansible-nix/files/admin_api_scripts/pg_upgrade_scripts/pgsodium_getkey.sh @@ -0,0 +1,12 @@ +#!/bin/bash + +set -euo pipefail + +KEY_FILE=/etc/postgresql-custom/pgsodium_root.key + +# if key file doesn't exist (project previously didn't use pgsodium), generate a new key +if [[ ! -f "${KEY_FILE}" ]]; then + head -c 32 /dev/urandom | od -A n -t x1 | tr -d ' \n' > $KEY_FILE +fi + +cat $KEY_FILE diff --git a/ansible-nix/files/admin_api_scripts/pg_upgrade_scripts/prepare.sh b/ansible-nix/files/admin_api_scripts/pg_upgrade_scripts/prepare.sh new file mode 100755 index 000000000..7d7eb9890 --- /dev/null +++ b/ansible-nix/files/admin_api_scripts/pg_upgrade_scripts/prepare.sh @@ -0,0 +1,15 @@ +#! /usr/bin/env bash +## This script is runs in advance of the database version upgrade, on the newly +## launched instance which will eventually be promoted to become the primary +## database instance once the upgrade successfully completes, terminating the +## previous (source) instance. +## The following commands safely stop the Postgres service and unmount +## the data disk off the newly launched instance, to be re-attached to the +## source instance and run the upgrade there. + +set -euo pipefail + +systemctl stop postgresql + +cp /etc/postgresql-custom/pgsodium_root.key /data/pgsodium_root.key +umount /data diff --git a/ansible-nix/files/adminapi.service.j2 b/ansible-nix/files/adminapi.service.j2 new file mode 100644 index 000000000..6078f3d1a --- /dev/null +++ b/ansible-nix/files/adminapi.service.j2 @@ -0,0 +1,13 @@ +[Unit] +Description=AdminAPI + +[Service] +Type=simple +ExecStart=/opt/supabase-admin-api +User=adminapi +Restart=always +RestartSec=3 +Environment="AWS_USE_DUALSTACK_ENDPOINT=true" + +[Install] +WantedBy=multi-user.target diff --git a/ansible-nix/files/adminapi.sudoers.conf b/ansible-nix/files/adminapi.sudoers.conf new file mode 100644 index 000000000..eada0a94b --- /dev/null +++ b/ansible-nix/files/adminapi.sudoers.conf @@ -0,0 +1,28 @@ +Cmnd_Alias ENVOY = /bin/systemctl start envoy.service, /bin/systemctl stop envoy.service, /bin/systemctl restart envoy.service, /bin/systemctl disable envoy.service, /bin/systemctl enable envoy.service, /bin/systemctl reload envoy.service, /bin/systemctl try-restart envoy.service +Cmnd_Alias KONG = /bin/systemctl start kong.service, /bin/systemctl stop kong.service, /bin/systemctl restart kong.service, /bin/systemctl disable kong.service, /bin/systemctl enable kong.service, /bin/systemctl reload kong.service, /bin/systemctl try-restart kong.service +Cmnd_Alias POSTGREST = /bin/systemctl start postgrest.service, /bin/systemctl stop postgrest.service, /bin/systemctl restart postgrest.service, /bin/systemctl disable postgrest.service, /bin/systemctl enable postgrest.service, /bin/systemctl try-restart postgrest.service +Cmnd_Alias GOTRUE = /bin/systemctl start gotrue.service, /bin/systemctl stop gotrue.service, /bin/systemctl restart gotrue.service, /bin/systemctl disable gotrue.service, /bin/systemctl enable gotrue.service, /bin/systemctl try-restart gotrue.service +Cmnd_Alias PGBOUNCER = /bin/systemctl start pgbouncer.service, /bin/systemctl stop pgbouncer.service, /bin/systemctl restart pgbouncer.service, /bin/systemctl disable pgbouncer.service, /bin/systemctl enable pgbouncer.service, /bin/systemctl reload pgbouncer.service, /bin/systemctl try-restart pgbouncer.service + +%adminapi ALL= NOPASSWD: /root/grow_fs.sh +%adminapi ALL= NOPASSWD: /root/manage_readonly_mode.sh +%adminapi ALL= NOPASSWD: /etc/adminapi/pg_upgrade_scripts/prepare.sh +%adminapi ALL= NOPASSWD: /etc/adminapi/pg_upgrade_scripts/initiate.sh +%adminapi ALL= NOPASSWD: /etc/adminapi/pg_upgrade_scripts/complete.sh +%adminapi ALL= NOPASSWD: /etc/adminapi/pg_upgrade_scripts/check.sh +%adminapi ALL= NOPASSWD: /etc/adminapi/pg_upgrade_scripts/common.sh +%adminapi ALL= NOPASSWD: /etc/adminapi/pg_upgrade_scripts/pgsodium_getkey.sh +%adminapi ALL= NOPASSWD: /usr/bin/systemctl daemon-reload +%adminapi ALL= NOPASSWD: /usr/bin/systemctl reload postgresql.service +%adminapi ALL= NOPASSWD: /usr/bin/systemctl restart postgresql.service +%adminapi ALL= NOPASSWD: /usr/bin/systemctl show -p NRestarts postgresql.service +%adminapi ALL= NOPASSWD: /usr/bin/systemctl restart adminapi.service +%adminapi ALL= NOPASSWD: /bin/systemctl daemon-reload +%adminapi ALL= NOPASSWD: /bin/systemctl restart services.slice +%adminapi ALL= NOPASSWD: /usr/sbin/nft -f /etc/nftables/supabase_managed.conf +%adminapi ALL= NOPASSWD: /usr/bin/admin-mgr +%adminapi ALL= NOPASSWD: ENVOY +%adminapi ALL= NOPASSWD: KONG +%adminapi ALL= NOPASSWD: POSTGREST +%adminapi ALL= NOPASSWD: GOTRUE +%adminapi ALL= NOPASSWD: PGBOUNCER diff --git a/ansible-nix/files/ansible-pull.service b/ansible-nix/files/ansible-pull.service new file mode 100644 index 000000000..3e061b31b --- /dev/null +++ b/ansible-nix/files/ansible-pull.service @@ -0,0 +1,20 @@ +[Unit] +Description=Ansible pull + +[Service] +Type=simple +User=ubuntu + +ExecStart=/usr/bin/ansible-pull --private-key "$SSH_READ_KEY_FILE" -U "$REPO" --accept-host-key -t "$REGION,db-all" -i localhost --clean --full "$PLAYBOOK" -v -o -C "$REPO_BRANCH" + +# --verify-commit +# temporarily disable commit verification, while we figure out how we want to balance commit signatures +# and PR reviews; an --ff-only merge options would have allowed us to use this pretty nicely + +MemoryAccounting=true +MemoryMax=30% + +StandardOutput=append:/var/log/ansible-pull.stdout +StandardError=append:/var/log/ansible-pull.error + +TimeoutStopSec=600 diff --git a/ansible-nix/files/ansible-pull.timer b/ansible-nix/files/ansible-pull.timer new file mode 100644 index 000000000..27ce24b99 --- /dev/null +++ b/ansible-nix/files/ansible-pull.timer @@ -0,0 +1,11 @@ +[Unit] +Description=Run ansible roughly every 3 hours + +[Timer] +OnBootSec=1h +OnUnitActiveSec=3h +RandomizedDelaySec=1h +Persistent=true + +[Install] +WantedBy=timers.target diff --git a/ansible-nix/files/apt_periodic b/ansible-nix/files/apt_periodic new file mode 100644 index 000000000..75870203d --- /dev/null +++ b/ansible-nix/files/apt_periodic @@ -0,0 +1,4 @@ +APT::Periodic::Update-Package-Lists "1"; +APT::Periodic::Download-Upgradeable-Packages "1"; +APT::Periodic::AutocleanInterval "7"; +APT::Periodic::Unattended-Upgrade "1"; \ No newline at end of file diff --git a/ansible-nix/files/cron.deny b/ansible-nix/files/cron.deny new file mode 100644 index 000000000..3b5199b06 --- /dev/null +++ b/ansible-nix/files/cron.deny @@ -0,0 +1,2 @@ +ubuntu +postgres diff --git a/ansible-nix/files/database-optimizations.service.j2 b/ansible-nix/files/database-optimizations.service.j2 new file mode 100644 index 000000000..f25fc09c6 --- /dev/null +++ b/ansible-nix/files/database-optimizations.service.j2 @@ -0,0 +1,12 @@ +[Unit] +Description=Postgresql optimizations + +[Service] +Type=oneshot +# we do not want failures from these commands to cause downstream service startup to fail +ExecStart=-/opt/supabase-admin-api optimize db --destination-config-file-path /etc/postgresql-custom/generated-optimizations.conf +ExecStart=-/opt/supabase-admin-api optimize pgbouncer --destination-config-file-path /etc/pgbouncer-custom/generated-optimizations.ini +User=adminapi + +[Install] +WantedBy=multi-user.target diff --git a/ansible-nix/files/default.sysstat b/ansible-nix/files/default.sysstat new file mode 100644 index 000000000..1b029ba6b --- /dev/null +++ b/ansible-nix/files/default.sysstat @@ -0,0 +1,9 @@ +# +# Default settings for /etc/init.d/sysstat, /etc/cron.d/sysstat +# and /etc/cron.daily/sysstat files +# + +# Should sadc collect system activity informations? Valid values +# are "true" and "false". Please do not put other values, they +# will be overwritten by debconf! +ENABLED="true" diff --git a/ansible-nix/files/envoy.service b/ansible-nix/files/envoy.service new file mode 100644 index 000000000..d739ffdd5 --- /dev/null +++ b/ansible-nix/files/envoy.service @@ -0,0 +1,31 @@ +[Unit] +Description=Envoy +After=postgrest.service gotrue.service adminapi.service +Wants=postgrest.service gotrue.service adminapi.service +Conflicts=kong.service + +[Service] +Type=simple + +ExecStartPre=sh -c 'if ss -lnt | grep -Eq ":(80|443) "; then echo "Port 80 or 443 already in use"; exit 1; fi' + +# Need to run via a restarter script to support hot restart when using a process +# manager, see: +# https://www.envoyproxy.io/docs/envoy/latest/operations/hot_restarter +ExecStart=/opt/envoy-hot-restarter.py /opt/start-envoy.sh + +ExecReload=/bin/kill -HUP $MAINPID +ExecStop=/bin/kill -TERM $MAINPID +User=envoy +Slice=services.slice +Restart=always +RestartSec=3 +LimitNOFILE=100000 + +# The envoy user is unprivileged and thus not permitted to bind on ports < 1024 +# Via systemd we grant the process a set of privileges to bind to 80/443 +# See http://archive.vn/36zJU +AmbientCapabilities=CAP_NET_BIND_SERVICE + +[Install] +WantedBy=multi-user.target diff --git a/ansible-nix/files/envoy_config/cds.yaml b/ansible-nix/files/envoy_config/cds.yaml new file mode 100644 index 000000000..8f921396a --- /dev/null +++ b/ansible-nix/files/envoy_config/cds.yaml @@ -0,0 +1,46 @@ +resources: + - '@type': type.googleapis.com/envoy.config.cluster.v3.Cluster + name: admin_api + load_assignment: + cluster_name: admin_api + endpoints: + - lb_endpoints: + - endpoint: + address: + socket_address: + address: 127.0.0.1 + port_value: 8085 + - '@type': type.googleapis.com/envoy.config.cluster.v3.Cluster + name: gotrue + load_assignment: + cluster_name: gotrue + endpoints: + - lb_endpoints: + - endpoint: + address: + socket_address: + address: 127.0.0.1 + port_value: 9999 + - '@type': type.googleapis.com/envoy.config.cluster.v3.Cluster + name: postgrest + load_assignment: + cluster_name: postgrest + endpoints: + - lb_endpoints: + - endpoint: + address: + socket_address: + address: 127.0.0.1 + port_value: 3000 + - '@type': type.googleapis.com/envoy.config.cluster.v3.Cluster + name: postgrest_admin + load_assignment: + cluster_name: postgrest_admin + endpoints: + - lb_endpoints: + - endpoint: + address: + socket_address: + address: 127.0.0.1 + port_value: 3001 + diff --git a/ansible-nix/files/envoy_config/envoy.yaml b/ansible-nix/files/envoy_config/envoy.yaml new file mode 100644 index 000000000..3d25c13cd --- /dev/null +++ b/ansible-nix/files/envoy_config/envoy.yaml @@ -0,0 +1,23 @@ +dynamic_resources: + cds_config: + path_config_source: + path: /etc/envoy/cds.yaml + resource_api_version: V3 + lds_config: + path_config_source: + path: /etc/envoy/lds.yaml + resource_api_version: V3 +node: + cluster: cluster_0 + id: node_0 +overload_manager: + resource_monitors: + - name: envoy.resource_monitors.global_downstream_max_connections + typed_config: + '@type': >- + type.googleapis.com/envoy.extensions.resource_monitors.downstream_connections.v3.DownstreamConnectionsConfig + max_active_downstream_connections: 30000 +stats_config: + stats_matcher: + reject_all: true + diff --git a/ansible-nix/files/envoy_config/lds.yaml b/ansible-nix/files/envoy_config/lds.yaml new file mode 100644 index 000000000..84acfc041 --- /dev/null +++ b/ansible-nix/files/envoy_config/lds.yaml @@ -0,0 +1,315 @@ +resources: + - '@type': type.googleapis.com/envoy.config.listener.v3.Listener + name: http_listener + address: + socket_address: + address: '::' + port_value: 80 + ipv4_compat: true + filter_chains: + - filters: &ref_1 + - name: envoy.filters.network.http_connection_manager + typed_config: + '@type': >- + type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager + access_log: + - name: envoy.access_loggers.stdout + filter: + status_code_filter: + comparison: + op: GE + value: + default_value: 400 + runtime_key: unused + typed_config: + '@type': >- + type.googleapis.com/envoy.extensions.access_loggers.stream.v3.StdoutAccessLog + generate_request_id: false + http_filters: + - name: envoy.filters.http.cors + typed_config: + '@type': >- + type.googleapis.com/envoy.extensions.filters.http.cors.v3.Cors + - name: envoy.filters.http.rbac + typed_config: + '@type': >- + type.googleapis.com/envoy.extensions.filters.http.rbac.v3.RBAC + rules: + action: DENY + policies: + api_key_missing: + permissions: + - any: true + principals: + - not_id: + or_ids: + ids: + - header: + name: apikey + present_match: true + - header: + name: ':path' + string_match: + contains: apikey= + api_key_not_valid: + permissions: + - any: true + principals: + - not_id: + or_ids: + ids: + - header: + name: apikey + string_match: + exact: anon_key + - header: + name: apikey + string_match: + exact: service_key + - header: + name: apikey + string_match: + exact: supabase_admin_key + - header: + name: ':path' + string_match: + contains: apikey=anon_key + - header: + name: ':path' + string_match: + contains: apikey=service_key + - header: + name: ':path' + string_match: + contains: apikey=supabase_admin_key + - name: envoy.filters.http.lua + typed_config: + '@type': >- + type.googleapis.com/envoy.extensions.filters.http.lua.v3.Lua + source_codes: + remove_apikey_query_parameter: + filename: /etc/envoy/remove_apikey_query_parameter.lua + - name: envoy.filters.http.router + typed_config: + '@type': >- + type.googleapis.com/envoy.extensions.filters.http.router.v3.Router + dynamic_stats: false + local_reply_config: + mappers: + - filter: + and_filter: + filters: + - status_code_filter: + comparison: + value: + default_value: 403 + runtime_key: unused + - header_filter: + header: + name: ':path' + string_match: + prefix: /customer/v1/privileged/ + status_code: 401 + body: + inline_string: Unauthorized + headers_to_add: + - header: + key: WWW-Authenticate + value: Basic realm="Unknown" + - filter: + and_filter: + filters: + - status_code_filter: + comparison: + value: + default_value: 403 + runtime_key: unused + - header_filter: + header: + name: ':path' + string_match: + prefix: /metrics/aggregated + invert_match: true + status_code: 401 + body_format_override: + json_format: + message: >- + `apikey` request header or query parameter is either + missing or invalid. Double check your Supabase `anon` + or `service_role` API key. + hint: '%RESPONSE_CODE_DETAILS%' + json_format_options: + sort_properties: false + route_config: + name: route_config_0 + virtual_hosts: + - name: virtual_host_0 + domains: + - '*' + typed_per_filter_config: + envoy.filters.http.cors: + '@type': >- + type.googleapis.com/envoy.extensions.filters.http.cors.v3.CorsPolicy + allow_origin_string_match: + - safe_regex: + regex: \* + allow_methods: GET,HEAD,PUT,PATCH,POST,DELETE,OPTIONS,TRACE,CONNECT + allow_headers: apikey,authorization,x-client-info + max_age: '3600' + routes: + - match: + path: /health + direct_response: + status: 200 + body: + inline_string: Healthy + typed_per_filter_config: &ref_0 + envoy.filters.http.rbac: + '@type': >- + type.googleapis.com/envoy.extensions.filters.http.rbac.v3.RBACPerRoute + - match: + safe_regex: + regex: >- + /auth/v1/(verify|callback|authorize|sso/saml/(acs|metadata|slo)) + route: + cluster: gotrue + regex_rewrite: + pattern: + regex: ^/auth/v1 + substitution: '' + retry_policy: + num_retries: 3 + retry_on: 5xx + typed_per_filter_config: *ref_0 + - match: + prefix: /auth/v1/ + route: + cluster: gotrue + prefix_rewrite: / + - match: + prefix: /rest/v1/ + query_parameters: + - name: apikey + present_match: true + request_headers_to_remove: + - apikey + route: + cluster: postgrest + prefix_rewrite: / + timeout: 120s + typed_per_filter_config: + envoy.filters.http.lua: + '@type': >- + type.googleapis.com/envoy.extensions.filters.http.lua.v3.LuaPerRoute + name: remove_apikey_query_parameter + - match: + prefix: /rest/v1/ + request_headers_to_remove: + - apikey + route: + cluster: postgrest + prefix_rewrite: / + timeout: 120s + - match: + prefix: /rest-admin/v1/ + query_parameters: + - name: apikey + present_match: true + request_headers_to_remove: + - apikey + route: + cluster: postgrest_admin + prefix_rewrite: / + typed_per_filter_config: + envoy.filters.http.lua: + '@type': >- + type.googleapis.com/envoy.extensions.filters.http.lua.v3.LuaPerRoute + name: remove_apikey_query_parameter + - match: + prefix: /rest-admin/v1/ + request_headers_to_remove: + - apikey + route: + cluster: postgrest_admin + prefix_rewrite: / + - match: + path: /graphql/v1 + request_headers_to_add: + header: + key: Content-Profile + value: graphql_public + route: + cluster: postgrest + prefix_rewrite: /rpc/graphql + timeout: 120s + - match: + prefix: /admin/v1/ + route: + cluster: admin_api + prefix_rewrite: / + - match: + prefix: /customer/v1/privileged/ + route: + cluster: admin_api + prefix_rewrite: /privileged/ + typed_per_filter_config: + envoy.filters.http.rbac: + '@type': >- + type.googleapis.com/envoy.extensions.filters.http.rbac.v3.RBACPerRoute + rbac: + rules: + action: DENY + policies: + basic_auth: + permissions: + - any: true + principals: + - header: + name: authorization + invert_match: true + string_match: + exact: Basic c2VydmljZV9yb2xlOnNlcnZpY2Vfa2V5 + treat_missing_header_as_empty: true + - match: + prefix: /metrics/aggregated + route: + cluster: admin_api + prefix_rewrite: /supabase-internal/metrics + typed_per_filter_config: + envoy.filters.http.rbac: + '@type': >- + type.googleapis.com/envoy.extensions.filters.http.rbac.v3.RBACPerRoute + rbac: + rules: + action: DENY + policies: + not_private_ip: + permissions: + - any: true + principals: + - not_id: + direct_remote_ip: + address_prefix: 10.0.0.0 + prefix_len: 8 + stat_prefix: ingress_http + - '@type': type.googleapis.com/envoy.config.listener.v3.Listener + name: https_listener + address: + socket_address: + address: '::' + port_value: 443 + ipv4_compat: true + filter_chains: + - filters: *ref_1 + transport_socket: + name: envoy.transport_sockets.tls + typed_config: + '@type': >- + type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext + common_tls_context: + tls_certificates: + - certificate_chain: + filename: /etc/envoy/fullChain.pem + private_key: + filename: /etc/envoy/privKey.pem + diff --git a/ansible-nix/files/envoy_config/remove_apikey_query_parameter.lua b/ansible-nix/files/envoy_config/remove_apikey_query_parameter.lua new file mode 100644 index 000000000..0aeabaeb1 --- /dev/null +++ b/ansible-nix/files/envoy_config/remove_apikey_query_parameter.lua @@ -0,0 +1,8 @@ +function envoy_on_request(request_handle) + local path = request_handle:headers():get(":path") + + -- Remove `apikey` query parameter since PostgREST treats query parameters as conditions. + request_handle + :headers() + :replace(":path", path:gsub("([&?])apikey=[^&]+&?", "%1"):gsub("&$", "")) +end diff --git a/ansible-nix/files/fail2ban_config/fail2ban.service.conf b/ansible-nix/files/fail2ban_config/fail2ban.service.conf new file mode 100644 index 000000000..431d1db5b --- /dev/null +++ b/ansible-nix/files/fail2ban_config/fail2ban.service.conf @@ -0,0 +1,6 @@ +[Unit] +After=nftables.service +Wants=nftables.service + +[Service] +ExecStartPost=/bin/bash -c "sleep 5 && chmod g+w /var/run/fail2ban/fail2ban.sock" diff --git a/ansible-nix/files/fail2ban_config/filter-pgbouncer.conf.j2 b/ansible-nix/files/fail2ban_config/filter-pgbouncer.conf.j2 new file mode 100644 index 000000000..3a3a52ec6 --- /dev/null +++ b/ansible-nix/files/fail2ban_config/filter-pgbouncer.conf.j2 @@ -0,0 +1,3 @@ +[Definition] +failregex = ^.+@:.+password authentication failed$ +journalmatch = _SYSTEMD_UNIT=pgbouncer.service diff --git a/ansible-nix/files/fail2ban_config/filter-postgresql.conf.j2 b/ansible-nix/files/fail2ban_config/filter-postgresql.conf.j2 new file mode 100644 index 000000000..fd0895aee --- /dev/null +++ b/ansible-nix/files/fail2ban_config/filter-postgresql.conf.j2 @@ -0,0 +1,3 @@ +[Definition] +failregex = ^.*,.*,.*,.*,":.*password authentication failed for user.*$ +ignoreregex = ^.*,.*,.*,.*,"127\.0\.0\.1.*password authentication failed for user.*$ \ No newline at end of file diff --git a/ansible-nix/files/fail2ban_config/jail-pgbouncer.conf.j2 b/ansible-nix/files/fail2ban_config/jail-pgbouncer.conf.j2 new file mode 100644 index 000000000..60a9eb3d9 --- /dev/null +++ b/ansible-nix/files/fail2ban_config/jail-pgbouncer.conf.j2 @@ -0,0 +1,7 @@ +[pgbouncer] +enabled = true +port = 6543 +protocol = tcp +filter = pgbouncer +backend = systemd[journalflags=1] +maxretry = 3 diff --git a/ansible-nix/files/fail2ban_config/jail-postgresql.conf.j2 b/ansible-nix/files/fail2ban_config/jail-postgresql.conf.j2 new file mode 100644 index 000000000..a021035a9 --- /dev/null +++ b/ansible-nix/files/fail2ban_config/jail-postgresql.conf.j2 @@ -0,0 +1,8 @@ +[postgresql] +enabled = true +port = 5432 +protocol = tcp +filter = postgresql +logpath = /var/log/postgresql/auth-failures.csv +maxretry = 3 +ignoreip = 192.168.0.0/16 172.17.1.0/20 diff --git a/ansible-nix/files/fail2ban_config/jail-ssh.conf b/ansible-nix/files/fail2ban_config/jail-ssh.conf new file mode 100644 index 000000000..5476c3093 --- /dev/null +++ b/ansible-nix/files/fail2ban_config/jail-ssh.conf @@ -0,0 +1,4 @@ +[sshd] + +backend = systemd +mode = aggressive diff --git a/ansible-nix/files/fail2ban_config/jail.local b/ansible-nix/files/fail2ban_config/jail.local new file mode 100644 index 000000000..44e8210f1 --- /dev/null +++ b/ansible-nix/files/fail2ban_config/jail.local @@ -0,0 +1,4 @@ +[DEFAULT] + +banaction = nftables-multiport +banaction_allports = nftables-allports diff --git a/ansible-nix/files/gotrue.service.j2 b/ansible-nix/files/gotrue.service.j2 new file mode 100644 index 000000000..f0bd60ab0 --- /dev/null +++ b/ansible-nix/files/gotrue.service.j2 @@ -0,0 +1,21 @@ +[Unit] +Description=Gotrue + +[Service] +Type=simple +WorkingDirectory=/opt/gotrue +ExecStart=/opt/gotrue/gotrue +User=gotrue +Restart=always +RestartSec=3 + +MemoryAccounting=true +MemoryMax=50% + +EnvironmentFile=/etc/gotrue.env +EnvironmentFile=-/etc/gotrue.overrides.env + +Slice=services.slice + +[Install] +WantedBy=multi-user.target diff --git a/ansible-nix/files/journald.conf b/ansible-nix/files/journald.conf new file mode 100644 index 000000000..2eb89f91f --- /dev/null +++ b/ansible-nix/files/journald.conf @@ -0,0 +1,6 @@ +[Journal] +Storage=persistent +SystemMaxUse=3G +SystemKeepFree=3G +SystemMaxFileSize=200M +ForwardToSyslog=no diff --git a/ansible-nix/files/kong_config/kong.conf.j2 b/ansible-nix/files/kong_config/kong.conf.j2 new file mode 100644 index 000000000..39067575e --- /dev/null +++ b/ansible-nix/files/kong_config/kong.conf.j2 @@ -0,0 +1,7 @@ +database = off +declarative_config = /etc/kong/kong.yml + +# plugins defined in the dockerfile +plugins = request-transformer,cors,key-auth,http-log + +proxy_listen = 0.0.0.0:80 reuseport backlog=16384, 0.0.0.0:443 http2 ssl reuseport backlog=16834, [::]:80 reuseport backlog=16384, [::]:443 http2 ssl reuseport backlog=16384 diff --git a/ansible-nix/files/kong_config/kong.env.j2 b/ansible-nix/files/kong_config/kong.env.j2 new file mode 100644 index 000000000..57613fdbb --- /dev/null +++ b/ansible-nix/files/kong_config/kong.env.j2 @@ -0,0 +1,8 @@ +KONG_NGINX_HTTP_GZIP=on +KONG_NGINX_HTTP_GZIP_COMP_LEVEL=6 +KONG_NGINX_HTTP_GZIP_MIN_LENGTH=256 +KONG_NGINX_HTTP_GZIP_PROXIED=any +KONG_NGINX_HTTP_GZIP_VARY=on +KONG_NGINX_HTTP_GZIP_TYPES=text/plain application/xml application/openapi+json application/json +KONG_PROXY_ERROR_LOG=syslog:server=unix:/dev/log +KONG_ADMIN_ERROR_LOG=syslog:server=unix:/dev/log diff --git a/ansible-nix/files/kong_config/kong.service.j2 b/ansible-nix/files/kong_config/kong.service.j2 new file mode 100644 index 000000000..6a36520bc --- /dev/null +++ b/ansible-nix/files/kong_config/kong.service.j2 @@ -0,0 +1,28 @@ +[Unit] +Description=Kong server +After=postgrest.service gotrue.service adminapi.service +Wants=postgrest.service gotrue.service adminapi.service +Conflicts=envoy.service + +# Ensures that Kong service is stopped before Envoy service is started +Before=envoy.service + +[Service] +Type=forking +ExecStart=/usr/local/bin/kong start -c /etc/kong/kong.conf +ExecReload=/usr/local/bin/kong reload -c /etc/kong/kong.conf +ExecStop=/usr/local/bin/kong quit +User=kong +EnvironmentFile=/etc/kong/kong.env +Slice=services.slice +Restart=always +RestartSec=3 +LimitNOFILE=100000 + +# The kong user is unprivileged and thus not permitted to bind on ports < 1024 +# Via systemd we grant the process a set of privileges to bind to 80/443 +# See http://archive.vn/36zJU +AmbientCapabilities=CAP_NET_BIND_SERVICE + +[Install] +WantedBy=multi-user.target diff --git a/ansible-nix/files/logind.conf b/ansible-nix/files/logind.conf new file mode 100644 index 000000000..732900f3c --- /dev/null +++ b/ansible-nix/files/logind.conf @@ -0,0 +1,2 @@ +[Login] +RemoveIPC=no diff --git a/ansible-nix/files/logrotate_config/logrotate-postgres-auth.conf b/ansible-nix/files/logrotate_config/logrotate-postgres-auth.conf new file mode 100644 index 000000000..050210e60 --- /dev/null +++ b/ansible-nix/files/logrotate_config/logrotate-postgres-auth.conf @@ -0,0 +1,8 @@ +/var/log/postgresql/auth-failures.csv { + size 10M + rotate 5 + compress + delaycompress + notifempty + missingok +} diff --git a/ansible-nix/files/logrotate_config/logrotate-postgres-csv.conf b/ansible-nix/files/logrotate_config/logrotate-postgres-csv.conf new file mode 100644 index 000000000..e5418e8e0 --- /dev/null +++ b/ansible-nix/files/logrotate_config/logrotate-postgres-csv.conf @@ -0,0 +1,11 @@ +/var/log/postgresql/postgresql.csv { + size 50M + rotate 9 + compress + delaycompress + notifempty + missingok + postrotate + sudo -u postgres /usr/lib/postgresql/bin/pg_ctl -D /var/lib/postgresql/data logrotate + endscript +} diff --git a/ansible-nix/files/logrotate_config/logrotate-postgres.conf b/ansible-nix/files/logrotate_config/logrotate-postgres.conf new file mode 100644 index 000000000..c802320c4 --- /dev/null +++ b/ansible-nix/files/logrotate_config/logrotate-postgres.conf @@ -0,0 +1,9 @@ +/var/log/postgresql/postgresql.log { + size 50M + rotate 3 + copytruncate + delaycompress + compress + notifempty + missingok +} diff --git a/ansible-nix/files/logrotate_config/logrotate-walg.conf b/ansible-nix/files/logrotate_config/logrotate-walg.conf new file mode 100644 index 000000000..49eeb59eb --- /dev/null +++ b/ansible-nix/files/logrotate_config/logrotate-walg.conf @@ -0,0 +1,9 @@ +/var/log/wal-g/*.log { + size 50M + rotate 3 + copytruncate + delaycompress + compress + notifempty + missingok +} diff --git a/ansible-nix/files/manifest.json b/ansible-nix/files/manifest.json new file mode 100644 index 000000000..3a20e76a0 --- /dev/null +++ b/ansible-nix/files/manifest.json @@ -0,0 +1 @@ +{{ vars | to_json }} diff --git a/ansible-nix/files/nginx.service.j2 b/ansible-nix/files/nginx.service.j2 new file mode 100644 index 000000000..872e3346a --- /dev/null +++ b/ansible-nix/files/nginx.service.j2 @@ -0,0 +1,22 @@ +[Unit] +Description=nginx server +After=postgrest.service gotrue.service adminapi.service +Wants=postgrest.service gotrue.service adminapi.service + +[Service] +Type=forking +ExecStart=/usr/local/nginx/sbin/nginx -c /etc/nginx/nginx.conf +ExecReload=/usr/local/nginx/sbin/nginx -s reload -c /etc/nginx/nginx.conf +ExecStop=/usr/local/nginx/sbin/nginx -s quit +User=nginx +Slice=services.slice +Restart=always +RestartSec=3 +LimitNOFILE=100000 + +# Via systemd we grant the process a set of privileges to bind to 80/443 +# See http://archive.vn/36zJU +AmbientCapabilities=CAP_NET_BIND_SERVICE + +[Install] +WantedBy=multi-user.target diff --git a/ansible-nix/files/permission_check.py b/ansible-nix/files/permission_check.py new file mode 100644 index 000000000..724acb10a --- /dev/null +++ b/ansible-nix/files/permission_check.py @@ -0,0 +1,204 @@ +import subprocess +import json +import sys + +# Expected groups for each user +expected_results = { + "postgres": [ + {"groupname": "postgres", "username": "postgres"}, + {"groupname": "ssl-cert", "username": "postgres"} + ], + "ubuntu": [ + {"groupname":"ubuntu","username":"ubuntu"}, + {"groupname":"adm","username":"ubuntu"}, + {"groupname":"dialout","username":"ubuntu"}, + {"groupname":"cdrom","username":"ubuntu"}, + {"groupname":"floppy","username":"ubuntu"}, + {"groupname":"sudo","username":"ubuntu"}, + {"groupname":"audio","username":"ubuntu"}, + {"groupname":"dip","username":"ubuntu"}, + {"groupname":"video","username":"ubuntu"}, + {"groupname":"plugdev","username":"ubuntu"}, + {"groupname":"lxd","username":"ubuntu"}, + {"groupname":"netdev","username":"ubuntu"} + ], + "root": [ + {"groupname":"root","username":"root"} + ], + "daemon": [ + {"groupname":"daemon","username":"daemon"} + ], + "bin": [ + {"groupname":"bin","username":"bin"} + ], + "sys": [ + {"groupname":"sys","username":"sys"} + ], + "sync": [ + {"groupname":"nogroup","username":"sync"} + ], + "games": [ + {"groupname":"games","username":"games"} + ], + "man": [ + {"groupname":"man","username":"man"} + ], + "lp": [ + {"groupname":"lp","username":"lp"} + ], + "mail": [ + {"groupname":"mail","username":"mail"} + ], + "news": [ + {"groupname":"news","username":"news"} + ], + "uucp": [ + {"groupname":"uucp","username":"uucp"} + ], + "proxy": [ + {"groupname":"proxy","username":"proxy"} + ], + "www-data": [ + {"groupname":"www-data","username":"www-data"} + ], + "backup": [ + {"groupname":"backup","username":"backup"} + ], + "list": [ + {"groupname":"list","username":"list"} + ], + "irc": [ + {"groupname":"irc","username":"irc"} + ], + "gnats": [ + {"groupname":"gnats","username":"gnats"} + ], + "nobody": [ + {"groupname":"nogroup","username":"nobody"} + ], + "systemd-network": [ + {"groupname":"systemd-network","username":"systemd-network"} + ], + "systemd-resolve": [ + {"groupname":"systemd-resolve","username":"systemd-resolve"} + ], + "systemd-timesync": [ + {"groupname":"systemd-timesync","username":"systemd-timesync"} + ], + "messagebus": [ + {"groupname":"messagebus","username":"messagebus"} + ], + "ec2-instance-connect": [ + {"groupname":"nogroup","username":"ec2-instance-connect"} + ], + "sshd": [ + {"groupname":"nogroup","username":"sshd"} + ], + "wal-g": [ + {"groupname":"wal-g","username":"wal-g"}, + {"groupname":"postgres","username":"wal-g"} + ], + "pgbouncer": [ + {"groupname":"pgbouncer","username":"pgbouncer"}, + {"groupname":"ssl-cert","username":"pgbouncer"}, + {"groupname":"postgres","username":"pgbouncer"} + ], + "gotrue": [ + {"groupname":"gotrue","username":"gotrue"} + ], + "envoy": [ + {"groupname":"envoy","username":"envoy"} + ], + "kong": [ + {"groupname":"kong","username":"kong"} + ], + "nginx": [ + {"groupname":"nginx","username":"nginx"} + ], + "vector": [ + {"groupname":"vector","username":"vector"}, + {"groupname":"adm","username":"vector"}, + {"groupname":"systemd-journal","username":"vector"}, + {"groupname":"postgres","username":"vector"} + ], + "adminapi": [ + {"groupname":"adminapi","username":"adminapi"}, + {"groupname":"root","username":"adminapi"}, + {"groupname":"systemd-journal","username":"adminapi"}, + {"groupname":"admin","username":"adminapi"}, + {"groupname":"postgres","username":"adminapi"}, + {"groupname":"pgbouncer","username":"adminapi"}, + {"groupname":"wal-g","username":"adminapi"}, + {"groupname":"postgrest","username":"adminapi"}, + {"groupname":"envoy","username":"adminapi"}, + {"groupname":"kong","username":"adminapi"}, + {"groupname":"vector","username":"adminapi"} + ], + "postgrest": [ + {"groupname":"postgrest","username":"postgrest"} + ], + "tcpdump": [ + {"groupname":"tcpdump","username":"tcpdump"} + ], + "systemd-coredump": [ + {"groupname":"systemd-coredump","username":"systemd-coredump"} + ] +} +# This program depends on osquery being installed on the system +# Function to run osquery +def run_osquery(query): + process = subprocess.Popen(['osqueryi', '--json', query], stdout=subprocess.PIPE, stderr=subprocess.PIPE) + output, error = process.communicate() + return output.decode('utf-8') + +def parse_json(json_str): + try: + return json.loads(json_str) + except json.JSONDecodeError as e: + print("Error decoding JSON:", e) + sys.exit(1) + +def compare_results(username, query_result): + expected_result = expected_results.get(username) + if expected_result is None: + print(f"No expected result defined for user '{username}'") + sys.exit(1) + + if query_result == expected_result: + print(f"The query result for user '{username}' matches the expected result.") + else: + print(f"The query result for user '{username}' does not match the expected result.") + print("Expected:", expected_result) + print("Got:", query_result) + sys.exit(1) + +def check_nixbld_users(): + query = """ + SELECT u.username, g.groupname + FROM users u + JOIN user_groups ug ON u.uid = ug.uid + JOIN groups g ON ug.gid = g.gid + WHERE u.username LIKE 'nixbld%'; + """ + query_result = run_osquery(query) + parsed_result = parse_json(query_result) + + for user in parsed_result: + if user['groupname'] != 'nixbld': + print(f"User '{user['username']}' is in group '{user['groupname']}' instead of 'nixbld'.") + sys.exit(1) + + print("All nixbld users are in the 'nixbld' group.") + +# Define usernames for which you want to compare results +usernames = ["postgres", "ubuntu", "root", "daemon", "bin", "sys", "sync", "games","man","lp","mail","news","uucp","proxy","www-data","backup","list","irc","gnats","nobody","systemd-network","systemd-resolve","systemd-timesync","messagebus","ec2-instance-connect","sshd","wal-g","pgbouncer","gotrue","envoy","kong","nginx","vector","adminapi","postgrest","tcpdump","systemd-coredump"] + +# Iterate over usernames, run the query, and compare results +for username in usernames: + query = f"SELECT u.username, g.groupname FROM users u JOIN user_groups ug ON u.uid = ug.uid JOIN groups g ON ug.gid = g.gid WHERE u.username = '{username}';" + query_result = run_osquery(query) + parsed_result = parse_json(query_result) + compare_results(username, parsed_result) + +# Check if all nixbld users are in the nixbld group +check_nixbld_users() diff --git a/ansible-nix/files/pg_egress_collect.service.j2 b/ansible-nix/files/pg_egress_collect.service.j2 new file mode 100644 index 000000000..7ac04f47d --- /dev/null +++ b/ansible-nix/files/pg_egress_collect.service.j2 @@ -0,0 +1,13 @@ +[Unit] +Description=Postgres Egress Collector + +[Service] +Type=simple +ExecStart=/bin/bash -c "tcpdump -s 128 -Q out -nn -tt -vv -p -l 'tcp and (port 5432 or port 6543)' | perl /root/pg_egress_collect.pl" +User=root +Slice=services.slice +Restart=always +RestartSec=3 + +[Install] +WantedBy=multi-user.target diff --git a/ansible-nix/files/pgbouncer_config/pgbouncer.ini.j2 b/ansible-nix/files/pgbouncer_config/pgbouncer.ini.j2 new file mode 100644 index 000000000..e4518c007 --- /dev/null +++ b/ansible-nix/files/pgbouncer_config/pgbouncer.ini.j2 @@ -0,0 +1,364 @@ +;;; +;;; PgBouncer configuration file +;;; + +;; database name = connect string +;; +;; connect string params: +;; dbname= host= port= user= password= auth_user= +;; client_encoding= datestyle= timezone= +;; pool_size= reserve_pool= max_db_connections= +;; pool_mode= connect_query= application_name= +[databases] +* = host=localhost auth_user=pgbouncer + +;; foodb over Unix socket +;foodb = + +;; redirect bardb to bazdb on localhost +;bardb = host=localhost dbname=bazdb + +;; access to dest database will go with single user +;forcedb = host=localhost port=300 user=baz password=foo client_encoding=UNICODE datestyle=ISO connect_query='SELECT 1' + +;; use custom pool sizes +;nondefaultdb = pool_size=50 reserve_pool=10 + +;; use auth_user with auth_query if user not present in auth_file +;; auth_user must exist in auth_file +; foodb = auth_user=bar + +;; fallback connect string +;* = host=testserver + +;; User-specific configuration +[users] + +;user1 = pool_mode=transaction max_user_connections=10 + +;; Configuration section +[pgbouncer] + +;;; +;;; Administrative settings +;;; + +;logfile = /var/log/pgbouncer.log +pidfile = /var/run/pgbouncer/pgbouncer.pid + +;;; +;;; Where to wait for clients +;;; + +;; IP address or * which means all IPs +listen_addr = * +listen_port = 6543 + +;; Unix socket is also used for -R. +;; On Debian it should be /var/run/postgresql +unix_socket_dir = /tmp +;unix_socket_mode = 0777 +;unix_socket_group = + +;;; +;;; TLS settings for accepting clients +;;; + +;; disable, allow, require, verify-ca, verify-full +;client_tls_sslmode = disable + +;; Path to file that contains trusted CA certs +;client_tls_ca_file = + +;; Private key and cert to present to clients. +;; Required for accepting TLS connections from clients. +;client_tls_key_file = +;client_tls_cert_file = + +;; fast, normal, secure, legacy, +;client_tls_ciphers = fast + +;; all, secure, tlsv1.0, tlsv1.1, tlsv1.2, tlsv1.3 +;client_tls_protocols = secure + +;; none, auto, legacy +;client_tls_dheparams = auto + +;; none, auto, +;client_tls_ecdhcurve = auto + +;;; +;;; TLS settings for connecting to backend databases +;;; + +;; disable, allow, require, verify-ca, verify-full +;server_tls_sslmode = disable + +;; Path to that contains trusted CA certs +;server_tls_ca_file = + +;; Private key and cert to present to backend. +;; Needed only if backend server require client cert. +;server_tls_key_file = +;server_tls_cert_file = + +;; all, secure, tlsv1.0, tlsv1.1, tlsv1.2, tlsv1.3 +;server_tls_protocols = secure + +;; fast, normal, secure, legacy, +;server_tls_ciphers = fast + +;;; +;;; Authentication settings +;;; + +;; any, trust, plain, md5, cert, hba, pam +auth_type = scram-sha-256 +auth_file = /etc/pgbouncer/userlist.txt + +;; Path to HBA-style auth config +;auth_hba_file = + +;; Query to use to fetch password from database. Result +;; must have 2 columns - username and password hash. +auth_query = SELECT * FROM pgbouncer.get_auth($1) + +;;; +;;; Users allowed into database 'pgbouncer' +;;; + +;; comma-separated list of users who are allowed to change settings +admin_users = pgbouncer + +;; comma-separated list of users who are just allowed to use SHOW command +stats_users = pgbouncer + +;;; +;;; Pooler personality questions +;;; + +;; When server connection is released back to pool: +;; session - after client disconnects (default) +;; transaction - after transaction finishes +;; statement - after statement finishes +pool_mode = transaction + +;; Query for cleaning connection immediately after releasing from +;; client. No need to put ROLLBACK here, pgbouncer does not reuse +;; connections where transaction is left open. +;server_reset_query = DISCARD ALL + +;; Whether server_reset_query should run in all pooling modes. If it +;; is off, server_reset_query is used only for session-pooling. +;server_reset_query_always = 0 + +;; Comma-separated list of parameters to ignore when given in startup +;; packet. Newer JDBC versions require the extra_float_digits here. +ignore_startup_parameters = extra_float_digits + +;; When taking idle server into use, this query is run first. +;server_check_query = select 1 + +;; If server was used more recently that this many seconds ago, +; skip the check query. Value 0 may or may not run in immediately. +;server_check_delay = 30 + +;; Close servers in session pooling mode after a RECONNECT, RELOAD, +;; etc. when they are idle instead of at the end of the session. +;server_fast_close = 0 + +;; Use as application_name on server. +;application_name_add_host = 0 + +;; Period for updating aggregated stats. +;stats_period = 60 + +;;; +;;; Connection limits +;;; + +;; Total number of clients that can connect +;max_client_conn = 100 + +;; Default pool size. 20 is good number when transaction pooling +;; is in use, in session pooling it needs to be the number of +;; max clients you want to handle at any moment +default_pool_size = 15 + +;; Minimum number of server connections to keep in pool. +;min_pool_size = 0 + +; how many additional connection to allow in case of trouble +;reserve_pool_size = 0 + +;; If a clients needs to wait more than this many seconds, use reserve +;; pool. +;reserve_pool_timeout = 5 + +;; Maximum number of server connections for a database +;max_db_connections = 0 + +;; Maximum number of server connections for a user +;max_user_connections = 0 + +;; If off, then server connections are reused in LIFO manner +;server_round_robin = 0 + +;;; +;;; Logging +;;; + +;; Syslog settings +;syslog = 0 +;syslog_facility = daemon +;syslog_ident = pgbouncer + +;; log if client connects or server connection is made +;log_connections = 1 + +;; log if and why connection was closed +;log_disconnections = 1 + +;; log error messages pooler sends to clients +;log_pooler_errors = 1 + +;; write aggregated stats into log +;log_stats = 1 + +;; Logging verbosity. Same as -v switch on command line. +;verbose = 0 + +;;; +;;; Timeouts +;;; + +;; Close server connection if its been connected longer. +;server_lifetime = 3600 + +;; Close server connection if its not been used in this time. Allows +;; to clean unnecessary connections from pool after peak. +;server_idle_timeout = 600 + +;; Cancel connection attempt if server does not answer takes longer. +;server_connect_timeout = 15 + +;; If server login failed (server_connect_timeout or auth failure) +;; then wait this many second. +;server_login_retry = 15 + +;; Dangerous. Server connection is closed if query does not return in +;; this time. Should be used to survive network problems, _not_ as +;; statement_timeout. (default: 0) +;query_timeout = 0 + +;; Dangerous. Client connection is closed if the query is not +;; assigned to a server in this time. Should be used to limit the +;; number of queued queries in case of a database or network +;; failure. (default: 120) +;query_wait_timeout = 120 + +;; Dangerous. Client connection is closed if no activity in this +;; time. Should be used to survive network problems. (default: 0) +;client_idle_timeout = 0 + +;; Disconnect clients who have not managed to log in after connecting +;; in this many seconds. +;client_login_timeout = 60 + +;; Clean automatically created database entries (via "*") if they stay +;; unused in this many seconds. +; autodb_idle_timeout = 3600 + +;; Close connections which are in "IDLE in transaction" state longer +;; than this many seconds. +;idle_transaction_timeout = 0 + +;; How long SUSPEND/-R waits for buffer flush before closing +;; connection. +;suspend_timeout = 10 + +;;; +;;; Low-level tuning options +;;; + +;; buffer for streaming packets +;pkt_buf = 4096 + +;; man 2 listen +;listen_backlog = 128 + +;; Max number pkt_buf to process in one event loop. +;sbuf_loopcnt = 5 + +;; Maximum PostgreSQL protocol packet size. +;max_packet_size = 2147483647 + +;; Set SO_REUSEPORT socket option +;so_reuseport = 0 + +;; networking options, for info: man 7 tcp + +;; Linux: Notify program about new connection only if there is also +;; data received. (Seconds to wait.) On Linux the default is 45, on +;; other OS'es 0. +;tcp_defer_accept = 0 + +;; In-kernel buffer size (Linux default: 4096) +;tcp_socket_buffer = 0 + +;; whether tcp keepalive should be turned on (0/1) +;tcp_keepalive = 1 + +;; The following options are Linux-specific. They also require +;; tcp_keepalive=1. + +;; Count of keepalive packets +;tcp_keepcnt = 0 + +;; How long the connection can be idle before sending keepalive +;; packets +;tcp_keepidle = 0 + +;; The time between individual keepalive probes +;tcp_keepintvl = 0 + +;; How long may transmitted data remain unacknowledged before TCP +;; connection is closed (in milliseconds) +;tcp_user_timeout = 0 + +;; DNS lookup caching time +;dns_max_ttl = 15 + +;; DNS zone SOA lookup period +;dns_zone_check_period = 0 + +;; DNS negative result caching time +;dns_nxdomain_ttl = 15 + +;; Custom resolv.conf file, to set custom DNS servers or other options +;; (default: empty = use OS settings) +;resolv_conf = /etc/pgbouncer/resolv.conf + +;;; +;;; Random stuff +;;; + +;; Hackish security feature. Helps against SQL injection: when PQexec +;; is disabled, multi-statement cannot be made. +;disable_pqexec = 0 + +;; Config file to use for next RELOAD/SIGHUP +;; By default contains config file from command line. +;conffile + +;; Windows service name to register as. job_name is alias for +;; service_name, used by some Skytools scripts. +;service_name = pgbouncer +;job_name = pgbouncer + +;; Read additional config from other file +;%include /etc/pgbouncer/pgbouncer-other.ini + +%include /etc/pgbouncer-custom/generated-optimizations.ini +%include /etc/pgbouncer-custom/custom-overrides.ini +%include /etc/pgbouncer-custom/ssl-config.ini diff --git a/ansible-nix/files/pgbouncer_config/pgbouncer.service.j2 b/ansible-nix/files/pgbouncer_config/pgbouncer.service.j2 new file mode 100644 index 000000000..1ec5ea378 --- /dev/null +++ b/ansible-nix/files/pgbouncer_config/pgbouncer.service.j2 @@ -0,0 +1,20 @@ +[Unit] +Description=connection pooler for PostgreSQL +Documentation=man:pgbouncer(1) +Documentation=https://www.pgbouncer.org/ +After=network.target +{% if supabase_internal is defined %} +Requires=database-optimizations.service +After=database-optimizations.service +{% endif %} + +[Service] +Type=notify +User=pgbouncer +ExecStart=/usr/local/bin/pgbouncer /etc/pgbouncer/pgbouncer.ini +ExecReload=/bin/kill -HUP $MAINPID +KillSignal=SIGINT +LimitNOFILE=65536 + +[Install] +WantedBy=multi-user.target diff --git a/ansible-nix/files/pgbouncer_config/pgbouncer_auth_schema.sql b/ansible-nix/files/pgbouncer_config/pgbouncer_auth_schema.sql new file mode 100644 index 000000000..c10ce44fd --- /dev/null +++ b/ansible-nix/files/pgbouncer_config/pgbouncer_auth_schema.sql @@ -0,0 +1,20 @@ +CREATE USER pgbouncer; + +REVOKE ALL PRIVILEGES ON SCHEMA public FROM pgbouncer; + +CREATE SCHEMA pgbouncer AUTHORIZATION pgbouncer; + +CREATE OR REPLACE FUNCTION pgbouncer.get_auth(p_usename TEXT) +RETURNS TABLE(username TEXT, password TEXT) AS +$$ +BEGIN + RAISE WARNING 'PgBouncer auth request: %', p_usename; + + RETURN QUERY + SELECT usename::TEXT, passwd::TEXT FROM pg_catalog.pg_shadow + WHERE usename = p_usename; +END; +$$ LANGUAGE plpgsql SECURITY DEFINER; + +REVOKE ALL ON FUNCTION pgbouncer.get_auth(p_usename TEXT) FROM PUBLIC; +GRANT EXECUTE ON FUNCTION pgbouncer.get_auth(p_usename TEXT) TO pgbouncer; diff --git a/ansible-nix/files/pgbouncer_config/tmpfiles.d-pgbouncer.conf.j2 b/ansible-nix/files/pgbouncer_config/tmpfiles.d-pgbouncer.conf.j2 new file mode 100644 index 000000000..d5d2cd49d --- /dev/null +++ b/ansible-nix/files/pgbouncer_config/tmpfiles.d-pgbouncer.conf.j2 @@ -0,0 +1,2 @@ +# Directory for PostgreSQL sockets, lockfiles and stats tempfiles +d /run/pgbouncer 2775 pgbouncer postgres - - \ No newline at end of file diff --git a/ansible-nix/files/pgsodium_getkey_readonly.sh.j2 b/ansible-nix/files/pgsodium_getkey_readonly.sh.j2 new file mode 100644 index 000000000..e0a72733f --- /dev/null +++ b/ansible-nix/files/pgsodium_getkey_readonly.sh.j2 @@ -0,0 +1,14 @@ +#!/bin/bash + +set -euo pipefail + +KEY_FILE=/etc/postgresql-custom/pgsodium_root.key + +# On the hosted platform, the root key is generated and managed for each project +# If for some reason the key is missing, we want to fail loudly, +# rather than generating a new one. +if [[ ! -f "${KEY_FILE}" ]]; then + echo "Key file ${KEY_FILE} does not exist." >&2 + exit 1 +fi +cat $KEY_FILE diff --git a/ansible-nix/files/pgsodium_getkey_urandom.sh.j2 b/ansible-nix/files/pgsodium_getkey_urandom.sh.j2 new file mode 100755 index 000000000..e8039d037 --- /dev/null +++ b/ansible-nix/files/pgsodium_getkey_urandom.sh.j2 @@ -0,0 +1,10 @@ +#!/bin/bash + +set -euo pipefail + +KEY_FILE=/etc/postgresql-custom/pgsodium_root.key + +if [[ ! -f "${KEY_FILE}" ]]; then + head -c 32 /dev/urandom | od -A n -t x1 | tr -d ' \n' > "${KEY_FILE}" +fi +cat $KEY_FILE diff --git a/ansible-nix/files/postgres_exporter.service.j2 b/ansible-nix/files/postgres_exporter.service.j2 new file mode 100644 index 000000000..0066a76b2 --- /dev/null +++ b/ansible-nix/files/postgres_exporter.service.j2 @@ -0,0 +1,14 @@ +[Unit] +Description=Postgres Exporter + +[Service] +Type=simple +ExecStart=/opt/postgres_exporter/postgres_exporter --disable-settings-metrics --extend.query-path="/opt/postgres_exporter/queries.yml" --disable-default-metrics --no-collector.locks --no-collector.replication --no-collector.replication_slot --no-collector.stat_bgwriter --no-collector.stat_database --no-collector.stat_user_tables --no-collector.statio_user_tables --no-collector.wal +User=postgres +Group=postgres +Restart=always +RestartSec=3 +Environment="DATA_SOURCE_NAME=host=localhost dbname=postgres sslmode=disable user=supabase_admin pg_stat_statements.track=none application_name=postgres_exporter" + +[Install] +WantedBy=multi-user.target diff --git a/ansible-nix/files/postgresql_config/custom_read_replica.conf.j2 b/ansible-nix/files/postgresql_config/custom_read_replica.conf.j2 new file mode 100644 index 000000000..7d52f92a7 --- /dev/null +++ b/ansible-nix/files/postgresql_config/custom_read_replica.conf.j2 @@ -0,0 +1,5 @@ +# hot_standby = on +# restore_command = '/usr/bin/admin-mgr wal-fetch %f %p >> /var/log/wal-g/wal-fetch.log 2>&1' +# recovery_target_timeline = 'latest' + +# primary_conninfo = 'host=localhost port=6543 user=replication' diff --git a/ansible-nix/files/postgresql_config/custom_walg.conf.j2 b/ansible-nix/files/postgresql_config/custom_walg.conf.j2 new file mode 100644 index 000000000..7ef7256d8 --- /dev/null +++ b/ansible-nix/files/postgresql_config/custom_walg.conf.j2 @@ -0,0 +1,21 @@ +# - Archiving - + +#archive_mode = on +#archive_command = '/usr/bin/admin-mgr wal-push %p >> /var/log/wal-g/wal-push.log 2>&1' +#archive_timeout = 120 + + +# - Archive Recovery - + +#restore_command = '/usr/bin/admin-mgr wal-fetch %f %p >> /var/log/wal-g/wal-fetch.log 2>&1' + +# - Recovery Target - + +#recovery_target_lsn = '' +#recovery_target_time = '' +#recovery_target_action = 'promote' +#recovery_target_timeline = 'current' +#recovery_target_inclusive = off + +# - Hot Standby - +hot_standby = off diff --git a/ansible-nix/files/postgresql_config/pg_hba.conf.j2 b/ansible-nix/files/postgresql_config/pg_hba.conf.j2 new file mode 100755 index 000000000..9cafd4146 --- /dev/null +++ b/ansible-nix/files/postgresql_config/pg_hba.conf.j2 @@ -0,0 +1,94 @@ +# PostgreSQL Client Authentication Configuration File +# =================================================== +# +# Refer to the "Client Authentication" section in the PostgreSQL +# documentation for a complete description of this file. A short +# synopsis follows. +# +# This file controls: which hosts are allowed to connect, how clients +# are authenticated, which PostgreSQL user names they can use, which +# databases they can access. Records take one of these forms: +# +# local DATABASE USER METHOD [OPTIONS] +# host DATABASE USER ADDRESS METHOD [OPTIONS] +# hostssl DATABASE USER ADDRESS METHOD [OPTIONS] +# hostnossl DATABASE USER ADDRESS METHOD [OPTIONS] +# hostgssenc DATABASE USER ADDRESS METHOD [OPTIONS] +# hostnogssenc DATABASE USER ADDRESS METHOD [OPTIONS] +# +# (The uppercase items must be replaced by actual values.) +# +# The first field is the connection type: "local" is a Unix-domain +# socket, "host" is either a plain or SSL-encrypted TCP/IP socket, +# "hostssl" is an SSL-encrypted TCP/IP socket, and "hostnossl" is a +# non-SSL TCP/IP socket. Similarly, "hostgssenc" uses a +# GSSAPI-encrypted TCP/IP socket, while "hostnogssenc" uses a +# non-GSSAPI socket. +# +# DATABASE can be "all", "sameuser", "samerole", "replication", a +# database name, or a comma-separated list thereof. The "all" +# keyword does not match "replication". Access to replication +# must be enabled in a separate record (see example below). +# +# USER can be "all", a user name, a group name prefixed with "+", or a +# comma-separated list thereof. In both the DATABASE and USER fields +# you can also write a file name prefixed with "@" to include names +# from a separate file. +# +# ADDRESS specifies the set of hosts the record matches. It can be a +# host name, or it is made up of an IP address and a CIDR mask that is +# an integer (between 0 and 32 (IPv4) or 128 (IPv6) inclusive) that +# specifies the number of significant bits in the mask. A host name +# that starts with a dot (.) matches a suffix of the actual host name. +# Alternatively, you can write an IP address and netmask in separate +# columns to specify the set of hosts. Instead of a CIDR-address, you +# can write "samehost" to match any of the server's own IP addresses, +# or "samenet" to match any address in any subnet that the server is +# directly connected to. +# +# METHOD can be "trust", "reject", "md5", "password", "scram-sha-256", +# "gss", "sspi", "ident", "peer", "pam", "ldap", "radius" or "cert". +# Note that "password" sends passwords in clear text; "md5" or +# "scram-sha-256" are preferred since they send encrypted passwords. +# +# OPTIONS are a set of options for the authentication in the format +# NAME=VALUE. The available options depend on the different +# authentication methods -- refer to the "Client Authentication" +# section in the documentation for a list of which options are +# available for which authentication methods. +# +# Database and user names containing spaces, commas, quotes and other +# special characters must be quoted. Quoting one of the keywords +# "all", "sameuser", "samerole" or "replication" makes the name lose +# its special character, and just match a database or username with +# that name. +# +# This file is read on server startup and when the server receives a +# SIGHUP signal. If you edit the file on a running system, you have to +# SIGHUP the server for the changes to take effect, run "pg_ctl reload", +# or execute "SELECT pg_reload_conf()". +# +# Put your actual configuration here +# ---------------------------------- +# +# If you want to allow non-local connections, you need to add more +# "host" records. In that case you will also need to make PostgreSQL +# listen on a non-local interface via the listen_addresses +# configuration parameter, or via the -i or -h command line switches. + +# TYPE DATABASE USER ADDRESS METHOD + +# trust local connections +local all supabase_admin scram-sha-256 +local all all peer map=supabase_map +host all all 127.0.0.1/32 trust +host all all ::1/128 trust + +# IPv4 external connections +host all all 10.0.0.0/8 scram-sha-256 +host all all 172.16.0.0/12 scram-sha-256 +host all all 192.168.0.0/16 scram-sha-256 +host all all 0.0.0.0/0 scram-sha-256 + +# IPv6 external connections +host all all ::0/0 scram-sha-256 diff --git a/ansible-nix/files/postgresql_config/pg_ident.conf.j2 b/ansible-nix/files/postgresql_config/pg_ident.conf.j2 new file mode 100755 index 000000000..d8891f416 --- /dev/null +++ b/ansible-nix/files/postgresql_config/pg_ident.conf.j2 @@ -0,0 +1,50 @@ +# PostgreSQL User Name Maps +# ========================= +# +# Refer to the PostgreSQL documentation, chapter "Client +# Authentication" for a complete description. A short synopsis +# follows. +# +# This file controls PostgreSQL user name mapping. It maps external +# user names to their corresponding PostgreSQL user names. Records +# are of the form: +# +# MAPNAME SYSTEM-USERNAME PG-USERNAME +# +# (The uppercase quantities must be replaced by actual values.) +# +# MAPNAME is the (otherwise freely chosen) map name that was used in +# pg_hba.conf. SYSTEM-USERNAME is the detected user name of the +# client. PG-USERNAME is the requested PostgreSQL user name. The +# existence of a record specifies that SYSTEM-USERNAME may connect as +# PG-USERNAME. +# +# If SYSTEM-USERNAME starts with a slash (/), it will be treated as a +# regular expression. Optionally this can contain a capture (a +# parenthesized subexpression). The substring matching the capture +# will be substituted for \1 (backslash-one) if present in +# PG-USERNAME. +# +# Multiple maps may be specified in this file and used by pg_hba.conf. +# +# No map names are defined in the default configuration. If all +# system user names and PostgreSQL user names are the same, you don't +# need anything in this file. +# +# This file is read on server startup and when the postmaster receives +# a SIGHUP signal. If you edit the file on a running system, you have +# to SIGHUP the postmaster for the changes to take effect. You can +# use "pg_ctl reload" to do that. + +# Put your actual configuration here +# ---------------------------------- + +# MAPNAME SYSTEM-USERNAME PG-USERNAME +supabase_map postgres postgres +supabase_map root postgres +supabase_map ubuntu postgres + +# supabase-specific users +supabase_map gotrue supabase_auth_admin +supabase_map postgrest authenticator +supabase_map adminapi postgres diff --git a/ansible-nix/files/postgresql_config/postgresql-csvlog.conf b/ansible-nix/files/postgresql_config/postgresql-csvlog.conf new file mode 100644 index 000000000..b8d64da51 --- /dev/null +++ b/ansible-nix/files/postgresql_config/postgresql-csvlog.conf @@ -0,0 +1,33 @@ +# - Where to Log - + +log_destination = 'csvlog' # Valid values are combinations of + # stderr, csvlog, syslog, and eventlog, + # depending on platform. csvlog + # requires logging_collector to be on. + +# This is used when logging to stderr: +logging_collector = on # Enable capturing of stderr and csvlog + # into log files. Required to be on for + # csvlogs. + # (change requires restart) + +# These are only used if logging_collector is on: +log_directory = '/var/log/postgresql' # directory where log files are written, + # can be absolute or relative to PGDATA +log_filename = 'postgresql.log' # log file name pattern, + # can include strftime() escapes +log_file_mode = 0640 # creation mode for log files, + # begin with 0 to use octal notation +log_rotation_age = 0 # Automatic rotation of logfiles will + # happen after that time. 0 disables. +log_rotation_size = 0 # Automatic rotation of logfiles will + # happen after that much log output. + # 0 disables. +#log_truncate_on_rotation = off # If on, an existing log file with the + # same name as the new log file will be + # truncated rather than appended to. + # But such truncation only occurs on + # time-driven rotation, not on restarts + # or size-driven rotation. Default is + # off, meaning append to existing files + # in all cases. diff --git a/ansible-nix/files/postgresql_config/postgresql-stdout-log.conf b/ansible-nix/files/postgresql_config/postgresql-stdout-log.conf new file mode 100644 index 000000000..6ae4ff456 --- /dev/null +++ b/ansible-nix/files/postgresql_config/postgresql-stdout-log.conf @@ -0,0 +1,4 @@ +logging_collector = off # Enable capturing of stderr and csvlog + # into log files. Required to be on for + # csvlogs. + # (change requires restart) diff --git a/ansible-nix/files/postgresql_config/postgresql.conf.j2 b/ansible-nix/files/postgresql_config/postgresql.conf.j2 new file mode 100644 index 000000000..fdca6643d --- /dev/null +++ b/ansible-nix/files/postgresql_config/postgresql.conf.j2 @@ -0,0 +1,776 @@ +# ----------------------------- +# PostgreSQL configuration file +# ----------------------------- +# +# This file consists of lines of the form: +# +# name = value +# +# (The "=" is optional.) Whitespace may be used. Comments are introduced with +# "#" anywhere on a line. The complete list of parameter names and allowed +# values can be found in the PostgreSQL documentation. +# +# The commented-out settings shown in this file represent the default values. +# Re-commenting a setting is NOT sufficient to revert it to the default value; +# you need to reload the server. +# +# This file is read on server startup and when the server receives a SIGHUP +# signal. If you edit the file on a running system, you have to SIGHUP the +# server for the changes to take effect, run "pg_ctl reload", or execute +# "SELECT pg_reload_conf()". Some parameters, which are marked below, +# require a server shutdown and restart to take effect. +# +# Any parameter can also be given as a command-line option to the server, e.g., +# "postgres -c log_connections=on". Some parameters can be changed at run time +# with the "SET" SQL command. +# +# Memory units: B = bytes Time units: us = microseconds +# kB = kilobytes ms = milliseconds +# MB = megabytes s = seconds +# GB = gigabytes min = minutes +# TB = terabytes h = hours +# d = days + + +#------------------------------------------------------------------------------ +# FILE LOCATIONS +#------------------------------------------------------------------------------ + +# The default values of these variables are driven from the -D command-line +# option or PGDATA environment variable, represented here as ConfigDir. + +data_directory = '/var/lib/postgresql/data' # use data in another directory + # (change requires restart) +hba_file = '/etc/postgresql/pg_hba.conf' # host-based authentication file + # (change requires restart) +ident_file = '/etc/postgresql/pg_ident.conf' # ident configuration file + # (change requires restart) + +# If external_pid_file is not explicitly set, no extra PID file is written. +#external_pid_file = '' # write an extra PID file + # (change requires restart) + + +#------------------------------------------------------------------------------ +# CONNECTIONS AND AUTHENTICATION +#------------------------------------------------------------------------------ + +# - Connection Settings - + +listen_addresses = '*' # what IP address(es) to listen on; + # comma-separated list of addresses; + # defaults to 'localhost'; use '*' for all + # (change requires restart) +#port = 5432 # (change requires restart) +#max_connections = 100 # (change requires restart) +#superuser_reserved_connections = 3 # (change requires restart) +#unix_socket_directories = '/tmp' # comma-separated list of directories + # (change requires restart) +#unix_socket_group = '' # (change requires restart) +#unix_socket_permissions = 0777 # begin with 0 to use octal notation + # (change requires restart) +#bonjour = off # advertise server via Bonjour + # (change requires restart) +#bonjour_name = '' # defaults to the computer name + # (change requires restart) + +# - TCP settings - +# see "man tcp" for details + +#tcp_keepalives_idle = 0 # TCP_KEEPIDLE, in seconds; + # 0 selects the system default +#tcp_keepalives_interval = 0 # TCP_KEEPINTVL, in seconds; + # 0 selects the system default +#tcp_keepalives_count = 0 # TCP_KEEPCNT; + # 0 selects the system default +#tcp_user_timeout = 0 # TCP_USER_TIMEOUT, in milliseconds; + # 0 selects the system default + +#client_connection_check_interval = 0 # time between checks for client + # disconnection while running queries; + # 0 for never + +# - Authentication - + +authentication_timeout = 1min # 1s-600s +password_encryption = scram-sha-256 # scram-sha-256 or md5 +db_user_namespace = off + +# GSSAPI using Kerberos +#krb_server_keyfile = 'FILE:${sysconfdir}/krb5.keytab' +#krb_caseins_users = off + +# - SSL - + +ssl = off +ssl_ca_file = '' +ssl_cert_file = '' +ssl_crl_file = '' +ssl_crl_dir = '' +ssl_key_file = '' +ssl_ciphers = 'HIGH:MEDIUM:+3DES:!aNULL' # allowed SSL ciphers +ssl_prefer_server_ciphers = on +ssl_ecdh_curve = 'prime256v1' +ssl_min_protocol_version = 'TLSv1.2' +ssl_max_protocol_version = '' +ssl_dh_params_file = '' +ssl_passphrase_command = '' +ssl_passphrase_command_supports_reload = off + + +#------------------------------------------------------------------------------ +# RESOURCE USAGE (except WAL) +#------------------------------------------------------------------------------ + +# - Memory - + +shared_buffers = 128MB # min 128kB + # (change requires restart) +#huge_pages = try # on, off, or try + # (change requires restart) +#huge_page_size = 0 # zero for system default + # (change requires restart) +#temp_buffers = 8MB # min 800kB +#max_prepared_transactions = 0 # zero disables the feature + # (change requires restart) +# Caution: it is not advisable to set max_prepared_transactions nonzero unless +# you actively intend to use prepared transactions. +#work_mem = 4MB # min 64kB +#hash_mem_multiplier = 1.0 # 1-1000.0 multiplier on hash table work_mem +#maintenance_work_mem = 64MB # min 1MB +#autovacuum_work_mem = -1 # min 1MB, or -1 to use maintenance_work_mem +#logical_decoding_work_mem = 64MB # min 64kB +#max_stack_depth = 2MB # min 100kB +#shared_memory_type = mmap # the default is the first option + # supported by the operating system: + # mmap + # sysv + # windows + # (change requires restart) +#dynamic_shared_memory_type = posix # the default is the first option + # supported by the operating system: + # posix + # sysv + # windows + # mmap + # (change requires restart) +#min_dynamic_shared_memory = 0MB # (change requires restart) + +# - Disk - + +#temp_file_limit = -1 # limits per-process temp file space + # in kilobytes, or -1 for no limit + +# - Kernel Resources - + +#max_files_per_process = 1000 # min 64 + # (change requires restart) + +# - Cost-Based Vacuum Delay - + +#vacuum_cost_delay = 0 # 0-100 milliseconds (0 disables) +#vacuum_cost_page_hit = 1 # 0-10000 credits +#vacuum_cost_page_miss = 2 # 0-10000 credits +#vacuum_cost_page_dirty = 20 # 0-10000 credits +#vacuum_cost_limit = 200 # 1-10000 credits + +# - Background Writer - + +#bgwriter_delay = 200ms # 10-10000ms between rounds +#bgwriter_lru_maxpages = 100 # max buffers written/round, 0 disables +#bgwriter_lru_multiplier = 2.0 # 0-10.0 multiplier on buffers scanned/round +#bgwriter_flush_after = 0 # measured in pages, 0 disables + +# - Asynchronous Behavior - + +#backend_flush_after = 0 # measured in pages, 0 disables +#effective_io_concurrency = 1 # 1-1000; 0 disables prefetching +#maintenance_io_concurrency = 10 # 1-1000; 0 disables prefetching +#max_worker_processes = 8 # (change requires restart) +#max_parallel_workers_per_gather = 2 # taken from max_parallel_workers +#max_parallel_maintenance_workers = 2 # taken from max_parallel_workers +#max_parallel_workers = 8 # maximum number of max_worker_processes that + # can be used in parallel operations +#parallel_leader_participation = on +#old_snapshot_threshold = -1 # 1min-60d; -1 disables; 0 is immediate + # (change requires restart) + + +#------------------------------------------------------------------------------ +# WRITE-AHEAD LOG +#------------------------------------------------------------------------------ + +# - Settings - + +wal_level = logical # minimal, replica, or logical + # (change requires restart) +#fsync = on # flush data to disk for crash safety + # (turning this off can cause + # unrecoverable data corruption) +#synchronous_commit = on # synchronization level; + # off, local, remote_write, remote_apply, or on +#wal_sync_method = fsync # the default is the first option + # supported by the operating system: + # open_datasync + # fdatasync (default on Linux and FreeBSD) + # fsync + # fsync_writethrough + # open_sync +#full_page_writes = on # recover from partial page writes +#wal_log_hints = off # also do full page writes of non-critical updates + # (change requires restart) +#wal_compression = off # enable compression of full-page writes +#wal_init_zero = on # zero-fill new WAL files +#wal_recycle = on # recycle WAL files +#wal_buffers = -1 # min 32kB, -1 sets based on shared_buffers + # (change requires restart) +#wal_writer_delay = 200ms # 1-10000 milliseconds +#wal_writer_flush_after = 1MB # measured in pages, 0 disables +#wal_skip_threshold = 2MB + +#commit_delay = 0 # range 0-100000, in microseconds +#commit_siblings = 5 # range 1-1000 + +# - Checkpoints - + +#checkpoint_timeout = 5min # range 30s-1d +checkpoint_completion_target = 0.5 # checkpoint target duration, 0.0 - 1.0 +checkpoint_flush_after = 256kB # measured in pages, 0 disables +#checkpoint_warning = 30s # 0 disables +#max_wal_size = 1GB +#min_wal_size = 80MB + +# - Archiving - + +#archive_mode = off # enables archiving; off, on, or always + # (change requires restart) +#archive_command = '' # command to use to archive a logfile segment + # placeholders: %p = path of file to archive + # %f = file name only + # e.g. 'test ! -f /mnt/server/archivedir/%f && cp %p /mnt/server/archivedir/%f' +#archive_timeout = 0 # force a logfile segment switch after this + # number of seconds; 0 disables + +# - Archive Recovery - + +# These are only used in recovery mode. + +#restore_command = '' # command to use to restore an archived logfile segment + # placeholders: %p = path of file to restore + # %f = file name only + # e.g. 'cp /mnt/server/archivedir/%f %p' +#archive_cleanup_command = '' # command to execute at every restartpoint +#recovery_end_command = '' # command to execute at completion of recovery + +# - Recovery Target - + +# Set these only when performing a targeted recovery. + +#recovery_target = '' # 'immediate' to end recovery as soon as a + # consistent state is reached + # (change requires restart) +#recovery_target_name = '' # the named restore point to which recovery will proceed + # (change requires restart) +#recovery_target_time = '' # the time stamp up to which recovery will proceed + # (change requires restart) +#recovery_target_xid = '' # the transaction ID up to which recovery will proceed + # (change requires restart) +#recovery_target_lsn = '' # the WAL LSN up to which recovery will proceed + # (change requires restart) +#recovery_target_inclusive = on # Specifies whether to stop: + # just after the specified recovery target (on) + # just before the recovery target (off) + # (change requires restart) +#recovery_target_timeline = 'latest' # 'current', 'latest', or timeline ID + # (change requires restart) +#recovery_target_action = 'pause' # 'pause', 'promote', 'shutdown' + # (change requires restart) + + +#------------------------------------------------------------------------------ +# REPLICATION +#------------------------------------------------------------------------------ + +# - Sending Servers - + +# Set these on the primary and on any standby that will send replication data. + +max_wal_senders = 10 # max number of walsender processes + # (change requires restart) +max_replication_slots = 5 # max number of replication slots + # (change requires restart) +#wal_keep_size = 0 # in megabytes; 0 disables +max_slot_wal_keep_size = 1024 # in megabytes; -1 disables +#wal_sender_timeout = 60s # in milliseconds; 0 disables +#track_commit_timestamp = off # collect timestamp of transaction commit + # (change requires restart) + +# - Primary Server - + +# These settings are ignored on a standby server. + +#synchronous_standby_names = '' # standby servers that provide sync rep + # method to choose sync standbys, number of sync standbys, + # and comma-separated list of application_name + # from standby(s); '*' = all +#vacuum_defer_cleanup_age = 0 # number of xacts by which cleanup is delayed + +# - Standby Servers - + +# These settings are ignored on a primary server. + +#primary_conninfo = '' # connection string to sending server +#primary_slot_name = '' # replication slot on sending server +#promote_trigger_file = '' # file name whose presence ends recovery +#hot_standby = on # "off" disallows queries during recovery + # (change requires restart) +#max_standby_archive_delay = 30s # max delay before canceling queries + # when reading WAL from archive; + # -1 allows indefinite delay +#max_standby_streaming_delay = 30s # max delay before canceling queries + # when reading streaming WAL; + # -1 allows indefinite delay +#wal_receiver_create_temp_slot = off # create temp slot if primary_slot_name + # is not set +#wal_receiver_status_interval = 10s # send replies at least this often + # 0 disables +#hot_standby_feedback = off # send info from standby to prevent + # query conflicts +#wal_receiver_timeout = 60s # time that receiver waits for + # communication from primary + # in milliseconds; 0 disables +#wal_retrieve_retry_interval = 5s # time to wait before retrying to + # retrieve WAL after a failed attempt +#recovery_min_apply_delay = 0 # minimum delay for applying changes during recovery + +# - Subscribers - + +# These settings are ignored on a publisher. + +#max_logical_replication_workers = 4 # taken from max_worker_processes + # (change requires restart) +#max_sync_workers_per_subscription = 2 # taken from max_logical_replication_workers + + +#------------------------------------------------------------------------------ +# QUERY TUNING +#------------------------------------------------------------------------------ + +# - Planner Method Configuration - + +#enable_async_append = on +#enable_bitmapscan = on +#enable_gathermerge = on +#enable_hashagg = on +#enable_hashjoin = on +#enable_incremental_sort = on +#enable_indexscan = on +#enable_indexonlyscan = on +#enable_material = on +#enable_resultcache = on +#enable_mergejoin = on +#enable_nestloop = on +#enable_parallel_append = on +#enable_parallel_hash = on +#enable_partition_pruning = on +#enable_partitionwise_join = off +#enable_partitionwise_aggregate = off +#enable_seqscan = on +#enable_sort = on +#enable_tidscan = on + +# - Planner Cost Constants - + +#seq_page_cost = 1.0 # measured on an arbitrary scale +#random_page_cost = 4.0 # same scale as above +#cpu_tuple_cost = 0.01 # same scale as above +#cpu_index_tuple_cost = 0.005 # same scale as above +#cpu_operator_cost = 0.0025 # same scale as above +#parallel_setup_cost = 1000.0 # same scale as above +#parallel_tuple_cost = 0.1 # same scale as above +#min_parallel_table_scan_size = 8MB +#min_parallel_index_scan_size = 512kB +effective_cache_size = 128MB + +#jit_above_cost = 100000 # perform JIT compilation if available + # and query more expensive than this; + # -1 disables +#jit_inline_above_cost = 500000 # inline small functions if query is + # more expensive than this; -1 disables +#jit_optimize_above_cost = 500000 # use expensive JIT optimizations if + # query is more expensive than this; + # -1 disables + +# - Genetic Query Optimizer - + +#geqo = on +#geqo_threshold = 12 +#geqo_effort = 5 # range 1-10 +#geqo_pool_size = 0 # selects default based on effort +#geqo_generations = 0 # selects default based on effort +#geqo_selection_bias = 2.0 # range 1.5-2.0 +#geqo_seed = 0.0 # range 0.0-1.0 + +# - Other Planner Options - + +#default_statistics_target = 100 # range 1-10000 +#constraint_exclusion = partition # on, off, or partition +#cursor_tuple_fraction = 0.1 # range 0.0-1.0 +#from_collapse_limit = 8 +#jit = on # allow JIT compilation +#join_collapse_limit = 8 # 1 disables collapsing of explicit + # JOIN clauses +#plan_cache_mode = auto # auto, force_generic_plan or + # force_custom_plan + + +#------------------------------------------------------------------------------ +# REPORTING AND LOGGING +#------------------------------------------------------------------------------ + +include = '/etc/postgresql/logging.conf' + +# These are relevant when logging to syslog: +#syslog_facility = 'LOCAL0' +#syslog_ident = 'postgres' +#syslog_sequence_numbers = on +#syslog_split_messages = on + +# This is only relevant when logging to eventlog (Windows): +# (change requires restart) +#event_source = 'PostgreSQL' + +# - When to Log - + +#log_min_messages = warning # values in order of decreasing detail: + # debug5 + # debug4 + # debug3 + # debug2 + # debug1 + # info + # notice + # warning + # error + # log + # fatal + # panic + +#log_min_error_statement = error # values in order of decreasing detail: + # debug5 + # debug4 + # debug3 + # debug2 + # debug1 + # info + # notice + # warning + # error + # log + # fatal + # panic (effectively off) + +#log_min_duration_statement = -1 # -1 is disabled, 0 logs all statements + # and their durations, > 0 logs only + # statements running at least this number + # of milliseconds + +#log_min_duration_sample = -1 # -1 is disabled, 0 logs a sample of statements + # and their durations, > 0 logs only a sample of + # statements running at least this number + # of milliseconds; + # sample fraction is determined by log_statement_sample_rate + +#log_statement_sample_rate = 1.0 # fraction of logged statements exceeding + # log_min_duration_sample to be logged; + # 1.0 logs all such statements, 0.0 never logs + + +#log_transaction_sample_rate = 0.0 # fraction of transactions whose statements + # are logged regardless of their duration; 1.0 logs all + # statements from all transactions, 0.0 never logs + +# - What to Log - + +#debug_print_parse = off +#debug_print_rewritten = off +#debug_print_plan = off +#debug_pretty_print = on +#log_autovacuum_min_duration = -1 # log autovacuum activity; + # -1 disables, 0 logs all actions and + # their durations, > 0 logs only + # actions running at least this number + # of milliseconds. +#log_checkpoints = off +#log_connections = off +#log_disconnections = off +#log_duration = off +#log_error_verbosity = default # terse, default, or verbose messages +#log_hostname = off +log_line_prefix = '%h %m [%p] %q%u@%d ' # special values: + # %a = application name + # %u = user name + # %d = database name + # %r = remote host and port + # %h = remote host + # %b = backend type + # %p = process ID + # %P = process ID of parallel group leader + # %t = timestamp without milliseconds + # %m = timestamp with milliseconds + # %n = timestamp with milliseconds (as a Unix epoch) + # %Q = query ID (0 if none or not computed) + # %i = command tag + # %e = SQL state + # %c = session ID + # %l = session line number + # %s = session start timestamp + # %v = virtual transaction ID + # %x = transaction ID (0 if none) + # %q = stop here in non-session + # processes + # %% = '%' + # e.g. '<%u%%%d> ' +#log_lock_waits = off # log lock waits >= deadlock_timeout +#log_recovery_conflict_waits = off # log standby recovery conflict waits + # >= deadlock_timeout +#log_parameter_max_length = -1 # when logging statements, limit logged + # bind-parameter values to N bytes; + # -1 means print in full, 0 disables +#log_parameter_max_length_on_error = 0 # when logging an error, limit logged + # bind-parameter values to N bytes; + # -1 means print in full, 0 disables +log_statement = 'none' # none, ddl, mod, all +#log_replication_commands = off +#log_temp_files = -1 # log temporary files equal or larger + # than the specified size in kilobytes; + # -1 disables, 0 logs all temp files +log_timezone = 'UTC' + +#------------------------------------------------------------------------------ +# PROCESS TITLE +#------------------------------------------------------------------------------ + +cluster_name = 'main' # added to process titles if nonempty + # (change requires restart) +#update_process_title = on + + +#------------------------------------------------------------------------------ +# STATISTICS +#------------------------------------------------------------------------------ + +# - Query and Index Statistics Collector - + +#track_activities = on +#track_activity_query_size = 1024 # (change requires restart) +#track_counts = on +#track_io_timing = off +#track_wal_io_timing = off +#track_functions = none # none, pl, all +#stats_temp_directory = 'pg_stat_tmp' + + +# - Monitoring - + +#compute_query_id = auto +#log_statement_stats = off +#log_parser_stats = off +#log_planner_stats = off +#log_executor_stats = off + + +#------------------------------------------------------------------------------ +# AUTOVACUUM +#------------------------------------------------------------------------------ + +#autovacuum = on # Enable autovacuum subprocess? 'on' + # requires track_counts to also be on. +#autovacuum_max_workers = 3 # max number of autovacuum subprocesses + # (change requires restart) +#autovacuum_naptime = 1min # time between autovacuum runs +#autovacuum_vacuum_threshold = 50 # min number of row updates before + # vacuum +#autovacuum_vacuum_insert_threshold = 1000 # min number of row inserts + # before vacuum; -1 disables insert + # vacuums +#autovacuum_analyze_threshold = 50 # min number of row updates before + # analyze +#autovacuum_vacuum_scale_factor = 0.2 # fraction of table size before vacuum +#autovacuum_vacuum_insert_scale_factor = 0.2 # fraction of inserts over table + # size before insert vacuum +#autovacuum_analyze_scale_factor = 0.1 # fraction of table size before analyze +#autovacuum_freeze_max_age = 200000000 # maximum XID age before forced vacuum + # (change requires restart) +#autovacuum_multixact_freeze_max_age = 400000000 # maximum multixact age + # before forced vacuum + # (change requires restart) +#autovacuum_vacuum_cost_delay = 2ms # default vacuum cost delay for + # autovacuum, in milliseconds; + # -1 means use vacuum_cost_delay +#autovacuum_vacuum_cost_limit = -1 # default vacuum cost limit for + # autovacuum, -1 means use + # vacuum_cost_limit + + +#------------------------------------------------------------------------------ +# CLIENT CONNECTION DEFAULTS +#------------------------------------------------------------------------------ + +# - Statement Behavior - + +#client_min_messages = notice # values in order of decreasing detail: + # debug5 + # debug4 + # debug3 + # debug2 + # debug1 + # log + # notice + # warning + # error +#search_path = '"$user", public' # schema names +row_security = on +#default_table_access_method = 'heap' +#default_tablespace = '' # a tablespace name, '' uses the default +#default_toast_compression = 'pglz' # 'pglz' or 'lz4' +#temp_tablespaces = '' # a list of tablespace names, '' uses + # only default tablespace +#check_function_bodies = on +#default_transaction_isolation = 'read committed' +#default_transaction_read_only = off +#default_transaction_deferrable = off +#session_replication_role = 'origin' +#statement_timeout = 0 # in milliseconds, 0 is disabled +#lock_timeout = 0 # in milliseconds, 0 is disabled +#idle_in_transaction_session_timeout = 0 # in milliseconds, 0 is disabled +#idle_session_timeout = 0 # in milliseconds, 0 is disabled +#vacuum_freeze_table_age = 150000000 +#vacuum_freeze_min_age = 50000000 +#vacuum_failsafe_age = 1600000000 +#vacuum_multixact_freeze_table_age = 150000000 +#vacuum_multixact_freeze_min_age = 5000000 +#vacuum_multixact_failsafe_age = 1600000000 +#bytea_output = 'hex' # hex, escape +#xmlbinary = 'base64' +#xmloption = 'content' +#gin_pending_list_limit = 4MB + +# - Locale and Formatting - + +#datestyle = 'iso, mdy' +#intervalstyle = 'postgres' +timezone = 'UTC' +#timezone_abbreviations = 'Default' # Select the set of available time zone + # abbreviations. Currently, there are + # Default + # Australia (historical usage) + # India + # You can create your own file in + # share/timezonesets/. +extra_float_digits = 0 # min -15, max 3; any value >0 actually + # selects precise output mode +#client_encoding = sql_ascii # actually, defaults to database + # encoding + +# These settings are initialized by initdb, but they can be changed. +lc_messages = 'en_US.UTF-8' # locale for system error message + # strings +lc_monetary = 'en_US.UTF-8' # locale for monetary formatting +lc_numeric = 'en_US.UTF-8' # locale for number formatting +lc_time = 'en_US.UTF-8' # locale for time formatting + +# default configuration for text search +default_text_search_config = 'pg_catalog.english' + +# - Shared Library Preloading - + +#local_preload_libraries = '' +#session_preload_libraries = '' + +shared_preload_libraries = 'pg_stat_statements, pg_stat_monitor, pgaudit, plpgsql, plpgsql_check, pg_cron, pg_net, pgsodium, timescaledb, auto_explain, pg_tle' # (change requires restart) +jit_provider = 'llvmjit' # JIT library to use + +# - Other Defaults - + +#dynamic_library_path = '$libdir' +#gin_fuzzy_search_limit = 0 + +#------------------------------------------------------------------------------ +# LOCK MANAGEMENT +#------------------------------------------------------------------------------ + +#deadlock_timeout = 1s +#max_locks_per_transaction = 64 # min 10 + # (change requires restart) +#max_pred_locks_per_transaction = 64 # min 10 + # (change requires restart) +#max_pred_locks_per_relation = -2 # negative values mean + # (max_pred_locks_per_transaction + # / -max_pred_locks_per_relation) - 1 +#max_pred_locks_per_page = 2 # min 0 + + +#------------------------------------------------------------------------------ +# VERSION AND PLATFORM COMPATIBILITY +#------------------------------------------------------------------------------ + +# - Previous PostgreSQL Versions - + +#array_nulls = on +#backslash_quote = safe_encoding # on, off, or safe_encoding +#escape_string_warning = on +#lo_compat_privileges = off +#quote_all_identifiers = off +#standard_conforming_strings = on +#synchronize_seqscans = on + +# - Other Platforms and Clients - + +#transform_null_equals = off + + +#------------------------------------------------------------------------------ +# ERROR HANDLING +#------------------------------------------------------------------------------ + +#exit_on_error = off # terminate session on any error? +#restart_after_crash = on # reinitialize after backend crash? +#data_sync_retry = off # retry or panic on failure to fsync + # data? + # (change requires restart) +#recovery_init_sync_method = fsync # fsync, syncfs (Linux 5.8+) + + +#------------------------------------------------------------------------------ +# CONFIG FILE INCLUDES +#------------------------------------------------------------------------------ + +# These options allow settings to be loaded from files other than the +# default postgresql.conf. Note that these are directives, not variable +# assignments, so they can usefully be given more than once. + +#include_dir = '...' # include files ending in '.conf' from + # a directory, e.g., 'conf.d' +#include_if_exists = '...' # include file only if it exists +#include = '...' # include file + +# Automatically generated optimizations +#include = '/etc/postgresql-custom/generated-optimizations.conf' +# User-supplied custom parameters, override any automatically generated ones +#include = '/etc/postgresql-custom/custom-overrides.conf' + +# WAL-G specific configurations +#include = '/etc/postgresql-custom/wal-g.conf' + +# read replica specific configurations +include = '/etc/postgresql-custom/read-replica.conf' + +# supautils specific configurations +#include = '/etc/postgresql-custom/supautils.conf' + +#------------------------------------------------------------------------------ +# CUSTOMIZED OPTIONS +#------------------------------------------------------------------------------ + +# Add settings for extensions here diff --git a/ansible-nix/files/postgresql_config/postgresql.service.j2 b/ansible-nix/files/postgresql_config/postgresql.service.j2 new file mode 100644 index 000000000..41a0d0d80 --- /dev/null +++ b/ansible-nix/files/postgresql_config/postgresql.service.j2 @@ -0,0 +1,24 @@ +[Unit] +Description=PostgreSQL database server +Documentation=man:postgres(1) +{% if supabase_internal is defined %} +Requires=database-optimizations.service +After=database-optimizations.service +{% endif %} + +[Service] +Type=notify +User=postgres +ExecStart=/usr/lib/postgresql/bin/postgres -D /etc/postgresql +ExecReload=/bin/kill -HUP $MAINPID +KillMode=mixed +KillSignal=SIGINT +TimeoutStopSec=90 +TimeoutStartSec=86400 +Restart=always +RestartSec=5 +OOMScoreAdjust=-1000 +EnvironmentFile=-/etc/environment.d/postgresql.env + +[Install] +WantedBy=multi-user.target diff --git a/ansible-nix/files/postgresql_config/supautils.conf.j2 b/ansible-nix/files/postgresql_config/supautils.conf.j2 new file mode 100644 index 000000000..bfbd590f9 --- /dev/null +++ b/ansible-nix/files/postgresql_config/supautils.conf.j2 @@ -0,0 +1,12 @@ +supautils.extensions_parameter_overrides = '{"pg_cron":{"schema":"pg_catalog"}}' +supautils.policy_grants = '{"postgres":["auth.audit_log_entries","auth.identities","auth.refresh_tokens","auth.sessions","auth.users","realtime.broadcasts","realtime.channels","realtime.presences","storage.buckets","storage.migrations","storage.objects"]}' +# full list: address_standardizer, address_standardizer_data_us, adminpack, amcheck, autoinc, bloom, btree_gin, btree_gist, citext, cube, dblink, dict_int, dict_xsyn, earthdistance, file_fdw, fuzzystrmatch, hstore, http, hypopg, index_advisor, insert_username, intagg, intarray, isn, lo, ltree, moddatetime, old_snapshot, orioledb, pageinspect, pg_buffercache, pg_cron, pg_freespacemap, pg_graphql, pg_hashids, pg_jsonschema, pg_net, pg_prewarm, pg_repack, pg_stat_monitor, pg_stat_statements, pg_surgery, pg_tle, pg_trgm, pg_visibility, pg_walinspect, pgaudit, pgcrypto, pgjwt, pgroonga, pgroonga_database, pgrouting, pgrowlocks, pgsodium, pgstattuple, pgtap, plcoffee, pljava, plls, plpgsql, plpgsql_check, plv8, postgis, postgis_raster, postgis_sfcgal, postgis_tiger_geocoder, postgis_topology, postgres_fdw, refint, rum, seg, sslinfo, supabase_vault, supautils, tablefunc, tcn, timescaledb, tsm_system_rows, tsm_system_time, unaccent, uuid-ossp, vector, wrappers, xml2 +# omitted because may be unsafe: adminpack, amcheck, file_fdw, lo, old_snapshot, pageinspect, pg_buffercache, pg_freespacemap, pg_surgery, pg_visibility +# omitted because deprecated: intagg, xml2 +supautils.privileged_extensions = 'address_standardizer, address_standardizer_data_us, autoinc, bloom, btree_gin, btree_gist, citext, cube, dblink, dict_int, dict_xsyn, earthdistance, fuzzystrmatch, hstore, http, hypopg, index_advisor, insert_username, intarray, isn, ltree, moddatetime, orioledb, pg_cron, pg_graphql, pg_hashids, pg_jsonschema, pg_net, pg_repack, pg_stat_monitor, pg_stat_statements, pg_tle, pg_trgm, pg_walinspect, pgaudit, pgcrypto, pgjwt, pg_prewarm, pgroonga, pgroonga_database, pgrouting, pgrowlocks, pgstattuple, pgsodium, pgtap, plcoffee, pljava, plls, plpgsql, plpgsql_check, plv8, postgis, postgis_raster, postgis_sfcgal, postgis_tiger_geocoder, postgis_topology, postgres_fdw, refint, rum, seg, sslinfo, supabase_vault, supautils, tablefunc, tcn, timescaledb, tsm_system_rows, tsm_system_time, unaccent, uuid-ossp, vector, wrappers' +supautils.privileged_extensions_custom_scripts_path = '/etc/postgresql-custom/extension-custom-scripts' +supautils.privileged_extensions_superuser = 'supabase_admin' +supautils.privileged_role = 'postgres' +supautils.privileged_role_allowed_configs = 'log_min_messages, pgaudit.log, pgaudit.log_catalog, pgaudit.log_client, pgaudit.log_level, pgaudit.log_relation, pgaudit.log_rows, pgaudit.log_statement, pgaudit.log_statement_once, pgaudit.role, pgrst.*, session_replication_role, track_io_timing' +supautils.reserved_memberships = 'pg_read_server_files, pg_write_server_files, pg_execute_server_program, authenticator' +supautils.reserved_roles = 'supabase_admin, supabase_auth_admin, supabase_storage_admin, supabase_read_only_user, supabase_replication_admin, dashboard_user, pgbouncer, service_role*, authenticator*, authenticated*, anon*' diff --git a/ansible-nix/files/postgresql_config/tmpfiles.postgresql.conf b/ansible-nix/files/postgresql_config/tmpfiles.postgresql.conf new file mode 100644 index 000000000..b5ea54948 --- /dev/null +++ b/ansible-nix/files/postgresql_config/tmpfiles.postgresql.conf @@ -0,0 +1,5 @@ +# unchanged from upstream package +d /run/postgresql 2775 postgres postgres - - +# Log directory - ensure that our logging setup gets preserved +# and that vector can keep writing to a file here as well +d /var/log/postgresql 1775 postgres postgres - - diff --git a/ansible-nix/files/postgresql_extension_custom_scripts/before-create.sql b/ansible-nix/files/postgresql_extension_custom_scripts/before-create.sql new file mode 100644 index 000000000..f2f238668 --- /dev/null +++ b/ansible-nix/files/postgresql_extension_custom_scripts/before-create.sql @@ -0,0 +1,84 @@ +-- If the following are true: +-- * the extension to be created is a TLE +-- * the extension is created with `cascade` +-- +-- then we pre-`create` all nested extension dependencies which are part of +-- `supautils.privileged_extensions`. This is because supautils can't intercept +-- the extension creation for dependencies - it can only intercept the `create +-- extension` statement. +do $$ +declare + _extname text := @extname@; + _extschema text := @extschema@; + _extversion text := @extversion@; + _extcascade bool := @extcascade@; + _r record; +begin + if not _extcascade then + return; + end if; + + if not exists (select from pg_extension where extname = 'pg_tle') then + return; + end if; + + if not exists (select from pgtle.available_extensions() where name = _extname) then + return; + end if; + + if _extversion is null then + select default_version + from pgtle.available_extensions() + where name = _extname + into _extversion; + end if; + + if _extschema is null then + select schema + from pgtle.available_extension_versions() + where name = _extname and version = _extversion + into _extschema; + end if; + + for _r in ( + with recursive available_extensions(name, default_version) as ( + select name, default_version + from pg_available_extensions + union + select name, default_version + from pgtle.available_extensions() + ) + , available_extension_versions(name, version, requires) as ( + select name, version, requires + from pg_available_extension_versions + union + select name, version, requires + from pgtle.available_extension_versions() + ) + , all_dependencies(name, dependency) as ( + select e.name, unnest(ev.requires) as dependency + from available_extensions e + join available_extension_versions ev on ev.name = e.name and ev.version = e.default_version + ) + , dependencies(name) AS ( + select unnest(requires) + from available_extension_versions + where name = _extname and version = _extversion + union + select all_dependencies.dependency + from all_dependencies + join dependencies d on d.name = all_dependencies.name + ) + select name + from dependencies + intersect + select name + from regexp_split_to_table(current_setting('supautils.privileged_extensions', true), '\s*,\s*') as t(name) + ) loop + if _extschema is null then + execute(format('create extension if not exists %I cascade', _r.name)); + else + execute(format('create extension if not exists %I schema %I cascade', _r.name, _extschema)); + end if; + end loop; +end $$; diff --git a/ansible-nix/files/postgresql_extension_custom_scripts/dblink/after-create.sql b/ansible-nix/files/postgresql_extension_custom_scripts/dblink/after-create.sql new file mode 100644 index 000000000..22261bc77 --- /dev/null +++ b/ansible-nix/files/postgresql_extension_custom_scripts/dblink/after-create.sql @@ -0,0 +1,14 @@ +do $$ +declare + r record; +begin + for r in (select oid, (aclexplode(proacl)).grantee from pg_proc where proname = 'dblink_connect_u') loop + continue when r.grantee = 'supabase_admin'::regrole; + execute( + format( + 'revoke all on function %s(%s) from %s;', r.oid::regproc, pg_get_function_identity_arguments(r.oid), r.grantee::regrole + ) + ); + end loop; +end +$$; diff --git a/ansible-nix/files/postgresql_extension_custom_scripts/pg_cron/after-create.sql b/ansible-nix/files/postgresql_extension_custom_scripts/pg_cron/after-create.sql new file mode 100644 index 000000000..6ac9d6b6e --- /dev/null +++ b/ansible-nix/files/postgresql_extension_custom_scripts/pg_cron/after-create.sql @@ -0,0 +1,13 @@ +grant usage on schema cron to postgres with grant option; +grant all on all functions in schema cron to postgres with grant option; + +alter default privileges for user supabase_admin in schema cron grant all + on sequences to postgres with grant option; +alter default privileges for user supabase_admin in schema cron grant all + on tables to postgres with grant option; +alter default privileges for user supabase_admin in schema cron grant all + on functions to postgres with grant option; + +grant all privileges on all tables in schema cron to postgres with grant option; +revoke all on table cron.job from postgres; +grant select on table cron.job to postgres with grant option; diff --git a/ansible-nix/files/postgresql_extension_custom_scripts/pg_tle/after-create.sql b/ansible-nix/files/postgresql_extension_custom_scripts/pg_tle/after-create.sql new file mode 100644 index 000000000..eb8aeff7e --- /dev/null +++ b/ansible-nix/files/postgresql_extension_custom_scripts/pg_tle/after-create.sql @@ -0,0 +1 @@ +grant pgtle_admin to postgres; diff --git a/ansible-nix/files/postgresql_extension_custom_scripts/pgsodium/after-create.sql b/ansible-nix/files/postgresql_extension_custom_scripts/pgsodium/after-create.sql new file mode 100644 index 000000000..907c67ebf --- /dev/null +++ b/ansible-nix/files/postgresql_extension_custom_scripts/pgsodium/after-create.sql @@ -0,0 +1,3 @@ +grant execute on function pgsodium.crypto_aead_det_decrypt(bytea, bytea, uuid, bytea) to service_role; +grant execute on function pgsodium.crypto_aead_det_encrypt(bytea, bytea, uuid, bytea) to service_role; +grant execute on function pgsodium.crypto_aead_det_keygen to service_role; diff --git a/ansible-nix/files/postgresql_extension_custom_scripts/postgis_tiger_geocoder/after-create.sql b/ansible-nix/files/postgresql_extension_custom_scripts/postgis_tiger_geocoder/after-create.sql new file mode 100644 index 000000000..f8ec163bb --- /dev/null +++ b/ansible-nix/files/postgresql_extension_custom_scripts/postgis_tiger_geocoder/after-create.sql @@ -0,0 +1,10 @@ +-- These schemas are created by extension to house all tiger related functions, owned by supabase_admin +grant usage on schema tiger, tiger_data to postgres with grant option; +-- Give postgres permission to all existing entities, also allows postgres to grant other roles +grant all on all tables in schema tiger, tiger_data to postgres with grant option; +grant all on all routines in schema tiger, tiger_data to postgres with grant option; +grant all on all sequences in schema tiger, tiger_data to postgres with grant option; +-- Update default privileges so that new entities are also accessible by postgres +alter default privileges in schema tiger, tiger_data grant all on tables to postgres with grant option; +alter default privileges in schema tiger, tiger_data grant all on routines to postgres with grant option; +alter default privileges in schema tiger, tiger_data grant all on sequences to postgres with grant option; diff --git a/ansible-nix/files/postgresql_extension_custom_scripts/postgres_fdw/after-create.sql b/ansible-nix/files/postgresql_extension_custom_scripts/postgres_fdw/after-create.sql new file mode 100644 index 000000000..1e83ee90e --- /dev/null +++ b/ansible-nix/files/postgresql_extension_custom_scripts/postgres_fdw/after-create.sql @@ -0,0 +1,21 @@ +do $$ +declare + is_super boolean; +begin + is_super = ( + select usesuper + from pg_user + where usename = 'postgres' + ); + + -- Need to be superuser to own FDWs, so we temporarily make postgres superuser. + if not is_super then + alter role postgres superuser; + end if; + + alter foreign data wrapper postgres_fdw owner to postgres; + + if not is_super then + alter role postgres nosuperuser; + end if; +end $$; diff --git a/ansible-nix/files/postgrest-optimizations.service.j2 b/ansible-nix/files/postgrest-optimizations.service.j2 new file mode 100644 index 000000000..38604b67a --- /dev/null +++ b/ansible-nix/files/postgrest-optimizations.service.j2 @@ -0,0 +1,11 @@ +[Unit] +Description=Postgrest optimizations + +[Service] +Type=oneshot +# we don't want failures from this command to cause PG startup to fail +ExecStart=/bin/bash -c "/opt/supabase-admin-api optimize postgrest --destination-config-file-path /etc/postgrest/generated.conf ; exit 0" +User=postgrest + +[Install] +WantedBy=multi-user.target diff --git a/ansible-nix/files/postgrest.service.j2 b/ansible-nix/files/postgrest.service.j2 new file mode 100644 index 000000000..290f07720 --- /dev/null +++ b/ansible-nix/files/postgrest.service.j2 @@ -0,0 +1,18 @@ +[Unit] +Description=PostgREST +Requires=postgrest-optimizations.service +After=postgrest-optimizations.service + +[Service] +Type=simple +# We allow the base config (sent from the worker) to override the generated config +ExecStartPre=/etc/postgrest/merge.sh /etc/postgrest/generated.conf /etc/postgrest/base.conf +ExecStart=/opt/postgrest /etc/postgrest/merged.conf +User=postgrest +Slice=services.slice +Restart=always +RestartSec=3 +LimitNOFILE=100000 + +[Install] +WantedBy=multi-user.target diff --git a/ansible-nix/files/services.slice.j2 b/ansible-nix/files/services.slice.j2 new file mode 100644 index 000000000..d45187fb8 --- /dev/null +++ b/ansible-nix/files/services.slice.j2 @@ -0,0 +1,6 @@ +# Used for general services grouping for easy visibility when running +# systemctl status +# See http://archive.vn/94IGa for an in depth article on systemd slices +[Unit] +Description=Slice used for PostgreSQL +Before=slices.target diff --git a/ansible-nix/files/sodium_extension.sql b/ansible-nix/files/sodium_extension.sql new file mode 100644 index 000000000..a19cabf72 --- /dev/null +++ b/ansible-nix/files/sodium_extension.sql @@ -0,0 +1,6 @@ +create schema if not exists pgsodium; +create extension if not exists pgsodium with schema pgsodium cascade; + +grant pgsodium_keyiduser to postgres with admin option; +grant pgsodium_keyholder to postgres with admin option; +grant pgsodium_keymaker to postgres with admin option; diff --git a/ansible-nix/files/start-envoy.sh b/ansible-nix/files/start-envoy.sh new file mode 100644 index 000000000..edd6fe09e --- /dev/null +++ b/ansible-nix/files/start-envoy.sh @@ -0,0 +1,12 @@ +#!/usr/bin/env bash +set -eou pipefail + +if [[ $(cat /sys/module/ipv6/parameters/disable) = 1 ]]; then + sed -i -e "s/address: '::'/address: '0.0.0.0'/" -e 's/ipv4_compat: true/ipv4_compat: false/' /etc/envoy/lds.yaml +else + sed -i -e "s/address: '0.0.0.0'/address: '::'/" -e 's/ipv4_compat: false/ipv4_compat: true/' /etc/envoy/lds.yaml +fi + +# Workaround using `tee` to get `/dev/stdout` access logging to work, see: +# https://github.com/envoyproxy/envoy/issues/8297#issuecomment-620659781 +exec /opt/envoy --config-path /etc/envoy/envoy.yaml --restart-epoch "${RESTART_EPOCH}" 2>&1 | tee diff --git a/ansible-nix/files/stat_extension.sql b/ansible-nix/files/stat_extension.sql new file mode 100644 index 000000000..937834004 --- /dev/null +++ b/ansible-nix/files/stat_extension.sql @@ -0,0 +1,2 @@ +CREATE SCHEMA IF NOT exists extensions; +CREATE EXTENSION IF NOT EXISTS pg_stat_statements with schema extensions; diff --git a/ansible-nix/files/supabase_facts.ini b/ansible-nix/files/supabase_facts.ini new file mode 100644 index 000000000..44e01b4c3 --- /dev/null +++ b/ansible-nix/files/supabase_facts.ini @@ -0,0 +1,2 @@ +[general] +postgres_version=15 diff --git a/ansible-nix/files/sysstat.sysstat b/ansible-nix/files/sysstat.sysstat new file mode 100644 index 000000000..52b7d07d1 --- /dev/null +++ b/ansible-nix/files/sysstat.sysstat @@ -0,0 +1,36 @@ +# How long to keep log files (in days). +# Used by sa2(8) script +# If value is greater than 28, then use sadc's option -D to prevent older +# data files from being overwritten. See sadc(8) and sysstat(5) manual pages. +HISTORY=7 + +# Compress (using xz, gzip or bzip2) sa and sar files older than (in days): +COMPRESSAFTER=10 + +# Parameters for the system activity data collector (see sadc(8) manual page) +# which are used for the generation of log files. +# By default contains the `-S DISK' option responsible for generating disk +# statisitcs. Use `-S XALL' to collect all available statistics. +SADC_OPTIONS="-S DISK" + +# Directory where sa and sar files are saved. The directory must exist. +SA_DIR=/var/log/sysstat + +# Compression program to use. +ZIP="xz" + +# By default sa2 script generates yesterday's summary, since the cron job +# usually runs right after midnight. If you want sa2 to generate the summary +# of the same day (for example when cron job runs at 23:53) set this variable. +#YESTERDAY=no + +# By default sa2 script generates reports files (the so called sarDD files). +# Set this variable to false to disable reports generation. +#REPORTS=false + +# The sa1 and sa2 scripts generate system activity data and report files in +# the /var/log/sysstat directory. By default the files are created with umask 0022 +# and are therefore readable for all users. Change this variable to restrict +# the permissions on the files (e.g. use 0027 to adhere to more strict +# security standards). +UMASK=0022 diff --git a/ansible-nix/files/systemd-resolved.conf b/ansible-nix/files/systemd-resolved.conf new file mode 100644 index 000000000..9280d88a1 --- /dev/null +++ b/ansible-nix/files/systemd-resolved.conf @@ -0,0 +1,8 @@ +# the default is RestartSec=0. If the service fails to start because +# of a systemic issue (e.g. rare case when disk is full) it will +# quickly hit the burst limit (default of 5 failures within 10secs) +# and thereafter be placed in a failed state. By increasing the +# restart interval, we avoid that, and ensure that the service will be +# started back up once any underlying issues are resolved. +[Service] +RestartSec=3 diff --git a/ansible-nix/files/ufw.service.conf b/ansible-nix/files/ufw.service.conf new file mode 100644 index 000000000..83b82efc7 --- /dev/null +++ b/ansible-nix/files/ufw.service.conf @@ -0,0 +1,4 @@ +[Unit] +After=nftables.service +Requires=nftables.service +PartOf=nftables.service diff --git a/ansible-nix/files/vector.service.j2 b/ansible-nix/files/vector.service.j2 new file mode 100644 index 000000000..1c88baa20 --- /dev/null +++ b/ansible-nix/files/vector.service.j2 @@ -0,0 +1,20 @@ +[Unit] +Description=Vector +Documentation=https://vector.dev +After=network-online.target +Requires=network-online.target + +[Service] +User=vector +Group=vector +ExecStartPre=/usr/bin/vector validate --config-yaml /etc/vector/vector.yaml +ExecStart=/usr/bin/vector --config-yaml /etc/vector/vector.yaml +ExecReload=/usr/bin/vector validate --config-yaml /etc/vector/vector.yaml +ExecReload=/bin/kill -HUP $MAINPID +Restart=always +RestartSec=3 +AmbientCapabilities=CAP_NET_BIND_SERVICE +EnvironmentFile=-/etc/default/vector + +[Install] +WantedBy=multi-user.target diff --git a/ansible-nix/files/walg_helper_scripts/wal_change_ownership.sh b/ansible-nix/files/walg_helper_scripts/wal_change_ownership.sh new file mode 100644 index 000000000..3f0112d2f --- /dev/null +++ b/ansible-nix/files/walg_helper_scripts/wal_change_ownership.sh @@ -0,0 +1,42 @@ +#! /usr/bin/env bash + +set -euo pipefail + +filename=$1 + +if [[ -z "$filename" ]]; then + echo "Nothing supplied. Exiting." + exit 1 +fi + +full_path=/tmp/wal_fetch_dir/$filename + +num_paths=$(readlink -f "$full_path" | wc -l) + +# Checks if supplied filename string contains multiple paths +# For example, "correct/path /var/lib/injected/path /var/lib/etc" +if [[ "$num_paths" -gt 1 ]]; then + echo "Multiple paths supplied. Exiting." + exit 1 +fi + +base_dir=$(readlink -f "$full_path" | cut -d'/' -f2) + +# Checks if directory/ file to be manipulated +# is indeed within the /tmp directory +# For example, "/tmp/../var/lib/postgresql/..." +# will return "var" as the value for $base_dir +if [[ "$base_dir" != "tmp" ]]; then + echo "Attempt to manipulate a file not in /tmp. Exiting." + exit 1 +fi + +# Checks if change of ownership will be applied to a file +# If not, exit +if [[ ! -f $full_path ]]; then + echo "Either file does not exist or is a directory. Exiting." + exit 1 +fi + +# once valid, proceed to change ownership +chown postgres:postgres "$full_path" diff --git a/ansible-nix/files/walg_helper_scripts/wal_fetch.sh b/ansible-nix/files/walg_helper_scripts/wal_fetch.sh new file mode 100644 index 000000000..33448ac95 --- /dev/null +++ b/ansible-nix/files/walg_helper_scripts/wal_fetch.sh @@ -0,0 +1,12 @@ +#! /usr/bin/env bash + +set -euo pipefail + +# Fetch the WAL file and temporarily store them in /tmp +sudo -u wal-g wal-g wal-fetch "$1" /tmp/wal_fetch_dir/"$1" --config /etc/wal-g/config.json + +# Ensure WAL file is owned by the postgres Linux user +sudo -u root /root/wal_change_ownership.sh "$1" + +# Move file to its final destination +mv /tmp/wal_fetch_dir/"$1" /var/lib/postgresql/data/"$2" diff --git a/ansible-nix/manifest-playbook.yml b/ansible-nix/manifest-playbook.yml new file mode 100644 index 000000000..93f0e15c5 --- /dev/null +++ b/ansible-nix/manifest-playbook.yml @@ -0,0 +1,91 @@ +- hosts: localhost + gather_facts: no + + vars_files: + - ./vars.yml + + tasks: + - name: Write out image manifest + action: template src=files/manifest.json dest=./image-manifest-{{ ami_release_version }}.json + + - name: Upload image manifest + shell: | + aws s3 cp ./image-manifest-{{ ami_release_version }}.json s3://{{ internal_artifacts_bucket }}/manifests/postgres-{{ ami_release_version }}/software-manifest.json + + # upload software artifacts of interest + # Generally - download, extract, repack as xz archive, upload + # currently, we upload gotrue, adminapi, postgrest + - name: gotrue - download commit archive + get_url: + url: "https://github.com/supabase/gotrue/releases/download/v{{ gotrue_release }}/auth-v{{ gotrue_release }}-arm64.tar.gz" + dest: /tmp/gotrue.tar.gz + checksum: "{{ gotrue_release_checksum }}" + timeout: 60 + + - name: gotrue - create /tmp/gotrue + file: + path: /tmp/gotrue + state: directory + mode: 0775 + + - name: gotrue - unpack archive in /tmp/gotrue + unarchive: + remote_src: yes + src: /tmp/gotrue.tar.gz + dest: /tmp/gotrue + + - name: gotrue - pack archive + shell: | + cd /tmp && tar -cJf gotrue-v{{ gotrue_release }}-arm64.tar.xz gotrue + + - name: PostgREST - download ubuntu binary archive (arm) + get_url: + url: "https://github.com/PostgREST/postgrest/releases/download/v{{ postgrest_release }}/postgrest-v{{ postgrest_release }}-ubuntu-aarch64.tar.xz" + dest: /tmp/postgrest-{{ postgrest_release }}-arm64.tar.xz + checksum: "{{ postgrest_arm_release_checksum }}" + timeout: 60 + + - name: Download adminapi archive + get_url: + url: "https://supabase-public-artifacts-bucket.s3.amazonaws.com/supabase-admin-api/v{{ adminapi_release }}/supabase-admin-api_{{ adminapi_release }}_linux_arm64.tar.gz" + dest: "/tmp/adminapi.tar.gz" + timeout: 90 + + - name: adminapi - unpack archive in /tmp + unarchive: + remote_src: yes + src: /tmp/adminapi.tar.gz + dest: /tmp + + - name: adminapi - pack archive + shell: | + cd /tmp && tar -cJf supabase-admin-api-{{ adminapi_release }}-arm64.tar.xz supabase-admin-api + + - name: Download admin-mgr archive + get_url: + url: "https://supabase-public-artifacts-bucket.s3.amazonaws.com/admin-mgr/v{{ adminmgr_release }}/admin-mgr_{{ adminmgr_release }}_linux_arm64.tar.gz" + dest: "/tmp/admin-mgr.tar.gz" + timeout: 90 + + - name: admin-mgr - unpack archive in /tmp + unarchive: + remote_src: yes + src: /tmp/admin-mgr.tar.gz + dest: /tmp + + - name: admin-mgr - pack archive + shell: | + cd /tmp && tar -cJf admin-mgr-{{ adminmgr_release }}-arm64.tar.xz admin-mgr + + - name: upload archives + shell: | + aws s3 cp /tmp/{{ item.file }} s3://{{ internal_artifacts_bucket }}/upgrades/{{ item.service }}/{{ item.file }} + with_items: + - service: gotrue + file: gotrue-v{{ gotrue_release }}-arm64.tar.xz + - service: postgrest + file: postgrest-{{ postgrest_release }}-arm64.tar.xz + - service: supabase-admin-api + file: supabase-admin-api-{{ adminapi_release }}-arm64.tar.xz + - service: admin-mgr + file: admin-mgr-{{ adminmgr_release }}-arm64.tar.xz diff --git a/ansible-nix/playbook.yml b/ansible-nix/playbook.yml new file mode 100644 index 000000000..c1bb3b898 --- /dev/null +++ b/ansible-nix/playbook.yml @@ -0,0 +1,120 @@ +- hosts: all + become: yes + + pre_tasks: + - import_tasks: tasks/setup-system.yml + + vars_files: + - ./vars.yml + + vars: + sql_files: + - { + source: "pgbouncer_config/pgbouncer_auth_schema.sql", + dest: "00-schema.sql", + } + - { source: "stat_extension.sql", dest: "01-extension.sql" } + + environment: + PATH: /usr/lib/postgresql/bin:{{ ansible_env.PATH }} + + tasks: + - set_fact: + supabase_internal: true + tags: + - install-supabase-internal + + - set_fact: + parallel_jobs: 16 + + - name: Prepare machine for Postgres installation + import_tasks: tasks/setup-postgres.yml + + - name: Install PgBouncer + import_tasks: tasks/setup-pgbouncer.yml + tags: + - install-pgbouncer + - install-supabase-internal + + - name: Install WAL-G + import_tasks: tasks/setup-wal-g.yml + + - name: Install Gotrue + import_tasks: tasks/setup-gotrue.yml + tags: + - install-gotrue + - install-supabase-internal + + - name: Install PostgREST + import_tasks: tasks/setup-postgrest.yml + tags: + - install-postgrest + - install-supabase-internal + + - name: Install Envoy + import_tasks: tasks/setup-envoy.yml + tags: + - install-supabase-internal + + - name: Install Kong + import_tasks: tasks/setup-kong.yml + tags: + - install-supabase-internal + + - name: Install nginx + import_tasks: tasks/setup-nginx.yml + tags: + - install-supabase-internal + + - name: Install Supabase specific content + import_tasks: tasks/setup-supabase-internal.yml + tags: + - install-supabase-internal + + - name: Adjust APT update intervals + copy: + src: files/apt_periodic + dest: /etc/apt/apt.conf.d/10periodic + + - name: Finalize AMI + import_tasks: tasks/finalize-ami.yml + tags: + - install-supabase-internal + + - name: Enhance fail2ban + import_tasks: tasks/setup-fail2ban.yml + + # Install EC2 instance connect + # Only for AWS images + - name: install EC2 instance connect + become: yes + apt: + pkg: + - ec2-instance-connect + tags: + - aws-only + + # Install this at the end to prevent it from kicking in during the apt process, causing conflicts + - name: Install security tools + become: yes + apt: + pkg: + - unattended-upgrades + update_cache: yes + cache_valid_time: 3600 + + - name: Clean out build dependencies + import_tasks: tasks/clean-build-dependencies.yml + + - name: Check if postgres user is part of users group + shell: "id -nG postgres | grep -qw users" + register: check_user_group + ignore_errors: yes + become: yes + args: + executable: /bin/bash + + - name: Print result to Ansible log output + debug: + msg: "The postgres user is {{ 'not ' if check_user_group.rc != 0 else '' }}part of the users group" + diff --git a/ansible-nix/tasks/clean-build-dependencies.yml b/ansible-nix/tasks/clean-build-dependencies.yml new file mode 100644 index 000000000..43ec05179 --- /dev/null +++ b/ansible-nix/tasks/clean-build-dependencies.yml @@ -0,0 +1,21 @@ +- name: Remove build dependencies + apt: + pkg: + - bison + - build-essential + - clang-11 + - cmake + - cpp + - flex + - g++ + - g++-10 + - g++-9 + - gcc-10 + - make + - manpages + - manpages-dev + - ninja-build + - patch + - python2 + state: absent + autoremove: yes diff --git a/ansible-nix/tasks/finalize-ami.yml b/ansible-nix/tasks/finalize-ami.yml new file mode 100644 index 000000000..81a89abeb --- /dev/null +++ b/ansible-nix/tasks/finalize-ami.yml @@ -0,0 +1,72 @@ +- name: PG logging conf + template: + src: files/postgresql_config/postgresql-csvlog.conf + dest: /etc/postgresql/logging.conf + group: postgres + +- name: UFW - Allow SSH connections + ufw: + rule: allow + name: OpenSSH + +- name: UFW - Allow connections to postgreSQL (5432) + ufw: + rule: allow + port: "5432" + +- name: UFW - Allow connections to postgreSQL (6543) + ufw: + rule: allow + port: "6543" + tags: + - install-pgbouncer + +- name: UFW - Allow connections to http (80) + ufw: + rule: allow + port: http + tags: + - install-supabase-internal + +- name: UFW - Allow connections to https (443) + ufw: + rule: allow + port: https + tags: + - install-supabase-internal + +- name: UFW - Deny all other incoming traffic by default + ufw: + state: enabled + policy: deny + direction: incoming + +- name: Move logrotate files to /etc/logrotate.d/ + copy: + src: "files/logrotate_config/{{ item.file }}" + dest: "/etc/logrotate.d/{{ item.file }}" + mode: "0700" + owner: root + loop: + - { file: "logrotate-postgres-csv.conf" } + - { file: "logrotate-postgres.conf" } + - { file: "logrotate-walg.conf" } + - { file: "logrotate-postgres-auth.conf" } + +- name: Ensure default Postgres logrotate config is removed + file: + path: /etc/logrotate.d/postgresql-common + state: absent + +- name: Disable cron access + copy: + src: files/cron.deny + dest: /etc/cron.deny + +- name: Configure logrotation to run every hour + shell: + cmd: | + cp /usr/lib/systemd/system/logrotate.timer /etc/systemd/system/logrotate.timer + sed -i -e 's;daily;*:0/5;' /etc/systemd/system/logrotate.timer + systemctl reenable logrotate.timer + become: yes diff --git a/ansible-nix/tasks/internal/admin-api.yml b/ansible-nix/tasks/internal/admin-api.yml new file mode 100644 index 000000000..cea0109fd --- /dev/null +++ b/ansible-nix/tasks/internal/admin-api.yml @@ -0,0 +1,92 @@ +- name: adminapi - system user + user: + name: adminapi + groups: root,admin,envoy,kong,pgbouncer,postgres,postgrest,systemd-journal,vector,wal-g + append: yes + +- name: Move shell scripts to /root dir + copy: + src: "files/admin_api_scripts/{{ item.file }}" + dest: "/root/{{ item.file }}" + mode: "0700" + owner: root + loop: + - { file: "grow_fs.sh" } + - { file: "manage_readonly_mode.sh" } + - { file: "pg_egress_collect.pl" } + +- name: give adminapi user permissions + copy: + src: files/adminapi.sudoers.conf + dest: /etc/sudoers.d/adminapi + mode: "0644" + +- name: perms for adminapi + shell: | + chmod g+w /etc + +- name: Setting arch (x86) + set_fact: + arch: "x86" + when: platform == "amd64" + +- name: Setting arch (arm) + set_fact: + arch: "arm64" + when: platform == "arm64" + +- name: Download adminapi archive + get_url: + url: "https://supabase-public-artifacts-bucket.s3.amazonaws.com/supabase-admin-api/v{{ adminapi_release }}/supabase-admin-api_{{ adminapi_release }}_linux_{{ arch }}.tar.gz" + dest: "/tmp/adminapi.tar.gz" + timeout: 90 + +- name: adminapi - unpack archive in /opt + unarchive: + remote_src: yes + src: /tmp/adminapi.tar.gz + dest: /opt + owner: adminapi + +- name: adminapi - config dir + file: + path: /etc/adminapi + owner: adminapi + state: directory + +- name: adminapi - pg_upgrade scripts dir + file: + path: /etc/adminapi/pg_upgrade_scripts + owner: adminapi + state: directory + +- name: Move shell scripts to /etc/adminapi/pg_upgrade_scripts/ + copy: + src: "files/admin_api_scripts/pg_upgrade_scripts/{{ item.file }}" + dest: "/etc/adminapi/pg_upgrade_scripts/{{ item.file }}" + mode: "0755" + owner: adminapi + loop: + - { file: "check.sh" } + - { file: "complete.sh" } + - { file: "initiate.sh" } + - { file: "prepare.sh" } + - { file: "pgsodium_getkey.sh" } + - { file: "common.sh" } + +- name: adminapi - create service file + template: + src: files/adminapi.service.j2 + dest: /etc/systemd/system/adminapi.service + +- name: UFW - Allow connections to adminapi ports + ufw: + rule: allow + port: "8085" + +- name: adminapi - reload systemd + systemd: + daemon_reload: yes + +- name: adminapi - grant extra priviliges to user + shell: chmod 775 /etc && chmod 775 /etc/kong diff --git a/ansible-nix/tasks/internal/admin-mgr.yml b/ansible-nix/tasks/internal/admin-mgr.yml new file mode 100644 index 000000000..073b8661f --- /dev/null +++ b/ansible-nix/tasks/internal/admin-mgr.yml @@ -0,0 +1,22 @@ +- name: Setting arch (x86) + set_fact: + arch: "amd64" + when: platform == "amd64" + +- name: Setting arch (arm) + set_fact: + arch: "arm64" + when: platform == "arm64" + +- name: Download admin-mgr archive + get_url: + url: "https://supabase-public-artifacts-bucket.s3.amazonaws.com/admin-mgr/v{{ adminmgr_release }}/admin-mgr_{{ adminmgr_release }}_linux_{{ arch }}.tar.gz" + dest: "/tmp/admin-mgr.tar.gz" + timeout: 90 + +- name: admin-mgr - unpack archive in /usr/bin/ + unarchive: + remote_src: yes + src: /tmp/admin-mgr.tar.gz + dest: /usr/bin/ + owner: root diff --git a/ansible-nix/tasks/internal/pg_egress_collect.yml b/ansible-nix/tasks/internal/pg_egress_collect.yml new file mode 100644 index 000000000..be9fefe02 --- /dev/null +++ b/ansible-nix/tasks/internal/pg_egress_collect.yml @@ -0,0 +1,15 @@ +- name: pg_egress_collect - install tcpdump and perl async lib + apt: + pkg: + - tcpdump + - libio-async-perl + +- name: pg_egress_collect - create service file + template: + src: files/pg_egress_collect.service.j2 + dest: /etc/systemd/system/pg_egress_collect.service + +- name: pg_egress_collect - reload systemd + systemd: + daemon_reload: yes + diff --git a/ansible-nix/tasks/internal/postgres-exporter.yml b/ansible-nix/tasks/internal/postgres-exporter.yml new file mode 100644 index 000000000..0292157b2 --- /dev/null +++ b/ansible-nix/tasks/internal/postgres-exporter.yml @@ -0,0 +1,48 @@ +- name: UFW - Allow connections to exporter for prometheus + ufw: + rule: allow + port: "9187" + +- name: create directories - systemd unit + file: + state: directory + path: /etc/systemd/system/postgres_exporter.service.d + owner: root + mode: '0700' + become: yes + +- name: create directories - service files + file: + state: directory + path: /opt/postgres_exporter + owner: postgres + group: postgres + mode: '0775' + become: yes + +- name: download postgres exporter + get_url: + url: "https://github.com/prometheus-community/postgres_exporter/releases/download/v{{ postgres_exporter_release }}/postgres_exporter-{{ postgres_exporter_release }}.linux-{{ platform }}.tar.gz" + dest: /tmp/postgres_exporter.tar.gz + checksum: "{{ postgres_exporter_release_checksum[platform] }}" + timeout: 60 + +- name: expand postgres exporter + unarchive: + remote_src: yes + src: /tmp/postgres_exporter.tar.gz + dest: /opt/postgres_exporter + extra_opts: [--strip-components=1] + become: yes + +- name: exporter create a service + template: + src: files/postgres_exporter.service.j2 + dest: /etc/systemd/system/postgres_exporter.service + +- name: exporter ensure service is present + systemd: + enabled: no + name: postgres_exporter + daemon_reload: yes + state: stopped diff --git a/ansible-nix/tasks/internal/setup-ansible-pull.yml b/ansible-nix/tasks/internal/setup-ansible-pull.yml new file mode 100644 index 000000000..7cce74a8c --- /dev/null +++ b/ansible-nix/tasks/internal/setup-ansible-pull.yml @@ -0,0 +1,29 @@ +- name: install ansible + shell: + cmd: | + apt install -y software-properties-common + add-apt-repository --yes --update ppa:ansible/ansible + apt install -y ansible + sed -i -e 's/#callback_whitelist.*/callback_whitelist = profile_tasks/' /etc/ansible/ansible.cfg + +- name: ansible pull systemd units + copy: + src: files/{{ item }} + dest: /etc/systemd/system/{{ item }} + with_items: + - ansible-pull.service + - ansible-pull.timer + +- name: create facts dir + file: + path: /etc/ansible/facts.d + state: directory + +- name: ansible facts + copy: + src: files/supabase_facts.ini + dest: /etc/ansible/facts.d/supabase.fact + +- name: reload systemd + systemd: + daemon_reload: yes diff --git a/ansible-nix/tasks/internal/setup-nftables.yml b/ansible-nix/tasks/internal/setup-nftables.yml new file mode 100644 index 000000000..fc8d0235a --- /dev/null +++ b/ansible-nix/tasks/internal/setup-nftables.yml @@ -0,0 +1,34 @@ +- name: nftables overrides + file: + state: directory + path: /etc/nftables + owner: adminapi + +- name: nftables empty config + file: + state: touch + path: /etc/nftables/supabase_managed.conf + owner: adminapi + +- name: include managed config + shell: | + cat >> "/etc/nftables.conf" << EOF + table inet supabase_managed { } + include "/etc/nftables/supabase_managed.conf"; + + EOF + +- name: ufw overrides dir + file: + state: directory + path: /etc/systemd/system/ufw.service.d + owner: root + +- name: Custom systemd overrides + copy: + src: files/ufw.service.conf + dest: /etc/systemd/system/ufw.service.d/overrides.conf + +- name: reload systemd + systemd: + daemon_reload: yes diff --git a/ansible-nix/tasks/internal/supautils.yml b/ansible-nix/tasks/internal/supautils.yml new file mode 100644 index 000000000..33811b5ac --- /dev/null +++ b/ansible-nix/tasks/internal/supautils.yml @@ -0,0 +1,77 @@ +# supautils +- name: supautils - download & install dependencies + apt: + pkg: + - build-essential + - clang-11 + update_cache: yes + cache_valid_time: 3600 + +- name: supautils - download latest release + get_url: + url: "https://github.com/supabase/supautils/archive/refs/tags/v{{ supautils_release }}.tar.gz" + dest: /tmp/supautils-{{ supautils_release }}.tar.gz + checksum: "{{ supautils_release_checksum }}" + timeout: 60 + +- name: supautils - unpack archive + unarchive: + remote_src: yes + src: /tmp/supautils-{{ supautils_release }}.tar.gz + dest: /tmp + become: yes + +- name: supautils - build + make: + chdir: /tmp/supautils-{{ supautils_release }} + become: yes + +- name: supautils - install + make: + chdir: /tmp/supautils-{{ supautils_release }} + target: install + become: yes + +- name: supautils - add supautils to session_preload_libraries + become: yes + replace: + path: /etc/postgresql/postgresql.conf + regexp: "#session_preload_libraries = ''" + replace: session_preload_libraries = 'supautils' + +- name: supautils - write custom supautils.conf + template: + src: "files/postgresql_config/supautils.conf.j2" + dest: /etc/postgresql-custom/supautils.conf + mode: 0664 + owner: postgres + group: postgres + +- name: supautils - copy extension custom scripts + copy: + src: files/postgresql_extension_custom_scripts/ + dest: /etc/postgresql-custom/extension-custom-scripts + become: yes + +- name: supautils - chown extension custom scripts + file: + mode: 0775 + owner: postgres + group: postgres + path: /etc/postgresql-custom/extension-custom-scripts + recurse: yes + become: yes + +- name: supautils - include /etc/postgresql-custom/supautils.conf in postgresql.conf + become: yes + replace: + path: /etc/postgresql/postgresql.conf + regexp: "#include = '/etc/postgresql-custom/supautils.conf'" + replace: "include = '/etc/postgresql-custom/supautils.conf'" + +- name: supautils - remove build dependencies + apt: + pkg: + - build-essential + - clang-11 + state: absent diff --git a/ansible-nix/tasks/setup-envoy.yml b/ansible-nix/tasks/setup-envoy.yml new file mode 100644 index 000000000..9843b5546 --- /dev/null +++ b/ansible-nix/tasks/setup-envoy.yml @@ -0,0 +1,60 @@ +- name: Envoy - system user + ansible.builtin.user: + name: envoy + +- name: Envoy - download binary + ansible.builtin.get_url: + checksum: "{{ envoy_release_checksum }}" + dest: /opt/envoy + group: envoy + mode: u+x + owner: envoy + # yamllint disable-line rule:line-length + url: "https://github.com/envoyproxy/envoy/releases/download/v{{ envoy_release }}/envoy-{{ envoy_release }}-linux-aarch_64" + +- name: Envoy - download hot restarter script + ansible.builtin.get_url: + checksum: "{{ envoy_hot_restarter_release_checksum }}" + dest: /opt/envoy-hot-restarter.py + group: envoy + mode: u+x + owner: envoy + # yamllint disable-line rule:line-length + url: https://raw.githubusercontent.com/envoyproxy/envoy/v{{ envoy_release }}/restarter/hot-restarter.py + +- name: Envoy - bump up ulimit + community.general.pam_limits: + domain: envoy + limit_item: nofile + limit_type: soft + value: 4096 + +- name: Envoy - create script to start envoy + ansible.builtin.copy: + dest: /opt/start-envoy.sh + group: envoy + mode: u+x + owner: envoy + src: files/start-envoy.sh + +- name: Envoy - create configuration files + ansible.builtin.copy: + dest: /etc/envoy/ + directory_mode: u=rwx,g=rwx,o=rx + group: envoy + mode: u=rw,g=rw,o=r + owner: envoy + src: files/envoy_config/ + +- name: Envoy - create service file + ansible.builtin.copy: + dest: /etc/systemd/system/envoy.service + mode: u=rw,g=r,o=r + src: files/envoy.service + +- name: Envoy - disable service + ansible.builtin.systemd: + daemon_reload: true + enabled: false + name: envoy + state: stopped diff --git a/ansible-nix/tasks/setup-extensions.yml b/ansible-nix/tasks/setup-extensions.yml new file mode 100644 index 000000000..0fb92c151 --- /dev/null +++ b/ansible-nix/tasks/setup-extensions.yml @@ -0,0 +1,94 @@ +- name: Install plv8 + import_tasks: tasks/postgres-extensions/13-plv8.yml + +- name: Install pg_jsonschema + import_tasks: tasks/postgres-extensions/22-pg_jsonschema.yml + +- name: Install postgis + import_tasks: tasks/postgres-extensions/01-postgis.yml + +- name: Install pgrouting + import_tasks: tasks/postgres-extensions/02-pgrouting.yml + +- name: Install pgtap + import_tasks: tasks/postgres-extensions/03-pgtap.yml + +- name: Install pg_cron + import_tasks: tasks/postgres-extensions/04-pg_cron.yml + +- name: Install pgaudit + import_tasks: tasks/postgres-extensions/05-pgaudit.yml + +- name: Install pgjwt + import_tasks: tasks/postgres-extensions/06-pgjwt.yml + +- name: Install pgsql-http + import_tasks: tasks/postgres-extensions/07-pgsql-http.yml + +- name: Install plpgsql_check + import_tasks: tasks/postgres-extensions/08-plpgsql_check.yml + +- name: Install pg-safeupdate + import_tasks: tasks/postgres-extensions/09-pg-safeupdate.yml + +- name: Install timescaledb + import_tasks: tasks/postgres-extensions/10-timescaledb.yml + +- name: Install wal2json + import_tasks: tasks/postgres-extensions/11-wal2json.yml + +- name: Install pljava + import_tasks: tasks/postgres-extensions/12-pljava.yml + tags: + - legacy-incompatible + +- name: Install pg_plan_filter + import_tasks: tasks/postgres-extensions/14-pg_plan_filter.yml + +- name: Install pg_net + import_tasks: tasks/postgres-extensions/15-pg_net.yml + +- name: Install rum + import_tasks: tasks/postgres-extensions/16-rum.yml + +- name: Install pg_hashids + import_tasks: tasks/postgres-extensions/17-pg_hashids.yml + +- name: Install pgsodium + import_tasks: tasks/postgres-extensions/18-pgsodium.yml + +- name: Install pg_graphql + import_tasks: tasks/postgres-extensions/19-pg_graphql.yml + tags: + - legacy-incompatible + +- name: Install pg_stat_monitor + import_tasks: tasks/postgres-extensions/20-pg_stat_monitor.yml + +- name: Install auto_explain + import_tasks: tasks/postgres-extensions/21-auto_explain.yml + +- name: Install vault + import_tasks: tasks/postgres-extensions/23-vault.yml + +- name: Install PGroonga + import_tasks: tasks/postgres-extensions/24-pgroonga.yml + +- name: Install wrappers + import_tasks: tasks/postgres-extensions/25-wrappers.yml + +- name: Install hypopg + import_tasks: tasks/postgres-extensions/26-hypopg.yml + +- name: Install pg_repack + import_tasks: tasks/postgres-extensions/27-pg_repack.yml + +- name: Install pgvector + import_tasks: tasks/postgres-extensions/28-pgvector.yml + +- name: Install Trusted Language Extensions + import_tasks: tasks/postgres-extensions/29-pg_tle.yml + +- name: Verify async task status + import_tasks: tasks/postgres-extensions/99-finish_async_tasks.yml + when: async_mode diff --git a/ansible-nix/tasks/setup-fail2ban.yml b/ansible-nix/tasks/setup-fail2ban.yml new file mode 100644 index 000000000..e1cec2d92 --- /dev/null +++ b/ansible-nix/tasks/setup-fail2ban.yml @@ -0,0 +1,70 @@ +# set default bantime to 1 hour +- name: extend bantime + become: yes + replace: + path: /etc/fail2ban/jail.conf + regexp: bantime = 10m + replace: bantime = 3600 + +- name: Configure journald + copy: + src: files/fail2ban_config/jail-ssh.conf + dest: /etc/fail2ban/jail.d/sshd.local + +- name: configure fail2ban to use nftables + copy: + src: files/fail2ban_config/jail.local + dest: /etc/fail2ban/jail.local + +# postgresql +- name: import jail.d/postgresql.conf + template: + src: files/fail2ban_config/jail-postgresql.conf.j2 + dest: /etc/fail2ban/jail.d/postgresql.conf + become: yes + +- name: import filter.d/postgresql.conf + template: + src: files/fail2ban_config/filter-postgresql.conf.j2 + dest: /etc/fail2ban/filter.d/postgresql.conf + become: yes + +- name: create overrides dir + file: + state: directory + owner: root + group: root + path: /etc/systemd/system/fail2ban.service.d + mode: '0700' + +- name: Custom systemd overrides + copy: + src: files/fail2ban_config/fail2ban.service.conf + dest: /etc/systemd/system/fail2ban.service.d/overrides.conf + +- name: add in supabase specific ignore filters + lineinfile: + path: /etc/fail2ban/filter.d/postgresql.conf + state: present + line: "{{ item.line }}" + loop: + - { line: ' ^.*,.*,.*,.*,":.*password authentication failed for user ""supabase_admin".*$' } + - { line: ' ^.*,.*,.*,.*,":.*password authentication failed for user ""supabase_auth_admin".*$' } + - { line: ' ^.*,.*,.*,.*,":.*password authentication failed for user ""supabase_storage_admin".*$' } + - { line: ' ^.*,.*,.*,.*,":.*password authentication failed for user ""authenticator".*$' } + - { line: ' ^.*,.*,.*,.*,":.*password authentication failed for user ""pgbouncer".*$' } + become: yes + tags: + - install-supabase-internal + +# Restart +- name: fail2ban - restart + systemd: + name: fail2ban + state: restarted + +- name: fail2ban - disable service + systemd: + name: fail2ban + enabled: no + daemon_reload: yes diff --git a/ansible-nix/tasks/setup-gotrue.yml b/ansible-nix/tasks/setup-gotrue.yml new file mode 100644 index 000000000..2a70caa4d --- /dev/null +++ b/ansible-nix/tasks/setup-gotrue.yml @@ -0,0 +1,54 @@ +- name: UFW - Allow connections to GoTrue metrics exporter + ufw: + rule: allow + port: "9122" + +# use this user for the Gotrue build and for running the service +- name: Gotrue - system user + user: name=gotrue + +- name: Setting arch (x86) + set_fact: + arch: "x86" + when: platform == "amd64" + +- name: Setting arch (arm) + set_fact: + arch: "arm64" + when: platform == "arm64" + +- name: gotrue - download commit archive + get_url: + url: "https://github.com/supabase/gotrue/releases/download/v{{ gotrue_release }}/auth-v{{ gotrue_release }}-{{ arch }}.tar.gz" + dest: /tmp/gotrue.tar.gz + checksum: "{{ gotrue_release_checksum }}" + +- name: gotrue - create /opt/gotrue + file: + path: /opt/gotrue + state: directory + owner: gotrue + mode: 0775 + +- name: gotrue - unpack archive in /opt/gotrue + unarchive: + remote_src: yes + src: /tmp/gotrue.tar.gz + dest: /opt/gotrue + owner: gotrue + +# libpq is a C library that enables user programs to communicate with +# the PostgreSQL database server. +- name: gotrue - system dependencies + apt: + pkg: + - libpq-dev + +- name: gotrue - create service file + template: + src: files/gotrue.service.j2 + dest: /etc/systemd/system/gotrue.service + +- name: gotrue - reload systemd + systemd: + daemon_reload: yes diff --git a/ansible-nix/tasks/setup-kong.yml b/ansible-nix/tasks/setup-kong.yml new file mode 100644 index 000000000..b34f96e78 --- /dev/null +++ b/ansible-nix/tasks/setup-kong.yml @@ -0,0 +1,62 @@ +- name: Kong - system user + user: name=kong + +# Kong installation steps from http://archive.vn/3HRQx +- name: Kong - system dependencies + apt: + pkg: + - openssl + - libpcre3 + - procps + - perl + +- name: Kong - download deb package + get_url: + url: "https://packages.konghq.com/public/gateway-28/deb/ubuntu/pool/{{ kong_release_target }}/main/k/ko/kong_2.8.1/{{ kong_deb }}" + dest: /tmp/kong.deb + checksum: "{{ kong_deb_checksum }}" + +- name: Kong - deb installation + apt: deb=file:///tmp/kong.deb + +- name: Kong - ensure it is NOT autoremoved + shell: | + set -e + apt-mark manual kong zlib1g* + +- name: Kong - configuration + template: + src: files/kong_config/kong.conf.j2 + dest: /etc/kong/kong.conf + +- name: Kong - hand over ownership of /usr/local/kong to user kong + file: + path: /usr/local/kong + recurse: yes + owner: kong + +# [warn] ulimit is currently set to "1024". For better performance set it to at least +# "4096" using "ulimit -n" +- name: Kong - bump up ulimit + pam_limits: + limit_item: nofile + limit_type: soft + domain: kong + value: "4096" + +- name: Kong - create env file + template: + src: files/kong_config/kong.env.j2 + dest: /etc/kong/kong.env + +- name: Kong - create service file + template: + src: files/kong_config/kong.service.j2 + dest: /etc/systemd/system/kong.service + +- name: Kong - disable service + systemd: + enabled: no + name: kong + state: stopped + daemon_reload: yes diff --git a/ansible-nix/tasks/setup-migrations.yml b/ansible-nix/tasks/setup-migrations.yml new file mode 100644 index 000000000..570f7763c --- /dev/null +++ b/ansible-nix/tasks/setup-migrations.yml @@ -0,0 +1,13 @@ +- name: Run migrate.sh script + shell: ./migrate.sh + register: retval + when: ebssurrogate_mode + args: + chdir: /tmp/migrations/db + failed_when: retval.rc != 0 + +- name: Create /root/MIGRATION-AMI file + file: + path: "/root/MIGRATION-AMI" + state: touch + when: ebssurrogate_mode diff --git a/ansible-nix/tasks/setup-nginx.yml b/ansible-nix/tasks/setup-nginx.yml new file mode 100644 index 000000000..77fb7707a --- /dev/null +++ b/ansible-nix/tasks/setup-nginx.yml @@ -0,0 +1,82 @@ +- name: nginx - system user + user: name=nginx + +# Kong installation steps from http://archive.vn/3HRQx +- name: nginx - system dependencies + apt: + pkg: + - openssl + - libpcre3-dev + - libssl-dev + - zlib1g-dev + +- name: nginx - download source + get_url: + url: "https://nginx.org/download/nginx-{{ nginx_release }}.tar.gz" + dest: /tmp/nginx-{{ nginx_release }}.tar.gz + checksum: "{{ nginx_release_checksum }}" + +- name: nginx - unpack archive + unarchive: + remote_src: yes + src: /tmp/nginx-{{ nginx_release }}.tar.gz + dest: /tmp + +- name: nginx - configure + shell: + chdir: /tmp/nginx-{{ nginx_release }} + cmd: | + set -e + + ./configure \ + --prefix=/usr/local/nginx \ + --conf-path=/etc/nginx/nginx.conf \ + --with-http_ssl_module \ + --with-http_realip_module \ + --with-threads + become: yes + +- name: nginx - build + community.general.make: + target: build + chdir: /tmp/nginx-{{ nginx_release }} + jobs: "{{ parallel_jobs | default(omit) }}" + become: yes + +- name: nginx - install + make: + chdir: /tmp/nginx-{{ nginx_release }} + target: install + become: yes + +- name: nginx - hand over ownership of /usr/local/nginx to user nginx + file: + path: /usr/local/nginx + recurse: yes + owner: nginx + +- name: nginx - hand over ownership of /etc/nginx to user nginx + file: + path: /etc/nginx + recurse: yes + owner: nginx + +# [warn] ulimit is currently set to "1024". For better performance set it to at least +# "4096" using "ulimit -n" +- name: nginx - bump up ulimit + pam_limits: + limit_item: nofile + limit_type: soft + domain: nginx + value: "4096" + +- name: nginx - create service file + template: + src: files/nginx.service.j2 + dest: /etc/systemd/system/nginx.service + +# Keep it dormant for the timebeing + +# - name: nginx - reload systemd +# systemd: +# daemon_reload: yes diff --git a/ansible-nix/tasks/setup-pgbouncer.yml b/ansible-nix/tasks/setup-pgbouncer.yml new file mode 100644 index 000000000..4381ba24d --- /dev/null +++ b/ansible-nix/tasks/setup-pgbouncer.yml @@ -0,0 +1,135 @@ +# PgBouncer +- name: PgBouncer - download & install dependencies + apt: + pkg: + - build-essential + - libssl-dev + - pkg-config + - libevent-dev + - libsystemd-dev + update_cache: yes + cache_valid_time: 3600 + +- name: PgBouncer - download latest release + get_url: + url: "https://www.pgbouncer.org/downloads/files/{{ pgbouncer_release }}/pgbouncer-{{ pgbouncer_release }}.tar.gz" + dest: /tmp/pgbouncer-{{ pgbouncer_release }}.tar.gz + checksum: "{{ pgbouncer_release_checksum }}" + timeout: 60 + +- name: PgBouncer - unpack archive + unarchive: + remote_src: yes + src: /tmp/pgbouncer-{{ pgbouncer_release }}.tar.gz + dest: /tmp + become: yes + +- name: PgBouncer - configure + shell: + cmd: "./configure --prefix=/usr/local --with-systemd" + chdir: /tmp/pgbouncer-{{ pgbouncer_release }} + become: yes + +- name: PgBouncer - build + make: + chdir: /tmp/pgbouncer-{{ pgbouncer_release }} + become: yes + +- name: PgBouncer - install + make: + chdir: /tmp/pgbouncer-{{ pgbouncer_release }} + target: install + become: yes + +- name: Create pgbouncer user + user: + name: pgbouncer + shell: /bin/false + comment: PgBouncer user + groups: postgres,ssl-cert + +- name: PgBouncer - create a directory if it does not exist + file: + path: /etc/pgbouncer + state: directory + owner: pgbouncer + group: pgbouncer + mode: '0700' + +- name: PgBouncer - create a directory if it does not exist + file: + state: directory + owner: pgbouncer + group: pgbouncer + path: '{{ item }}' + mode: '0775' + with_items: + - '/etc/pgbouncer-custom' + +- name: create placeholder config files + file: + path: '/etc/pgbouncer-custom/{{ item }}' + state: touch + owner: pgbouncer + group: pgbouncer + mode: 0664 + with_items: + - 'generated-optimizations.ini' + - 'custom-overrides.ini' + - 'ssl-config.ini' + +- name: PgBouncer - adjust pgbouncer.ini + copy: + src: files/pgbouncer_config/pgbouncer.ini.j2 + dest: /etc/pgbouncer/pgbouncer.ini + owner: pgbouncer + mode: '0700' + +- name: PgBouncer - create a directory if it does not exist + file: + path: /etc/pgbouncer/userlist.txt + state: touch + owner: pgbouncer + mode: '0700' + +- name: import /etc/tmpfiles.d/pgbouncer.conf + template: + src: files/pgbouncer_config/tmpfiles.d-pgbouncer.conf.j2 + dest: /etc/tmpfiles.d/pgbouncer.conf + become: yes + +- name: PgBouncer - By default allow ssl connections. + become: yes + copy: + dest: /etc/pgbouncer-custom/ssl-config.ini + content: | + client_tls_sslmode = allow + +- name: Grant pg_hba and pgbouncer grp perm for adminapi updates + shell: | + chmod g+w /etc/postgresql/pg_hba.conf + chmod g+w /etc/pgbouncer-custom/ssl-config.ini + +# Add fail2ban filter +- name: import jail.d/pgbouncer.conf + template: + src: files/fail2ban_config/jail-pgbouncer.conf.j2 + dest: /etc/fail2ban/jail.d/pgbouncer.conf + become: yes + +- name: import filter.d/pgbouncer.conf + template: + src: files/fail2ban_config/filter-pgbouncer.conf.j2 + dest: /etc/fail2ban/filter.d/pgbouncer.conf + become: yes + +# Add systemd file for PgBouncer +- name: PgBouncer - import postgresql.service + template: + src: files/pgbouncer_config/pgbouncer.service.j2 + dest: /etc/systemd/system/pgbouncer.service + become: yes + +- name: PgBouncer - reload systemd + systemd: + daemon_reload: yes diff --git a/ansible-nix/tasks/setup-postgres.yml b/ansible-nix/tasks/setup-postgres.yml new file mode 100644 index 000000000..0644f10dc --- /dev/null +++ b/ansible-nix/tasks/setup-postgres.yml @@ -0,0 +1,132 @@ +- name: create ssl-cert group + group: + name: ssl-cert + state: present + +# the old method of installing from debian creates this group, but we must create it explicitly +# for the nix built version + +- name: create postgres group + group: + name: postgres + state: present + +- name: create postgres user + shell: useradd -m -r -s /bin/bash -d /home/postgres postgres -g postgres + args: + executable: /bin/bash + become: yes + +- name: add postgres user to postgres group + shell: usermod -a -G ssl-cert postgres + args: + executable: /bin/bash + become: yes + +- name: Create relevant directories + file: + path: '{{ item }}' + recurse: yes + state: directory + owner: postgres + group: postgres + with_items: + - '/home/postgres' + - '/var/log/postgresql' + - '/var/lib/postgresql' + +- name: Allow adminapi to write custom config + file: + path: '{{ item }}' + recurse: yes + state: directory + owner: postgres + group: postgres + mode: 0775 + with_items: + - '/etc/postgresql' + - '/etc/postgresql-custom' + +- name: create placeholder config files + file: + path: '/etc/postgresql-custom/{{ item }}' + state: touch + owner: postgres + group: postgres + mode: 0664 + with_items: + - 'generated-optimizations.conf' + - 'custom-overrides.conf' + +- name: locale-gen + command: sudo locale-gen en_US.UTF-8 + +- name: Add LOCALE_ARCHIVE to .bashrc + lineinfile: + dest: "/home/postgres/.bashrc" + line: 'export LOCALE_ARCHIVE=/usr/lib/locale/locale-archive' + create: yes + become: yes + + +- name: Add LANG items to .bashrc + lineinfile: + dest: "/home/postgres/.bashrc" + line: "{{ item }}" + + loop: + - 'export LANG="en_US.UTF-8"' + - 'export LANGUAGE="en_US.UTF-8"' + - 'export LC_ALL="en_US.UTF-8"' + - 'export LANG="en_US.UTF-8"' + - 'export LC_CTYPE="en_US.UTF-8"' + become: yes + + +# Move Postgres configuration files into /etc/postgresql +# Add postgresql.conf +- name: import postgresql.conf + template: + src: files/postgresql_config/postgresql.conf.j2 + dest: /etc/postgresql/postgresql.conf + group: postgres + +# Add pg_hba.conf +- name: import pg_hba.conf + template: + src: files/postgresql_config/pg_hba.conf.j2 + dest: /etc/postgresql/pg_hba.conf + group: postgres + +# Add pg_ident.conf +- name: import pg_ident.conf + template: + src: files/postgresql_config/pg_ident.conf.j2 + dest: /etc/postgresql/pg_ident.conf + group: postgres + +# Add custom config for read replicas set up +- name: Move custom read-replica.conf file to /etc/postgresql-custom/read-replica.conf + template: + src: "files/postgresql_config/custom_read_replica.conf.j2" + dest: /etc/postgresql-custom/read-replica.conf + mode: 0664 + owner: postgres + group: postgres + +# # Install extensions before init +# (samrose) moved to tasks/stage2/setup-extensions.yml +# now called from stage2/stage2-setup-postgres.yml + + +# init DB +- name: Create directory on data volume + file: + path: '{{ item }}' + recurse: yes + state: directory + owner: postgres + group: postgres + mode: 0750 + with_items: + - "/data/pgdata" diff --git a/ansible-nix/tasks/setup-postgrest.yml b/ansible-nix/tasks/setup-postgrest.yml new file mode 100644 index 000000000..57b76e1ee --- /dev/null +++ b/ansible-nix/tasks/setup-postgrest.yml @@ -0,0 +1,84 @@ +- name: PostgREST - system user + user: name=postgrest + +# libpq is a C library that enables user programs to communicate with +# the PostgreSQL database server. +- name: PostgREST - system dependencies + apt: + pkg: + - libpq5 + - libnuma-dev + +- name: postgis - ensure dependencies do not get autoremoved + shell: | + set -e + apt-mark manual libnuma* + apt-mark auto libnuma*-dev + +- name: PostgREST - download ubuntu binary archive (arm) + get_url: + url: "https://github.com/PostgREST/postgrest/releases/download/v{{ postgrest_release }}/postgrest-v{{ postgrest_release }}-ubuntu-aarch64.tar.xz" + dest: /tmp/postgrest.tar.xz + checksum: "{{ postgrest_arm_release_checksum }}" + timeout: 60 + when: platform == "arm64" + +- name: PostgREST - download ubuntu binary archive (x86) + get_url: + url: "https://github.com/PostgREST/postgrest/releases/download/v{{ postgrest_release }}/postgrest-v{{ postgrest_release }}-linux-static-x64.tar.xz" + dest: /tmp/postgrest.tar.xz + checksum: "{{ postgrest_x86_release_checksum }}" + timeout: 60 + when: platform == "amd64" + +- name: PostgREST - unpack archive in /opt + unarchive: + remote_src: yes + src: /tmp/postgrest.tar.xz + dest: /opt + owner: postgrest + mode: '0755' + +- name: create directories + file: + state: directory + owner: postgrest + group: postgrest + mode: '0775' + path: /etc/postgrest + +- name: empty files + file: + state: touch + owner: postgrest + group: postgrest + path: /etc/postgrest/{{ item }} + with_items: + - base.conf + - generated.conf + +- name: create conf merging script + copy: + content: | + #! /usr/bin/env bash + set -euo pipefail + set -x + + cd "$(dirname "$0")" + cat $@ > merged.conf + dest: /etc/postgrest/merge.sh + mode: 0750 + owner: postgrest + group: postgrest + +- name: PostgREST - create service files + template: + src: files/{{ item }}.j2 + dest: /etc/systemd/system/{{ item }} + with_items: + - postgrest.service + - postgrest-optimizations.service + +- name: PostgREST - reload systemd + systemd: + daemon_reload: yes diff --git a/ansible-nix/tasks/setup-supabase-internal.yml b/ansible-nix/tasks/setup-supabase-internal.yml new file mode 100644 index 000000000..849c76954 --- /dev/null +++ b/ansible-nix/tasks/setup-supabase-internal.yml @@ -0,0 +1,108 @@ +- name: AWS CLI dep + apt: + pkg: + - unzip + - jq + install_recommends: no + +- name: AWS CLI (arm) + get_url: + url: "https://awscli.amazonaws.com/awscli-exe-linux-aarch64-{{ aws_cli_release }}.zip" + dest: "/tmp/awscliv2.zip" + timeout: 60 + when: platform == "arm64" + +- name: AWS CLI (x86) + get_url: + url: "https://awscli.amazonaws.com/awscli-exe-linux-x86_64-{{ aws_cli_release }}.zip" + dest: "/tmp/awscliv2.zip" + timeout: 60 + when: platform == "amd64" + +- name: AWS CLI - expand + unarchive: + remote_src: yes + src: "/tmp/awscliv2.zip" + dest: "/tmp" + +- name: AWS CLI - install + shell: "/tmp/aws/install --update" + become: true + +- name: AWS CLI - configure ipv6 support for s3 + shell: | + aws configure set default.s3.use_dualstack_endpoint true + +- name: install Vector for logging + become: yes + apt: + deb: "{{ vector_x86_deb }}" + when: platform == "amd64" + +- name: install Vector for logging + become: yes + apt: + deb: "{{ vector_arm_deb }}" + when: platform == "arm64" + +- name: add Vector to postgres group + become: yes + shell: + cmd: | + usermod -a -G postgres vector + +- name: create service files for Vector + template: + src: files/vector.service.j2 + dest: /etc/systemd/system/vector.service + +- name: configure tmpfiles for postgres - overwrites upstream package + template: + src: files/postgresql_config/tmpfiles.postgresql.conf + dest: /etc/tmpfiles.d/postgresql-common.conf + +- name: fix permissions for vector config to be managed + shell: + cmd: | + chown -R vector:vector /etc/vector + chmod 0775 /etc/vector + +- name: vector - reload systemd + systemd: + daemon_reload: yes + +- name: Create checkpoints dir + become: yes + file: + path: /var/lib/vector + state: directory + owner: vector + +- name: Include file for generated optimizations in postgresql.conf + become: yes + replace: + path: /etc/postgresql/postgresql.conf + regexp: "#include = '/etc/postgresql-custom/generated-optimizations.conf'" + replace: "include = '/etc/postgresql-custom/generated-optimizations.conf'" + +- name: Include file for custom overrides in postgresql.conf + become: yes + replace: + path: /etc/postgresql/postgresql.conf + regexp: "#include = '/etc/postgresql-custom/custom-overrides.conf'" + replace: "include = '/etc/postgresql-custom/custom-overrides.conf'" + +- name: Install Postgres exporter + import_tasks: internal/postgres-exporter.yml + +- name: Install admin-mgr + import_tasks: internal/admin-mgr.yml + +- name: Install adminapi + import_tasks: internal/admin-api.yml + +- name: Init nftabless + import_tasks: internal/setup-nftables.yml + +- name: Install pg_egress_collect + import_tasks: internal/pg_egress_collect.yml diff --git a/ansible-nix/tasks/setup-system.yml b/ansible-nix/tasks/setup-system.yml new file mode 100644 index 000000000..860d75cc2 --- /dev/null +++ b/ansible-nix/tasks/setup-system.yml @@ -0,0 +1,154 @@ +- name: System - apt update and apt upgrade + apt: update_cache=yes upgrade=yes + when: not ebssurrogate_mode + # SEE http://archive.vn/DKJjs#parameter-upgrade + +- name: Install required security updates + apt: + pkg: + - tzdata + - linux-libc-dev + +# SEE https://github.com/georchestra/ansible/issues/55#issuecomment-588313638 +# Without this, a similar error is faced +- name: Install Ansible dependencies + apt: + pkg: + - acl + +- name: Install security tools + apt: + pkg: + - nftables + - fail2ban + update_cache: yes + cache_valid_time: 3600 + +- name: Use nftables backend + shell: | + update-alternatives --set iptables /usr/sbin/iptables-nft + update-alternatives --set ip6tables /usr/sbin/ip6tables-nft + update-alternatives --set arptables /usr/sbin/arptables-nft + update-alternatives --set ebtables /usr/sbin/ebtables-nft + systemctl restart ufw + +- name: Create Sysstat log directory + file: + path: /var/log/sysstat + state: directory + +- name: Install other useful tools + apt: + pkg: + - bwm-ng + - htop + - net-tools + - ngrep + - sysstat + - vim-tiny + update_cache: yes + +- name: Configure sysstat + copy: + src: files/sysstat.sysstat + dest: /etc/sysstat/sysstat + +- name: Configure default sysstat + copy: + src: files/default.sysstat + dest: /etc/default/sysstat + + +- name: Adjust APT update intervals + copy: + src: files/apt_periodic + dest: /etc/apt/apt.conf.d/10periodic + +# Find platform architecture and set as a variable +- name: finding platform architecture + shell: if [ $(uname -m) = "aarch64" ]; then echo "arm64"; else echo "amd64"; fi + register: platform_output + tags: + - update + - update-only +- set_fact: + platform: "{{ platform_output.stdout }}" + tags: + - update + - update-only + +- name: create overrides dir + file: + state: directory + owner: root + group: root + path: /etc/systemd/system/systemd-resolved.service.d + mode: '0700' + +- name: Custom systemd overrides for resolved + copy: + src: files/systemd-resolved.conf + dest: /etc/systemd/system/systemd-resolved.service.d/override.conf + +- name: System - Create services.slice + template: + src: files/services.slice.j2 + dest: /etc/systemd/system/services.slice + when: not ebssurrogate_mode + +- name: System - systemd reload + systemd: daemon_reload=yes + +- name: Configure journald + copy: + src: files/journald.conf + dest: /etc/systemd/journald.conf + +- name: reload systemd-journald + systemd: + name: systemd-journald + state: restarted + +- name: Configure logind + copy: + src: files/logind.conf + dest: /etc/systemd/logind.conf + +- name: reload systemd-logind + systemd: + name: systemd-logind + state: restarted + +- name: enable timestamps for shell history + copy: + content: | + export HISTTIMEFORMAT='%d/%m/%y %T ' + dest: /etc/profile.d/09-history-timestamps.sh + mode: 0644 + owner: root + group: root + +- name: set hosts file + copy: + content: | + 127.0.0.1 localhost + ::1 localhost + dest: /etc/hosts + mode: 0644 + owner: root + group: root + +#Set Sysctl params for restarting the OS on oom after 10 +- name: Set vm.panic_on_oom=1 + ansible.builtin.sysctl: + name: vm.panic_on_oom + value: '1' + state: present + reload: yes + +- name: Set kernel.panic=10 + ansible.builtin.sysctl: + name: kernel.panic + value: '10' + state: present + reload: yes diff --git a/ansible-nix/tasks/setup-wal-g.yml b/ansible-nix/tasks/setup-wal-g.yml new file mode 100644 index 000000000..bbc64cdde --- /dev/null +++ b/ansible-nix/tasks/setup-wal-g.yml @@ -0,0 +1,130 @@ +# Downloading dependencies +- name: wal-g dependencies + become: yes + apt: + pkg: + - libbrotli-dev + - liblzo2-dev + - libsodium-dev + - cmake + +# install go dependency for WAL-G +- name: wal-g go dependency + get_url: + url: "https://golang.org/dl/go{{ golang_version }}.linux-{{ platform }}.tar.gz" + dest: /tmp + checksum: "{{ golang_version_checksum[platform] }}" + timeout: 60 + +- name: unpack go archive + unarchive: + remote_src: yes + src: "/tmp/go{{ golang_version }}.linux-{{ platform }}.tar.gz" + dest: /usr/local + +# Download WAL-G +- name: wal-g - download latest version + git: + repo: https://github.com/wal-g/wal-g.git + dest: /tmp/wal-g + version: "v{{ wal_g_release }}" + become: yes + +- name: wal-g - pg_clean + make: + chdir: /tmp/wal-g + target: pg_clean + params: + GOBIN: "/usr/local/bin" + PATH: "{{ ansible_env.PATH }}:/usr/local/go/bin" + USE_LIBSODIUM: true + become: yes + ignore_errors: yes + +- name: wal-g - deps + make: + chdir: /tmp/wal-g + target: deps + params: + GOBIN: "/usr/local/bin" + PATH: "{{ ansible_env.PATH }}:/usr/local/go/bin" + USE_LIBSODIUM: true + become: yes + ignore_errors: yes + +- name: wal-g - build and install + community.general.make: + chdir: /tmp/wal-g + target: pg_install + jobs: "{{ parallel_jobs | default(omit) }}" + params: + GOBIN: "/usr/local/bin" + PATH: "{{ ansible_env.PATH }}:/usr/local/go/bin" + USE_LIBSODIUM: true + become: yes + +- name: Create wal-g group + group: + name: wal-g + state: present + +- name: Create wal-g user + user: + name: wal-g + shell: /bin/false + comment: WAL-G user + group: wal-g + groups: wal-g, postgres + +- name: Create a config directory owned by wal-g + file: + path: /etc/wal-g + state: directory + owner: wal-g + group: wal-g + mode: '0770' + +- name: Create /etc/wal-g/config.json + file: + path: /etc/wal-g/config.json + state: touch + owner: wal-g + group: wal-g + mode: '0664' + +- name: Move custom wal-g.conf file to /etc/postgresql-custom/wal-g.conf + template: + src: "files/postgresql_config/custom_walg.conf.j2" + dest: /etc/postgresql-custom/wal-g.conf + mode: 0664 + owner: postgres + group: postgres + +- name: Add script to be run for restore_command + template: + src: "files/walg_helper_scripts/wal_fetch.sh" + dest: /home/postgres/wal_fetch.sh + mode: 0500 + owner: postgres + group: postgres + +- name: Add helper script for wal_fetch.sh + template: + src: "files/walg_helper_scripts/wal_change_ownership.sh" + dest: /root/wal_change_ownership.sh + mode: 0700 + owner: root + +- name: Include /etc/postgresql-custom/wal-g.conf in postgresql.conf + become: yes + replace: + path: /etc/postgresql/postgresql.conf + regexp: "#include = '/etc/postgresql-custom/wal-g.conf'" + replace: "include = '/etc/postgresql-custom/wal-g.conf'" + +# Clean up Go +- name: Uninstall Go + become: yes + file: + path: /usr/local/go + state: absent diff --git a/ansible-nix/tasks/stage2/optimizations.yml b/ansible-nix/tasks/stage2/optimizations.yml new file mode 100644 index 000000000..77ecb3697 --- /dev/null +++ b/ansible-nix/tasks/stage2/optimizations.yml @@ -0,0 +1,27 @@ +- name: ensure services are stopped and disabled for first boot + systemd: + enabled: no + name: '{{ item }}' + state: stopped + with_items: + - postgresql + - pgbouncer + - fail2ban + - motd-news + - vector + +- name: Remove snapd + apt: + state: absent + pkg: + - snapd + +- name: disable man-db + become: yes + file: + state: absent + path: "/etc/cron.daily/{{ item }}" + with_items: + - man-db + - popularity-contest + - ubuntu-advantage-tools diff --git a/ansible-nix/tasks/stage2/playbook.yml b/ansible-nix/tasks/stage2/playbook.yml new file mode 100644 index 000000000..aa27602ec --- /dev/null +++ b/ansible-nix/tasks/stage2/playbook.yml @@ -0,0 +1,79 @@ +- hosts: localhost + become: yes + + vars: + sql_files: + - "/tmp/ansible-playbook/files/pgbouncer_config/pgbouncer_auth_schema.sql" + - "/tmp/ansible-playbook/files/stat_extension.sql" + + + tasks: + - set_fact: + supabase_internal: true + tags: + - install-supabase-internal + + - set_fact: + parallel_jobs: 16 + + - name: stat unit test file copy + copy: + src: /tmp/unit-tests/unit-test-01.sql + dest: /home/postgres/unit-test-01.sql + # state: present + owner: postgres + group: postgres + mode: '0644' + + - name: locale-gen + command: sudo locale-gen en_US.UTF-8 + + # - name: Ensure en_US.UTF-8 locale is enabled + # shell: | + # echo "LC_ALL=en_US.UTF-8" >> /etc/environment + # echo "en_US.UTF-8 UTF-8" >> /etc/locale.gen + # echo "LANG=en_US.UTF-8" > /etc/locale.conf + # locale-gen en_US.UTF-8 + # become: yes + + - name: check locales + command: locale -a + register: locales + + - name: Install Postgres from nix binary cache + import_tasks: stage2-setup-postgres.yml + + - name: First boot optimizations + import_tasks: optimizations.yml + + - name: Run unit tests + import_tasks: test-image.yml + tags: + - unit-tests + + - name: Check if postgres user is part of users group + shell: "id -nG postgres | grep -qw users" + register: check_user_group + ignore_errors: yes + become: yes + args: + executable: /bin/bash + + - name: Print result to Ansible log output + debug: + msg: "The postgres user is {{ 'not ' if check_user_group.rc != 0 else '' }}part of the users group" + + - name: Install osquery from nixpkgs binary cache + become: yes + shell: | + sudo -u ubuntu bash -c ". /nix/var/nix/profiles/default/etc/profile.d/nix-daemon.sh && nix profile install nixpkgs#osquery" + + - name: Run osquery permission checks + become: yes + shell: | + sudo -u ubuntu bash -c ". /nix/var/nix/profiles/default/etc/profile.d/nix-daemon.sh && /usr/bin/python3 /tmp/ansible-playbook/files/permission_check.py" + + - name: Remove osquery + become: yes + shell: | + sudo -u ubuntu bash -c ". /nix/var/nix/profiles/default/etc/profile.d/nix-daemon.sh && nix profile remove osquery" diff --git a/ansible-nix/tasks/stage2/setup-extensions.yml b/ansible-nix/tasks/stage2/setup-extensions.yml new file mode 100644 index 000000000..3f13d12e6 --- /dev/null +++ b/ansible-nix/tasks/stage2/setup-extensions.yml @@ -0,0 +1,70 @@ +# - name: pljava - libjvm.so location in postgresql.conf +# become: yes +# lineinfile: +# path: /etc/postgresql/postgresql.conf +# state: present +# line: pljava.libjvm_location = '/home/postgres/.nix-profile/lib/openjdk/lib/server/libjvm.so' +# It was decided to leave pljava disabled at https://github.com/supabase/postgres/pull/690 therefore removing this task + +- name: pg_cron - set cron.database_name + become: yes + lineinfile: + path: /etc/postgresql/postgresql.conf + state: present + line: cron.database_name = 'postgres' + +- set_fact: + pg_bindir: "/usr/lib/postgresql/bin" + +- name: pgsodium - set pgsodium.getkey_script + become: yes + lineinfile: + path: /etc/postgresql/postgresql.conf + state: present + # script is expected to be placed by finalization tasks for different target platforms + line: pgsodium.getkey_script= '{{ pg_bindir }}/pgsodium_getkey.sh' + +- name: auto_explain - set auto_explain.log_min_duration + become: yes + lineinfile: + path: /etc/postgresql/postgresql.conf + state: present + line: auto_explain.log_min_duration = 10s + +# supautils +- name: supautils - add supautils to session_preload_libraries + become: yes + replace: + path: /etc/postgresql/postgresql.conf + regexp: "#session_preload_libraries = ''" + replace: session_preload_libraries = 'supautils' + +- name: supautils - write custom supautils.conf + template: + src: "/tmp/ansible-playbook/files/postgresql_config/supautils.conf.j2" + dest: /etc/postgresql-custom/supautils.conf + mode: 0664 + owner: postgres + group: postgres + +- name: supautils - copy extension custom scripts + copy: + src: /tmp/ansible-playbook/files/postgresql_extension_custom_scripts/ + dest: /etc/postgresql-custom/extension-custom-scripts + become: yes + +- name: supautils - chown extension custom scripts + file: + mode: 0775 + owner: postgres + group: postgres + path: /etc/postgresql-custom/extension-custom-scripts + recurse: yes + become: yes + +- name: supautils - include /etc/postgresql-custom/supautils.conf in postgresql.conf + become: yes + replace: + path: /etc/postgresql/postgresql.conf + regexp: "#include = '/etc/postgresql-custom/supautils.conf'" + replace: "include = '/etc/postgresql-custom/supautils.conf'" diff --git a/ansible-nix/tasks/stage2/setup-migrations.yml b/ansible-nix/tasks/stage2/setup-migrations.yml new file mode 100644 index 000000000..d69fba024 --- /dev/null +++ b/ansible-nix/tasks/stage2/setup-migrations.yml @@ -0,0 +1,13 @@ +- name: Run migrate.sh script + shell: . /nix/var/nix/profiles/default/etc/profile.d/nix-daemon.sh && ./migrate.sh + register: retval + args: + chdir: /tmp/migrations/db + become: yes + become_user: postgres + failed_when: retval.rc != 0 + +- name: Create /root/MIGRATION-AMI file + file: + path: "/root/MIGRATION-AMI" + state: touch diff --git a/ansible-nix/tasks/stage2/stage2-setup-postgres.yml b/ansible-nix/tasks/stage2/stage2-setup-postgres.yml new file mode 100644 index 000000000..3bc0fa91a --- /dev/null +++ b/ansible-nix/tasks/stage2/stage2-setup-postgres.yml @@ -0,0 +1,279 @@ +# - name: Install openjdk11 for pljava from nix binary cache +# become: yes +# shell: | +# sudo -u postgres bash -c ". /nix/var/nix/profiles/default/etc/profile.d/nix-daemon.sh && nix profile install nixpkgs#openjdk11" +# It was decided to leave pljava disabled at https://github.com/supabase/postgres/pull/690 therefore removing this task +- name: Install Postgres from nix binary cache + become: yes + shell: | + sudo -u postgres bash -c ". /nix/var/nix/profiles/default/etc/profile.d/nix-daemon.sh && nix profile install github:supabase/postgres/sam/2-stage-ami-nix#psql_15/bin" +#TODO (samrose) switch pg_prove sourcing to develop branch once PR is merged + +- name: Install pg_prove from nix binary cache + become: yes + shell: | + sudo -u postgres bash -c ". /nix/var/nix/profiles/default/etc/profile.d/nix-daemon.sh && nix profile install github:supabase/postgres/sam/2-stage-ami-nix#pg_prove" + +- name: Set ownership and permissions for /etc/ssl/private + become: yes + file: + path: /etc/ssl/private + owner: root + group: postgres + mode: '0750' + +- name: Set permissions for postgresql.env + become: yes + file: + path: /etc/environment.d/postgresql.env + owner: postgres + group: postgres + mode: '0644' + +- name: Ensure /usr/lib/postgresql/bin directory exists + file: + path: /usr/lib/postgresql/bin + state: directory + owner: postgres + group: postgres + + +- name: Ensure /usr/lib/postgresql/share directory exists + file: + path: /usr/lib/postgresql/share/postgresql + state: directory + owner: postgres + group: postgres + +- name: Ensure /usr/lib/postgresql/share/contrib directory exists + file: + path: /usr/lib/postgresql/share/postgresql/contrib + state: directory + owner: postgres + group: postgres + +- name: Ensure /usr/lib/postgresql/share/timezonesets directory exists + file: + path: /usr/lib/postgresql/share/postgresql/timezonesets + state: directory + owner: postgres + group: postgres + +- name: Ensure /usr/lib/postgresql/share/tsearch_data directory exists + file: + path: /usr/lib/postgresql/share/postgresql/tsearch_data + state: directory + owner: postgres + group: postgres + +- name: Ensure /usr/lib/postgresql/share/extension directory exists + file: + path: /usr/lib/postgresql/share/postgresql/extension + state: directory + owner: postgres + group: postgres + +# - name: Ensure /usr/lib/postgresql/share/postgresql/pljava directory exists +# file: +# path: /usr/lib/postgresql/share/postgresql/pljava +# state: directory +# owner: postgres +# group: postgres +# It was decided to leave pljava disabled at https://github.com/supabase/postgres/pull/690 therefore removing this task + +- name: import pgsodium_getkey script + template: + src: /tmp/ansible-playbook/files/pgsodium_getkey_readonly.sh.j2 + dest: "/usr/lib/postgresql/bin/pgsodium_getkey.sh" + owner: postgres + group: postgres + mode: 0700 + +- name: Create symbolic links from /home/postgres/.nix-profile/bin to /usr/lib/postgresql/bin + file: + src: "{{ item }}" + dest: "/usr/lib/postgresql/bin/{{ item | basename }}" + state: link + with_fileglob: + - "/home/postgres/.nix-profile/bin/*" + become: yes + +- name: Create symbolic links from /home/postgres/.nix-profile/bin to /usr/bin + file: + src: "/home/postgres/.nix-profile/bin/psql" + dest: "/usr/bin/psql" + state: link + become: yes + +# - name: Create symbolic links from /home/postgres/.nix-profile/share/pljava to /usr/lib/postgresql/share/postgresql/pljava +# file: +# src: "{{ item }}" +# dest: "/usr/lib/postgresql/share/postgresql/pljava/{{ item | basename }}" +# state: link +# with_fileglob: +# - "/home/postgres/.nix-profile/share/pljava/*" +# become: yes +# It was decided to leave pljava disabled at https://github.com/supabase/postgres/pull/690 therefore removing this task + +- name: Create symbolic links from /home/postgres/.nix-profile/bin to /usr/bin + file: + src: "/home/postgres/.nix-profile/bin/psql" + dest: "/usr/bin/psql" + state: link + become: yes + +- name: Create symbolic links from /home/postgres/.nix-profile/share/postgresql to /usr/lib/postgresql/share/postgresql + file: + src: "{{ item }}" + dest: "/usr/lib/postgresql/share/postgresql/{{ item | basename }}" + state: link + with_fileglob: + - "/home/postgres/.nix-profile/share/postgresql/*" + become: yes + +- name: Create symbolic links from /home/postgres/.nix-profile/share/postgresql/extension to /usr/lib/postgresql/share/postgresql/extension + file: + src: "{{ item }}" + dest: "/usr/lib/postgresql/share/postgresql/extension/{{ item | basename }}" + state: link + with_fileglob: + - "/home/postgres/.nix-profile/share/postgresql/extension/*" + become: yes + +- name: create destination directory + file: + path: /usr/lib/postgresql/share/postgresql/contrib/ + state: directory + recurse: yes + +- name: Recursively create symbolic links and set permissions for the contrib/postgis-* dir + shell: > + sudo mkdir -p /usr/lib/postgresql/share/postgresql/contrib && \ + sudo find /home/postgres/.nix-profile/share/postgresql/contrib/ -mindepth 1 -type d -exec sh -c 'for dir do sudo ln -s "$dir" "/usr/lib/postgresql/share/postgresql/contrib/$(basename "$dir")"; done' sh {} + \ + && chown -R postgres:postgres "/usr/lib/postgresql/share/postgresql/contrib/" + become: yes + +- name: Create symbolic links from /home/postgres/.nix-profile/share/postgresql/timezonesets to /usr/lib/postgresql/share/postgresql/timeszonesets + file: + src: "{{ item }}" + dest: "/usr/lib/postgresql/share/postgresql/timezonesets/{{ item | basename }}" + state: link + with_fileglob: + - "/home/postgres/.nix-profile/share/postgresql/timezonesets/*" + become: yes + +- name: Create symbolic links from /home/postgres/.nix-profile/share/postgresql/tsearch_data to /usr/lib/postgresql/share/postgresql/tsearch_data + file: + src: "{{ item }}" + dest: "/usr/lib/postgresql/share/postgresql/tsearch_data/{{ item | basename }}" + state: link + with_fileglob: + - "/home/postgres/.nix-profile/share/postgresql/tsearch_data/*" + become: yes + + +#Install configure before init +- name: Install Postgres extensions + import_tasks: setup-extensions.yml + +- name: Link database data_dir to data volume directory + file: + src: "/data/pgdata" + path: "/var/lib/postgresql/data" + state: link + force: yes + owner: postgres + group: postgres + +- name: Initialize the database + become: yes + become_user: postgres + shell: source /home/postgres/.bashrc && /usr/lib/postgresql/bin/pg_ctl -D /var/lib/postgresql/data initdb -o "--allow-group-access" + args: + executable: /bin/bash + environment: + LANG: en_US.UTF-8 + LANGUAGE: en_US.UTF-8 + LC_ALL: en_US.UTF-8 + LC_CTYPE: en_US.UTF-8 + LOCALE_ARCHIVE: /usr/lib/locale/locale-archive + vars: + ansible_command_timeout: 60 + # Circumvents the following error: + # "Timeout (12s) waiting for privilege escalation prompt" + +- name: copy PG systemd unit + template: + src: /tmp/ansible-playbook/files/postgresql_config/postgresql.service.j2 + dest: /etc/systemd/system/postgresql.service + +- name: copy optimizations systemd unit + template: + src: /tmp/ansible-playbook/files/database-optimizations.service.j2 + dest: /etc/systemd/system/database-optimizations.service + +- name: Restart Postgres Database without Systemd + become: yes + become_user: postgres + shell: | + source /home/postgres/.bashrc + /usr/lib/postgresql/bin/pg_ctl -D /var/lib/postgresql/data start + environment: + LANG: en_US.UTF-8 + LANGUAGE: en_US.UTF-8 + LC_ALL: en_US.UTF-8 + LC_CTYPE: en_US.UTF-8 + LOCALE_ARCHIVE: /usr/lib/locale/locale-archive + +- name: Execute init SQL files + become: yes + become_user: postgres + shell: + cmd: /usr/lib/postgresql/bin/psql -f {{ item }} + loop: "{{ sql_files }}" + +- name: Delete SQL scripts + file: + path: "{{ item }}" + state: absent + loop: "{{ sql_files }}" + +- name: Restart Postgres Database without Systemd + become: yes + become_user: postgres + shell: | + source /home/postgres/.bashrc && \ + /usr/lib/postgresql/bin/pg_ctl -D /var/lib/postgresql/data restart -o "-c shared_preload_libraries='pg_tle'" + args: + executable: /bin/bash + environment: + LANG: en_US.UTF-8 + LANGUAGE: en_US.UTF-8 + LC_ALL: en_US.UTF-8 + LC_CTYPE: en_US.UTF-8 + LOCALE_ARCHIVE: /usr/lib/locale/locale-archive + +- name: Run migrations + import_tasks: setup-migrations.yml + tags: + - migrations + + +# # # Reload +- name: System - systemd reload + systemd: + enabled: yes + name: postgresql + daemon_reload: yes + +- name: Stop Postgres with systemd + systemd: + state: stopped + name: postgresql + + +- name: Stop Postgres Database without systemd + become: yes + become_user: postgres + shell: + cmd: /usr/lib/postgresql/bin/pg_ctl -D /var/lib/postgresql/data stop diff --git a/ansible-nix/tasks/stage2/test-image.yml b/ansible-nix/tasks/stage2/test-image.yml new file mode 100644 index 000000000..bc46efd44 --- /dev/null +++ b/ansible-nix/tasks/stage2/test-image.yml @@ -0,0 +1,104 @@ +- name: Temporarily disable PG Sodium references in config + become: yes + become_user: postgres + shell: + cmd: sed -i.bak -e "s/pg_net,\ pgsodium,\ timescaledb/pg_net,\ timescaledb/g" -e "s/pgsodium.getkey_script=/#pgsodium.getkey_script=/g" /etc/postgresql/postgresql.conf + +- name: Start Postgres Database to load all extensions. + become: yes + become_user: postgres + shell: source /home/postgres/.bashrc && /usr/lib/postgresql/bin/pg_ctl -D /var/lib/postgresql/data start "-o -c config_file=/etc/postgresql/postgresql.conf" + args: + executable: /bin/bash + environment: + LANG: en_US.UTF-8 + LANGUAGE: en_US.UTF-8 + LC_ALL: en_US.UTF-8 + LC_CTYPE: en_US.UTF-8 + LOCALE_ARCHIVE: /usr/lib/locale/locale-archive + + +- name: check contents of unit test file + become: yes + become_user: postgres + shell: cat /home/postgres/unit-test-01.sql && ls -l /home/postgres/unit-test-01.sql + +- name: verify postgres server is running + become: yes + become_user: postgres + shell: psql -U postgres -h localhost -c "SELECT version();" + register: pg_isready + failed_when: pg_isready.rc != 0 + args: + executable: /bin/bash + environment: + LANG: en_US.UTF-8 + LANGUAGE: en_US.UTF-8 + LC_ALL: en_US.UTF-8 + LC_CTYPE: en_US.UTF-8 + LOCALE_ARCHIVE: /usr/lib/locale/locale-archive + PATH: /home/postgres/.nix-profile/bin:$PATH + +- name: Run Unit tests (with filename unit-test-*) on Postgres Database + become: yes + become_user: postgres + shell: source /home/postgres/.bashrc && /home/postgres/.nix-profile/bin/pg_prove -U postgres -h localhost -d postgres -f /home/postgres/unit-test-01.sql + register: retval + failed_when: retval.rc != 0 + args: + executable: /bin/bash + environment: + LANG: en_US.UTF-8 + LANGUAGE: en_US.UTF-8 + LC_ALL: en_US.UTF-8 + LC_CTYPE: en_US.UTF-8 + LOCALE_ARCHIVE: /usr/lib/locale/locale-archive + PATH: /home/postgres/.nix-profile/bin:$PATH + +- name: Run migrations tests + shell: /home/postgres/.nix-profile/bin/pg_prove -U supabase_admin -h localhost -d postgres -v tests/test.sql + register: retval + failed_when: retval.rc != 0 + args: + executable: /bin/bash + chdir: /tmp/migrations + environment: + LANG: en_US.UTF-8 + LANGUAGE: en_US.UTF-8 + LC_ALL: en_US.UTF-8 + LC_CTYPE: en_US.UTF-8 + LOCALE_ARCHIVE: /usr/lib/locale/locale-archive + PATH: /home/postgres/.nix-profile/bin:$PATH + +- name: Re-enable PG Sodium references in config + become: yes + become_user: postgres + shell: + cmd: mv /etc/postgresql/postgresql.conf.bak /etc/postgresql/postgresql.conf + +- name: Reset db stats + become: yes + become_user: postgres + shell: | + source /home/postgres/.bashrc && \ + /usr/lib/postgresql/bin/psql --no-password --no-psqlrc -d postgres -h localhost -U supabase_admin -c 'SELECT pg_stat_statements_reset(); SELECT pg_stat_reset();' + args: + executable: /bin/bash + environment: + LANG: en_US.UTF-8 + LANGUAGE: en_US.UTF-8 + LC_ALL: en_US.UTF-8 + LC_CTYPE: en_US.UTF-8 + LOCALE_ARCHIVE: /usr/lib/locale/locale-archive + +# - name: remove pg_prove +- name: Remove pg_prove + become: yes + shell: | + sudo -u postgres bash -c ". /nix/var/nix/profiles/default/etc/profile.d/nix-daemon.sh && nix profile remove pg_prove" + +- name: Stop Postgres Database + become: yes + become_user: postgres + shell: + cmd: /usr/lib/postgresql/bin/pg_ctl -D /var/lib/postgresql/data stop diff --git a/common-nix.vars.pkr.hcl b/common-nix.vars.pkr.hcl new file mode 100644 index 000000000..4508be3d3 --- /dev/null +++ b/common-nix.vars.pkr.hcl @@ -0,0 +1 @@ +postgres-version = "15.6.1.68-nix-staged" diff --git a/ebssurrogate/scripts/chroot-bootstrap-nix.sh b/ebssurrogate/scripts/chroot-bootstrap-nix.sh new file mode 100755 index 000000000..cda6bd2aa --- /dev/null +++ b/ebssurrogate/scripts/chroot-bootstrap-nix.sh @@ -0,0 +1,219 @@ +#!/usr/bin/env bash +# +# This script runs inside chrooted environment. It installs grub and its +# Configuration file. +# + +set -o errexit +set -o pipefail +set -o xtrace + +export DEBIAN_FRONTEND=noninteractive + +export APT_OPTIONS="-oAPT::Install-Recommends=false \ + -oAPT::Install-Suggests=false \ + -oAcquire::Languages=none" + +if [ $(dpkg --print-architecture) = "amd64" ]; +then + ARCH="amd64"; +else + ARCH="arm64"; +fi + + + +function update_install_packages { + source /etc/os-release + + # Update APT with new sources + cat /etc/apt/sources.list + apt-get $APT_OPTIONS update && apt-get $APT_OPTIONS --yes dist-upgrade + + # Do not configure grub during package install + if [ "${ARCH}" = "amd64" ]; then + echo 'grub-pc grub-pc/install_devices_empty select true' | debconf-set-selections + echo 'grub-pc grub-pc/install_devices select' | debconf-set-selections + # Install various packages needed for a booting system + apt-get install -y \ + linux-aws \ + grub-pc \ + e2fsprogs + else + apt-get install -y e2fsprogs + fi + # Install standard packages + apt-get install -y \ + sudo \ + wget \ + cloud-init \ + acpid \ + ec2-hibinit-agent \ + ec2-instance-connect \ + hibagent \ + ncurses-term \ + ssh-import-id \ + + # apt upgrade + apt-get upgrade -y + + # Install OpenSSH and other packages + sudo add-apt-repository universe + apt-get update + apt-get install -y --no-install-recommends \ + openssh-server \ + git \ + ufw \ + cron \ + logrotate \ + fail2ban \ + locales \ + at \ + less \ + python3-systemd + + if [ "${ARCH}" = "arm64" ]; then + apt-get $APT_OPTIONS --yes install linux-aws initramfs-tools dosfstools + fi +} + +function setup_locale { +cat << EOF >> /etc/locale.gen +en_US.UTF-8 UTF-8 +EOF + +cat << EOF > /etc/default/locale +LANG="C.UTF-8" +LC_CTYPE="C.UTF-8" +EOF + locale-gen en_US.UTF-8 +} + +function setup_postgesql_env { + # Create the directory if it doesn't exist + sudo mkdir -p /etc/environment.d + + # Define the contents of the PostgreSQL environment file + cat </dev/null +LOCALE_ARCHIVE=/usr/lib/locale/locale-archive +LANG="en_US.UTF-8" +LANGUAGE="en_US.UTF-8" +LC_ALL="en_US.UTF-8" +LC_CTYPE="en_US.UTF-8" +EOF +} + +function install_packages_for_build { + apt-get install -y --no-install-recommends linux-libc-dev \ + acl \ + magic-wormhole sysstat \ + build-essential libreadline-dev zlib1g-dev flex bison libxml2-dev libxslt-dev libssl-dev libsystemd-dev libpq-dev libxml2-utils uuid-dev xsltproc ssl-cert \ + gcc-10 g++-10 \ + libgeos-dev libproj-dev libgdal-dev libjson-c-dev libboost-all-dev libcgal-dev libmpfr-dev libgmp-dev cmake \ + libkrb5-dev \ + maven default-jre default-jdk \ + curl gpp apt-transport-https cmake libc++-dev libc++abi-dev libc++1 libglib2.0-dev libtinfo5 libc++abi1 ninja-build python \ + liblzo2-dev + + source /etc/os-release + + apt-get install -y --no-install-recommends llvm-11-dev clang-11 + # Mark llvm as manual to prevent auto removal + apt-mark manual libllvm11:arm64 +} + +function setup_apparmor { + apt-get install -y apparmor apparmor-utils auditd + + # Copy apparmor profiles + cp -rv /tmp/apparmor_profiles/* /etc/apparmor.d/ +} + +function setup_grub_conf_arm64 { +cat << EOF > /etc/default/grub +GRUB_DEFAULT=0 +GRUB_TIMEOUT=0 +GRUB_TIMEOUT_STYLE="hidden" +GRUB_DISTRIBUTOR="Supabase postgresql" +GRUB_CMDLINE_LINUX_DEFAULT="nomodeset console=tty1 console=ttyS0 ipv6.disable=0" +EOF +} + +# Install GRUB +function install_configure_grub { + if [ "${ARCH}" = "arm64" ]; then + apt-get $APT_OPTIONS --yes install cloud-guest-utils fdisk grub-efi-arm64 efibootmgr + setup_grub_conf_arm64 + rm -rf /etc/grub.d/30_os-prober + sleep 1 + fi + grub-install /dev/xvdf && update-grub +} + +# skip fsck for first boot +function disable_fsck { + touch /fastboot +} + +# Don't request hostname during boot but set hostname +function setup_hostname { + sed -i 's/gethostname()/ubuntu /g' /etc/dhcp/dhclient.conf + sed -i 's/host-name,//g' /etc/dhcp/dhclient.conf + echo "ubuntu" > /etc/hostname + chmod 644 /etc/hostname +} + +# Set options for the default interface +function setup_eth0_interface { +cat << EOF > /etc/netplan/eth0.yaml +network: + version: 2 + ethernets: + eth0: + dhcp4: true +EOF +} + +function disable_sshd_passwd_auth { + sed -i -E -e 's/^#?\s*PasswordAuthentication\s+(yes|no)\s*$/PasswordAuthentication no/g' \ + -e 's/^#?\s*ChallengeResponseAuthentication\s+(yes|no)\s*$/ChallengeResponseAuthentication no/g' \ + /etc/ssh/sshd_config +} + +function create_admin_account { + groupadd admin +} + +#Set default target as multi-user +function set_default_target { + rm -f /etc/systemd/system/default.target + ln -s /lib/systemd/system/multi-user.target /etc/systemd/system/default.target +} + +# Setup ccache +function setup_ccache { + apt-get install ccache -y + mkdir -p /tmp/ccache + export PATH=/usr/lib/ccache:$PATH + echo "PATH=$PATH" >> /etc/environment +} + +# Clear apt caches +function cleanup_cache { + apt-get clean +} + +update_install_packages +setup_locale +setup_postgesql_env +#install_packages_for_build +install_configure_grub +setup_apparmor +setup_hostname +create_admin_account +set_default_target +setup_eth0_interface +disable_sshd_passwd_auth +disable_fsck +#setup_ccache +cleanup_cache diff --git a/ebssurrogate/scripts/surrogate-bootstrap-nix.sh b/ebssurrogate/scripts/surrogate-bootstrap-nix.sh new file mode 100755 index 000000000..0daa6e517 --- /dev/null +++ b/ebssurrogate/scripts/surrogate-bootstrap-nix.sh @@ -0,0 +1,324 @@ +#!/usr/bin/env bash +# +# This script creates filesystem and setups up chrooted +# enviroment for further processing. It also runs +# ansible playbook and finally does system cleanup. +# +# Adapted from: https://github.com/jen20/packer-ubuntu-zfs + +set -o errexit +set -o pipefail +set -o xtrace + +if [ $(dpkg --print-architecture) = "amd64" ]; +then + ARCH="amd64"; +else + ARCH="arm64"; +fi + +function waitfor_boot_finished { + export DEBIAN_FRONTEND=noninteractive + + echo "args: ${ARGS}" + # Wait for cloudinit on the surrogate to complete before making progress + while [[ ! -f /var/lib/cloud/instance/boot-finished ]]; do + echo 'Waiting for cloud-init...' + sleep 1 + done +} + +function install_packages { + # Setup Ansible on host VM + apt-get update && sudo apt-get install software-properties-common -y + add-apt-repository --yes --update ppa:ansible/ansible && sudo apt-get install ansible -y + ansible-galaxy collection install community.general + + # Update apt and install required packages + apt-get update + apt-get install -y \ + gdisk \ + e2fsprogs \ + debootstrap \ + nvme-cli +} + +# Partition the new root EBS volume +function create_partition_table { + + if [ "${ARCH}" = "arm64" ]; then + parted --script /dev/xvdf \ + mklabel gpt \ + mkpart UEFI 1MiB 100MiB \ + mkpart ROOT 100MiB 100% + set 1 esp on \ + set 1 boot on + parted --script /dev/xvdf print + else + sgdisk -Zg -n1:0:4095 -t1:EF02 -c1:GRUB -n2:0:0 -t2:8300 -c2:EXT4 /dev/xvdf + fi + + sleep 2 +} + +function device_partition_mappings { + # NVMe EBS launch device mappings (symlinks): /dev/nvme*n* to /dev/xvd* + declare -A blkdev_mappings + for blkdev in $(nvme list | awk '/^\/dev/ { print $1 }'); do # /dev/nvme*n* + # Mapping info from disk headers + header=$(nvme id-ctrl --raw-binary "${blkdev}" | cut -c3073-3104 | tr -s ' ' | sed 's/ $//g' | sed 's!/dev/!!') + mapping="/dev/${header%%[0-9]}" # normalize sda1 => sda + + # Create /dev/xvd* device symlink + if [[ ! -z "$mapping" ]] && [[ -b "${blkdev}" ]] && [[ ! -L "${mapping}" ]]; then + ln -s "$blkdev" "$mapping" + + blkdev_mappings["$blkdev"]="$mapping" + fi + done + + create_partition_table + + # NVMe EBS launch device partition mappings (symlinks): /dev/nvme*n*p* to /dev/xvd*[0-9]+ + declare -A partdev_mappings + for blkdev in "${!blkdev_mappings[@]}"; do # /dev/nvme*n* + mapping="${blkdev_mappings[$blkdev]}" + + # Create /dev/xvd*[0-9]+ partition device symlink + for partdev in "${blkdev}"p*; do + partnum=${partdev##*p} + if [[ ! -L "${mapping}${partnum}" ]]; then + ln -s "${blkdev}p${partnum}" "${mapping}${partnum}" + + partdev_mappings["${blkdev}p${partnum}"]="${mapping}${partnum}" + fi + done + done +} + + +#Download and install latest e2fsprogs for fast_commit feature,if required. +function format_and_mount_rootfs { + mkfs.ext4 -m0.1 /dev/xvdf2 + + mount -o noatime,nodiratime /dev/xvdf2 /mnt + if [ "${ARCH}" = "arm64" ]; then + mkfs.fat -F32 /dev/xvdf1 + mkdir -p /mnt/boot/efi + sleep 2 + mount /dev/xvdf1 /mnt/boot/efi + fi + + mkfs.ext4 /dev/xvdh + mkdir -p /mnt/data + mount -o defaults,discard /dev/xvdh /mnt/data +} + +function create_swapfile { + fallocate -l 1G /mnt/swapfile + chmod 600 /mnt/swapfile + mkswap /mnt/swapfile +} + +function format_build_partition { + mkfs.ext4 -O ^has_journal /dev/xvdc +} +function pull_docker { + apt-get install -y docker.io + docker run -itd --name ccachedata "${DOCKER_IMAGE}:${DOCKER_IMAGE_TAG}" sh + docker exec -itd ccachedata mkdir -p /build/ccache +} + +# Create fstab +function create_fstab { + FMT="%-42s %-11s %-5s %-17s %-5s %s" +cat > "/mnt/etc/fstab" << EOF +$(printf "${FMT}" "# DEVICE UUID" "MOUNTPOINT" "TYPE" "OPTIONS" "DUMP" "FSCK") +$(findmnt -no SOURCE /mnt | xargs blkid -o export | awk -v FMT="${FMT}" '/^UUID=/ { printf(FMT, $0, "/", "ext4", "defaults,discard", "0", "1" ) }') +$(findmnt -no SOURCE /mnt/boot/efi | xargs blkid -o export | awk -v FMT="${FMT}" '/^UUID=/ { printf(FMT, $0, "/boot/efi", "vfat", "umask=0077", "0", "1" ) }') +$(findmnt -no SOURCE /mnt/data | xargs blkid -o export | awk -v FMT="${FMT}" '/^UUID=/ { printf(FMT, $0, "/data", "ext4", "defaults,discard", "0", "2" ) }') +$(printf "$FMT" "/swapfile" "none" "swap" "sw" "0" "0") +EOF + unset FMT +} + +function setup_chroot_environment { + UBUNTU_VERSION=$(lsb_release -cs) # 'focal' for Ubuntu 20.04 + + # Bootstrap Ubuntu into /mnt + debootstrap --arch ${ARCH} --variant=minbase "$UBUNTU_VERSION" /mnt + + # Update ec2-region + REGION=$(curl --silent --fail http://169.254.169.254/latest/meta-data/placement/availability-zone | sed -E 's|[a-z]+$||g') + sed -i "s/REGION/${REGION}/g" /tmp/sources.list + cp /tmp/sources.list /mnt/etc/apt/sources.list + + if [ "${ARCH}" = "arm64" ]; then + create_fstab + fi + + # Create mount points and mount the filesystem + mkdir -p /mnt/{dev,proc,sys} + mount --rbind /dev /mnt/dev + mount --rbind /proc /mnt/proc + mount --rbind /sys /mnt/sys + + # Create build mount point and mount + mkdir -p /mnt/tmp + mount /dev/xvdc /mnt/tmp + chmod 777 /mnt/tmp + + # Copy apparmor profiles + chmod 644 /tmp/apparmor_profiles/* + cp -r /tmp/apparmor_profiles /mnt/tmp/ + + # Copy migrations + cp -r /tmp/migrations /mnt/tmp/ + + # Copy unit tests + cp -r /tmp/unit-tests /mnt/tmp/ + + # Copy the bootstrap script into place and execute inside chroot + cp /tmp/chroot-bootstrap-nix.sh /mnt/tmp/chroot-bootstrap-nix.sh + chroot /mnt /tmp/chroot-bootstrap-nix.sh + rm -f /mnt/tmp/chroot-bootstrap-nix.sh + echo "${POSTGRES_SUPABASE_VERSION}" > /mnt/root/supabase-release + + # Copy the nvme identification script into /sbin inside the chroot + mkdir -p /mnt/sbin + cp /tmp/ebsnvme-id /mnt/sbin/ebsnvme-id + chmod +x /mnt/sbin/ebsnvme-id + + # Copy the udev rules for identifying nvme devices into the chroot + mkdir -p /mnt/etc/udev/rules.d + cp /tmp/70-ec2-nvme-devices.rules \ + /mnt/etc/udev/rules.d/70-ec2-nvme-devices.rules + + #Copy custom cloud-init + rm -f /mnt/etc/cloud/cloud.cfg + cp /tmp/cloud.cfg /mnt/etc/cloud/cloud.cfg + + sleep 2 +} + +function download_ccache { + docker cp ccachedata:/build/ccache/. /mnt/tmp/ccache +} + +function execute_playbook { + +tee /etc/ansible/ansible.cfg <logfile 2>&1 & sleep 2 @@ -551,6 +551,11 @@ nix-update pg_prove shellcheck + ansible + ansible-lint + (packer.overrideAttrs (oldAttrs: { + version = "1.7.8"; + })) basePackages.start-server basePackages.start-client diff --git a/nix/ext/postgis.nix b/nix/ext/postgis.nix index dc9b31e34..e0b6dfbeb 100644 --- a/nix/ext/postgis.nix +++ b/nix/ext/postgis.nix @@ -13,10 +13,12 @@ , libiconv , pcre2 , nixosTests +, callPackage }: let gdal = gdalMinimal; + sfcgal = callPackage ./sfcgal/sfcgal.nix { }; in stdenv.mkDerivation rec { pname = "postgis"; @@ -29,7 +31,7 @@ stdenv.mkDerivation rec { sha256 = "sha256-miohnaAFoXMKOdGVmhx87GGbHvsAm2W+gP/CW60pkGg="; }; - buildInputs = [ libxml2 postgresql geos proj gdal json_c protobufc pcre2.dev ] + buildInputs = [ libxml2 postgresql geos proj gdal json_c protobufc pcre2.dev sfcgal ] ++ lib.optional stdenv.isDarwin libiconv; nativeBuildInputs = [ perl pkg-config ]; dontDisableStatic = true; @@ -40,7 +42,7 @@ stdenv.mkDerivation rec { preConfigure = '' sed -i 's@/usr/bin/file@${file}/bin/file@' configure - configureFlags="--datadir=$out/share/postgresql --datarootdir=$out/share/postgresql --bindir=$out/bin --docdir=$doc/share/doc/${pname} --with-gdalconfig=${gdal}/bin/gdal-config --with-jsondir=${json_c.dev} --disable-extension-upgrades-install" + configureFlags="--datadir=$out/share/postgresql --datarootdir=$out/share/postgresql --bindir=$out/bin --docdir=$doc/share/doc/${pname} --with-gdalconfig=${gdal}/bin/gdal-config --with-jsondir=${json_c.dev} --disable-extension-upgrades-install --with-sfcgal" makeFlags="PERL=${perl}/bin/perl datadir=$out/share/postgresql pkglibdir=$out/lib bindir=$out/bin docdir=$doc/share/doc/${pname}" ''; @@ -79,7 +81,7 @@ stdenv.mkDerivation rec { homepage = "https://postgis.net/"; changelog = "https://git.osgeo.org/gitea/postgis/postgis/raw/tag/${version}/NEWS"; license = licenses.gpl2; - maintainers = with maintainers; teams.geospatial.members ++ [ marcweber wolfgangwalther ]; + maintainers = with maintainers; [ samrose ]; inherit (postgresql.meta) platforms; }; } diff --git a/nix/ext/sfcgal/sfcgal.nix b/nix/ext/sfcgal/sfcgal.nix new file mode 100644 index 000000000..54d7b52cb --- /dev/null +++ b/nix/ext/sfcgal/sfcgal.nix @@ -0,0 +1,31 @@ +{ lib, stdenv, fetchFromGitLab, cgal, cmake, pkg-config, gmp, mpfr, boost }: + +stdenv.mkDerivation rec { + pname = "sfcgal"; + version = "61f3b08ade49493b56c6bafa98c7c1f84addbc10"; + + src = fetchFromGitLab { + owner = "sfcgal"; + repo = "SFCGAL"; + rev = "${version}"; + hash = "sha256-nKSqiFyMkZAYptIeShb1zFg9lYSny3kcGJfxdeTFqxw="; + }; + + nativeBuildInputs = [ cmake pkg-config cgal gmp mpfr boost ]; + + cmakeFlags = [ "-DCGAL_DIR=${cgal}" "-DCMAKE_PREFIX_PATH=${cgal}" ]; + + + postPatch = '' + substituteInPlace sfcgal.pc.in \ + --replace '$'{prefix}/@CMAKE_INSTALL_LIBDIR@ @CMAKE_INSTALL_FULL_LIBDIR@ + ''; + + meta = with lib; { + description = "A wrapper around CGAL that intents to implement 2D and 3D operations on OGC standards models"; + homepage = "https://sfcgal.gitlab.io/SFCGAL/"; + license = with licenses; [ gpl3Plus lgpl3Plus]; + platforms = platforms.all; + maintainers = with maintainers; [ samrose ]; + }; +} diff --git a/nix/overlays/postgis.nix b/nix/overlays/postgis.nix deleted file mode 100644 index 8d022f564..000000000 --- a/nix/overlays/postgis.nix +++ /dev/null @@ -1,7 +0,0 @@ -final: prev: { - postgis = prev.postgresqlPackages.postgis.overrideAttrs (old: { - version = "3.3.2"; - sha256 = ""; - }); - postgresqlPackages.postgis = final.postgis; -} diff --git a/nix/tests/postgresql.conf.in b/nix/tests/postgresql.conf.in index 22d1b93fc..4c5075aa1 100644 --- a/nix/tests/postgresql.conf.in +++ b/nix/tests/postgresql.conf.in @@ -793,4 +793,3 @@ shared_preload_libraries = 'auto_explain,pgsodium' # Add settings for extensions here pgsodium.getkey_script = '@PGSODIUM_GETKEY_SCRIPT@' -pljava.libjvm_location = '@PLJAVA_LIBJVM_LOCATION@' diff --git a/nix/tests/prime.sql b/nix/tests/prime.sql index 5a0e88f58..084ad3b52 100644 --- a/nix/tests/prime.sql +++ b/nix/tests/prime.sql @@ -20,4 +20,3 @@ CREATE EXTENSION IF NOT EXISTS pg_graphql; CREATE EXTENSION IF NOT EXISTS pg_jsonschema; CREATE EXTENSION IF NOT EXISTS hypopg; CREATE EXTENSION IF NOT EXISTS index_advisor; -CREATE EXTENSION IF NOT EXISTS pljava; diff --git a/scripts/nix-provision.sh b/scripts/nix-provision.sh new file mode 100644 index 000000000..1b7804e78 --- /dev/null +++ b/scripts/nix-provision.sh @@ -0,0 +1,43 @@ +#!/usr/bin/env bash +# shellcheck shell=bash + +set -o errexit +set -o pipefail +set -o xtrace + +function install_packages { + # Setup Ansible on host VM + sudo apt-get update && sudo apt-get install software-properties-common -y + sudo add-apt-repository --yes --update ppa:ansible/ansible && sudo apt-get install ansible -y + ansible-galaxy collection install community.general + +} + + + +function install_nix() { + sudo su -c "curl --proto '=https' --tlsv1.2 -sSf -L https://install.determinate.systems/nix | sh -s -- install --no-confirm \ + --extra-conf \"substituters = https://cache.nixos.org https://nix-postgres-artifacts.s3.amazonaws.com\" \ + --extra-conf \"trusted-public-keys = nix-postgres-artifacts:dGZlQOvKcNEjvT7QEAJbcV6b6uk7VF/hWMjhYleiaLI=% cache.nixos.org-1:6NCHdD59X431o0gWypbMrAURkbJ16ZPMQFGspcDShjY=\" " -s /bin/bash root + . /nix/var/nix/profiles/default/etc/profile.d/nix-daemon.sh + +} + + +function execute_stage2_playbook { + +sudo tee /etc/ansible/ansible.cfg < Date: Mon, 24 Jun 2024 13:39:18 -0400 Subject: [PATCH 02/45] chore: version bump --- common-nix.vars.pkr.hcl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common-nix.vars.pkr.hcl b/common-nix.vars.pkr.hcl index 4508be3d3..e2819d5da 100644 --- a/common-nix.vars.pkr.hcl +++ b/common-nix.vars.pkr.hcl @@ -1 +1 @@ -postgres-version = "15.6.1.68-nix-staged" +postgres-version = "15.6.1.69-nix-staged" From 12ab01468c7ea3c41f32ef25de5c7b07aca7e8ee Mon Sep 17 00:00:00 2001 From: samrose Date: Mon, 24 Jun 2024 13:41:49 -0400 Subject: [PATCH 03/45] chore: remap branch for ami build --- .github/workflows/ami-release-nix.yml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.github/workflows/ami-release-nix.yml b/.github/workflows/ami-release-nix.yml index abc119bbc..faceb88cd 100644 --- a/.github/workflows/ami-release-nix.yml +++ b/.github/workflows/ami-release-nix.yml @@ -3,8 +3,7 @@ name: Release AMI Nix on: push: branches: - - sam/2-stage-ami-nix - paths: + - sam/nix-and-conventional-ami - '.github/workflows/ami-release-nix.yml' - 'common-nix.vars.pkr.hcl' workflow_dispatch: From 91ec53b012c6e412cc7c4bcd718e3bd9eb5354f7 Mon Sep 17 00:00:00 2001 From: samrose Date: Mon, 24 Jun 2024 13:55:57 -0400 Subject: [PATCH 04/45] chore: bump version --- amazon-arm64-nix.pkr.hcl | 2 +- common-nix.vars.pkr.hcl | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/amazon-arm64-nix.pkr.hcl b/amazon-arm64-nix.pkr.hcl index 0fcf6a4ac..2231afe8b 100644 --- a/amazon-arm64-nix.pkr.hcl +++ b/amazon-arm64-nix.pkr.hcl @@ -250,7 +250,7 @@ build { provisioner "file" { source = "ansible/vars.yml" - destination = "/tmp/ansible-playbook/vars.yml" + destination = "/tmp/ansible-playbook" } provisioner "shell" { diff --git a/common-nix.vars.pkr.hcl b/common-nix.vars.pkr.hcl index e2819d5da..a163719ba 100644 --- a/common-nix.vars.pkr.hcl +++ b/common-nix.vars.pkr.hcl @@ -1 +1 @@ -postgres-version = "15.6.1.69-nix-staged" +postgres-version = "15.6.1.70-nix-staged" From e014e2249b4f0b9a965d670918759c4bda82a6b8 Mon Sep 17 00:00:00 2001 From: samrose Date: Mon, 24 Jun 2024 14:00:23 -0400 Subject: [PATCH 05/45] chore: bump version to trigger build --- amazon-arm64-nix.pkr.hcl | 2 +- common-nix.vars.pkr.hcl | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/amazon-arm64-nix.pkr.hcl b/amazon-arm64-nix.pkr.hcl index 2231afe8b..88b50ced8 100644 --- a/amazon-arm64-nix.pkr.hcl +++ b/amazon-arm64-nix.pkr.hcl @@ -250,7 +250,7 @@ build { provisioner "file" { source = "ansible/vars.yml" - destination = "/tmp/ansible-playbook" + destination = "/tmp/ansible-playbook/ansible-nix/vars.yml" } provisioner "shell" { diff --git a/common-nix.vars.pkr.hcl b/common-nix.vars.pkr.hcl index a163719ba..85f34a924 100644 --- a/common-nix.vars.pkr.hcl +++ b/common-nix.vars.pkr.hcl @@ -1 +1 @@ -postgres-version = "15.6.1.70-nix-staged" +postgres-version = "15.6.1.71-nix-staged" From 5c6d7771ad232fd495eb627000c891b837eb9f63 Mon Sep 17 00:00:00 2001 From: samrose Date: Mon, 24 Jun 2024 16:10:31 -0400 Subject: [PATCH 06/45] feat: use /var/lib/postgresql as home for postgres user --- ansible-nix/tasks/setup-postgres.yml | 7 ++-- ansible-nix/tasks/setup-wal-g.yml | 2 +- ansible-nix/tasks/stage2/playbook.yml | 2 +- ansible-nix/tasks/stage2/setup-extensions.yml | 2 +- .../tasks/stage2/stage2-setup-postgres.yml | 40 +++++++++---------- ansible-nix/tasks/stage2/test-image.yml | 16 ++++---- common-nix.vars.pkr.hcl | 2 +- 7 files changed, 35 insertions(+), 36 deletions(-) diff --git a/ansible-nix/tasks/setup-postgres.yml b/ansible-nix/tasks/setup-postgres.yml index 0644f10dc..49d33f9c8 100644 --- a/ansible-nix/tasks/setup-postgres.yml +++ b/ansible-nix/tasks/setup-postgres.yml @@ -12,7 +12,7 @@ state: present - name: create postgres user - shell: useradd -m -r -s /bin/bash -d /home/postgres postgres -g postgres + shell: adduser --system --home /var/lib/postgresql --no-create-home --shell /bin/bash --group --gecos "PostgreSQL administrator" postgres args: executable: /bin/bash become: yes @@ -31,7 +31,6 @@ owner: postgres group: postgres with_items: - - '/home/postgres' - '/var/log/postgresql' - '/var/lib/postgresql' @@ -63,7 +62,7 @@ - name: Add LOCALE_ARCHIVE to .bashrc lineinfile: - dest: "/home/postgres/.bashrc" + dest: "/var/lib/postgressql/.bashrc" line: 'export LOCALE_ARCHIVE=/usr/lib/locale/locale-archive' create: yes become: yes @@ -71,7 +70,7 @@ - name: Add LANG items to .bashrc lineinfile: - dest: "/home/postgres/.bashrc" + dest: "/var/lib/postgresql/.bashrc" line: "{{ item }}" loop: diff --git a/ansible-nix/tasks/setup-wal-g.yml b/ansible-nix/tasks/setup-wal-g.yml index bbc64cdde..a36b77a6d 100644 --- a/ansible-nix/tasks/setup-wal-g.yml +++ b/ansible-nix/tasks/setup-wal-g.yml @@ -103,7 +103,7 @@ - name: Add script to be run for restore_command template: src: "files/walg_helper_scripts/wal_fetch.sh" - dest: /home/postgres/wal_fetch.sh + dest: /var/lib/postgresql/wal_fetch.sh mode: 0500 owner: postgres group: postgres diff --git a/ansible-nix/tasks/stage2/playbook.yml b/ansible-nix/tasks/stage2/playbook.yml index aa27602ec..022e8e9b4 100644 --- a/ansible-nix/tasks/stage2/playbook.yml +++ b/ansible-nix/tasks/stage2/playbook.yml @@ -19,7 +19,7 @@ - name: stat unit test file copy copy: src: /tmp/unit-tests/unit-test-01.sql - dest: /home/postgres/unit-test-01.sql + dest: /var/lib/postgresql/unit-test-01.sql # state: present owner: postgres group: postgres diff --git a/ansible-nix/tasks/stage2/setup-extensions.yml b/ansible-nix/tasks/stage2/setup-extensions.yml index 3f13d12e6..6cc1038f7 100644 --- a/ansible-nix/tasks/stage2/setup-extensions.yml +++ b/ansible-nix/tasks/stage2/setup-extensions.yml @@ -3,7 +3,7 @@ # lineinfile: # path: /etc/postgresql/postgresql.conf # state: present -# line: pljava.libjvm_location = '/home/postgres/.nix-profile/lib/openjdk/lib/server/libjvm.so' +# line: pljava.libjvm_location = '/var/lib/postgresql/.nix-profile/lib/openjdk/lib/server/libjvm.so' # It was decided to leave pljava disabled at https://github.com/supabase/postgres/pull/690 therefore removing this task - name: pg_cron - set cron.database_name diff --git a/ansible-nix/tasks/stage2/stage2-setup-postgres.yml b/ansible-nix/tasks/stage2/stage2-setup-postgres.yml index 3bc0fa91a..3ebd743fd 100644 --- a/ansible-nix/tasks/stage2/stage2-setup-postgres.yml +++ b/ansible-nix/tasks/stage2/stage2-setup-postgres.yml @@ -89,55 +89,55 @@ group: postgres mode: 0700 -- name: Create symbolic links from /home/postgres/.nix-profile/bin to /usr/lib/postgresql/bin +- name: Create symbolic links from /var/lib/postgresql/.nix-profile/bin to /usr/lib/postgresql/bin file: src: "{{ item }}" dest: "/usr/lib/postgresql/bin/{{ item | basename }}" state: link with_fileglob: - - "/home/postgres/.nix-profile/bin/*" + - "/var/lib/postgresql/.nix-profile/bin/*" become: yes -- name: Create symbolic links from /home/postgres/.nix-profile/bin to /usr/bin +- name: Create symbolic links from /var/lib/postgresql/.nix-profile/bin to /usr/bin file: - src: "/home/postgres/.nix-profile/bin/psql" + src: "/var/lib/postgresql/.nix-profile/bin/psql" dest: "/usr/bin/psql" state: link become: yes -# - name: Create symbolic links from /home/postgres/.nix-profile/share/pljava to /usr/lib/postgresql/share/postgresql/pljava +# - name: Create symbolic links from /var/lib/postgresql/.nix-profile/share/pljava to /usr/lib/postgresql/share/postgresql/pljava # file: # src: "{{ item }}" # dest: "/usr/lib/postgresql/share/postgresql/pljava/{{ item | basename }}" # state: link # with_fileglob: -# - "/home/postgres/.nix-profile/share/pljava/*" +# - "/var/lib/postgresql/.nix-profile/share/pljava/*" # become: yes # It was decided to leave pljava disabled at https://github.com/supabase/postgres/pull/690 therefore removing this task -- name: Create symbolic links from /home/postgres/.nix-profile/bin to /usr/bin +- name: Create symbolic links from /var/lib/postgresql/.nix-profile/bin to /usr/bin file: - src: "/home/postgres/.nix-profile/bin/psql" + src: "/var/lib/postgresql/.nix-profile/bin/psql" dest: "/usr/bin/psql" state: link become: yes -- name: Create symbolic links from /home/postgres/.nix-profile/share/postgresql to /usr/lib/postgresql/share/postgresql +- name: Create symbolic links from /var/lib/postgresql/.nix-profile/share/postgresql to /usr/lib/postgresql/share/postgresql file: src: "{{ item }}" dest: "/usr/lib/postgresql/share/postgresql/{{ item | basename }}" state: link with_fileglob: - - "/home/postgres/.nix-profile/share/postgresql/*" + - "/var/lib/postgresql/.nix-profile/share/postgresql/*" become: yes -- name: Create symbolic links from /home/postgres/.nix-profile/share/postgresql/extension to /usr/lib/postgresql/share/postgresql/extension +- name: Create symbolic links from /var/lib/postgresql/.nix-profile/share/postgresql/extension to /usr/lib/postgresql/share/postgresql/extension file: src: "{{ item }}" dest: "/usr/lib/postgresql/share/postgresql/extension/{{ item | basename }}" state: link with_fileglob: - - "/home/postgres/.nix-profile/share/postgresql/extension/*" + - "/var/lib/postgresql/.nix-profile/share/postgresql/extension/*" become: yes - name: create destination directory @@ -149,26 +149,26 @@ - name: Recursively create symbolic links and set permissions for the contrib/postgis-* dir shell: > sudo mkdir -p /usr/lib/postgresql/share/postgresql/contrib && \ - sudo find /home/postgres/.nix-profile/share/postgresql/contrib/ -mindepth 1 -type d -exec sh -c 'for dir do sudo ln -s "$dir" "/usr/lib/postgresql/share/postgresql/contrib/$(basename "$dir")"; done' sh {} + \ + sudo find /var/lib/postgresql/.nix-profile/share/postgresql/contrib/ -mindepth 1 -type d -exec sh -c 'for dir do sudo ln -s "$dir" "/usr/lib/postgresql/share/postgresql/contrib/$(basename "$dir")"; done' sh {} + \ && chown -R postgres:postgres "/usr/lib/postgresql/share/postgresql/contrib/" become: yes -- name: Create symbolic links from /home/postgres/.nix-profile/share/postgresql/timezonesets to /usr/lib/postgresql/share/postgresql/timeszonesets +- name: Create symbolic links from /var/lib/postgresql/.nix-profile/share/postgresql/timezonesets to /usr/lib/postgresql/share/postgresql/timeszonesets file: src: "{{ item }}" dest: "/usr/lib/postgresql/share/postgresql/timezonesets/{{ item | basename }}" state: link with_fileglob: - - "/home/postgres/.nix-profile/share/postgresql/timezonesets/*" + - "/var/lib/postgresql/.nix-profile/share/postgresql/timezonesets/*" become: yes -- name: Create symbolic links from /home/postgres/.nix-profile/share/postgresql/tsearch_data to /usr/lib/postgresql/share/postgresql/tsearch_data +- name: Create symbolic links from /var/lib/postgresql/.nix-profile/share/postgresql/tsearch_data to /usr/lib/postgresql/share/postgresql/tsearch_data file: src: "{{ item }}" dest: "/usr/lib/postgresql/share/postgresql/tsearch_data/{{ item | basename }}" state: link with_fileglob: - - "/home/postgres/.nix-profile/share/postgresql/tsearch_data/*" + - "/var/lib/postgresql/.nix-profile/share/postgresql/tsearch_data/*" become: yes @@ -188,7 +188,7 @@ - name: Initialize the database become: yes become_user: postgres - shell: source /home/postgres/.bashrc && /usr/lib/postgresql/bin/pg_ctl -D /var/lib/postgresql/data initdb -o "--allow-group-access" + shell: source /var/lib/postgresql/.bashrc && /usr/lib/postgresql/bin/pg_ctl -D /var/lib/postgresql/data initdb -o "--allow-group-access" args: executable: /bin/bash environment: @@ -216,7 +216,7 @@ become: yes become_user: postgres shell: | - source /home/postgres/.bashrc + source /var/lib/postgresql/.bashrc /usr/lib/postgresql/bin/pg_ctl -D /var/lib/postgresql/data start environment: LANG: en_US.UTF-8 @@ -242,7 +242,7 @@ become: yes become_user: postgres shell: | - source /home/postgres/.bashrc && \ + source /var/lib/postgresql/.bashrc && \ /usr/lib/postgresql/bin/pg_ctl -D /var/lib/postgresql/data restart -o "-c shared_preload_libraries='pg_tle'" args: executable: /bin/bash diff --git a/ansible-nix/tasks/stage2/test-image.yml b/ansible-nix/tasks/stage2/test-image.yml index bc46efd44..e6a7bc249 100644 --- a/ansible-nix/tasks/stage2/test-image.yml +++ b/ansible-nix/tasks/stage2/test-image.yml @@ -7,7 +7,7 @@ - name: Start Postgres Database to load all extensions. become: yes become_user: postgres - shell: source /home/postgres/.bashrc && /usr/lib/postgresql/bin/pg_ctl -D /var/lib/postgresql/data start "-o -c config_file=/etc/postgresql/postgresql.conf" + shell: source /var/lib/postgresql/.bashrc && /usr/lib/postgresql/bin/pg_ctl -D /var/lib/postgresql/data start "-o -c config_file=/etc/postgresql/postgresql.conf" args: executable: /bin/bash environment: @@ -21,7 +21,7 @@ - name: check contents of unit test file become: yes become_user: postgres - shell: cat /home/postgres/unit-test-01.sql && ls -l /home/postgres/unit-test-01.sql + shell: cat /var/lib/postgresql/unit-test-01.sql && ls -l /var/lib/postgresql/unit-test-01.sql - name: verify postgres server is running become: yes @@ -37,12 +37,12 @@ LC_ALL: en_US.UTF-8 LC_CTYPE: en_US.UTF-8 LOCALE_ARCHIVE: /usr/lib/locale/locale-archive - PATH: /home/postgres/.nix-profile/bin:$PATH + PATH: /var/lib/postgresql/.nix-profile/bin:$PATH - name: Run Unit tests (with filename unit-test-*) on Postgres Database become: yes become_user: postgres - shell: source /home/postgres/.bashrc && /home/postgres/.nix-profile/bin/pg_prove -U postgres -h localhost -d postgres -f /home/postgres/unit-test-01.sql + shell: source /var/lib/postgresql/.bashrc && /var/lib/postgresql/.nix-profile/bin/pg_prove -U postgres -h localhost -d postgres -f /var/lib/postgresql/unit-test-01.sql register: retval failed_when: retval.rc != 0 args: @@ -53,10 +53,10 @@ LC_ALL: en_US.UTF-8 LC_CTYPE: en_US.UTF-8 LOCALE_ARCHIVE: /usr/lib/locale/locale-archive - PATH: /home/postgres/.nix-profile/bin:$PATH + PATH: /var/lib/postgresql/.nix-profile/bin:$PATH - name: Run migrations tests - shell: /home/postgres/.nix-profile/bin/pg_prove -U supabase_admin -h localhost -d postgres -v tests/test.sql + shell: /var/lib/postgresql/.nix-profile/bin/pg_prove -U supabase_admin -h localhost -d postgres -v tests/test.sql register: retval failed_when: retval.rc != 0 args: @@ -68,7 +68,7 @@ LC_ALL: en_US.UTF-8 LC_CTYPE: en_US.UTF-8 LOCALE_ARCHIVE: /usr/lib/locale/locale-archive - PATH: /home/postgres/.nix-profile/bin:$PATH + PATH: /var/lib/postgresql/.nix-profile/bin:$PATH - name: Re-enable PG Sodium references in config become: yes @@ -80,7 +80,7 @@ become: yes become_user: postgres shell: | - source /home/postgres/.bashrc && \ + source /var/lib/postgresql/.bashrc && \ /usr/lib/postgresql/bin/psql --no-password --no-psqlrc -d postgres -h localhost -U supabase_admin -c 'SELECT pg_stat_statements_reset(); SELECT pg_stat_reset();' args: executable: /bin/bash diff --git a/common-nix.vars.pkr.hcl b/common-nix.vars.pkr.hcl index 85f34a924..7741e93fe 100644 --- a/common-nix.vars.pkr.hcl +++ b/common-nix.vars.pkr.hcl @@ -1 +1 @@ -postgres-version = "15.6.1.71-nix-staged" +postgres-version = "15.6.1.72-nix-staged" From e2fa32917fac52707f2c491b82c21c1480be3d3c Mon Sep 17 00:00:00 2001 From: samrose Date: Mon, 24 Jun 2024 21:19:14 -0400 Subject: [PATCH 07/45] fix: makre sure bashrc exists --- ansible-nix/tasks/setup-postgres.yml | 6 ++++++ common-nix.vars.pkr.hcl | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/ansible-nix/tasks/setup-postgres.yml b/ansible-nix/tasks/setup-postgres.yml index 49d33f9c8..c29d7e482 100644 --- a/ansible-nix/tasks/setup-postgres.yml +++ b/ansible-nix/tasks/setup-postgres.yml @@ -67,6 +67,12 @@ create: yes become: yes +- name: Make sure .bashrc exists + file: + path: /var/lib/postgresql/.bashrc + state: touch + owner: postgres + group: postgres - name: Add LANG items to .bashrc lineinfile: diff --git a/common-nix.vars.pkr.hcl b/common-nix.vars.pkr.hcl index 7741e93fe..a4b580a0b 100644 --- a/common-nix.vars.pkr.hcl +++ b/common-nix.vars.pkr.hcl @@ -1 +1 @@ -postgres-version = "15.6.1.72-nix-staged" +postgres-version = "15.6.1.73-nix-staged" From 426954adecdfa5927cc987954709f6a934978e17 Mon Sep 17 00:00:00 2001 From: samrose Date: Tue, 25 Jun 2024 11:00:55 -0400 Subject: [PATCH 08/45] fix: minor refactor --- ansible-nix/tasks/setup-postgres.yml | 16 +++++++++------- common-nix.vars.pkr.hcl | 2 +- 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/ansible-nix/tasks/setup-postgres.yml b/ansible-nix/tasks/setup-postgres.yml index c29d7e482..6677f470d 100644 --- a/ansible-nix/tasks/setup-postgres.yml +++ b/ansible-nix/tasks/setup-postgres.yml @@ -60,13 +60,6 @@ - name: locale-gen command: sudo locale-gen en_US.UTF-8 -- name: Add LOCALE_ARCHIVE to .bashrc - lineinfile: - dest: "/var/lib/postgressql/.bashrc" - line: 'export LOCALE_ARCHIVE=/usr/lib/locale/locale-archive' - create: yes - become: yes - - name: Make sure .bashrc exists file: path: /var/lib/postgresql/.bashrc @@ -74,6 +67,15 @@ owner: postgres group: postgres + +- name: Add LOCALE_ARCHIVE to .bashrc + lineinfile: + dest: "/var/lib/postgresql/.bashrc" + line: 'export LOCALE_ARCHIVE=/usr/lib/locale/locale-archive' + create: yes + become: yes + + - name: Add LANG items to .bashrc lineinfile: dest: "/var/lib/postgresql/.bashrc" diff --git a/common-nix.vars.pkr.hcl b/common-nix.vars.pkr.hcl index a4b580a0b..fc7c66823 100644 --- a/common-nix.vars.pkr.hcl +++ b/common-nix.vars.pkr.hcl @@ -1 +1 @@ -postgres-version = "15.6.1.73-nix-staged" +postgres-version = "15.6.1.74-nix-staged" From d87200277849a510ae89327ea9ad973891b5818e Mon Sep 17 00:00:00 2001 From: samrose Date: Tue, 25 Jun 2024 12:16:59 -0400 Subject: [PATCH 09/45] chore: moving to a different PR --- .github/workflows/text-nix.yml | 117 ---------------------- .github/workflows/textinfra-nix.yml | 145 ---------------------------- 2 files changed, 262 deletions(-) delete mode 100644 .github/workflows/text-nix.yml delete mode 100644 .github/workflows/textinfra-nix.yml diff --git a/.github/workflows/text-nix.yml b/.github/workflows/text-nix.yml deleted file mode 100644 index 6c5778c7f..000000000 --- a/.github/workflows/text-nix.yml +++ /dev/null @@ -1,117 +0,0 @@ -name: Test Database - -on: - # push: - # branches: - # - develop - # pull_request: - workflow_dispatch: - -jobs: - build: - strategy: - matrix: - include: - - runner: [self-hosted, X64] - arch: amd64 - - runner: arm-runner - arch: arm64 - runs-on: ${{ matrix.runner }} - timeout-minutes: 180 - env: - POSTGRES_PORT: 5478 - POSTGRES_PASSWORD: password - steps: - - uses: actions/checkout@v3 - - id: args - uses: mikefarah/yq@master - with: - cmd: yq 'to_entries | map(select(.value|type == "!!str")) | map(.key + "=" + .value) | join("\n")' 'ansible/vars.yml' - - - run: docker context create builders - - uses: docker/setup-buildx-action@v3 - with: - endpoint: builders - - uses: docker/build-push-action@v5 - with: - load: true - context: . - target: production - build-args: | - ${{ steps.args.outputs.result }} - tags: samrose/nix-experimental-postgresql-15-aarch64-linux:latest - cache-from: | - type=gha,scope=${{ github.ref_name }}-latest-${{ matrix.arch }} - type=gha,scope=${{ github.base_ref }}-latest-${{ matrix.arch }} - cache-to: type=gha,mode=max,scope=${{ github.ref_name }}-latest-${{ matrix.arch }} - - - name: Start Postgres - run: | - docker run --rm --pull=never \ - -e POSTGRES_PASSWORD=${{ env.POSTGRES_PASSWORD }} \ - -p ${{ env.POSTGRES_PORT }}:5432 \ - --name supabase_postgres \ - -d supabase/postgres:latest - - - name: Install psql - run: | - sudo apt update - sudo apt install -y --no-install-recommends postgresql-client - - - name: Install pg_prove - run: sudo cpan -T TAP::Parser::SourceHandler::pgTAP - env: - SHELL: /bin/bash - - - name: Wait for healthy database - run: | - count=0 - until [ "$(docker inspect -f '{{.State.Health.Status}}' "$container")" == "healthy" ]; do - exit=$? - count=$((count + 1)) - if [ $count -ge "$retries" ]; then - echo "Retry $count/$retries exited $exit, no more retries left." - docker stop -t 2 "$container" - return $exit - fi - sleep 1; - done; - echo "$container container is healthy" - env: - retries: 20 - container: supabase_postgres - - - name: Run tests - run: pg_prove migrations/tests/test.sql - env: - PGHOST: localhost - PGPORT: ${{ env.POSTGRES_PORT }} - PGDATABASE: postgres - PGUSER: supabase_admin - PGPASSWORD: ${{ env.POSTGRES_PASSWORD }} - - - name: Check migrations are idempotent - run: | - for sql in ./migrations/db/migrations/*.sql; do - echo "$0: running $sql" - psql -v ON_ERROR_STOP=1 --no-password --no-psqlrc -f "$sql" - done - env: - PGHOST: localhost - PGPORT: ${{ env.POSTGRES_PORT }} - PGDATABASE: postgres - PGUSER: supabase_admin - PGPASSWORD: ${{ env.POSTGRES_PASSWORD }} - - schema: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v3 - - name: verify schema.sql is committed - run: | - docker compose -f migrations/docker-compose.yaml up db dbmate --abort-on-container-exit - if ! git diff --ignore-space-at-eol --exit-code --quiet migrations/schema.sql; then - echo "Detected uncommitted changes after build. See status below:" - git diff - exit 1 - fi diff --git a/.github/workflows/textinfra-nix.yml b/.github/workflows/textinfra-nix.yml deleted file mode 100644 index f88cc6077..000000000 --- a/.github/workflows/textinfra-nix.yml +++ /dev/null @@ -1,145 +0,0 @@ -name: Testinfra Integration Tests - -on: - #pull_request: - workflow_dispatch: - -jobs: - # test-all-in-one: - # strategy: - # matrix: - # include: - # - runner: [self-hosted, X64] - # arch: amd64 - # - runner: arm-runner - # arch: arm64 - # runs-on: ${{ matrix.runner }} - # timeout-minutes: 30 - # steps: - # - uses: actions/checkout@v3 - - # - run: docker context create builders - # - uses: docker/setup-buildx-action@v3 - # with: - # endpoint: builders - - # - name: Run aio integration tests - # run: | - # # TODO: use poetry for pkg mgmt - # pip3 install boto3 boto3-stubs[essential] docker ec2instanceconnectcli pytest pytest-testinfra[paramiko,docker] requests - - - # if ! pytest -vv testinfra/test_all_in_one.py; then - # # display container logs if the test fails - - # if [ -f testinfra-aio-container-logs.log ]; then - # echo "AIO container logs:" - # cat testinfra-aio-container-logs.log - # fi - # exit 1 - # fi - - test-ami: - strategy: - matrix: - include: - - runner: arm-runner - arch: arm64 - ubuntu_release: focal - ubuntu_version: 20.04 - mcpu: neoverse-n1 - runs-on: ${{ matrix.runner }} - timeout-minutes: 150 - permissions: - contents: write - packages: write - id-token: write - - steps: - - name: Checkout Repo - uses: actions/checkout@v4 - - - id: args - uses: mikefarah/yq@master - with: - cmd: yq 'to_entries | map(select(.value|type == "!!str")) | map(.key + "=" + .value) | join("\n")' 'ansible/vars.yml' - - - run: docker context create builders - - - uses: docker/setup-buildx-action@v3 - with: - endpoint: builders - - - uses: docker/build-push-action@v5 - with: - build-args: | - ${{ steps.args.outputs.result }} - target: extensions - tags: supabase/postgres:extensions - platforms: linux/${{ matrix.arch }} - outputs: type=tar,dest=/tmp/extensions.tar - cache-from: | - type=gha,scope=${{ github.ref_name }}-extensions - type=gha,scope=${{ github.base_ref }}-extensions - type=gha,scope=develop-extensions - cache-to: type=gha,mode=max,scope=${{ github.ref_name }}-extensions - - - name: Extract built packages - run: | - mkdir -p ansible/files/extensions - tar xvf /tmp/extensions.tar -C ansible/files/extensions --strip-components 1 - - - id: version - run: echo "${{ steps.args.outputs.result }}" | grep "postgresql" >> "$GITHUB_OUTPUT" - - - name: Build Postgres deb - uses: docker/build-push-action@v5 - with: - file: docker/Dockerfile - target: pg-deb - build-args: | - ubuntu_release=${{ matrix.ubuntu_release }} - ubuntu_release_no=${{ matrix.ubuntu_version }} - postgresql_major=${{ steps.version.outputs.postgresql_major }} - postgresql_release=${{ steps.version.outputs.postgresql_release }} - CPPFLAGS=-mcpu=${{ matrix.mcpu }} - tags: supabase/postgres:deb - platforms: linux/${{ matrix.arch }} - outputs: type=tar,dest=/tmp/pg-deb.tar - cache-from: | - type=gha,scope=${{ github.ref_name }}-deb - type=gha,scope=${{ github.base_ref }}-deb - type=gha,scope=develop-deb - cache-to: type=gha,mode=max,scope=${{ github.ref_name }}-deb - - - name: Extract Postgres deb - run: | - mkdir -p ansible/files/postgres - tar xvf /tmp/pg-deb.tar -C ansible/files/postgres --strip-components 1 - - # Packer doesn't support skipping registering the AMI for the ebssurrogate - # builder, so we register an AMI with a fixed name and run tests on an - # instance launched from that - # https://github.com/hashicorp/packer/issues/4899 - - name: Build AMI - run: | - packer init amazon-arm64.pkr.hcl - GIT_SHA=${{github.sha}} - packer build -var "git-head-version=${GIT_SHA}" -var "packer-execution-id=${GITHUB_RUN_ID}" -var-file="development-arm.vars.pkr.hcl" -var-file="common.vars.pkr.hcl" -var "ansible_arguments=" -var "postgres-version=ci-ami-test" -var "region=ap-southeast-1" -var 'ami_regions=["ap-southeast-1"]' -var "force-deregister=true" amazon-arm64.pkr.hcl - - - name: Run tests - timeout-minutes: 10 - run: | - # TODO: use poetry for pkg mgmt - pip3 install boto3 boto3-stubs[essential] docker ec2instanceconnectcli pytest pytest-testinfra[paramiko,docker] requests - pytest -vv -s testinfra/test_ami.py - - - name: Cleanup resources on build cancellation - if: ${{ cancelled() }} - run: | - aws ec2 --region ap-southeast-1 describe-instances --filters "Name=tag:packerExecutionId,Values=${GITHUB_RUN_ID}" --query "Reservations[].Instances[].InstanceId" --output text | xargs -n 1 -I {} aws ec2 terminate-instances --region ap-southeast-1 --instance-ids {} - - - name: Cleanup resources on build cancellation - if: ${{ always() }} - run: | - aws ec2 --region ap-southeast-1 describe-instances --filters "Name=tag:testinfra-run-id,Values=${GITHUB_RUN_ID}" --query "Reservations[].Instances[].InstanceId" --output text | xargs -n 1 -I {} aws ec2 terminate-instances --region ap-southeast-1 --instance-ids {} || true From ea28a10816a66a8032883265343e26290c74ad03 Mon Sep 17 00:00:00 2001 From: samrose Date: Tue, 25 Jun 2024 12:22:15 -0400 Subject: [PATCH 10/45] chore: bump version and remove deprecated workflow --- .github/workflows/nix-cache-upload.yml | 52 -------------------------- common-nix.vars.pkr.hcl | 2 +- 2 files changed, 1 insertion(+), 53 deletions(-) delete mode 100644 .github/workflows/nix-cache-upload.yml diff --git a/.github/workflows/nix-cache-upload.yml b/.github/workflows/nix-cache-upload.yml deleted file mode 100644 index ea7f628e9..000000000 --- a/.github/workflows/nix-cache-upload.yml +++ /dev/null @@ -1,52 +0,0 @@ -name: Nix Cache upload - -on: - push: - branches: - - main - -permissions: - contents: write - packages: write - id-token: write - -jobs: - build: - strategy: - fail-fast: false - matrix: - include: - - runner: [self-hosted, X64] - arch: amd64 - - runner: arm-runner - arch: arm64 - runs-on: ${{ matrix.runner }} - name: nix-build - steps: - - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 - with: - fetch-depth: 0 - - uses: DeterminateSystems/nix-installer-action@65d7c888b2778e8cf30a07a88422ccb23499bfb8 - - uses: DeterminateSystems/magic-nix-cache-action@749fc5bbc9fa49d60c2b93f6c4bc867b82e1d295 - - name: configure aws credentials for s3 - uses: aws-actions/configure-aws-credentials@v1 - with: - role-to-assume: ${{ secrets.DEV_AWS_ROLE }} - aws-region: "us-east-1" - kvm: true - extra-conf: | - system-features = kvm - - - name: write secret key - # use python so we don't interpolate the secret into the workflow logs, in case of bugs - run: | - python -c "import os; file = open('nix-secret-key', 'w'); file.write(os.environ['NIX_SIGN_SECRET_KEY']); file.close()" - env: - NIX_SIGN_SECRET_KEY: ${{ secrets.NIX_SIGN_SECRET_KEY }} - - - name: build and copy to S3 - run: | - for x in 15 16 orioledb_16; do - nix build .#psql_$x/bin -o result-$x - done - nix copy --to s3://nix-postgres-artifacts?secret-key=nix-secret-key ./result* diff --git a/common-nix.vars.pkr.hcl b/common-nix.vars.pkr.hcl index fc7c66823..59a177d0a 100644 --- a/common-nix.vars.pkr.hcl +++ b/common-nix.vars.pkr.hcl @@ -1 +1 @@ -postgres-version = "15.6.1.74-nix-staged" +postgres-version = "15.6.1.75-nix-staged" From 3d55e1a254ffc8f6f22729c2dd1ec66453247a69 Mon Sep 17 00:00:00 2001 From: samrose Date: Tue, 25 Jun 2024 12:54:17 -0400 Subject: [PATCH 11/45] feat: parallel testinfra-nix just for ami test --- .github/workflows/testinfra-nix.yml | 64 +++++++++++++++++++++++++++++ common-nix.vars.pkr.hcl | 2 +- 2 files changed, 65 insertions(+), 1 deletion(-) create mode 100644 .github/workflows/testinfra-nix.yml diff --git a/.github/workflows/testinfra-nix.yml b/.github/workflows/testinfra-nix.yml new file mode 100644 index 000000000..59b7ec3bd --- /dev/null +++ b/.github/workflows/testinfra-nix.yml @@ -0,0 +1,64 @@ +name: Testinfra Integration Tests + +on: + pull_request: + workflow_dispatch: + +jobs: + test-ami: + strategy: + matrix: + include: + - runner: arm-runner + arch: arm64 + ubuntu_release: focal + ubuntu_version: 20.04 + mcpu: neoverse-n1 + runs-on: ${{ matrix.runner }} + timeout-minutes: 150 + permissions: + contents: write + packages: write + id-token: write + + steps: + - name: Checkout Repo + uses: actions/checkout@v4 + + - id: args + uses: mikefarah/yq@master + with: + cmd: yq 'to_entries | map(select(.value|type == "!!str")) | map(.key + "=" + .value) | join("\n")' 'ansible/vars.yml' + + - run: docker context create builders + + - uses: docker/setup-buildx-action@v3 + with: + endpoint: builders + + - name: Build AMI stage 1 + run: | + packer init amazon-arm64-nix.pkr.hcl + GIT_SHA=${{github.sha}} + packer build -var "git-head-version=${GIT_SHA}" -var "packer-execution-id=${GITHUB_RUN_ID}" -var-file="development-arm.vars.pkr.hcl" -var-file="common-nix.vars.pkr.hcl" -var "ansible_arguments=" amazon-arm64-nix.pkr.hcl + + - name: Build AMI stage 2 + run: | + packer init stage2-nix-psql.pkr.hcl + GIT_SHA=${{github.sha}} + packer build -var "git-head-version=${GIT_SHA}" -var "packer-execution-id=${GITHUB_RUN_ID}" -var-file="development-arm.vars.pkr.hcl" -var-file="common-nix.vars.pkr.hcl" -var "ansible_arguments=" -var "postgres-version=ci-ami-test" -var "region=ap-southeast-1" -var 'ami_regions=["ap-southeast-1"]' -var "force-deregister=true" stage2-nix-psql.pkr.hcl + + - name: Run tests + timeout-minutes: 10 + run: | + # TODO: use poetry for pkg mgmt + pip3 install boto3 boto3-stubs[essential] docker ec2instanceconnectcli pytest pytest-testinfra[paramiko,docker] requests + pytest -vv -s testinfra/test_ami.py + - name: Cleanup resources on build cancellation + if: ${{ cancelled() }} + run: | + aws ec2 --region ap-southeast-1 describe-instances --filters "Name=tag:packerExecutionId,Values=${GITHUB_RUN_ID}" --query "Reservations[].Instances[].InstanceId" --output text | xargs -n 1 -I {} aws ec2 terminate-instances --region ap-southeast-1 --instance-ids {} + - name: Cleanup resources on build cancellation + if: ${{ always() }} + run: | + aws ec2 --region ap-southeast-1 describe-instances --filters "Name=tag:testinfra-run-id,Values=${GITHUB_RUN_ID}" --query "Reservations[].Instances[].InstanceId" --output text | xargs -n 1 -I {} aws ec2 terminate-instances --region ap-southeast-1 --instance-ids {} || true diff --git a/common-nix.vars.pkr.hcl b/common-nix.vars.pkr.hcl index 59a177d0a..b6682e752 100644 --- a/common-nix.vars.pkr.hcl +++ b/common-nix.vars.pkr.hcl @@ -1 +1 @@ -postgres-version = "15.6.1.75-nix-staged" +postgres-version = "15.6.1.76-nix-staged" From f15580daca0fbb7589840332d83d8601e5812ce8 Mon Sep 17 00:00:00 2001 From: samrose Date: Tue, 25 Jun 2024 13:30:53 -0400 Subject: [PATCH 12/45] chore: testing just testinfra-nix workflow --- .github/workflows/ami-release-nix.yml | 10 +++++----- common-nix.vars.pkr.hcl | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/workflows/ami-release-nix.yml b/.github/workflows/ami-release-nix.yml index faceb88cd..da61c9e2a 100644 --- a/.github/workflows/ami-release-nix.yml +++ b/.github/workflows/ami-release-nix.yml @@ -1,11 +1,11 @@ name: Release AMI Nix on: - push: - branches: - - sam/nix-and-conventional-ami - - '.github/workflows/ami-release-nix.yml' - - 'common-nix.vars.pkr.hcl' + # push: + # branches: + # - sam/nix-and-conventional-ami + # - '.github/workflows/ami-release-nix.yml' + # - 'common-nix.vars.pkr.hcl' workflow_dispatch: jobs: diff --git a/common-nix.vars.pkr.hcl b/common-nix.vars.pkr.hcl index b6682e752..a712c3dbd 100644 --- a/common-nix.vars.pkr.hcl +++ b/common-nix.vars.pkr.hcl @@ -1 +1 @@ -postgres-version = "15.6.1.76-nix-staged" +postgres-version = "15.6.1.77-nix-staged" From 887d8da4dde0cc0d4731fff38d8f48278d3d07d8 Mon Sep 17 00:00:00 2001 From: samrose Date: Tue, 25 Jun 2024 14:03:05 -0400 Subject: [PATCH 13/45] chore: re-run build --- .github/workflows/testinfra-nix.yml | 2 +- common-nix.vars.pkr.hcl | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/testinfra-nix.yml b/.github/workflows/testinfra-nix.yml index 59b7ec3bd..2df5033dc 100644 --- a/.github/workflows/testinfra-nix.yml +++ b/.github/workflows/testinfra-nix.yml @@ -46,7 +46,7 @@ jobs: run: | packer init stage2-nix-psql.pkr.hcl GIT_SHA=${{github.sha}} - packer build -var "git-head-version=${GIT_SHA}" -var "packer-execution-id=${GITHUB_RUN_ID}" -var-file="development-arm.vars.pkr.hcl" -var-file="common-nix.vars.pkr.hcl" -var "ansible_arguments=" -var "postgres-version=ci-ami-test" -var "region=ap-southeast-1" -var 'ami_regions=["ap-southeast-1"]' -var "force-deregister=true" stage2-nix-psql.pkr.hcl + packer build -var "git-head-version=${GIT_SHA}" -var "packer-execution-id=${GITHUB_RUN_ID}" -var-file="development-arm.vars.pkr.hcl" -var-file="common-nix.vars.pkr.hcl" -var "postgres-version=ci-ami-test" -var "region=ap-southeast-1" -var 'ami_regions=["ap-southeast-1"]' -var "force-deregister=true" stage2-nix-psql.pkr.hcl - name: Run tests timeout-minutes: 10 diff --git a/common-nix.vars.pkr.hcl b/common-nix.vars.pkr.hcl index a712c3dbd..6de97aca3 100644 --- a/common-nix.vars.pkr.hcl +++ b/common-nix.vars.pkr.hcl @@ -1 +1 @@ -postgres-version = "15.6.1.77-nix-staged" +postgres-version = "15.6.1.78-nix-staged" From 34fe05256d12dffa88b002a18046cd6f62655220 Mon Sep 17 00:00:00 2001 From: samrose Date: Tue, 25 Jun 2024 14:36:03 -0400 Subject: [PATCH 14/45] chore: re-trigger testinfra --- .github/workflows/testinfra-nix.yml | 2 +- common-nix.vars.pkr.hcl | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/testinfra-nix.yml b/.github/workflows/testinfra-nix.yml index 2df5033dc..c60348e17 100644 --- a/.github/workflows/testinfra-nix.yml +++ b/.github/workflows/testinfra-nix.yml @@ -46,7 +46,7 @@ jobs: run: | packer init stage2-nix-psql.pkr.hcl GIT_SHA=${{github.sha}} - packer build -var "git-head-version=${GIT_SHA}" -var "packer-execution-id=${GITHUB_RUN_ID}" -var-file="development-arm.vars.pkr.hcl" -var-file="common-nix.vars.pkr.hcl" -var "postgres-version=ci-ami-test" -var "region=ap-southeast-1" -var 'ami_regions=["ap-southeast-1"]' -var "force-deregister=true" stage2-nix-psql.pkr.hcl + packer build -var "git-head-version=${GIT_SHA}" -var "packer-execution-id=${GITHUB_RUN_ID}" -var-file="development-arm.vars.pkr.hcl" -var-file="common-nix.vars.pkr.hcl" -var "region=ap-southeast-1" -var 'ami_regions=["ap-southeast-1"]' -var "force-deregister=true" stage2-nix-psql.pkr.hcl - name: Run tests timeout-minutes: 10 diff --git a/common-nix.vars.pkr.hcl b/common-nix.vars.pkr.hcl index 6de97aca3..549709de4 100644 --- a/common-nix.vars.pkr.hcl +++ b/common-nix.vars.pkr.hcl @@ -1 +1 @@ -postgres-version = "15.6.1.78-nix-staged" +postgres-version = "15.6.1.79-nix-staged" From 7ed365119add90af360ef6d12d08855ad58f2544 Mon Sep 17 00:00:00 2001 From: samrose Date: Tue, 25 Jun 2024 15:04:38 -0400 Subject: [PATCH 15/45] fix: wait for AMI to reach available state --- .github/workflows/testinfra-nix.yml | 17 +++++++++++++++-- common-nix.vars.pkr.hcl | 2 +- 2 files changed, 16 insertions(+), 3 deletions(-) diff --git a/.github/workflows/testinfra-nix.yml b/.github/workflows/testinfra-nix.yml index c60348e17..6c8ae0b7e 100644 --- a/.github/workflows/testinfra-nix.yml +++ b/.github/workflows/testinfra-nix.yml @@ -40,8 +40,21 @@ jobs: run: | packer init amazon-arm64-nix.pkr.hcl GIT_SHA=${{github.sha}} - packer build -var "git-head-version=${GIT_SHA}" -var "packer-execution-id=${GITHUB_RUN_ID}" -var-file="development-arm.vars.pkr.hcl" -var-file="common-nix.vars.pkr.hcl" -var "ansible_arguments=" amazon-arm64-nix.pkr.hcl - + AMI_ID=$(packer build -machine-readable -var "git-head-version=${GIT_SHA}" -var "packer-execution-id=${GITHUB_RUN_ID}" -var-file="development-arm.vars.pkr.hcl" -var-file="common-nix.vars.pkr.hcl" -var "ansible_arguments=" amazon-arm64-nix.pkr.hcl | tee >(cat >&2) | awk -F, '$0 ~/artifact,0,id/ {print $6}' | cut -d ':' -f2) + echo "AMI_ID=${AMI_ID}" >> $GITHUB_ENV + + - name: Wait for AMI to be available + run: | + while true; do + AMI_STATUS=$(aws ec2 describe-images --image-ids ${{ env.AMI_ID }} --query 'Images[0].State' --output text) + if [ "$AMI_STATUS" == "available" ]; then + echo "AMI is now available." + break + fi + echo "AMI status: $AMI_STATUS. Waiting for 30 seconds..." + sleep 30 + done + - name: Build AMI stage 2 run: | packer init stage2-nix-psql.pkr.hcl diff --git a/common-nix.vars.pkr.hcl b/common-nix.vars.pkr.hcl index 549709de4..f57ea3e23 100644 --- a/common-nix.vars.pkr.hcl +++ b/common-nix.vars.pkr.hcl @@ -1 +1 @@ -postgres-version = "15.6.1.79-nix-staged" +postgres-version = "15.6.1.80-nix-staged" From 463079b43ac469b0308227a8884763349327f50b Mon Sep 17 00:00:00 2001 From: samrose Date: Tue, 25 Jun 2024 15:59:04 -0400 Subject: [PATCH 16/45] fix: use ami id in stage 3 testinfra ami-test --- .github/workflows/testinfra-nix.yml | 2 +- common-nix.vars.pkr.hcl | 2 +- stage2-nix-psql-testinfra.pkr.hcl | 130 ++++++++++++++++++++++++++++ 3 files changed, 132 insertions(+), 2 deletions(-) create mode 100644 stage2-nix-psql-testinfra.pkr.hcl diff --git a/.github/workflows/testinfra-nix.yml b/.github/workflows/testinfra-nix.yml index 6c8ae0b7e..ce20eec8c 100644 --- a/.github/workflows/testinfra-nix.yml +++ b/.github/workflows/testinfra-nix.yml @@ -59,7 +59,7 @@ jobs: run: | packer init stage2-nix-psql.pkr.hcl GIT_SHA=${{github.sha}} - packer build -var "git-head-version=${GIT_SHA}" -var "packer-execution-id=${GITHUB_RUN_ID}" -var-file="development-arm.vars.pkr.hcl" -var-file="common-nix.vars.pkr.hcl" -var "region=ap-southeast-1" -var 'ami_regions=["ap-southeast-1"]' -var "force-deregister=true" stage2-nix-psql.pkr.hcl + packer build -var "git-head-version=${GIT_SHA}" -var "packer-execution-id=${GITHUB_RUN_ID}" -var-file="development-arm.vars.pkr.hcl" -var-file="common-nix.vars.pkr.hcl" -var "region=ap-southeast-1" -var 'ami_regions=["ap-southeast-1"]' -var "force-deregister=true" -var "source_ami=${{ env.AMI_ID }}" stage2-nix-psql-testinfra.pkr.hcl - name: Run tests timeout-minutes: 10 diff --git a/common-nix.vars.pkr.hcl b/common-nix.vars.pkr.hcl index f57ea3e23..a5b5e0046 100644 --- a/common-nix.vars.pkr.hcl +++ b/common-nix.vars.pkr.hcl @@ -1 +1 @@ -postgres-version = "15.6.1.80-nix-staged" +postgres-version = "15.6.1.82-nix-staged" diff --git a/stage2-nix-psql-testinfra.pkr.hcl b/stage2-nix-psql-testinfra.pkr.hcl new file mode 100644 index 000000000..1d8d4e7e1 --- /dev/null +++ b/stage2-nix-psql-testinfra.pkr.hcl @@ -0,0 +1,130 @@ +variable "profile" { + type = string + default = "${env("AWS_PROFILE")}" +} + +variable "ami_regions" { + type = list(string) + default = ["ap-southeast-2"] +} + +variable "environment" { + type = string + default = "prod" +} + +variable "region" { + type = string +} + +variable "ami_name" { + type = string + default = "supabase-postgres" +} + +variable "source_ami" { + type = string +} + +variable "postgres-version" { + type = string + default = "" +} + +variable "git-head-version" { + type = string + default = "unknown" +} + +variable "packer-execution-id" { + type = string + default = "unknown" +} + +variable "force-deregister" { + type = bool + default = false +} + +packer { + required_plugins { + amazon = { + version = ">= 0.0.2" + source = "github.com/hashicorp/amazon" + } + } +} + +source "amazon-ebs" "ubuntu" { + ami_name = "${var.ami_name}-${var.postgres-version}-nix" + instance_type = "c6g.4xlarge" + region = "${var.region}" + source_ami = "${var.source_ami}" + + communicator = "ssh" + ssh_pty = true + ssh_username = "ubuntu" + ssh_timeout = "5m" + + associate_public_ip_address = true + + + ena_support = true + + run_tags = { + creator = "packer" + appType = "postgres" + packerExecutionId = "${var.packer-execution-id}" + } + run_volume_tags = { + creator = "packer" + appType = "postgres" + } + snapshot_tags = { + creator = "packer" + appType = "postgres" + } + tags = { + creator = "packer" + appType = "postgres" + postgresVersion = "${var.postgres-version}" + sourceSha = "${var.git-head-version}" + } +} + +build { + name = "nix-packer-ubuntu" + sources = [ + "source.amazon-ebs.ubuntu" + ] + + # Copy ansible playbook + provisioner "shell" { + inline = ["mkdir /tmp/ansible-playbook"] + } + + provisioner "file" { + source = "ansible-nix/tasks/stage2" + destination = "/tmp/ansible-playbook" + } + + provisioner "file" { + source = "ansible-nix/files" + destination = "/tmp/ansible-playbook/files" + } + + provisioner "file" { + source = "migrations" + destination = "/tmp" + } + + provisioner "file" { + source = "ebssurrogate/files/unit-tests" + destination = "/tmp/unit-tests" + } + + provisioner "shell" { + script = "scripts/nix-provision.sh" + } + +} From e43f0f2510c104acb3575cf273db14f862c6be85 Mon Sep 17 00:00:00 2001 From: samrose Date: Tue, 25 Jun 2024 16:29:18 -0400 Subject: [PATCH 17/45] fix: env vars --- .github/workflows/testinfra-nix.yml | 3 ++- common-nix.vars.pkr.hcl | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/.github/workflows/testinfra-nix.yml b/.github/workflows/testinfra-nix.yml index ce20eec8c..a139d1fa5 100644 --- a/.github/workflows/testinfra-nix.yml +++ b/.github/workflows/testinfra-nix.yml @@ -59,7 +59,8 @@ jobs: run: | packer init stage2-nix-psql.pkr.hcl GIT_SHA=${{github.sha}} - packer build -var "git-head-version=${GIT_SHA}" -var "packer-execution-id=${GITHUB_RUN_ID}" -var-file="development-arm.vars.pkr.hcl" -var-file="common-nix.vars.pkr.hcl" -var "region=ap-southeast-1" -var 'ami_regions=["ap-southeast-1"]' -var "force-deregister=true" -var "source_ami=${{ env.AMI_ID }}" stage2-nix-psql-testinfra.pkr.hcl + AMI_ID=${{ env.AMI_ID }} + packer build -var "git-head-version=${GIT_SHA}" -var "packer-execution-id=${GITHUB_RUN_ID}" -var-file="development-arm.vars.pkr.hcl" -var-file="common-nix.vars.pkr.hcl" -var "region=ap-southeast-1" -var 'ami_regions=["ap-southeast-1"]' -var "force-deregister=true" -var "source_ami=${AMI_ID}" stage2-nix-psql-testinfra.pkr.hcl - name: Run tests timeout-minutes: 10 diff --git a/common-nix.vars.pkr.hcl b/common-nix.vars.pkr.hcl index a5b5e0046..f2288a56f 100644 --- a/common-nix.vars.pkr.hcl +++ b/common-nix.vars.pkr.hcl @@ -1 +1 @@ -postgres-version = "15.6.1.82-nix-staged" +postgres-version = "15.6.1.83-nix-staged" From 9b38c4b044c8d15f794c413cd2270e5f3339027d Mon Sep 17 00:00:00 2001 From: samrose Date: Tue, 25 Jun 2024 16:50:52 -0400 Subject: [PATCH 18/45] chore: bump version --- common-nix.vars.pkr.hcl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common-nix.vars.pkr.hcl b/common-nix.vars.pkr.hcl index f2288a56f..e14e76003 100644 --- a/common-nix.vars.pkr.hcl +++ b/common-nix.vars.pkr.hcl @@ -1 +1 @@ -postgres-version = "15.6.1.83-nix-staged" +postgres-version = "15.6.1.84-nix-staged" From 7237270c3713c76bdaffa0331d4e851c1d3715d5 Mon Sep 17 00:00:00 2001 From: samrose Date: Tue, 25 Jun 2024 21:24:48 -0400 Subject: [PATCH 19/45] chore: restore packer build --- .github/workflows/testinfra-nix.yml | 20 +---- common-nix.vars.pkr.hcl | 2 +- stage2-nix-psql-testinfra.pkr.hcl | 130 ---------------------------- 3 files changed, 4 insertions(+), 148 deletions(-) delete mode 100644 stage2-nix-psql-testinfra.pkr.hcl diff --git a/.github/workflows/testinfra-nix.yml b/.github/workflows/testinfra-nix.yml index a139d1fa5..10d3f4f8e 100644 --- a/.github/workflows/testinfra-nix.yml +++ b/.github/workflows/testinfra-nix.yml @@ -40,28 +40,14 @@ jobs: run: | packer init amazon-arm64-nix.pkr.hcl GIT_SHA=${{github.sha}} - AMI_ID=$(packer build -machine-readable -var "git-head-version=${GIT_SHA}" -var "packer-execution-id=${GITHUB_RUN_ID}" -var-file="development-arm.vars.pkr.hcl" -var-file="common-nix.vars.pkr.hcl" -var "ansible_arguments=" amazon-arm64-nix.pkr.hcl | tee >(cat >&2) | awk -F, '$0 ~/artifact,0,id/ {print $6}' | cut -d ':' -f2) - echo "AMI_ID=${AMI_ID}" >> $GITHUB_ENV - - - name: Wait for AMI to be available - run: | - while true; do - AMI_STATUS=$(aws ec2 describe-images --image-ids ${{ env.AMI_ID }} --query 'Images[0].State' --output text) - if [ "$AMI_STATUS" == "available" ]; then - echo "AMI is now available." - break - fi - echo "AMI status: $AMI_STATUS. Waiting for 30 seconds..." - sleep 30 - done + packer build -var "git-head-version=${GIT_SHA}" -var "packer-execution-id=${GITHUB_RUN_ID}" -var-file="development-arm.vars.pkr.hcl" -var-file="common-nix.vars.pkr.hcl" -var "ansible_arguments=" amazon-arm64-nix.pkr.hcl - name: Build AMI stage 2 run: | packer init stage2-nix-psql.pkr.hcl GIT_SHA=${{github.sha}} - AMI_ID=${{ env.AMI_ID }} - packer build -var "git-head-version=${GIT_SHA}" -var "packer-execution-id=${GITHUB_RUN_ID}" -var-file="development-arm.vars.pkr.hcl" -var-file="common-nix.vars.pkr.hcl" -var "region=ap-southeast-1" -var 'ami_regions=["ap-southeast-1"]' -var "force-deregister=true" -var "source_ami=${AMI_ID}" stage2-nix-psql-testinfra.pkr.hcl - + packer build -var "git-head-version=${GIT_SHA}" -var "packer-execution-id=${GITHUB_RUN_ID}" -var-file="development-arm.vars.pkr.hcl" -var-file="common-nix.vars.pkr.hcl" stage2-nix-psql.pkr.hcl + - name: Run tests timeout-minutes: 10 run: | diff --git a/common-nix.vars.pkr.hcl b/common-nix.vars.pkr.hcl index e14e76003..d898ad0ed 100644 --- a/common-nix.vars.pkr.hcl +++ b/common-nix.vars.pkr.hcl @@ -1 +1 @@ -postgres-version = "15.6.1.84-nix-staged" +postgres-version = "15.6.1.85-nix-staged" diff --git a/stage2-nix-psql-testinfra.pkr.hcl b/stage2-nix-psql-testinfra.pkr.hcl deleted file mode 100644 index 1d8d4e7e1..000000000 --- a/stage2-nix-psql-testinfra.pkr.hcl +++ /dev/null @@ -1,130 +0,0 @@ -variable "profile" { - type = string - default = "${env("AWS_PROFILE")}" -} - -variable "ami_regions" { - type = list(string) - default = ["ap-southeast-2"] -} - -variable "environment" { - type = string - default = "prod" -} - -variable "region" { - type = string -} - -variable "ami_name" { - type = string - default = "supabase-postgres" -} - -variable "source_ami" { - type = string -} - -variable "postgres-version" { - type = string - default = "" -} - -variable "git-head-version" { - type = string - default = "unknown" -} - -variable "packer-execution-id" { - type = string - default = "unknown" -} - -variable "force-deregister" { - type = bool - default = false -} - -packer { - required_plugins { - amazon = { - version = ">= 0.0.2" - source = "github.com/hashicorp/amazon" - } - } -} - -source "amazon-ebs" "ubuntu" { - ami_name = "${var.ami_name}-${var.postgres-version}-nix" - instance_type = "c6g.4xlarge" - region = "${var.region}" - source_ami = "${var.source_ami}" - - communicator = "ssh" - ssh_pty = true - ssh_username = "ubuntu" - ssh_timeout = "5m" - - associate_public_ip_address = true - - - ena_support = true - - run_tags = { - creator = "packer" - appType = "postgres" - packerExecutionId = "${var.packer-execution-id}" - } - run_volume_tags = { - creator = "packer" - appType = "postgres" - } - snapshot_tags = { - creator = "packer" - appType = "postgres" - } - tags = { - creator = "packer" - appType = "postgres" - postgresVersion = "${var.postgres-version}" - sourceSha = "${var.git-head-version}" - } -} - -build { - name = "nix-packer-ubuntu" - sources = [ - "source.amazon-ebs.ubuntu" - ] - - # Copy ansible playbook - provisioner "shell" { - inline = ["mkdir /tmp/ansible-playbook"] - } - - provisioner "file" { - source = "ansible-nix/tasks/stage2" - destination = "/tmp/ansible-playbook" - } - - provisioner "file" { - source = "ansible-nix/files" - destination = "/tmp/ansible-playbook/files" - } - - provisioner "file" { - source = "migrations" - destination = "/tmp" - } - - provisioner "file" { - source = "ebssurrogate/files/unit-tests" - destination = "/tmp/unit-tests" - } - - provisioner "shell" { - script = "scripts/nix-provision.sh" - } - -} From 05a52f113ac2eabb520c493c38cee57e8b3a3419 Mon Sep 17 00:00:00 2001 From: Sam Rose Date: Wed, 26 Jun 2024 05:10:56 -0400 Subject: [PATCH 20/45] chore: create a parallel test --- .github/workflows/testinfra-nix.yml | 4 +- testinfra/test_ami_nix.py | 390 ++++++++++++++++++++++++++++ 2 files changed, 392 insertions(+), 2 deletions(-) create mode 100644 testinfra/test_ami_nix.py diff --git a/.github/workflows/testinfra-nix.yml b/.github/workflows/testinfra-nix.yml index 10d3f4f8e..b9cb86897 100644 --- a/.github/workflows/testinfra-nix.yml +++ b/.github/workflows/testinfra-nix.yml @@ -46,14 +46,14 @@ jobs: run: | packer init stage2-nix-psql.pkr.hcl GIT_SHA=${{github.sha}} - packer build -var "git-head-version=${GIT_SHA}" -var "packer-execution-id=${GITHUB_RUN_ID}" -var-file="development-arm.vars.pkr.hcl" -var-file="common-nix.vars.pkr.hcl" stage2-nix-psql.pkr.hcl + packer build -var "git-head-version=${GIT_SHA}" -var "packer-execution-id=${GITHUB_RUN_ID}" -var-file="development-arm.vars.pkr.hcl" -var-file="common-nix.vars.pkr.hcl" -var "postgres-version=ci-ami-test" -var "region=ap-southeast-1" -var 'ami_regions=["ap-southeast-1"]' -var "force-deregister=true" stage2-nix-psql.pkr.hcl - name: Run tests timeout-minutes: 10 run: | # TODO: use poetry for pkg mgmt pip3 install boto3 boto3-stubs[essential] docker ec2instanceconnectcli pytest pytest-testinfra[paramiko,docker] requests - pytest -vv -s testinfra/test_ami.py + pytest -vv -s testinfra/test_ami_nix.py - name: Cleanup resources on build cancellation if: ${{ cancelled() }} run: | diff --git a/testinfra/test_ami_nix.py b/testinfra/test_ami_nix.py new file mode 100644 index 000000000..c2de11be3 --- /dev/null +++ b/testinfra/test_ami_nix.py @@ -0,0 +1,390 @@ +import base64 +import boto3 +import gzip +import logging +import os +import pytest +import requests +import socket +import testinfra +from ec2instanceconnectcli.EC2InstanceConnectLogger import EC2InstanceConnectLogger +from ec2instanceconnectcli.EC2InstanceConnectKey import EC2InstanceConnectKey +from time import sleep + +# if GITHUB_RUN_ID is not set, use a default value that includes the user and hostname +RUN_ID = os.environ.get("GITHUB_RUN_ID", "unknown-ci-run-" + os.environ.get("USER", "unknown-user") + '@' + socket.gethostname()) + +postgresql_schema_sql_content = """ +ALTER DATABASE postgres SET "app.settings.jwt_secret" TO 'my_jwt_secret_which_is_not_so_secret'; +ALTER DATABASE postgres SET "app.settings.jwt_exp" TO 3600; + +ALTER USER supabase_admin WITH PASSWORD 'postgres'; +ALTER USER postgres WITH PASSWORD 'postgres'; +ALTER USER authenticator WITH PASSWORD 'postgres'; +ALTER USER pgbouncer WITH PASSWORD 'postgres'; +ALTER USER supabase_auth_admin WITH PASSWORD 'postgres'; +ALTER USER supabase_storage_admin WITH PASSWORD 'postgres'; +ALTER USER supabase_replication_admin WITH PASSWORD 'postgres'; +ALTER ROLE supabase_read_only_user WITH PASSWORD 'postgres'; +ALTER ROLE supabase_admin SET search_path TO "$user",public,auth,extensions; +""" +realtime_env_content = "" +adminapi_yaml_content = """ +port: 8085 +host: 0.0.0.0 +ref: aaaaaaaaaaaaaaaaaaaa +jwt_secret: my_jwt_secret_which_is_not_so_secret +metric_collectors: + - filesystem + - meminfo + - netdev + - loadavg + - cpu + - diskstats + - vmstat +node_exporter_additional_args: + - '--collector.filesystem.ignored-mount-points=^/(boot|sys|dev|run).*' + - '--collector.netdev.device-exclude=lo' +cert_path: /etc/ssl/adminapi/server.crt +key_path: /etc/ssl/adminapi/server.key +upstream_metrics_refresh_duration: 60s +pgbouncer_endpoints: + - 'postgres://pgbouncer:postgres@localhost:6543/pgbouncer' +fail2ban_socket: /var/run/fail2ban/fail2ban.sock +upstream_metrics_sources: + - + name: system + url: 'https://localhost:8085/metrics' + labels_to_attach: [{name: supabase_project_ref, value: aaaaaaaaaaaaaaaaaaaa}, {name: service_type, value: db}] + skip_tls_verify: true + - + name: postgresql + url: 'http://localhost:9187/metrics' + labels_to_attach: [{name: supabase_project_ref, value: aaaaaaaaaaaaaaaaaaaa}, {name: service_type, value: postgresql}] + - + name: gotrue + url: 'http://localhost:9122/metrics' + labels_to_attach: [{name: supabase_project_ref, value: aaaaaaaaaaaaaaaaaaaa}, {name: service_type, value: gotrue}] +monitoring: + disk_usage: + enabled: true +firewall: + enabled: true + internal_ports: + - 9187 + - 8085 + - 9122 + privileged_ports: + - 22 + privileged_ports_allowlist: + - 0.0.0.0/0 + filtered_ports: + - 5432 + - 6543 + unfiltered_ports: + - 80 + - 443 + managed_rules_file: /etc/nftables/supabase_managed.conf +pg_egress_collect_path: /tmp/pg_egress_collect.txt +aws_config: + creds: + enabled: false + check_frequency: 1h + refresh_buffer_duration: 6h +""" +pgsodium_root_key_content = ( + "0000000000000000000000000000000000000000000000000000000000000000" +) +postgrest_base_conf_content = """ +db-uri = "postgres://authenticator:postgres@localhost:5432/postgres?application_name=postgrest" +db-schema = "public, storage, graphql_public" +db-anon-role = "anon" +jwt-secret = "my_jwt_secret_which_is_not_so_secret" +role-claim-key = ".role" +openapi-mode = "ignore-privileges" +db-use-legacy-gucs = true +admin-server-port = 3001 +server-host = "*6" +db-pool-acquisition-timeout = 10 +max-rows = 1000 +db-extra-search-path = "public, extensions" +""" +gotrue_env_content = """ +API_EXTERNAL_URL=http://localhost +GOTRUE_API_HOST=0.0.0.0 +GOTRUE_SITE_URL= +GOTRUE_DB_DRIVER=postgres +GOTRUE_DB_DATABASE_URL=postgres://supabase_auth_admin@localhost/postgres?sslmode=disable +GOTRUE_JWT_ADMIN_ROLES=supabase_admin,service_role +GOTRUE_JWT_AUD=authenticated +GOTRUE_JWT_SECRET=my_jwt_secret_which_is_not_so_secret +""" +walg_config_json_content = """ +{ + "AWS_REGION": "ap-southeast-1", + "WALG_S3_PREFIX": "", + "PGDATABASE": "postgres", + "PGUSER": "supabase_admin", + "PGPORT": 5432, + "WALG_DELTA_MAX_STEPS": 6, + "WALG_COMPRESSION_METHOD": "lz4" +} +""" +anon_key = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6ImFhYWFhYWFhYWFhYWFhYWFhYWFhIiwicm9sZSI6ImFub24iLCJpYXQiOjE2OTYyMjQ5NjYsImV4cCI6MjAxMTgwMDk2Nn0.QW95aRPA-4QuLzuvaIeeoFKlJP9J2hvAIpJ3WJ6G5zo" +service_role_key = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6ImFhYWFhYWFhYWFhYWFhYWFhYWFhIiwicm9sZSI6InNlcnZpY2Vfcm9sZSIsImlhdCI6MTY5NjIyNDk2NiwiZXhwIjoyMDExODAwOTY2fQ.Om7yqv15gC3mLGitBmvFRB3M4IsLsX9fXzTQnFM7lu0" +supabase_admin_key = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6ImFhYWFhYWFhYWFhYWFhYWFhYWFhIiwicm9sZSI6InN1cGFiYXNlX2FkbWluIiwiaWF0IjoxNjk2MjI0OTY2LCJleHAiOjIwMTE4MDA5NjZ9.jrD3j2rBWiIx0vhVZzd1CXFv7qkAP392nBMadvXxk1c" +init_json_content = f""" +{{ + "jwt_secret": "my_jwt_secret_which_is_not_so_secret", + "project_ref": "aaaaaaaaaaaaaaaaaaaa", + "logflare_api_key": "", + "logflare_pitr_errors_source": "", + "logflare_postgrest_source": "", + "logflare_pgbouncer_source": "", + "logflare_db_source": "", + "logflare_gotrue_source": "", + "anon_key": "{anon_key}", + "service_key": "{service_role_key}", + "supabase_admin_key": "{supabase_admin_key}", + "common_name": "db.aaaaaaaaaaaaaaaaaaaa.supabase.red", + "region": "ap-southeast-1", + "init_database_only": false +}} +""" + +logger = logging.getLogger("ami-tests") +handler = logging.StreamHandler() +formatter = logging.Formatter( + '%(asctime)s %(name)-12s %(levelname)-8s %(message)s') +handler.setFormatter(formatter) +logger.addHandler(handler) +logger.setLevel(logging.DEBUG) + +# scope='session' uses the same container for all the tests; +# scope='function' uses a new container per test function. +@pytest.fixture(scope="session") +def host(): + ec2 = boto3.resource("ec2", region_name="ap-southeast-1") + images = list( + ec2.images.filter( + Filters=[{"Name": "name", "Values": ["supabase-postgres-ci-ami-test-nix"]}] + ) + ) + assert len(images) == 1 + image = images[0] + + def gzip_then_base64_encode(s: str) -> str: + return base64.b64encode(gzip.compress(s.encode())).decode() + + instance = list( + ec2.create_instances( + BlockDeviceMappings=[ + { + "DeviceName": "/dev/sda1", + "Ebs": { + "VolumeSize": 8, # gb + "Encrypted": True, + "DeleteOnTermination": True, + "VolumeType": "gp3", + }, + }, + ], + MetadataOptions={ + "HttpTokens": "required", + "HttpEndpoint": "enabled", + }, + IamInstanceProfile={"Name": "pg-ap-southeast-1"}, + InstanceType="t4g.micro", + MinCount=1, + MaxCount=1, + ImageId=image.id, + NetworkInterfaces=[ + { + "DeviceIndex": 0, + "AssociatePublicIpAddress": True, + "Groups": ["sg-0a883ca614ebfbae0", "sg-014d326be5a1627dc"], + } + ], + UserData=f"""#cloud-config +hostname: db-aaaaaaaaaaaaaaaaaaaa +write_files: + - {{path: /etc/postgresql.schema.sql, content: {gzip_then_base64_encode(postgresql_schema_sql_content)}, permissions: '0600', encoding: gz+b64}} + - {{path: /etc/realtime.env, content: {gzip_then_base64_encode(realtime_env_content)}, permissions: '0664', encoding: gz+b64}} + - {{path: /etc/adminapi/adminapi.yaml, content: {gzip_then_base64_encode(adminapi_yaml_content)}, permissions: '0600', owner: 'adminapi:root', encoding: gz+b64}} + - {{path: /etc/postgresql-custom/pgsodium_root.key, content: {gzip_then_base64_encode(pgsodium_root_key_content)}, permissions: '0600', owner: 'postgres:postgres', encoding: gz+b64}} + - {{path: /etc/postgrest/base.conf, content: {gzip_then_base64_encode(postgrest_base_conf_content)}, permissions: '0664', encoding: gz+b64}} + - {{path: /etc/gotrue.env, content: {gzip_then_base64_encode(gotrue_env_content)}, permissions: '0664', encoding: gz+b64}} + - {{path: /etc/wal-g/config.json, content: {gzip_then_base64_encode(walg_config_json_content)}, permissions: '0664', owner: 'wal-g:wal-g', encoding: gz+b64}} + - {{path: /tmp/init.json, content: {gzip_then_base64_encode(init_json_content)}, permissions: '0600', encoding: gz+b64}} +runcmd: + - 'sudo echo \"pgbouncer\" \"postgres\" >> /etc/pgbouncer/userlist.txt' + - 'cd /tmp && aws s3 cp --region ap-southeast-1 s3://init-scripts-staging/project/init.sh .' + - 'bash init.sh "staging"' + - 'rm -rf /tmp/*' +""", + TagSpecifications=[ + { + "ResourceType": "instance", + "Tags": [ + {"Key": "Name", "Value": "ci-ami-test"}, + {"Key": "creator", "Value": "testinfra-ci"}, + {"Key": "testinfra-run-id", "Value": RUN_ID} + ], + } + ], + ) + )[0] + instance.wait_until_running() + + ec2logger = EC2InstanceConnectLogger(debug=False) + temp_key = EC2InstanceConnectKey(ec2logger.get_logger()) + ec2ic = boto3.client("ec2-instance-connect", region_name="ap-southeast-1") + response = ec2ic.send_ssh_public_key( + InstanceId=instance.id, + InstanceOSUser="ubuntu", + SSHPublicKey=temp_key.get_pub_key(), + ) + assert response["Success"] + + # instance doesn't have public ip yet + while not instance.public_ip_address: + logger.warning("waiting for ip to be available") + sleep(5) + instance.reload() + + while True: + sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + if sock.connect_ex((instance.public_ip_address, 22)) == 0: + break + else: + logger.warning("waiting for ssh to be available") + sleep(10) + + host = testinfra.get_host( + # paramiko is an ssh backend + f"paramiko://ubuntu@{instance.public_ip_address}?timeout=60", + ssh_identity_file=temp_key.get_priv_key_file(), + ) + + def is_healthy(host) -> bool: + cmd = host.run("pg_isready -U postgres") + if cmd.failed is True: + logger.warning("pg not ready") + return False + + cmd = host.run(f"curl -sf -k --connect-timeout 30 --max-time 60 https://localhost:8085/health -H 'apikey: {supabase_admin_key}'") + if cmd.failed is True: + logger.warning("adminapi not ready") + return False + + cmd = host.run("curl -sf --connect-timeout 30 --max-time 60 http://localhost:3001/ready") + if cmd.failed is True: + logger.warning("postgrest not ready") + return False + + cmd = host.run("curl -sf --connect-timeout 30 --max-time 60 http://localhost:8081/health") + if cmd.failed is True: + logger.warning("gotrue not ready") + return False + + # TODO(thebengeu): switch to checking Envoy once it's the default. + cmd = host.run("sudo kong health") + if cmd.failed is True: + logger.warning("kong not ready") + return False + + cmd = host.run("sudo fail2ban-client status") + if cmd.failed is True: + logger.warning("fail2ban not ready") + return False + + return True + + while True: + if is_healthy(host): + break + sleep(1) + + # return a testinfra connection to the instance + yield host + + # at the end of the test suite, destroy the instance + instance.terminate() + + +def test_postgrest_is_running(host): + postgrest = host.service("postgrest") + assert postgrest.is_running + + +def test_postgrest_responds_to_requests(host): + res = requests.get( + f"http://{host.backend.get_hostname()}/rest/v1/", + headers={ + "apikey": anon_key, + "authorization": f"Bearer {anon_key}", + }, + ) + assert res.ok + + +def test_postgrest_can_connect_to_db(host): + res = requests.get( + f"http://{host.backend.get_hostname()}/rest/v1/buckets", + headers={ + "apikey": service_role_key, + "authorization": f"Bearer {service_role_key}", + "accept-profile": "storage", + }, + ) + assert res.ok + + +# There would be an error if the `apikey` query parameter isn't removed, +# since PostgREST treats query parameters as conditions. +# +# Worth testing since remove_apikey_query_parameter.lua uses regexp instead +# of parsed query parameters. +def test_postgrest_starting_apikey_query_parameter_is_removed(host): + res = requests.get( + f"http://{host.backend.get_hostname()}/rest/v1/buckets", + headers={ + "accept-profile": "storage", + }, + params={ + "apikey": service_role_key, + "id": "eq.absent", + "name": "eq.absent", + }, + ) + assert res.ok + + +def test_postgrest_middle_apikey_query_parameter_is_removed(host): + res = requests.get( + f"http://{host.backend.get_hostname()}/rest/v1/buckets", + headers={ + "accept-profile": "storage", + }, + params={ + "id": "eq.absent", + "apikey": service_role_key, + "name": "eq.absent", + }, + ) + assert res.ok + + +def test_postgrest_ending_apikey_query_parameter_is_removed(host): + res = requests.get( + f"http://{host.backend.get_hostname()}/rest/v1/buckets", + headers={ + "accept-profile": "storage", + }, + params={ + "id": "eq.absent", + "name": "eq.absent", + "apikey": service_role_key, + }, + ) + assert res.ok From d86253ced98074d352babeb244bf9c084f17d496 Mon Sep 17 00:00:00 2001 From: Sam Rose Date: Wed, 26 Jun 2024 05:12:14 -0400 Subject: [PATCH 21/45] chore: bump version --- common-nix.vars.pkr.hcl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common-nix.vars.pkr.hcl b/common-nix.vars.pkr.hcl index d898ad0ed..9f7196a05 100644 --- a/common-nix.vars.pkr.hcl +++ b/common-nix.vars.pkr.hcl @@ -1 +1 @@ -postgres-version = "15.6.1.85-nix-staged" +postgres-version = "15.6.1.86-nix-staged" From 3f83665d2209d69e7642b8779a0ac9b3c376297e Mon Sep 17 00:00:00 2001 From: Sam Rose Date: Wed, 26 Jun 2024 06:39:19 -0400 Subject: [PATCH 22/45] fix: capture and use ami name --- .github/workflows/testinfra-nix.yml | 8 ++++++-- common-nix.vars.pkr.hcl | 2 +- testinfra/test_ami_nix.py | 2 +- 3 files changed, 8 insertions(+), 4 deletions(-) diff --git a/.github/workflows/testinfra-nix.yml b/.github/workflows/testinfra-nix.yml index b9cb86897..97836c1cc 100644 --- a/.github/workflows/testinfra-nix.yml +++ b/.github/workflows/testinfra-nix.yml @@ -46,14 +46,18 @@ jobs: run: | packer init stage2-nix-psql.pkr.hcl GIT_SHA=${{github.sha}} - packer build -var "git-head-version=${GIT_SHA}" -var "packer-execution-id=${GITHUB_RUN_ID}" -var-file="development-arm.vars.pkr.hcl" -var-file="common-nix.vars.pkr.hcl" -var "postgres-version=ci-ami-test" -var "region=ap-southeast-1" -var 'ami_regions=["ap-southeast-1"]' -var "force-deregister=true" stage2-nix-psql.pkr.hcl - + packer build -var "git-head-version=${GIT_SHA}" -var "packer-execution-id=${GITHUB_RUN_ID}" -var-file="development-arm.vars.pkr.hcl" -var-file="common-nix.vars.pkr.hcl" -var "region=ap-southeast-1" -var 'ami_regions=["ap-southeast-1"]' -var "force-deregister=true" stage2-nix-psql.pkr.hcl + AMI_ID=$(grep -oP 'artifact,0,id,ami-\w+' output.txt | cut -d',' -f4) + AMI_NAME=$(aws ec2 describe-images --image-ids $AMI_ID --query 'Images[0].Name' --output text) + echo "AMI_NAME=$AMI_NAME" >> $GITHUB_ENV - name: Run tests timeout-minutes: 10 run: | # TODO: use poetry for pkg mgmt pip3 install boto3 boto3-stubs[essential] docker ec2instanceconnectcli pytest pytest-testinfra[paramiko,docker] requests pytest -vv -s testinfra/test_ami_nix.py + env: + AMI_NAME: ${{ env.AMI_NAME }} - name: Cleanup resources on build cancellation if: ${{ cancelled() }} run: | diff --git a/common-nix.vars.pkr.hcl b/common-nix.vars.pkr.hcl index 9f7196a05..2206646e0 100644 --- a/common-nix.vars.pkr.hcl +++ b/common-nix.vars.pkr.hcl @@ -1 +1 @@ -postgres-version = "15.6.1.86-nix-staged" +postgres-version = "15.6.1.87-nix-staged" diff --git a/testinfra/test_ami_nix.py b/testinfra/test_ami_nix.py index c2de11be3..7b6fa0fa6 100644 --- a/testinfra/test_ami_nix.py +++ b/testinfra/test_ami_nix.py @@ -167,7 +167,7 @@ def host(): ec2 = boto3.resource("ec2", region_name="ap-southeast-1") images = list( ec2.images.filter( - Filters=[{"Name": "name", "Values": ["supabase-postgres-ci-ami-test-nix"]}] + Filters=[{"Name": "name", "Values": [os.environ["AMI_NAME"]]}] ) ) assert len(images) == 1 From c51bb545b812d1f3c6a836fd45c85004535481d2 Mon Sep 17 00:00:00 2001 From: Sam Rose Date: Wed, 26 Jun 2024 07:10:14 -0400 Subject: [PATCH 23/45] fix: aws regions --- .github/workflows/testinfra-nix.yml | 2 +- common-nix.vars.pkr.hcl | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/testinfra-nix.yml b/.github/workflows/testinfra-nix.yml index 97836c1cc..cfea3111d 100644 --- a/.github/workflows/testinfra-nix.yml +++ b/.github/workflows/testinfra-nix.yml @@ -40,7 +40,7 @@ jobs: run: | packer init amazon-arm64-nix.pkr.hcl GIT_SHA=${{github.sha}} - packer build -var "git-head-version=${GIT_SHA}" -var "packer-execution-id=${GITHUB_RUN_ID}" -var-file="development-arm.vars.pkr.hcl" -var-file="common-nix.vars.pkr.hcl" -var "ansible_arguments=" amazon-arm64-nix.pkr.hcl + packer build -var "git-head-version=${GIT_SHA}" -var "packer-execution-id=${GITHUB_RUN_ID}" -var-file="development-arm.vars.pkr.hcl" -var-file="common-nix.vars.pkr.hcl" -var "ansible_arguments=" -var "region=ap-southeast-1" -var 'ami_regions=["ap-southeast-1"]' amazon-arm64-nix.pkr.hcl - name: Build AMI stage 2 run: | diff --git a/common-nix.vars.pkr.hcl b/common-nix.vars.pkr.hcl index 2206646e0..eaa096f94 100644 --- a/common-nix.vars.pkr.hcl +++ b/common-nix.vars.pkr.hcl @@ -1 +1 @@ -postgres-version = "15.6.1.87-nix-staged" +postgres-version = "15.6.1.88-nix-staged" From d57add212f451a5a7176098585970a76011897f4 Mon Sep 17 00:00:00 2001 From: Sam Rose Date: Wed, 26 Jun 2024 09:19:46 -0400 Subject: [PATCH 24/45] chore: capture ami name --- .github/workflows/testinfra-nix.yml | 6 +++--- common-nix.vars.pkr.hcl | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/testinfra-nix.yml b/.github/workflows/testinfra-nix.yml index cfea3111d..9d1b9c77e 100644 --- a/.github/workflows/testinfra-nix.yml +++ b/.github/workflows/testinfra-nix.yml @@ -7,6 +7,7 @@ on: jobs: test-ami: strategy: + fail-fast: false matrix: include: - runner: arm-runner @@ -46,9 +47,8 @@ jobs: run: | packer init stage2-nix-psql.pkr.hcl GIT_SHA=${{github.sha}} - packer build -var "git-head-version=${GIT_SHA}" -var "packer-execution-id=${GITHUB_RUN_ID}" -var-file="development-arm.vars.pkr.hcl" -var-file="common-nix.vars.pkr.hcl" -var "region=ap-southeast-1" -var 'ami_regions=["ap-southeast-1"]' -var "force-deregister=true" stage2-nix-psql.pkr.hcl - AMI_ID=$(grep -oP 'artifact,0,id,ami-\w+' output.txt | cut -d',' -f4) - AMI_NAME=$(aws ec2 describe-images --image-ids $AMI_ID --query 'Images[0].Name' --output text) + packer build -var "git-head-version=${GIT_SHA}" -var "packer-execution-id=${GITHUB_RUN_ID}" -var-file="development-arm.vars.pkr.hcl" -var-file="common-nix.vars.pkr.hcl" -var "region=ap-southeast-1" -var 'ami_regions=["ap-southeast-1"]' -var "force-deregister=true" stage2-nix-psql.pkr.hcl | tee build.log + AMI_NAME=$(grep -oP 'packer-demo-\d{10}' build.log | head -n 1) echo "AMI_NAME=$AMI_NAME" >> $GITHUB_ENV - name: Run tests timeout-minutes: 10 diff --git a/common-nix.vars.pkr.hcl b/common-nix.vars.pkr.hcl index eaa096f94..ce914fc26 100644 --- a/common-nix.vars.pkr.hcl +++ b/common-nix.vars.pkr.hcl @@ -1 +1 @@ -postgres-version = "15.6.1.88-nix-staged" +postgres-version = "15.6.1.90-nix-staged" From a1fc00bb5fe5272eef15117b4447c3fb1080990b Mon Sep 17 00:00:00 2001 From: samrose Date: Wed, 26 Jun 2024 12:56:38 -0400 Subject: [PATCH 25/45] chore: force_deregister all ami prior to create new --- .github/workflows/testinfra-nix.yml | 11 +++++------ testinfra/test_ami_nix.py | 2 +- 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/.github/workflows/testinfra-nix.yml b/.github/workflows/testinfra-nix.yml index 9d1b9c77e..0353fe700 100644 --- a/.github/workflows/testinfra-nix.yml +++ b/.github/workflows/testinfra-nix.yml @@ -41,27 +41,26 @@ jobs: run: | packer init amazon-arm64-nix.pkr.hcl GIT_SHA=${{github.sha}} - packer build -var "git-head-version=${GIT_SHA}" -var "packer-execution-id=${GITHUB_RUN_ID}" -var-file="development-arm.vars.pkr.hcl" -var-file="common-nix.vars.pkr.hcl" -var "ansible_arguments=" -var "region=ap-southeast-1" -var 'ami_regions=["ap-southeast-1"]' amazon-arm64-nix.pkr.hcl + packer build -var "git-head-version=${GIT_SHA}" -var "packer-execution-id=${GITHUB_RUN_ID}" -var-file="development-arm.vars.pkr.hcl" -var-file="common-nix.vars.pkr.hcl" -var "ansible_arguments=" -var "postgres-version=ci-ami-test" -var "region=ap-southeast-1" -var 'ami_regions=["ap-southeast-1"]' -var "force-deregister=true" amazon-arm64-nix.pkr.hcl - name: Build AMI stage 2 run: | packer init stage2-nix-psql.pkr.hcl GIT_SHA=${{github.sha}} - packer build -var "git-head-version=${GIT_SHA}" -var "packer-execution-id=${GITHUB_RUN_ID}" -var-file="development-arm.vars.pkr.hcl" -var-file="common-nix.vars.pkr.hcl" -var "region=ap-southeast-1" -var 'ami_regions=["ap-southeast-1"]' -var "force-deregister=true" stage2-nix-psql.pkr.hcl | tee build.log - AMI_NAME=$(grep -oP 'packer-demo-\d{10}' build.log | head -n 1) - echo "AMI_NAME=$AMI_NAME" >> $GITHUB_ENV + packer build -var "git-head-version=${GIT_SHA}" -var "packer-execution-id=${GITHUB_RUN_ID}" -var-file="development-arm.vars.pkr.hcl" -var-file="common-nix.vars.pkr.hcl" -var "ansible_arguments=" -var "region=ap-southeast-1" -var 'ami_regions=["ap-southeast-1"]' -var "force-deregister=true" stage2-nix-psql.pkr.hcl + - name: Run tests timeout-minutes: 10 run: | # TODO: use poetry for pkg mgmt pip3 install boto3 boto3-stubs[essential] docker ec2instanceconnectcli pytest pytest-testinfra[paramiko,docker] requests pytest -vv -s testinfra/test_ami_nix.py - env: - AMI_NAME: ${{ env.AMI_NAME }} + - name: Cleanup resources on build cancellation if: ${{ cancelled() }} run: | aws ec2 --region ap-southeast-1 describe-instances --filters "Name=tag:packerExecutionId,Values=${GITHUB_RUN_ID}" --query "Reservations[].Instances[].InstanceId" --output text | xargs -n 1 -I {} aws ec2 terminate-instances --region ap-southeast-1 --instance-ids {} + - name: Cleanup resources on build cancellation if: ${{ always() }} run: | diff --git a/testinfra/test_ami_nix.py b/testinfra/test_ami_nix.py index 7b6fa0fa6..c2de11be3 100644 --- a/testinfra/test_ami_nix.py +++ b/testinfra/test_ami_nix.py @@ -167,7 +167,7 @@ def host(): ec2 = boto3.resource("ec2", region_name="ap-southeast-1") images = list( ec2.images.filter( - Filters=[{"Name": "name", "Values": [os.environ["AMI_NAME"]]}] + Filters=[{"Name": "name", "Values": ["supabase-postgres-ci-ami-test-nix"]}] ) ) assert len(images) == 1 From 2b42a8b93880e041aaacd8c9cab740141e83c015 Mon Sep 17 00:00:00 2001 From: samrose Date: Wed, 26 Jun 2024 12:58:53 -0400 Subject: [PATCH 26/45] fix: pass same ami name each time --- .github/workflows/testinfra-nix.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/testinfra-nix.yml b/.github/workflows/testinfra-nix.yml index 0353fe700..f955c8162 100644 --- a/.github/workflows/testinfra-nix.yml +++ b/.github/workflows/testinfra-nix.yml @@ -47,7 +47,7 @@ jobs: run: | packer init stage2-nix-psql.pkr.hcl GIT_SHA=${{github.sha}} - packer build -var "git-head-version=${GIT_SHA}" -var "packer-execution-id=${GITHUB_RUN_ID}" -var-file="development-arm.vars.pkr.hcl" -var-file="common-nix.vars.pkr.hcl" -var "ansible_arguments=" -var "region=ap-southeast-1" -var 'ami_regions=["ap-southeast-1"]' -var "force-deregister=true" stage2-nix-psql.pkr.hcl + packer build -var "git-head-version=${GIT_SHA}" -var "packer-execution-id=${GITHUB_RUN_ID}" -var-file="development-arm.vars.pkr.hcl" -var-file="common-nix.vars.pkr.hcl" -var "ansible_arguments=" -var "postgres-version=ci-ami-test" -var "region=ap-southeast-1" -var 'ami_regions=["ap-southeast-1"]' -var "force-deregister=true" stage2-nix-psql.pkr.hcl - name: Run tests timeout-minutes: 10 From 00b69b16d14514c197ea0841858c4b7d1b526980 Mon Sep 17 00:00:00 2001 From: samrose Date: Wed, 26 Jun 2024 13:17:03 -0400 Subject: [PATCH 27/45] fix: manage concurrency of testinfra builds --- .github/workflows/testinfra-nix.yml | 5 ++++- .github/workflows/testinfra.yml | 5 ++++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/.github/workflows/testinfra-nix.yml b/.github/workflows/testinfra-nix.yml index f955c8162..60ae51702 100644 --- a/.github/workflows/testinfra-nix.yml +++ b/.github/workflows/testinfra-nix.yml @@ -1,4 +1,4 @@ -name: Testinfra Integration Tests +name: Testinfra Integration Tests Nix on: pull_request: @@ -16,6 +16,9 @@ jobs: ubuntu_version: 20.04 mcpu: neoverse-n1 runs-on: ${{ matrix.runner }} + concurrency: + group: build-${{ github.ref }} + cancel-in-progress: false timeout-minutes: 150 permissions: contents: write diff --git a/.github/workflows/testinfra.yml b/.github/workflows/testinfra.yml index 1b022eff2..652392943 100644 --- a/.github/workflows/testinfra.yml +++ b/.github/workflows/testinfra.yml @@ -1,7 +1,7 @@ name: Testinfra Integration Tests on: - pull_request: + #tmp deactivating pull_request: workflow_dispatch: jobs: @@ -14,6 +14,9 @@ jobs: - runner: arm-runner arch: arm64 runs-on: ${{ matrix.runner }} + concurrency: + group: build-${{ github.ref }} + cancel-in-progress: false timeout-minutes: 30 steps: - uses: actions/checkout@v3 From 2c4f72f07aadad4d702c478e6ac4e362600ac922 Mon Sep 17 00:00:00 2001 From: samrose Date: Wed, 26 Jun 2024 14:04:20 -0400 Subject: [PATCH 28/45] fix: no args on stage 2 --- .github/workflows/testinfra-nix.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/testinfra-nix.yml b/.github/workflows/testinfra-nix.yml index 60ae51702..1e4e828be 100644 --- a/.github/workflows/testinfra-nix.yml +++ b/.github/workflows/testinfra-nix.yml @@ -50,7 +50,7 @@ jobs: run: | packer init stage2-nix-psql.pkr.hcl GIT_SHA=${{github.sha}} - packer build -var "git-head-version=${GIT_SHA}" -var "packer-execution-id=${GITHUB_RUN_ID}" -var-file="development-arm.vars.pkr.hcl" -var-file="common-nix.vars.pkr.hcl" -var "ansible_arguments=" -var "postgres-version=ci-ami-test" -var "region=ap-southeast-1" -var 'ami_regions=["ap-southeast-1"]' -var "force-deregister=true" stage2-nix-psql.pkr.hcl + packer build -var "git-head-version=${GIT_SHA}" -var "packer-execution-id=${GITHUB_RUN_ID}" -var-file="development-arm.vars.pkr.hcl" -var-file="common-nix.vars.pkr.hcl" -var "postgres-version=ci-ami-test" -var "region=ap-southeast-1" -var 'ami_regions=["ap-southeast-1"]' -var "force-deregister=true" stage2-nix-psql.pkr.hcl - name: Run tests timeout-minutes: 10 From c527c59e38f990b21dec5e62574bff0c33d8d804 Mon Sep 17 00:00:00 2001 From: samrose Date: Wed, 26 Jun 2024 14:05:56 -0400 Subject: [PATCH 29/45] fix: re-intro original testinfra --- .github/workflows/testinfra.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/testinfra.yml b/.github/workflows/testinfra.yml index 652392943..a5fa7d9b2 100644 --- a/.github/workflows/testinfra.yml +++ b/.github/workflows/testinfra.yml @@ -1,7 +1,7 @@ name: Testinfra Integration Tests on: - #tmp deactivating pull_request: + pull_request: workflow_dispatch: jobs: From a4753dc0849c87655b7baca8b3881cc2e7a0f278 Mon Sep 17 00:00:00 2001 From: samrose Date: Wed, 26 Jun 2024 14:16:11 -0400 Subject: [PATCH 30/45] Revert "fix: re-intro original testinfra" This reverts commit f719e661dc04f21e97d1b8876930e6adcb0a402f. --- .github/workflows/testinfra.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/testinfra.yml b/.github/workflows/testinfra.yml index a5fa7d9b2..652392943 100644 --- a/.github/workflows/testinfra.yml +++ b/.github/workflows/testinfra.yml @@ -1,7 +1,7 @@ name: Testinfra Integration Tests on: - pull_request: + #tmp deactivating pull_request: workflow_dispatch: jobs: From 7355a299fe64e60e5bdf9d6ae1331d35829968f2 Mon Sep 17 00:00:00 2001 From: samrose Date: Wed, 26 Jun 2024 15:37:17 -0400 Subject: [PATCH 31/45] chore: push to re-trigger build --- .github/workflows/testinfra.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/testinfra.yml b/.github/workflows/testinfra.yml index 652392943..b1d82ea5a 100644 --- a/.github/workflows/testinfra.yml +++ b/.github/workflows/testinfra.yml @@ -1,7 +1,7 @@ name: Testinfra Integration Tests on: - #tmp deactivating pull_request: + #pull_request: workflow_dispatch: jobs: From 20c0224d4660de78312ed2b1a31a62dc139a1e58 Mon Sep 17 00:00:00 2001 From: samrose Date: Wed, 26 Jun 2024 16:06:21 -0400 Subject: [PATCH 32/45] chore: update instance name --- testinfra/test_ami_nix.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/testinfra/test_ami_nix.py b/testinfra/test_ami_nix.py index c2de11be3..cdcc0c44a 100644 --- a/testinfra/test_ami_nix.py +++ b/testinfra/test_ami_nix.py @@ -226,7 +226,7 @@ def gzip_then_base64_encode(s: str) -> str: { "ResourceType": "instance", "Tags": [ - {"Key": "Name", "Value": "ci-ami-test"}, + {"Key": "Name", "Value": "ci-ami-test-nix"}, {"Key": "creator", "Value": "testinfra-ci"}, {"Key": "testinfra-run-id", "Value": RUN_ID} ], From 2369eb1d3d3c0319470b0caab8f09bc31a75170f Mon Sep 17 00:00:00 2001 From: samrose Date: Mon, 1 Jul 2024 11:14:11 -0400 Subject: [PATCH 33/45] fix: location of pg_isready binary --- testinfra/test_ami_nix.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/testinfra/test_ami_nix.py b/testinfra/test_ami_nix.py index cdcc0c44a..97d336b2e 100644 --- a/testinfra/test_ami_nix.py +++ b/testinfra/test_ami_nix.py @@ -267,7 +267,7 @@ def gzip_then_base64_encode(s: str) -> str: ) def is_healthy(host) -> bool: - cmd = host.run("pg_isready -U postgres") + cmd = host.run("sudo -u postgres /var/lib/postgresql/.nix-profile/bin/pg_isready -U postgres") if cmd.failed is True: logger.warning("pg not ready") return False From 61b86a6a33d334b25eacadd613c5ac9f774e0926 Mon Sep 17 00:00:00 2001 From: samrose Date: Mon, 1 Jul 2024 12:01:12 -0400 Subject: [PATCH 34/45] fix: re-intro conventional ami infra test + more symlinks where expected --- .github/workflows/testinfra.yml | 2 +- .../tasks/stage2/stage2-setup-postgres.yml | 16 +++++++++------- 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/.github/workflows/testinfra.yml b/.github/workflows/testinfra.yml index b1d82ea5a..a5fa7d9b2 100644 --- a/.github/workflows/testinfra.yml +++ b/.github/workflows/testinfra.yml @@ -1,7 +1,7 @@ name: Testinfra Integration Tests on: - #pull_request: + pull_request: workflow_dispatch: jobs: diff --git a/ansible-nix/tasks/stage2/stage2-setup-postgres.yml b/ansible-nix/tasks/stage2/stage2-setup-postgres.yml index 3ebd743fd..41a543726 100644 --- a/ansible-nix/tasks/stage2/stage2-setup-postgres.yml +++ b/ansible-nix/tasks/stage2/stage2-setup-postgres.yml @@ -98,6 +98,15 @@ - "/var/lib/postgresql/.nix-profile/bin/*" become: yes +- name: Create symbolic links from /var/lib/postgresql/.nix-profile/bin to /usr/bin + file: + src: "{{ item }}" + dest: "/usr/bin/{{ item | basename }}" + state: link + with_fileglob: + - "/var/lib/postgresql/.nix-profile/bin/*" + become: yes + - name: Create symbolic links from /var/lib/postgresql/.nix-profile/bin to /usr/bin file: src: "/var/lib/postgresql/.nix-profile/bin/psql" @@ -115,13 +124,6 @@ # become: yes # It was decided to leave pljava disabled at https://github.com/supabase/postgres/pull/690 therefore removing this task -- name: Create symbolic links from /var/lib/postgresql/.nix-profile/bin to /usr/bin - file: - src: "/var/lib/postgresql/.nix-profile/bin/psql" - dest: "/usr/bin/psql" - state: link - become: yes - - name: Create symbolic links from /var/lib/postgresql/.nix-profile/share/postgresql to /usr/lib/postgresql/share/postgresql file: src: "{{ item }}" From 1a36906be81e4ec5a1edd30aa47f86ee74958574 Mon Sep 17 00:00:00 2001 From: samrose Date: Mon, 1 Jul 2024 12:55:27 -0400 Subject: [PATCH 35/45] fix: dealing with symlink creation issues --- .github/workflows/testinfra.yml | 6 ++--- .../tasks/stage2/stage2-setup-postgres.yml | 24 +++++++++++++++---- 2 files changed, 22 insertions(+), 8 deletions(-) diff --git a/.github/workflows/testinfra.yml b/.github/workflows/testinfra.yml index a5fa7d9b2..10dddccd8 100644 --- a/.github/workflows/testinfra.yml +++ b/.github/workflows/testinfra.yml @@ -14,9 +14,6 @@ jobs: - runner: arm-runner arch: arm64 runs-on: ${{ matrix.runner }} - concurrency: - group: build-${{ github.ref }} - cancel-in-progress: false timeout-minutes: 30 steps: - uses: actions/checkout@v3 @@ -52,6 +49,9 @@ jobs: ubuntu_version: 20.04 mcpu: neoverse-n1 runs-on: ${{ matrix.runner }} + concurrency: + group: build-${{ github.ref }} + cancel-in-progress: false timeout-minutes: 150 permissions: contents: write diff --git a/ansible-nix/tasks/stage2/stage2-setup-postgres.yml b/ansible-nix/tasks/stage2/stage2-setup-postgres.yml index 41a543726..261e550bc 100644 --- a/ansible-nix/tasks/stage2/stage2-setup-postgres.yml +++ b/ansible-nix/tasks/stage2/stage2-setup-postgres.yml @@ -98,6 +98,19 @@ - "/var/lib/postgresql/.nix-profile/bin/*" become: yes +- name: Check if /usr/bin/pg_config exists + stat: + path: /usr/bin/pg_config + register: pg_config_stat + +- name: Remove existing /usr/bin/pg_config if it is not a symlink + file: + path: /usr/bin/pg_config + state: absent + when: pg_config_stat.stat.exists and not pg_config_stat.stat.islnk + become: yes + + - name: Create symbolic links from /var/lib/postgresql/.nix-profile/bin to /usr/bin file: src: "{{ item }}" @@ -107,13 +120,14 @@ - "/var/lib/postgresql/.nix-profile/bin/*" become: yes -- name: Create symbolic links from /var/lib/postgresql/.nix-profile/bin to /usr/bin +- name: Ensure postgres user has ownership of symlink file: - src: "/var/lib/postgresql/.nix-profile/bin/psql" - dest: "/usr/bin/psql" - state: link + path: "/usr/bin/{{ item | basename }}" + owner: postgres + group: postgres + with_fileglob: + - "/var/lib/postgresql/.nix-profile/bin/*" become: yes - # - name: Create symbolic links from /var/lib/postgresql/.nix-profile/share/pljava to /usr/lib/postgresql/share/postgresql/pljava # file: # src: "{{ item }}" From 27f2aee5246635848daeb5776b69d872d8678795 Mon Sep 17 00:00:00 2001 From: samrose Date: Mon, 1 Jul 2024 13:44:20 -0400 Subject: [PATCH 36/45] fix: try concurrency rules on on all large builds --- .github/workflows/test.yml | 3 +++ .github/workflows/testinfra.yml | 3 +++ 2 files changed, 6 insertions(+) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index f2de89a82..107935651 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -18,6 +18,9 @@ jobs: arch: arm64 runs-on: ${{ matrix.runner }} timeout-minutes: 180 + concurrency: + group: build-${{ github.ref }} + cancel-in-progress: false env: POSTGRES_PORT: 5478 POSTGRES_PASSWORD: password diff --git a/.github/workflows/testinfra.yml b/.github/workflows/testinfra.yml index 10dddccd8..283ff0fb3 100644 --- a/.github/workflows/testinfra.yml +++ b/.github/workflows/testinfra.yml @@ -14,6 +14,9 @@ jobs: - runner: arm-runner arch: arm64 runs-on: ${{ matrix.runner }} + concurrency: + group: build-${{ github.ref }} + cancel-in-progress: false timeout-minutes: 30 steps: - uses: actions/checkout@v3 From c3b5aa92d077770ca435bde7a314c44e27cd487d Mon Sep 17 00:00:00 2001 From: samrose Date: Mon, 1 Jul 2024 13:48:13 -0400 Subject: [PATCH 37/45] chore; try with no concurrency rules --- .github/workflows/test.yml | 3 --- .github/workflows/testinfra-nix.yml | 3 --- .github/workflows/testinfra.yml | 6 ------ 3 files changed, 12 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 107935651..f2de89a82 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -18,9 +18,6 @@ jobs: arch: arm64 runs-on: ${{ matrix.runner }} timeout-minutes: 180 - concurrency: - group: build-${{ github.ref }} - cancel-in-progress: false env: POSTGRES_PORT: 5478 POSTGRES_PASSWORD: password diff --git a/.github/workflows/testinfra-nix.yml b/.github/workflows/testinfra-nix.yml index 1e4e828be..201140de0 100644 --- a/.github/workflows/testinfra-nix.yml +++ b/.github/workflows/testinfra-nix.yml @@ -16,9 +16,6 @@ jobs: ubuntu_version: 20.04 mcpu: neoverse-n1 runs-on: ${{ matrix.runner }} - concurrency: - group: build-${{ github.ref }} - cancel-in-progress: false timeout-minutes: 150 permissions: contents: write diff --git a/.github/workflows/testinfra.yml b/.github/workflows/testinfra.yml index 283ff0fb3..1b022eff2 100644 --- a/.github/workflows/testinfra.yml +++ b/.github/workflows/testinfra.yml @@ -14,9 +14,6 @@ jobs: - runner: arm-runner arch: arm64 runs-on: ${{ matrix.runner }} - concurrency: - group: build-${{ github.ref }} - cancel-in-progress: false timeout-minutes: 30 steps: - uses: actions/checkout@v3 @@ -52,9 +49,6 @@ jobs: ubuntu_version: 20.04 mcpu: neoverse-n1 runs-on: ${{ matrix.runner }} - concurrency: - group: build-${{ github.ref }} - cancel-in-progress: false timeout-minutes: 150 permissions: contents: write From b9b4741c1a89a263337aa00684ce319739d35748 Mon Sep 17 00:00:00 2001 From: samrose Date: Mon, 1 Jul 2024 14:20:41 -0400 Subject: [PATCH 38/45] chore: rerun --- .github/workflows/testinfra-nix.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/testinfra-nix.yml b/.github/workflows/testinfra-nix.yml index 201140de0..7a3e4eea0 100644 --- a/.github/workflows/testinfra-nix.yml +++ b/.github/workflows/testinfra-nix.yml @@ -5,7 +5,7 @@ on: workflow_dispatch: jobs: - test-ami: + test-ami-nix: strategy: fail-fast: false matrix: From 25a2fa286c8d1eb58037ba5c188be5fe07f407f3 Mon Sep 17 00:00:00 2001 From: samrose Date: Fri, 12 Jul 2024 11:24:12 -0400 Subject: [PATCH 39/45] chore: rebasing on develop Sam/nix and conventional consolidate (#1025) * feat: consolidate ansible and use vars to toggle AMI builds * fix: resolving merge conflict * chore: merge conflict * Revert "chore: merge conflict" This reverts commit ddc6b1d56b616026fd02ca30ed150fd548a49d70. * fix: update ansible location for script * fix: ansible consolidated location * fix: set up modes on system-setup * fix: set vars * fix: python True and False in extra_vars * fix: adj vars * fix: set all ami vars * fix: args as json * fix: nixpkg_mode * fix: refining mode rules * fix: consolidate create dirs * fix: cleaning up modes * fix: systemd psql service reload targets * fix: starting postgres issues * fix: timing for pgsodium_getkey script * fix: packer file upload on stage 2 * fix: consolidation of ansible location * fix: stage2 fix hostname * fix: limit stage that tasks run on * fix: setting hosts only on stage 2 nix ami * fix: rewrite hosts in ansible to allow for re-use of playbook file * chore: trigger checks * fix: pgsodium getkey is different for deb vs nix builds * fix: consolidated files location * fix: on stage2 postgres server is already started at this point * fix: without env vars * fix: vars on the right mode * fix: dedupe * fix: locales * fix: locales * chore: try step with no env vars * fix: no need to start pg at this point stage2 * fix: yaml * fix: more cleanup of modes * fix: snapd already absent at this point + consolidate tasks * fix: already absent at this point * fix: service not present at this stage * fix: disable different services for first boot depending on mode * fix: pg already restarted at this point in stage 2 * fix: no start on stage2 * fix: try to start in stage2 * chore: include env vars for stage2 * fix: stop before starting * fix: debpkg mode only * fix: should use conventional path * fix: need to locale-gen prior to initdb * fix: nix build needs .env * fix: stage2 treatment of pgsodium_getket * chore: re-introduce permission checks via osquery * fix: correct the path to files --------- Co-authored-by: Sam Rose --- amazon-arm64-nix.pkr.hcl | 4 +- .../files/admin_api_scripts/grow_fs.sh | 23 - .../admin_api_scripts/manage_readonly_mode.sh | 45 - .../admin_api_scripts/pg_egress_collect.pl | 132 --- .../pg_upgrade_scripts/check.sh | 16 - .../pg_upgrade_scripts/common.sh | 63 -- .../pg_upgrade_scripts/complete.sh | 153 ---- .../pg_upgrade_scripts/initiate.sh | 333 -------- .../pg_upgrade_scripts/pgsodium_getkey.sh | 12 - .../pg_upgrade_scripts/prepare.sh | 15 - ansible-nix/files/adminapi.service.j2 | 13 - ansible-nix/files/adminapi.sudoers.conf | 28 - ansible-nix/files/ansible-pull.service | 20 - ansible-nix/files/ansible-pull.timer | 11 - ansible-nix/files/apt_periodic | 4 - ansible-nix/files/cron.deny | 2 - .../files/database-optimizations.service.j2 | 12 - ansible-nix/files/default.sysstat | 9 - ansible-nix/files/envoy.service | 31 - ansible-nix/files/envoy_config/cds.yaml | 46 -- ansible-nix/files/envoy_config/envoy.yaml | 23 - ansible-nix/files/envoy_config/lds.yaml | 315 ------- .../remove_apikey_query_parameter.lua | 8 - .../fail2ban_config/fail2ban.service.conf | 6 - .../fail2ban_config/filter-pgbouncer.conf.j2 | 3 - .../fail2ban_config/filter-postgresql.conf.j2 | 3 - .../fail2ban_config/jail-pgbouncer.conf.j2 | 7 - .../fail2ban_config/jail-postgresql.conf.j2 | 8 - .../files/fail2ban_config/jail-ssh.conf | 4 - ansible-nix/files/fail2ban_config/jail.local | 4 - ansible-nix/files/gotrue.service.j2 | 21 - ansible-nix/files/journald.conf | 6 - ansible-nix/files/kong_config/kong.conf.j2 | 7 - ansible-nix/files/kong_config/kong.env.j2 | 8 - ansible-nix/files/kong_config/kong.service.j2 | 28 - ansible-nix/files/logind.conf | 2 - .../logrotate-postgres-auth.conf | 8 - .../logrotate-postgres-csv.conf | 11 - .../logrotate_config/logrotate-postgres.conf | 9 - .../logrotate_config/logrotate-walg.conf | 9 - ansible-nix/files/manifest.json | 1 - ansible-nix/files/nginx.service.j2 | 22 - .../files/pg_egress_collect.service.j2 | 13 - .../files/pgbouncer_config/pgbouncer.ini.j2 | 364 -------- .../pgbouncer_config/pgbouncer.service.j2 | 20 - .../pgbouncer_auth_schema.sql | 20 - .../tmpfiles.d-pgbouncer.conf.j2 | 2 - .../files/pgsodium_getkey_readonly.sh.j2 | 14 - .../files/pgsodium_getkey_urandom.sh.j2 | 10 - .../files/postgres_exporter.service.j2 | 14 - .../custom_read_replica.conf.j2 | 5 - .../postgresql_config/custom_walg.conf.j2 | 21 - .../files/postgresql_config/pg_hba.conf.j2 | 94 --- .../files/postgresql_config/pg_ident.conf.j2 | 50 -- .../postgresql_config/postgresql-csvlog.conf | 33 - .../postgresql-stdout-log.conf | 4 - .../postgresql_config/postgresql.conf.j2 | 776 ------------------ .../postgresql_config/postgresql.service.j2 | 24 - .../files/postgresql_config/supautils.conf.j2 | 12 - .../tmpfiles.postgresql.conf | 5 - .../before-create.sql | 84 -- .../dblink/after-create.sql | 14 - .../pg_cron/after-create.sql | 13 - .../pg_tle/after-create.sql | 1 - .../pgsodium/after-create.sql | 3 - .../postgis_tiger_geocoder/after-create.sql | 10 - .../postgres_fdw/after-create.sql | 21 - .../files/postgrest-optimizations.service.j2 | 11 - ansible-nix/files/postgrest.service.j2 | 18 - ansible-nix/files/services.slice.j2 | 6 - ansible-nix/files/sodium_extension.sql | 6 - ansible-nix/files/start-envoy.sh | 12 - ansible-nix/files/stat_extension.sql | 2 - ansible-nix/files/supabase_facts.ini | 2 - ansible-nix/files/sysstat.sysstat | 36 - ansible-nix/files/systemd-resolved.conf | 8 - ansible-nix/files/ufw.service.conf | 4 - ansible-nix/files/vector.service.j2 | 20 - .../wal_change_ownership.sh | 42 - .../files/walg_helper_scripts/wal_fetch.sh | 12 - ansible-nix/manifest-playbook.yml | 91 -- ansible-nix/playbook.yml | 120 --- .../tasks/clean-build-dependencies.yml | 21 - ansible-nix/tasks/finalize-ami.yml | 72 -- ansible-nix/tasks/internal/admin-api.yml | 92 --- ansible-nix/tasks/internal/admin-mgr.yml | 22 - .../tasks/internal/pg_egress_collect.yml | 15 - .../tasks/internal/postgres-exporter.yml | 48 -- .../tasks/internal/setup-ansible-pull.yml | 29 - ansible-nix/tasks/internal/setup-nftables.yml | 34 - ansible-nix/tasks/internal/supautils.yml | 77 -- ansible-nix/tasks/setup-envoy.yml | 60 -- ansible-nix/tasks/setup-extensions.yml | 94 --- ansible-nix/tasks/setup-fail2ban.yml | 70 -- ansible-nix/tasks/setup-gotrue.yml | 54 -- ansible-nix/tasks/setup-kong.yml | 62 -- ansible-nix/tasks/setup-migrations.yml | 13 - ansible-nix/tasks/setup-nginx.yml | 82 -- ansible-nix/tasks/setup-pgbouncer.yml | 135 --- ansible-nix/tasks/setup-postgres.yml | 139 ---- ansible-nix/tasks/setup-postgrest.yml | 84 -- ansible-nix/tasks/setup-supabase-internal.yml | 108 --- ansible-nix/tasks/setup-system.yml | 154 ---- ansible-nix/tasks/setup-wal-g.yml | 130 --- ansible-nix/tasks/stage2/optimizations.yml | 27 - ansible-nix/tasks/stage2/playbook.yml | 79 -- ansible-nix/tasks/stage2/setup-extensions.yml | 70 -- ansible-nix/tasks/stage2/setup-migrations.yml | 13 - ansible-nix/tasks/stage2/test-image.yml | 104 --- .../files/permission_check.py | 0 .../postgresql_config/postgresql.service.j2 | 1 + ansible/playbook.yml | 60 +- ansible/tasks/finalize-ami.yml | 1 + ansible/tasks/internal/optimizations.yml | 32 +- ansible/tasks/setup-docker.yml | 12 + ansible/tasks/setup-fail2ban.yml | 10 + ansible/tasks/setup-migrations.yml | 4 +- ansible/tasks/setup-postgres.yml | 126 ++- ansible/tasks/setup-system.yml | 27 +- .../tasks}/stage2-setup-postgres.yml | 143 +--- ansible/tasks/test-image.yml | 44 +- .../scripts/surrogate-bootstrap-nix.sh | 2 +- ebssurrogate/scripts/surrogate-bootstrap.sh | 2 +- scripts/nix-provision.sh | 4 +- stage2-nix-psql.pkr.hcl | 12 +- testinfra/test_ami_nix.py | 2 +- 126 files changed, 315 insertions(+), 5557 deletions(-) delete mode 100644 ansible-nix/files/admin_api_scripts/grow_fs.sh delete mode 100644 ansible-nix/files/admin_api_scripts/manage_readonly_mode.sh delete mode 100644 ansible-nix/files/admin_api_scripts/pg_egress_collect.pl delete mode 100755 ansible-nix/files/admin_api_scripts/pg_upgrade_scripts/check.sh delete mode 100755 ansible-nix/files/admin_api_scripts/pg_upgrade_scripts/common.sh delete mode 100755 ansible-nix/files/admin_api_scripts/pg_upgrade_scripts/complete.sh delete mode 100755 ansible-nix/files/admin_api_scripts/pg_upgrade_scripts/initiate.sh delete mode 100755 ansible-nix/files/admin_api_scripts/pg_upgrade_scripts/pgsodium_getkey.sh delete mode 100755 ansible-nix/files/admin_api_scripts/pg_upgrade_scripts/prepare.sh delete mode 100644 ansible-nix/files/adminapi.service.j2 delete mode 100644 ansible-nix/files/adminapi.sudoers.conf delete mode 100644 ansible-nix/files/ansible-pull.service delete mode 100644 ansible-nix/files/ansible-pull.timer delete mode 100644 ansible-nix/files/apt_periodic delete mode 100644 ansible-nix/files/cron.deny delete mode 100644 ansible-nix/files/database-optimizations.service.j2 delete mode 100644 ansible-nix/files/default.sysstat delete mode 100644 ansible-nix/files/envoy.service delete mode 100644 ansible-nix/files/envoy_config/cds.yaml delete mode 100644 ansible-nix/files/envoy_config/envoy.yaml delete mode 100644 ansible-nix/files/envoy_config/lds.yaml delete mode 100644 ansible-nix/files/envoy_config/remove_apikey_query_parameter.lua delete mode 100644 ansible-nix/files/fail2ban_config/fail2ban.service.conf delete mode 100644 ansible-nix/files/fail2ban_config/filter-pgbouncer.conf.j2 delete mode 100644 ansible-nix/files/fail2ban_config/filter-postgresql.conf.j2 delete mode 100644 ansible-nix/files/fail2ban_config/jail-pgbouncer.conf.j2 delete mode 100644 ansible-nix/files/fail2ban_config/jail-postgresql.conf.j2 delete mode 100644 ansible-nix/files/fail2ban_config/jail-ssh.conf delete mode 100644 ansible-nix/files/fail2ban_config/jail.local delete mode 100644 ansible-nix/files/gotrue.service.j2 delete mode 100644 ansible-nix/files/journald.conf delete mode 100644 ansible-nix/files/kong_config/kong.conf.j2 delete mode 100644 ansible-nix/files/kong_config/kong.env.j2 delete mode 100644 ansible-nix/files/kong_config/kong.service.j2 delete mode 100644 ansible-nix/files/logind.conf delete mode 100644 ansible-nix/files/logrotate_config/logrotate-postgres-auth.conf delete mode 100644 ansible-nix/files/logrotate_config/logrotate-postgres-csv.conf delete mode 100644 ansible-nix/files/logrotate_config/logrotate-postgres.conf delete mode 100644 ansible-nix/files/logrotate_config/logrotate-walg.conf delete mode 100644 ansible-nix/files/manifest.json delete mode 100644 ansible-nix/files/nginx.service.j2 delete mode 100644 ansible-nix/files/pg_egress_collect.service.j2 delete mode 100644 ansible-nix/files/pgbouncer_config/pgbouncer.ini.j2 delete mode 100644 ansible-nix/files/pgbouncer_config/pgbouncer.service.j2 delete mode 100644 ansible-nix/files/pgbouncer_config/pgbouncer_auth_schema.sql delete mode 100644 ansible-nix/files/pgbouncer_config/tmpfiles.d-pgbouncer.conf.j2 delete mode 100644 ansible-nix/files/pgsodium_getkey_readonly.sh.j2 delete mode 100755 ansible-nix/files/pgsodium_getkey_urandom.sh.j2 delete mode 100644 ansible-nix/files/postgres_exporter.service.j2 delete mode 100644 ansible-nix/files/postgresql_config/custom_read_replica.conf.j2 delete mode 100644 ansible-nix/files/postgresql_config/custom_walg.conf.j2 delete mode 100755 ansible-nix/files/postgresql_config/pg_hba.conf.j2 delete mode 100755 ansible-nix/files/postgresql_config/pg_ident.conf.j2 delete mode 100644 ansible-nix/files/postgresql_config/postgresql-csvlog.conf delete mode 100644 ansible-nix/files/postgresql_config/postgresql-stdout-log.conf delete mode 100644 ansible-nix/files/postgresql_config/postgresql.conf.j2 delete mode 100644 ansible-nix/files/postgresql_config/postgresql.service.j2 delete mode 100644 ansible-nix/files/postgresql_config/supautils.conf.j2 delete mode 100644 ansible-nix/files/postgresql_config/tmpfiles.postgresql.conf delete mode 100644 ansible-nix/files/postgresql_extension_custom_scripts/before-create.sql delete mode 100644 ansible-nix/files/postgresql_extension_custom_scripts/dblink/after-create.sql delete mode 100644 ansible-nix/files/postgresql_extension_custom_scripts/pg_cron/after-create.sql delete mode 100644 ansible-nix/files/postgresql_extension_custom_scripts/pg_tle/after-create.sql delete mode 100644 ansible-nix/files/postgresql_extension_custom_scripts/pgsodium/after-create.sql delete mode 100644 ansible-nix/files/postgresql_extension_custom_scripts/postgis_tiger_geocoder/after-create.sql delete mode 100644 ansible-nix/files/postgresql_extension_custom_scripts/postgres_fdw/after-create.sql delete mode 100644 ansible-nix/files/postgrest-optimizations.service.j2 delete mode 100644 ansible-nix/files/postgrest.service.j2 delete mode 100644 ansible-nix/files/services.slice.j2 delete mode 100644 ansible-nix/files/sodium_extension.sql delete mode 100644 ansible-nix/files/start-envoy.sh delete mode 100644 ansible-nix/files/stat_extension.sql delete mode 100644 ansible-nix/files/supabase_facts.ini delete mode 100644 ansible-nix/files/sysstat.sysstat delete mode 100644 ansible-nix/files/systemd-resolved.conf delete mode 100644 ansible-nix/files/ufw.service.conf delete mode 100644 ansible-nix/files/vector.service.j2 delete mode 100644 ansible-nix/files/walg_helper_scripts/wal_change_ownership.sh delete mode 100644 ansible-nix/files/walg_helper_scripts/wal_fetch.sh delete mode 100644 ansible-nix/manifest-playbook.yml delete mode 100644 ansible-nix/playbook.yml delete mode 100644 ansible-nix/tasks/clean-build-dependencies.yml delete mode 100644 ansible-nix/tasks/finalize-ami.yml delete mode 100644 ansible-nix/tasks/internal/admin-api.yml delete mode 100644 ansible-nix/tasks/internal/admin-mgr.yml delete mode 100644 ansible-nix/tasks/internal/pg_egress_collect.yml delete mode 100644 ansible-nix/tasks/internal/postgres-exporter.yml delete mode 100644 ansible-nix/tasks/internal/setup-ansible-pull.yml delete mode 100644 ansible-nix/tasks/internal/setup-nftables.yml delete mode 100644 ansible-nix/tasks/internal/supautils.yml delete mode 100644 ansible-nix/tasks/setup-envoy.yml delete mode 100644 ansible-nix/tasks/setup-extensions.yml delete mode 100644 ansible-nix/tasks/setup-fail2ban.yml delete mode 100644 ansible-nix/tasks/setup-gotrue.yml delete mode 100644 ansible-nix/tasks/setup-kong.yml delete mode 100644 ansible-nix/tasks/setup-migrations.yml delete mode 100644 ansible-nix/tasks/setup-nginx.yml delete mode 100644 ansible-nix/tasks/setup-pgbouncer.yml delete mode 100644 ansible-nix/tasks/setup-postgres.yml delete mode 100644 ansible-nix/tasks/setup-postgrest.yml delete mode 100644 ansible-nix/tasks/setup-supabase-internal.yml delete mode 100644 ansible-nix/tasks/setup-system.yml delete mode 100644 ansible-nix/tasks/setup-wal-g.yml delete mode 100644 ansible-nix/tasks/stage2/optimizations.yml delete mode 100644 ansible-nix/tasks/stage2/playbook.yml delete mode 100644 ansible-nix/tasks/stage2/setup-extensions.yml delete mode 100644 ansible-nix/tasks/stage2/setup-migrations.yml delete mode 100644 ansible-nix/tasks/stage2/test-image.yml rename {ansible-nix => ansible}/files/permission_check.py (100%) rename {ansible-nix/tasks/stage2 => ansible/tasks}/stage2-setup-postgres.yml (69%) diff --git a/amazon-arm64-nix.pkr.hcl b/amazon-arm64-nix.pkr.hcl index 88b50ced8..118196473 100644 --- a/amazon-arm64-nix.pkr.hcl +++ b/amazon-arm64-nix.pkr.hcl @@ -239,7 +239,7 @@ build { } provisioner "file" { - source = "ansible-nix" + source = "ansible" destination = "/tmp/ansible-playbook" } @@ -250,7 +250,7 @@ build { provisioner "file" { source = "ansible/vars.yml" - destination = "/tmp/ansible-playbook/ansible-nix/vars.yml" + destination = "/tmp/ansible-playbook/vars.yml" } provisioner "shell" { diff --git a/ansible-nix/files/admin_api_scripts/grow_fs.sh b/ansible-nix/files/admin_api_scripts/grow_fs.sh deleted file mode 100644 index 6d2a4e5e4..000000000 --- a/ansible-nix/files/admin_api_scripts/grow_fs.sh +++ /dev/null @@ -1,23 +0,0 @@ -#! /usr/bin/env bash - -set -euo pipefail - -VOLUME_TYPE=${1:-data} - -if [ -b /dev/nvme1n1 ] ; then - if [[ "${VOLUME_TYPE}" == "data" ]]; then - resize2fs /dev/nvme1n1 - - elif [[ "${VOLUME_TYPE}" == "root" ]] ; then - growpart /dev/nvme0n1 2 - resize2fs /dev/nvme0n1p2 - - else - echo "Invalid disk specified: ${VOLUME_TYPE}" - exit 1 - fi -else - growpart /dev/nvme0n1 2 - resize2fs /dev/nvme0n1p2 -fi -echo "Done resizing disk" diff --git a/ansible-nix/files/admin_api_scripts/manage_readonly_mode.sh b/ansible-nix/files/admin_api_scripts/manage_readonly_mode.sh deleted file mode 100644 index 41c9f5a1e..000000000 --- a/ansible-nix/files/admin_api_scripts/manage_readonly_mode.sh +++ /dev/null @@ -1,45 +0,0 @@ -#! /usr/bin/env bash - -set -euo pipefail - -SUBCOMMAND=$1 - -function set_mode { - MODE=$1 - psql -h localhost -U supabase_admin -d postgres -c "ALTER SYSTEM SET default_transaction_read_only to ${MODE};" - psql -h localhost -U supabase_admin -d postgres -c "SELECT pg_reload_conf();" -} - -function check_override { - COMMAND=$(cat < 220.235.16.223.62599: Flags [S.], cksum 0x5de3 (incorrect -> 0x63da), seq 2314200657, ack 2071735457, win 62643, options [mss 8961,sackOK,TS val 3358598837 ecr 1277499190,nop,wscale 7], length 0 -# 1674013833.989257 IP (tos 0x0, ttl 64, id 24975, offset 0, flags [DF], proto TCP (6), length 52) -# 10.112.101.122.5432 > 220.235.16.223.62599: Flags [.], cksum 0x5ddb (incorrect -> 0xa25b), seq 1, ack 9, win 490, options [nop,nop,TS val 3358598885 ecr 1277499232], length 0 -# -# Sample IPv6 input lines: -# -# 1706483718.836526 IP6 (flowlabel 0x0bf27, hlim 64, next-header TCP (6) payload length: 125) 2406:da18:4fd:9b00:959:c52:ce68:10c8.5432 > 2406:da12:d78:f501:1273:296c:2482:c7a7.50530: Flags [P.], seq 25:118, ack 125, win 488, options [nop,nop,TS val 1026340732 ecr 1935666426], length 93 -# 1706483718.912083 IP6 (flowlabel 0x0bf27, hlim 64, next-header TCP (6) payload length: 501) 2406:da18:4fd:9b00:959:c52:ce68:10c8.5432 > 2406:da12:d78:f501:1273:296c:2482:c7a7.50530: Flags [P.], seq 118:587, ack 234, win 488, options [nop,nop,TS val 1026340807 ecr 1935666497], length 469 -# 1706483718.984001 IP6 (flowlabel 0x0bf27, hlim 64, next-header TCP (6) payload length: 151) 2406:da18:4fd:9b00:959:c52:ce68:10c8.5432 > 2406:da12:d78:f501:1273:296c:2482:c7a7.50530: Flags [P.], seq 587:706, ack 448, win 487, options [nop,nop,TS val 1026340879 ecr 1935666569], length 119 -sub extract_packet_length { - my ($line) = @_; - - #print("debug: >> " . $line); - - if ($line =~ /^.*, length (\d+)$/) { - # extract tcp packet length and add it up - my $len = $1; - $captured_len += $len; - } -} - -# write total length to file -sub write_file { - my ($output) = @_; - - my $now = strftime "%F %T", localtime time; - print "[$now] write captured len $captured_len to $output\n"; - - open(my $fh, "+>", $output) or die "Could not open file '$output' $!"; - print $fh "$captured_len"; - close($fh) or die "Could not write file '$output' $!"; -} - -# main -sub main { - # get arguments - GetOptions( - "interval:i" => \(my $interval = 60), - "output:s" => \(my $output = "/tmp/pg_egress_collect.txt"), - "help" => sub { HelpMessage(0) }, - ) or HelpMessage(1); - - my $loop = IO::Async::Loop->new; - - # tcpdump extractor - my $extractor = IO::Async::Stream->new_for_stdin( - on_read => sub { - my ($self, $buffref, $eof) = @_; - - while($$buffref =~ s/^(.*\n)//) { - my $line = $1; - extract_packet_length($line); - } - - return 0; - }, - ); - - # schedule file writer per minute - my $writer = IO::Async::Timer::Periodic->new( - interval => $interval, - on_tick => sub { - write_file($output); - - # reset total captured length - $captured_len = 0; - }, - ); - $writer->start; - - print "pg_egress_collect started, egress data will be saved to $output at interval $interval seconds.\n"; - - $loop->add($extractor); - $loop->add($writer); - $loop->run; -} - -main(); - -__END__ - -=head1 NAME - -pg_egress_collect.pl - collect egress from tcpdump output, extract TCP packet length, aggregate in specified interval and write to output file. - -=head1 SYNOPSIS - -pg_egress_collect.pl [-i interval] [-o output] - -Options: - - -i, --interval interval - output file write interval, in seconds, default is 60 seconds - - -o, --output output - output file path, default is /tmp/pg_egress_collect.txt - - -h, --help - print this help message - -=cut diff --git a/ansible-nix/files/admin_api_scripts/pg_upgrade_scripts/check.sh b/ansible-nix/files/admin_api_scripts/pg_upgrade_scripts/check.sh deleted file mode 100755 index f85e9571b..000000000 --- a/ansible-nix/files/admin_api_scripts/pg_upgrade_scripts/check.sh +++ /dev/null @@ -1,16 +0,0 @@ -#! /usr/bin/env bash -## This script provides a method to check the status of the database upgrade -## process, which is updated in /tmp/pg-upgrade-status by initiate.sh -## This runs on the old (source) instance. - -set -euo pipefail - -STATUS_FILE="/tmp/pg-upgrade-status" - -if [ -f "${STATUS_FILE}" ]; then - STATUS=$(cat "${STATUS_FILE}") - echo -n "${STATUS}" -else - echo -n "unknown" -fi - diff --git a/ansible-nix/files/admin_api_scripts/pg_upgrade_scripts/common.sh b/ansible-nix/files/admin_api_scripts/pg_upgrade_scripts/common.sh deleted file mode 100755 index bf549b212..000000000 --- a/ansible-nix/files/admin_api_scripts/pg_upgrade_scripts/common.sh +++ /dev/null @@ -1,63 +0,0 @@ -#! /usr/bin/env bash - -# Common functions and variables used by initiate.sh and complete.sh - -REPORTING_PROJECT_REF="ihmaxnjpcccasmrbkpvo" -REPORTING_CREDENTIALS_FILE="/root/upgrade-reporting-credentials" - -REPORTING_ANON_KEY="" -if [ -f "$REPORTING_CREDENTIALS_FILE" ]; then - REPORTING_ANON_KEY=$(cat "$REPORTING_CREDENTIALS_FILE") -fi - -function run_sql { - psql -h localhost -U supabase_admin -d postgres "$@" -} - -function ship_logs { - LOG_FILE=$1 - - if [ -z "$REPORTING_ANON_KEY" ]; then - echo "No reporting key found. Skipping log upload." - return 0 - fi - - if [ ! -f "$LOG_FILE" ]; then - echo "No log file found. Skipping log upload." - return 0 - fi - - if [ ! -s "$LOG_FILE" ]; then - echo "Log file is empty. Skipping log upload." - return 0 - fi - - HOSTNAME=$(hostname) - DERIVED_REF="${HOSTNAME##*-}" - - printf -v BODY '{ "ref": "%s", "step": "%s", "content": %s }' "$DERIVED_REF" "completion" "$(cat "$LOG_FILE" | jq -Rs '.')" - curl -sf -X POST "https://$REPORTING_PROJECT_REF.supabase.co/rest/v1/error_logs" \ - -H "apikey: ${REPORTING_ANON_KEY}" \ - -H 'Content-type: application/json' \ - -d "$BODY" -} - -function retry { - local retries=$1 - shift - - local count=0 - until "$@"; do - exit=$? - wait=$((2 ** (count + 1))) - count=$((count + 1)) - if [ $count -lt "$retries" ]; then - echo "Command $* exited with code $exit, retrying..." - sleep $wait - else - echo "Command $* exited with code $exit, no more retries left." - return $exit - fi - done - return 0 -} diff --git a/ansible-nix/files/admin_api_scripts/pg_upgrade_scripts/complete.sh b/ansible-nix/files/admin_api_scripts/pg_upgrade_scripts/complete.sh deleted file mode 100755 index b139091ed..000000000 --- a/ansible-nix/files/admin_api_scripts/pg_upgrade_scripts/complete.sh +++ /dev/null @@ -1,153 +0,0 @@ -#! /usr/bin/env bash - -## This script is run on the newly launched instance which is to be promoted to -## become the primary database instance once the upgrade successfully completes. -## The following commands copy custom PG configs and enable previously disabled -## extensions, containing regtypes referencing system OIDs. - -set -eEuo pipefail - -SCRIPT_DIR=$(dirname -- "$0";) -# shellcheck disable=SC1091 -source "$SCRIPT_DIR/common.sh" - -LOG_FILE="/var/log/pg-upgrade-complete.log" - -function cleanup { - UPGRADE_STATUS=${1:-"failed"} - EXIT_CODE=${?:-0} - - echo "$UPGRADE_STATUS" > /tmp/pg-upgrade-status - - ship_logs "$LOG_FILE" || true - - exit "$EXIT_CODE" -} - -function execute_patches { - # Patch pg_net grants - PG_NET_ENABLED=$(run_sql -A -t -c "select count(*) > 0 from pg_extension where extname = 'pg_net';") - - if [ "$PG_NET_ENABLED" = "t" ]; then - PG_NET_GRANT_QUERY=$(cat < 0 from pg_extension where extname = 'pg_cron' and extowner::regrole::text = 'postgres';") - - if [ "$HAS_PG_CRON_OWNED_BY_POSTGRES" = "t" ]; then - RECREATE_PG_CRON_QUERY=$(cat < /tmp/pg-upgrade-status - - echo "1. Mounting data disk" - retry 3 mount -a -v - - # copying custom configurations - echo "2. Copying custom configurations" - retry 3 copy_configs - - echo "3. Starting postgresql" - retry 3 service postgresql start - - echo "4. Running generated SQL files" - retry 3 run_generated_sql - - echo "4.1. Applying patches" - execute_patches || true - - run_sql -c "ALTER USER postgres WITH NOSUPERUSER;" - - echo "4.2. Applying authentication scheme updates" - retry 3 apply_auth_scheme_updates - - sleep 5 - - echo "5. Restarting postgresql" - retry 3 service postgresql restart - - echo "5.1. Restarting gotrue and postgrest" - retry 3 service gotrue restart - retry 3 service postgrest restart - - echo "6. Starting vacuum analyze" - retry 3 start_vacuum_analyze -} - -function copy_configs { - cp -R /data/conf/* /etc/postgresql-custom/ - chown -R postgres:postgres /var/lib/postgresql/data - chown -R postgres:postgres /data/pgdata -} - -function run_generated_sql { - if [ -d /data/sql ]; then - for FILE in /data/sql/*.sql; do - if [ -f "$FILE" ]; then - run_sql -f "$FILE" - fi - done - fi -} - -# Projects which had their passwords hashed using md5 need to have their passwords reset -# Passwords for managed roles are already present in /etc/postgresql.schema.sql -function apply_auth_scheme_updates { - PASSWORD_ENCRYPTION_SETTING=$(run_sql -A -t -c "SHOW password_encryption;") - if [ "$PASSWORD_ENCRYPTION_SETTING" = "md5" ]; then - run_sql -c "ALTER SYSTEM SET password_encryption TO 'scram-sha-256';" - run_sql -c "SELECT pg_reload_conf();" - run_sql -f /etc/postgresql.schema.sql - fi -} - -function start_vacuum_analyze { - echo "complete" > /tmp/pg-upgrade-status - su -c 'vacuumdb --all --analyze-in-stages' -s "$SHELL" postgres - echo "Upgrade job completed" -} - -trap cleanup ERR - - -complete_pg_upgrade >> $LOG_FILE 2>&1 & diff --git a/ansible-nix/files/admin_api_scripts/pg_upgrade_scripts/initiate.sh b/ansible-nix/files/admin_api_scripts/pg_upgrade_scripts/initiate.sh deleted file mode 100755 index 492890a1e..000000000 --- a/ansible-nix/files/admin_api_scripts/pg_upgrade_scripts/initiate.sh +++ /dev/null @@ -1,333 +0,0 @@ -#! /usr/bin/env bash - -## This script is run on the old (source) instance, mounting the data disk -## of the newly launched instance, disabling extensions containing regtypes, -## and running pg_upgrade. -## It reports the current status of the upgrade process to /tmp/pg-upgrade-status, -## which can then be subsequently checked through check.sh. - -# Extensions to disable before running pg_upgrade. -# Running an upgrade with these extensions enabled will result in errors due to -# them depending on regtypes referencing system OIDs or outdated library files. -EXTENSIONS_TO_DISABLE=( - "pg_graphql" -) - -PG14_EXTENSIONS_TO_DISABLE=( - "wrappers" - "pgrouting" -) - -PG13_EXTENSIONS_TO_DISABLE=( - "pgrouting" -) - -set -eEuo pipefail - -SCRIPT_DIR=$(dirname -- "$0";) -# shellcheck disable=SC1091 -source "$SCRIPT_DIR/common.sh" - -LOG_FILE="/var/log/pg-upgrade-initiate.log" - -PGVERSION=$1 -IS_DRY_RUN=${2:-false} -if [ "$IS_DRY_RUN" != false ]; then - IS_DRY_RUN=true -fi - -MOUNT_POINT="/data_migration" - -POST_UPGRADE_EXTENSION_SCRIPT="/tmp/pg_upgrade/pg_upgrade_extensions.sql" -OLD_PGVERSION=$(run_sql -A -t -c "SHOW server_version;") - -POSTGRES_CONFIG_PATH="/etc/postgresql/postgresql.conf" -PGBINOLD="/usr/lib/postgresql/bin" -PGLIBOLD="/usr/lib/postgresql/lib" - -# If upgrading from older major PG versions, disable specific extensions -if [[ "$OLD_PGVERSION" =~ ^14.* ]]; then - EXTENSIONS_TO_DISABLE+=("${PG14_EXTENSIONS_TO_DISABLE[@]}") -elif [[ "$OLD_PGVERSION" =~ ^13.* ]]; then - EXTENSIONS_TO_DISABLE+=("${PG13_EXTENSIONS_TO_DISABLE[@]}") -elif [[ "$OLD_PGVERSION" =~ ^12.* ]]; then - POSTGRES_CONFIG_PATH="/etc/postgresql/12/main/postgresql.conf" - PGBINOLD="/usr/lib/postgresql/12/bin" -fi - -echo "Detected PG version: $PGVERSION" - -cleanup() { - UPGRADE_STATUS=${1:-"failed"} - EXIT_CODE=${?:-0} - - if [ "$UPGRADE_STATUS" = "failed" ]; then - echo "Upgrade job failed. Cleaning up and exiting." - fi - - if [ -d "${MOUNT_POINT}/pgdata/pg_upgrade_output.d/" ]; then - echo "Copying pg_upgrade output to /var/log" - cp -R "${MOUNT_POINT}/pgdata/pg_upgrade_output.d/" /var/log/ || true - ship_logs "$LOG_FILE" || true - tail -n +1 /var/log/pg_upgrade_output.d/*/* > /var/log/pg_upgrade_output.d/pg_upgrade.log || true - ship_logs "/var/log/pg_upgrade_output.d/pg_upgrade.log" || true - fi - - if [ -L "/usr/share/postgresql/${PGVERSION}" ]; then - rm "/usr/share/postgresql/${PGVERSION}" - - if [ -f "/usr/share/postgresql/${PGVERSION}.bak" ]; then - mv "/usr/share/postgresql/${PGVERSION}.bak" "/usr/share/postgresql/${PGVERSION}" - fi - - if [ -d "/usr/share/postgresql/${PGVERSION}.bak" ]; then - mv "/usr/share/postgresql/${PGVERSION}.bak" "/usr/share/postgresql/${PGVERSION}" - fi - fi - - if [ "$IS_DRY_RUN" = false ]; then - echo "Restarting postgresql" - systemctl enable postgresql - retry 5 systemctl restart postgresql - fi - - echo "Re-enabling extensions" - if [ -f $POST_UPGRADE_EXTENSION_SCRIPT ]; then - run_sql -f $POST_UPGRADE_EXTENSION_SCRIPT - fi - - echo "Removing SUPERUSER grant from postgres" - run_sql -c "ALTER USER postgres WITH NOSUPERUSER;" - - if [ "$IS_DRY_RUN" = false ]; then - echo "Unmounting data disk from ${MOUNT_POINT}" - umount $MOUNT_POINT - fi - echo "$UPGRADE_STATUS" > /tmp/pg-upgrade-status - - exit "$EXIT_CODE" -} - -function handle_extensions { - rm -f $POST_UPGRADE_EXTENSION_SCRIPT - touch $POST_UPGRADE_EXTENSION_SCRIPT - - PASSWORD_ENCRYPTION_SETTING=$(run_sql -A -t -c "SHOW password_encryption;") - if [ "$PASSWORD_ENCRYPTION_SETTING" = "md5" ]; then - echo "ALTER SYSTEM SET password_encryption = 'md5';" >> $POST_UPGRADE_EXTENSION_SCRIPT - fi - - cat << EOF >> $POST_UPGRADE_EXTENSION_SCRIPT -ALTER SYSTEM SET jit = off; -SELECT pg_reload_conf(); -EOF - - # Disable extensions if they're enabled - # Generate SQL script to re-enable them after upgrade - for EXTENSION in "${EXTENSIONS_TO_DISABLE[@]}"; do - EXTENSION_ENABLED=$(run_sql -A -t -c "SELECT EXISTS(SELECT 1 FROM pg_extension WHERE extname = '${EXTENSION}');") - if [ "$EXTENSION_ENABLED" = "t" ]; then - echo "Disabling extension ${EXTENSION}" - run_sql -c "DROP EXTENSION IF EXISTS ${EXTENSION} CASCADE;" - cat << EOF >> $POST_UPGRADE_EXTENSION_SCRIPT -DO \$\$ -BEGIN - IF EXISTS (SELECT 1 FROM pg_available_extensions WHERE name = '${EXTENSION}') THEN - CREATE EXTENSION IF NOT EXISTS ${EXTENSION} CASCADE; - END IF; -END; -\$\$; -EOF - fi - done -} - -function initiate_upgrade { - mkdir -p "$MOUNT_POINT" - SHARED_PRELOAD_LIBRARIES=$(cat "$POSTGRES_CONFIG_PATH" | grep shared_preload_libraries | sed "s/shared_preload_libraries =\s\{0,1\}'\(.*\)'.*/\1/") - - # Wrappers officially launched in PG15; PG14 version is incompatible - if [[ "$OLD_PGVERSION" =~ 14* ]]; then - SHARED_PRELOAD_LIBRARIES=$(echo "$SHARED_PRELOAD_LIBRARIES" | sed "s/wrappers,//" | xargs) - fi - SHARED_PRELOAD_LIBRARIES=$(echo "$SHARED_PRELOAD_LIBRARIES" | sed "s/pg_cron,//" | xargs) - SHARED_PRELOAD_LIBRARIES=$(echo "$SHARED_PRELOAD_LIBRARIES" | sed "s/check_role_membership,//" | xargs) - - PGDATAOLD=$(cat "$POSTGRES_CONFIG_PATH" | grep data_directory | sed "s/data_directory = '\(.*\)'.*/\1/") - - PGDATANEW="$MOUNT_POINT/pgdata" - PG_UPGRADE_BIN_DIR="/tmp/pg_upgrade_bin/$PGVERSION" - PGBINNEW="$PG_UPGRADE_BIN_DIR/bin" - PGLIBNEW="$PG_UPGRADE_BIN_DIR/lib" - PGSHARENEW="$PG_UPGRADE_BIN_DIR/share" - - # running upgrade using at least 1 cpu core - WORKERS=$(nproc | awk '{ print ($1 == 1 ? 1 : $1 - 1) }') - - echo "1. Extracting pg_upgrade binaries" - mkdir -p "/tmp/pg_upgrade_bin" - tar zxf "/tmp/persistent/pg_upgrade_bin.tar.gz" -C "/tmp/pg_upgrade_bin" - - # copy upgrade-specific pgsodium_getkey script into the share dir - chmod +x "$SCRIPT_DIR/pgsodium_getkey.sh" - cp "$SCRIPT_DIR/pgsodium_getkey.sh" "$PGSHARENEW/extension/pgsodium_getkey" - if [ -d "/var/lib/postgresql/extension/" ]; then - cp "$SCRIPT_DIR/pgsodium_getkey.sh" "/var/lib/postgresql/extension/pgsodium_getkey" - chown postgres:postgres "/var/lib/postgresql/extension/pgsodium_getkey" - fi - - chown -R postgres:postgres "/tmp/pg_upgrade_bin/$PGVERSION" - - # upgrade job outputs a log in the cwd; needs write permissions - mkdir -p /tmp/pg_upgrade/ - chown -R postgres:postgres /tmp/pg_upgrade/ - cd /tmp/pg_upgrade/ - - # Fixing erros generated by previous dpkg executions (package upgrades et co) - echo "2. Fixing potential errors generated by dpkg" - DEBIAN_FRONTEND=noninteractive dpkg --configure -a --force-confold || true # handle errors generated by dpkg - - # Needed for PostGIS, since it's compiled with Protobuf-C support now - echo "3. Installing libprotobuf-c1 if missing" - if [[ ! "$(apt list --installed libprotobuf-c1 | grep "installed")" ]]; then - apt-get update && apt --fix-broken install -y libprotobuf-c1 - fi - - echo "4. Setup locale if required" - if ! grep -q "^en_US.UTF-8" /etc/locale.gen ; then - echo "en_US.UTF-8 UTF-8" >> /etc/locale.gen - locale-gen - fi - - if [ "$IS_DRY_RUN" = false ]; then - # awk NF==3 prints lines with exactly 3 fields, which are the block devices currently not mounted anywhere - # excluding nvme0 since it is the root disk - echo "5. Determining block device to mount" - BLOCK_DEVICE=$(lsblk -dprno name,size,mountpoint,type | grep "disk" | grep -v "nvme0" | awk 'NF==3 { print $1; }') - echo "Block device found: $BLOCK_DEVICE" - - mkdir -p "$MOUNT_POINT" - echo "6. Mounting block device" - - sleep 5 - e2fsck -pf "$BLOCK_DEVICE" - - sleep 1 - mount "$BLOCK_DEVICE" "$MOUNT_POINT" - - sleep 1 - resize2fs "$BLOCK_DEVICE" - fi - - if [ -f "$MOUNT_POINT/pgsodium_root.key" ]; then - cp "$MOUNT_POINT/pgsodium_root.key" /etc/postgresql-custom/pgsodium_root.key - chown postgres:postgres /etc/postgresql-custom/pgsodium_root.key - chmod 600 /etc/postgresql-custom/pgsodium_root.key - fi - - echo "7. Disabling extensions and generating post-upgrade script" - handle_extensions - - echo "8. Granting SUPERUSER to postgres user" - run_sql -c "ALTER USER postgres WITH SUPERUSER;" - - if [ -d "/usr/share/postgresql/${PGVERSION}" ]; then - mv "/usr/share/postgresql/${PGVERSION}" "/usr/share/postgresql/${PGVERSION}.bak" - fi - ln -s "$PGSHARENEW" "/usr/share/postgresql/${PGVERSION}" - - cp --remove-destination "$PGLIBNEW"/*.control "$PGSHARENEW/extension/" - cp --remove-destination "$PGLIBNEW"/*.sql "$PGSHARENEW/extension/" - - # This is a workaround for older versions of wrappers which don't have the expected - # naming scheme, containing the version in their library's file name - # e.g. wrappers-0.1.16.so, rather than wrappers.so - # pg_upgrade errors out when it doesn't find an equivalent file in the new PG version's - # library directory, so we're making sure the new version has the expected (old version's) - # file name. - # After the upgrade completes, the new version's library file is used. - # i.e. - # - old version: wrappers-0.1.16.so - # - new version: wrappers-0.1.18.so - # - workaround to make pg_upgrade happy: copy wrappers-0.1.18.so to wrappers-0.1.16.so - if [ -d "$PGLIBOLD" ]; then - WRAPPERS_LIB_PATH=$(find "$PGLIBNEW" -name "wrappers*so" -print -quit) - if [ -f "$WRAPPERS_LIB_PATH" ]; then - OLD_WRAPPER_LIB_PATH=$(find "$PGLIBOLD" -name "wrappers*so" -print -quit) - if [ -f "$OLD_WRAPPER_LIB_PATH" ]; then - LIB_FILE_NAME=$(basename "$OLD_WRAPPER_LIB_PATH") - if [ "$WRAPPERS_LIB_PATH" != "$PGLIBNEW/${LIB_FILE_NAME}" ]; then - echo "Copying $OLD_WRAPPER_LIB_PATH to $WRAPPERS_LIB_PATH" - cp "$WRAPPERS_LIB_PATH" "$PGLIBNEW/${LIB_FILE_NAME}" - fi - fi - fi - fi - - export LD_LIBRARY_PATH="${PGLIBNEW}" - - echo "9. Creating new data directory, initializing database" - chown -R postgres:postgres "$MOUNT_POINT/" - rm -rf "${PGDATANEW:?}/" - su -c "$PGBINNEW/initdb -L $PGSHARENEW -D $PGDATANEW/" -s "$SHELL" postgres - - UPGRADE_COMMAND=$(cat < /tmp/pg-upgrade-status -if [ "$IS_DRY_RUN" = true ]; then - initiate_upgrade -else - initiate_upgrade >> "$LOG_FILE" 2>&1 & - echo "Upgrade initiate job completed" -fi diff --git a/ansible-nix/files/admin_api_scripts/pg_upgrade_scripts/pgsodium_getkey.sh b/ansible-nix/files/admin_api_scripts/pg_upgrade_scripts/pgsodium_getkey.sh deleted file mode 100755 index 5a5a90e44..000000000 --- a/ansible-nix/files/admin_api_scripts/pg_upgrade_scripts/pgsodium_getkey.sh +++ /dev/null @@ -1,12 +0,0 @@ -#!/bin/bash - -set -euo pipefail - -KEY_FILE=/etc/postgresql-custom/pgsodium_root.key - -# if key file doesn't exist (project previously didn't use pgsodium), generate a new key -if [[ ! -f "${KEY_FILE}" ]]; then - head -c 32 /dev/urandom | od -A n -t x1 | tr -d ' \n' > $KEY_FILE -fi - -cat $KEY_FILE diff --git a/ansible-nix/files/admin_api_scripts/pg_upgrade_scripts/prepare.sh b/ansible-nix/files/admin_api_scripts/pg_upgrade_scripts/prepare.sh deleted file mode 100755 index 7d7eb9890..000000000 --- a/ansible-nix/files/admin_api_scripts/pg_upgrade_scripts/prepare.sh +++ /dev/null @@ -1,15 +0,0 @@ -#! /usr/bin/env bash -## This script is runs in advance of the database version upgrade, on the newly -## launched instance which will eventually be promoted to become the primary -## database instance once the upgrade successfully completes, terminating the -## previous (source) instance. -## The following commands safely stop the Postgres service and unmount -## the data disk off the newly launched instance, to be re-attached to the -## source instance and run the upgrade there. - -set -euo pipefail - -systemctl stop postgresql - -cp /etc/postgresql-custom/pgsodium_root.key /data/pgsodium_root.key -umount /data diff --git a/ansible-nix/files/adminapi.service.j2 b/ansible-nix/files/adminapi.service.j2 deleted file mode 100644 index 6078f3d1a..000000000 --- a/ansible-nix/files/adminapi.service.j2 +++ /dev/null @@ -1,13 +0,0 @@ -[Unit] -Description=AdminAPI - -[Service] -Type=simple -ExecStart=/opt/supabase-admin-api -User=adminapi -Restart=always -RestartSec=3 -Environment="AWS_USE_DUALSTACK_ENDPOINT=true" - -[Install] -WantedBy=multi-user.target diff --git a/ansible-nix/files/adminapi.sudoers.conf b/ansible-nix/files/adminapi.sudoers.conf deleted file mode 100644 index eada0a94b..000000000 --- a/ansible-nix/files/adminapi.sudoers.conf +++ /dev/null @@ -1,28 +0,0 @@ -Cmnd_Alias ENVOY = /bin/systemctl start envoy.service, /bin/systemctl stop envoy.service, /bin/systemctl restart envoy.service, /bin/systemctl disable envoy.service, /bin/systemctl enable envoy.service, /bin/systemctl reload envoy.service, /bin/systemctl try-restart envoy.service -Cmnd_Alias KONG = /bin/systemctl start kong.service, /bin/systemctl stop kong.service, /bin/systemctl restart kong.service, /bin/systemctl disable kong.service, /bin/systemctl enable kong.service, /bin/systemctl reload kong.service, /bin/systemctl try-restart kong.service -Cmnd_Alias POSTGREST = /bin/systemctl start postgrest.service, /bin/systemctl stop postgrest.service, /bin/systemctl restart postgrest.service, /bin/systemctl disable postgrest.service, /bin/systemctl enable postgrest.service, /bin/systemctl try-restart postgrest.service -Cmnd_Alias GOTRUE = /bin/systemctl start gotrue.service, /bin/systemctl stop gotrue.service, /bin/systemctl restart gotrue.service, /bin/systemctl disable gotrue.service, /bin/systemctl enable gotrue.service, /bin/systemctl try-restart gotrue.service -Cmnd_Alias PGBOUNCER = /bin/systemctl start pgbouncer.service, /bin/systemctl stop pgbouncer.service, /bin/systemctl restart pgbouncer.service, /bin/systemctl disable pgbouncer.service, /bin/systemctl enable pgbouncer.service, /bin/systemctl reload pgbouncer.service, /bin/systemctl try-restart pgbouncer.service - -%adminapi ALL= NOPASSWD: /root/grow_fs.sh -%adminapi ALL= NOPASSWD: /root/manage_readonly_mode.sh -%adminapi ALL= NOPASSWD: /etc/adminapi/pg_upgrade_scripts/prepare.sh -%adminapi ALL= NOPASSWD: /etc/adminapi/pg_upgrade_scripts/initiate.sh -%adminapi ALL= NOPASSWD: /etc/adminapi/pg_upgrade_scripts/complete.sh -%adminapi ALL= NOPASSWD: /etc/adminapi/pg_upgrade_scripts/check.sh -%adminapi ALL= NOPASSWD: /etc/adminapi/pg_upgrade_scripts/common.sh -%adminapi ALL= NOPASSWD: /etc/adminapi/pg_upgrade_scripts/pgsodium_getkey.sh -%adminapi ALL= NOPASSWD: /usr/bin/systemctl daemon-reload -%adminapi ALL= NOPASSWD: /usr/bin/systemctl reload postgresql.service -%adminapi ALL= NOPASSWD: /usr/bin/systemctl restart postgresql.service -%adminapi ALL= NOPASSWD: /usr/bin/systemctl show -p NRestarts postgresql.service -%adminapi ALL= NOPASSWD: /usr/bin/systemctl restart adminapi.service -%adminapi ALL= NOPASSWD: /bin/systemctl daemon-reload -%adminapi ALL= NOPASSWD: /bin/systemctl restart services.slice -%adminapi ALL= NOPASSWD: /usr/sbin/nft -f /etc/nftables/supabase_managed.conf -%adminapi ALL= NOPASSWD: /usr/bin/admin-mgr -%adminapi ALL= NOPASSWD: ENVOY -%adminapi ALL= NOPASSWD: KONG -%adminapi ALL= NOPASSWD: POSTGREST -%adminapi ALL= NOPASSWD: GOTRUE -%adminapi ALL= NOPASSWD: PGBOUNCER diff --git a/ansible-nix/files/ansible-pull.service b/ansible-nix/files/ansible-pull.service deleted file mode 100644 index 3e061b31b..000000000 --- a/ansible-nix/files/ansible-pull.service +++ /dev/null @@ -1,20 +0,0 @@ -[Unit] -Description=Ansible pull - -[Service] -Type=simple -User=ubuntu - -ExecStart=/usr/bin/ansible-pull --private-key "$SSH_READ_KEY_FILE" -U "$REPO" --accept-host-key -t "$REGION,db-all" -i localhost --clean --full "$PLAYBOOK" -v -o -C "$REPO_BRANCH" - -# --verify-commit -# temporarily disable commit verification, while we figure out how we want to balance commit signatures -# and PR reviews; an --ff-only merge options would have allowed us to use this pretty nicely - -MemoryAccounting=true -MemoryMax=30% - -StandardOutput=append:/var/log/ansible-pull.stdout -StandardError=append:/var/log/ansible-pull.error - -TimeoutStopSec=600 diff --git a/ansible-nix/files/ansible-pull.timer b/ansible-nix/files/ansible-pull.timer deleted file mode 100644 index 27ce24b99..000000000 --- a/ansible-nix/files/ansible-pull.timer +++ /dev/null @@ -1,11 +0,0 @@ -[Unit] -Description=Run ansible roughly every 3 hours - -[Timer] -OnBootSec=1h -OnUnitActiveSec=3h -RandomizedDelaySec=1h -Persistent=true - -[Install] -WantedBy=timers.target diff --git a/ansible-nix/files/apt_periodic b/ansible-nix/files/apt_periodic deleted file mode 100644 index 75870203d..000000000 --- a/ansible-nix/files/apt_periodic +++ /dev/null @@ -1,4 +0,0 @@ -APT::Periodic::Update-Package-Lists "1"; -APT::Periodic::Download-Upgradeable-Packages "1"; -APT::Periodic::AutocleanInterval "7"; -APT::Periodic::Unattended-Upgrade "1"; \ No newline at end of file diff --git a/ansible-nix/files/cron.deny b/ansible-nix/files/cron.deny deleted file mode 100644 index 3b5199b06..000000000 --- a/ansible-nix/files/cron.deny +++ /dev/null @@ -1,2 +0,0 @@ -ubuntu -postgres diff --git a/ansible-nix/files/database-optimizations.service.j2 b/ansible-nix/files/database-optimizations.service.j2 deleted file mode 100644 index f25fc09c6..000000000 --- a/ansible-nix/files/database-optimizations.service.j2 +++ /dev/null @@ -1,12 +0,0 @@ -[Unit] -Description=Postgresql optimizations - -[Service] -Type=oneshot -# we do not want failures from these commands to cause downstream service startup to fail -ExecStart=-/opt/supabase-admin-api optimize db --destination-config-file-path /etc/postgresql-custom/generated-optimizations.conf -ExecStart=-/opt/supabase-admin-api optimize pgbouncer --destination-config-file-path /etc/pgbouncer-custom/generated-optimizations.ini -User=adminapi - -[Install] -WantedBy=multi-user.target diff --git a/ansible-nix/files/default.sysstat b/ansible-nix/files/default.sysstat deleted file mode 100644 index 1b029ba6b..000000000 --- a/ansible-nix/files/default.sysstat +++ /dev/null @@ -1,9 +0,0 @@ -# -# Default settings for /etc/init.d/sysstat, /etc/cron.d/sysstat -# and /etc/cron.daily/sysstat files -# - -# Should sadc collect system activity informations? Valid values -# are "true" and "false". Please do not put other values, they -# will be overwritten by debconf! -ENABLED="true" diff --git a/ansible-nix/files/envoy.service b/ansible-nix/files/envoy.service deleted file mode 100644 index d739ffdd5..000000000 --- a/ansible-nix/files/envoy.service +++ /dev/null @@ -1,31 +0,0 @@ -[Unit] -Description=Envoy -After=postgrest.service gotrue.service adminapi.service -Wants=postgrest.service gotrue.service adminapi.service -Conflicts=kong.service - -[Service] -Type=simple - -ExecStartPre=sh -c 'if ss -lnt | grep -Eq ":(80|443) "; then echo "Port 80 or 443 already in use"; exit 1; fi' - -# Need to run via a restarter script to support hot restart when using a process -# manager, see: -# https://www.envoyproxy.io/docs/envoy/latest/operations/hot_restarter -ExecStart=/opt/envoy-hot-restarter.py /opt/start-envoy.sh - -ExecReload=/bin/kill -HUP $MAINPID -ExecStop=/bin/kill -TERM $MAINPID -User=envoy -Slice=services.slice -Restart=always -RestartSec=3 -LimitNOFILE=100000 - -# The envoy user is unprivileged and thus not permitted to bind on ports < 1024 -# Via systemd we grant the process a set of privileges to bind to 80/443 -# See http://archive.vn/36zJU -AmbientCapabilities=CAP_NET_BIND_SERVICE - -[Install] -WantedBy=multi-user.target diff --git a/ansible-nix/files/envoy_config/cds.yaml b/ansible-nix/files/envoy_config/cds.yaml deleted file mode 100644 index 8f921396a..000000000 --- a/ansible-nix/files/envoy_config/cds.yaml +++ /dev/null @@ -1,46 +0,0 @@ -resources: - - '@type': type.googleapis.com/envoy.config.cluster.v3.Cluster - name: admin_api - load_assignment: - cluster_name: admin_api - endpoints: - - lb_endpoints: - - endpoint: - address: - socket_address: - address: 127.0.0.1 - port_value: 8085 - - '@type': type.googleapis.com/envoy.config.cluster.v3.Cluster - name: gotrue - load_assignment: - cluster_name: gotrue - endpoints: - - lb_endpoints: - - endpoint: - address: - socket_address: - address: 127.0.0.1 - port_value: 9999 - - '@type': type.googleapis.com/envoy.config.cluster.v3.Cluster - name: postgrest - load_assignment: - cluster_name: postgrest - endpoints: - - lb_endpoints: - - endpoint: - address: - socket_address: - address: 127.0.0.1 - port_value: 3000 - - '@type': type.googleapis.com/envoy.config.cluster.v3.Cluster - name: postgrest_admin - load_assignment: - cluster_name: postgrest_admin - endpoints: - - lb_endpoints: - - endpoint: - address: - socket_address: - address: 127.0.0.1 - port_value: 3001 - diff --git a/ansible-nix/files/envoy_config/envoy.yaml b/ansible-nix/files/envoy_config/envoy.yaml deleted file mode 100644 index 3d25c13cd..000000000 --- a/ansible-nix/files/envoy_config/envoy.yaml +++ /dev/null @@ -1,23 +0,0 @@ -dynamic_resources: - cds_config: - path_config_source: - path: /etc/envoy/cds.yaml - resource_api_version: V3 - lds_config: - path_config_source: - path: /etc/envoy/lds.yaml - resource_api_version: V3 -node: - cluster: cluster_0 - id: node_0 -overload_manager: - resource_monitors: - - name: envoy.resource_monitors.global_downstream_max_connections - typed_config: - '@type': >- - type.googleapis.com/envoy.extensions.resource_monitors.downstream_connections.v3.DownstreamConnectionsConfig - max_active_downstream_connections: 30000 -stats_config: - stats_matcher: - reject_all: true - diff --git a/ansible-nix/files/envoy_config/lds.yaml b/ansible-nix/files/envoy_config/lds.yaml deleted file mode 100644 index 84acfc041..000000000 --- a/ansible-nix/files/envoy_config/lds.yaml +++ /dev/null @@ -1,315 +0,0 @@ -resources: - - '@type': type.googleapis.com/envoy.config.listener.v3.Listener - name: http_listener - address: - socket_address: - address: '::' - port_value: 80 - ipv4_compat: true - filter_chains: - - filters: &ref_1 - - name: envoy.filters.network.http_connection_manager - typed_config: - '@type': >- - type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager - access_log: - - name: envoy.access_loggers.stdout - filter: - status_code_filter: - comparison: - op: GE - value: - default_value: 400 - runtime_key: unused - typed_config: - '@type': >- - type.googleapis.com/envoy.extensions.access_loggers.stream.v3.StdoutAccessLog - generate_request_id: false - http_filters: - - name: envoy.filters.http.cors - typed_config: - '@type': >- - type.googleapis.com/envoy.extensions.filters.http.cors.v3.Cors - - name: envoy.filters.http.rbac - typed_config: - '@type': >- - type.googleapis.com/envoy.extensions.filters.http.rbac.v3.RBAC - rules: - action: DENY - policies: - api_key_missing: - permissions: - - any: true - principals: - - not_id: - or_ids: - ids: - - header: - name: apikey - present_match: true - - header: - name: ':path' - string_match: - contains: apikey= - api_key_not_valid: - permissions: - - any: true - principals: - - not_id: - or_ids: - ids: - - header: - name: apikey - string_match: - exact: anon_key - - header: - name: apikey - string_match: - exact: service_key - - header: - name: apikey - string_match: - exact: supabase_admin_key - - header: - name: ':path' - string_match: - contains: apikey=anon_key - - header: - name: ':path' - string_match: - contains: apikey=service_key - - header: - name: ':path' - string_match: - contains: apikey=supabase_admin_key - - name: envoy.filters.http.lua - typed_config: - '@type': >- - type.googleapis.com/envoy.extensions.filters.http.lua.v3.Lua - source_codes: - remove_apikey_query_parameter: - filename: /etc/envoy/remove_apikey_query_parameter.lua - - name: envoy.filters.http.router - typed_config: - '@type': >- - type.googleapis.com/envoy.extensions.filters.http.router.v3.Router - dynamic_stats: false - local_reply_config: - mappers: - - filter: - and_filter: - filters: - - status_code_filter: - comparison: - value: - default_value: 403 - runtime_key: unused - - header_filter: - header: - name: ':path' - string_match: - prefix: /customer/v1/privileged/ - status_code: 401 - body: - inline_string: Unauthorized - headers_to_add: - - header: - key: WWW-Authenticate - value: Basic realm="Unknown" - - filter: - and_filter: - filters: - - status_code_filter: - comparison: - value: - default_value: 403 - runtime_key: unused - - header_filter: - header: - name: ':path' - string_match: - prefix: /metrics/aggregated - invert_match: true - status_code: 401 - body_format_override: - json_format: - message: >- - `apikey` request header or query parameter is either - missing or invalid. Double check your Supabase `anon` - or `service_role` API key. - hint: '%RESPONSE_CODE_DETAILS%' - json_format_options: - sort_properties: false - route_config: - name: route_config_0 - virtual_hosts: - - name: virtual_host_0 - domains: - - '*' - typed_per_filter_config: - envoy.filters.http.cors: - '@type': >- - type.googleapis.com/envoy.extensions.filters.http.cors.v3.CorsPolicy - allow_origin_string_match: - - safe_regex: - regex: \* - allow_methods: GET,HEAD,PUT,PATCH,POST,DELETE,OPTIONS,TRACE,CONNECT - allow_headers: apikey,authorization,x-client-info - max_age: '3600' - routes: - - match: - path: /health - direct_response: - status: 200 - body: - inline_string: Healthy - typed_per_filter_config: &ref_0 - envoy.filters.http.rbac: - '@type': >- - type.googleapis.com/envoy.extensions.filters.http.rbac.v3.RBACPerRoute - - match: - safe_regex: - regex: >- - /auth/v1/(verify|callback|authorize|sso/saml/(acs|metadata|slo)) - route: - cluster: gotrue - regex_rewrite: - pattern: - regex: ^/auth/v1 - substitution: '' - retry_policy: - num_retries: 3 - retry_on: 5xx - typed_per_filter_config: *ref_0 - - match: - prefix: /auth/v1/ - route: - cluster: gotrue - prefix_rewrite: / - - match: - prefix: /rest/v1/ - query_parameters: - - name: apikey - present_match: true - request_headers_to_remove: - - apikey - route: - cluster: postgrest - prefix_rewrite: / - timeout: 120s - typed_per_filter_config: - envoy.filters.http.lua: - '@type': >- - type.googleapis.com/envoy.extensions.filters.http.lua.v3.LuaPerRoute - name: remove_apikey_query_parameter - - match: - prefix: /rest/v1/ - request_headers_to_remove: - - apikey - route: - cluster: postgrest - prefix_rewrite: / - timeout: 120s - - match: - prefix: /rest-admin/v1/ - query_parameters: - - name: apikey - present_match: true - request_headers_to_remove: - - apikey - route: - cluster: postgrest_admin - prefix_rewrite: / - typed_per_filter_config: - envoy.filters.http.lua: - '@type': >- - type.googleapis.com/envoy.extensions.filters.http.lua.v3.LuaPerRoute - name: remove_apikey_query_parameter - - match: - prefix: /rest-admin/v1/ - request_headers_to_remove: - - apikey - route: - cluster: postgrest_admin - prefix_rewrite: / - - match: - path: /graphql/v1 - request_headers_to_add: - header: - key: Content-Profile - value: graphql_public - route: - cluster: postgrest - prefix_rewrite: /rpc/graphql - timeout: 120s - - match: - prefix: /admin/v1/ - route: - cluster: admin_api - prefix_rewrite: / - - match: - prefix: /customer/v1/privileged/ - route: - cluster: admin_api - prefix_rewrite: /privileged/ - typed_per_filter_config: - envoy.filters.http.rbac: - '@type': >- - type.googleapis.com/envoy.extensions.filters.http.rbac.v3.RBACPerRoute - rbac: - rules: - action: DENY - policies: - basic_auth: - permissions: - - any: true - principals: - - header: - name: authorization - invert_match: true - string_match: - exact: Basic c2VydmljZV9yb2xlOnNlcnZpY2Vfa2V5 - treat_missing_header_as_empty: true - - match: - prefix: /metrics/aggregated - route: - cluster: admin_api - prefix_rewrite: /supabase-internal/metrics - typed_per_filter_config: - envoy.filters.http.rbac: - '@type': >- - type.googleapis.com/envoy.extensions.filters.http.rbac.v3.RBACPerRoute - rbac: - rules: - action: DENY - policies: - not_private_ip: - permissions: - - any: true - principals: - - not_id: - direct_remote_ip: - address_prefix: 10.0.0.0 - prefix_len: 8 - stat_prefix: ingress_http - - '@type': type.googleapis.com/envoy.config.listener.v3.Listener - name: https_listener - address: - socket_address: - address: '::' - port_value: 443 - ipv4_compat: true - filter_chains: - - filters: *ref_1 - transport_socket: - name: envoy.transport_sockets.tls - typed_config: - '@type': >- - type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext - common_tls_context: - tls_certificates: - - certificate_chain: - filename: /etc/envoy/fullChain.pem - private_key: - filename: /etc/envoy/privKey.pem - diff --git a/ansible-nix/files/envoy_config/remove_apikey_query_parameter.lua b/ansible-nix/files/envoy_config/remove_apikey_query_parameter.lua deleted file mode 100644 index 0aeabaeb1..000000000 --- a/ansible-nix/files/envoy_config/remove_apikey_query_parameter.lua +++ /dev/null @@ -1,8 +0,0 @@ -function envoy_on_request(request_handle) - local path = request_handle:headers():get(":path") - - -- Remove `apikey` query parameter since PostgREST treats query parameters as conditions. - request_handle - :headers() - :replace(":path", path:gsub("([&?])apikey=[^&]+&?", "%1"):gsub("&$", "")) -end diff --git a/ansible-nix/files/fail2ban_config/fail2ban.service.conf b/ansible-nix/files/fail2ban_config/fail2ban.service.conf deleted file mode 100644 index 431d1db5b..000000000 --- a/ansible-nix/files/fail2ban_config/fail2ban.service.conf +++ /dev/null @@ -1,6 +0,0 @@ -[Unit] -After=nftables.service -Wants=nftables.service - -[Service] -ExecStartPost=/bin/bash -c "sleep 5 && chmod g+w /var/run/fail2ban/fail2ban.sock" diff --git a/ansible-nix/files/fail2ban_config/filter-pgbouncer.conf.j2 b/ansible-nix/files/fail2ban_config/filter-pgbouncer.conf.j2 deleted file mode 100644 index 3a3a52ec6..000000000 --- a/ansible-nix/files/fail2ban_config/filter-pgbouncer.conf.j2 +++ /dev/null @@ -1,3 +0,0 @@ -[Definition] -failregex = ^.+@:.+password authentication failed$ -journalmatch = _SYSTEMD_UNIT=pgbouncer.service diff --git a/ansible-nix/files/fail2ban_config/filter-postgresql.conf.j2 b/ansible-nix/files/fail2ban_config/filter-postgresql.conf.j2 deleted file mode 100644 index fd0895aee..000000000 --- a/ansible-nix/files/fail2ban_config/filter-postgresql.conf.j2 +++ /dev/null @@ -1,3 +0,0 @@ -[Definition] -failregex = ^.*,.*,.*,.*,":.*password authentication failed for user.*$ -ignoreregex = ^.*,.*,.*,.*,"127\.0\.0\.1.*password authentication failed for user.*$ \ No newline at end of file diff --git a/ansible-nix/files/fail2ban_config/jail-pgbouncer.conf.j2 b/ansible-nix/files/fail2ban_config/jail-pgbouncer.conf.j2 deleted file mode 100644 index 60a9eb3d9..000000000 --- a/ansible-nix/files/fail2ban_config/jail-pgbouncer.conf.j2 +++ /dev/null @@ -1,7 +0,0 @@ -[pgbouncer] -enabled = true -port = 6543 -protocol = tcp -filter = pgbouncer -backend = systemd[journalflags=1] -maxretry = 3 diff --git a/ansible-nix/files/fail2ban_config/jail-postgresql.conf.j2 b/ansible-nix/files/fail2ban_config/jail-postgresql.conf.j2 deleted file mode 100644 index a021035a9..000000000 --- a/ansible-nix/files/fail2ban_config/jail-postgresql.conf.j2 +++ /dev/null @@ -1,8 +0,0 @@ -[postgresql] -enabled = true -port = 5432 -protocol = tcp -filter = postgresql -logpath = /var/log/postgresql/auth-failures.csv -maxretry = 3 -ignoreip = 192.168.0.0/16 172.17.1.0/20 diff --git a/ansible-nix/files/fail2ban_config/jail-ssh.conf b/ansible-nix/files/fail2ban_config/jail-ssh.conf deleted file mode 100644 index 5476c3093..000000000 --- a/ansible-nix/files/fail2ban_config/jail-ssh.conf +++ /dev/null @@ -1,4 +0,0 @@ -[sshd] - -backend = systemd -mode = aggressive diff --git a/ansible-nix/files/fail2ban_config/jail.local b/ansible-nix/files/fail2ban_config/jail.local deleted file mode 100644 index 44e8210f1..000000000 --- a/ansible-nix/files/fail2ban_config/jail.local +++ /dev/null @@ -1,4 +0,0 @@ -[DEFAULT] - -banaction = nftables-multiport -banaction_allports = nftables-allports diff --git a/ansible-nix/files/gotrue.service.j2 b/ansible-nix/files/gotrue.service.j2 deleted file mode 100644 index f0bd60ab0..000000000 --- a/ansible-nix/files/gotrue.service.j2 +++ /dev/null @@ -1,21 +0,0 @@ -[Unit] -Description=Gotrue - -[Service] -Type=simple -WorkingDirectory=/opt/gotrue -ExecStart=/opt/gotrue/gotrue -User=gotrue -Restart=always -RestartSec=3 - -MemoryAccounting=true -MemoryMax=50% - -EnvironmentFile=/etc/gotrue.env -EnvironmentFile=-/etc/gotrue.overrides.env - -Slice=services.slice - -[Install] -WantedBy=multi-user.target diff --git a/ansible-nix/files/journald.conf b/ansible-nix/files/journald.conf deleted file mode 100644 index 2eb89f91f..000000000 --- a/ansible-nix/files/journald.conf +++ /dev/null @@ -1,6 +0,0 @@ -[Journal] -Storage=persistent -SystemMaxUse=3G -SystemKeepFree=3G -SystemMaxFileSize=200M -ForwardToSyslog=no diff --git a/ansible-nix/files/kong_config/kong.conf.j2 b/ansible-nix/files/kong_config/kong.conf.j2 deleted file mode 100644 index 39067575e..000000000 --- a/ansible-nix/files/kong_config/kong.conf.j2 +++ /dev/null @@ -1,7 +0,0 @@ -database = off -declarative_config = /etc/kong/kong.yml - -# plugins defined in the dockerfile -plugins = request-transformer,cors,key-auth,http-log - -proxy_listen = 0.0.0.0:80 reuseport backlog=16384, 0.0.0.0:443 http2 ssl reuseport backlog=16834, [::]:80 reuseport backlog=16384, [::]:443 http2 ssl reuseport backlog=16384 diff --git a/ansible-nix/files/kong_config/kong.env.j2 b/ansible-nix/files/kong_config/kong.env.j2 deleted file mode 100644 index 57613fdbb..000000000 --- a/ansible-nix/files/kong_config/kong.env.j2 +++ /dev/null @@ -1,8 +0,0 @@ -KONG_NGINX_HTTP_GZIP=on -KONG_NGINX_HTTP_GZIP_COMP_LEVEL=6 -KONG_NGINX_HTTP_GZIP_MIN_LENGTH=256 -KONG_NGINX_HTTP_GZIP_PROXIED=any -KONG_NGINX_HTTP_GZIP_VARY=on -KONG_NGINX_HTTP_GZIP_TYPES=text/plain application/xml application/openapi+json application/json -KONG_PROXY_ERROR_LOG=syslog:server=unix:/dev/log -KONG_ADMIN_ERROR_LOG=syslog:server=unix:/dev/log diff --git a/ansible-nix/files/kong_config/kong.service.j2 b/ansible-nix/files/kong_config/kong.service.j2 deleted file mode 100644 index 6a36520bc..000000000 --- a/ansible-nix/files/kong_config/kong.service.j2 +++ /dev/null @@ -1,28 +0,0 @@ -[Unit] -Description=Kong server -After=postgrest.service gotrue.service adminapi.service -Wants=postgrest.service gotrue.service adminapi.service -Conflicts=envoy.service - -# Ensures that Kong service is stopped before Envoy service is started -Before=envoy.service - -[Service] -Type=forking -ExecStart=/usr/local/bin/kong start -c /etc/kong/kong.conf -ExecReload=/usr/local/bin/kong reload -c /etc/kong/kong.conf -ExecStop=/usr/local/bin/kong quit -User=kong -EnvironmentFile=/etc/kong/kong.env -Slice=services.slice -Restart=always -RestartSec=3 -LimitNOFILE=100000 - -# The kong user is unprivileged and thus not permitted to bind on ports < 1024 -# Via systemd we grant the process a set of privileges to bind to 80/443 -# See http://archive.vn/36zJU -AmbientCapabilities=CAP_NET_BIND_SERVICE - -[Install] -WantedBy=multi-user.target diff --git a/ansible-nix/files/logind.conf b/ansible-nix/files/logind.conf deleted file mode 100644 index 732900f3c..000000000 --- a/ansible-nix/files/logind.conf +++ /dev/null @@ -1,2 +0,0 @@ -[Login] -RemoveIPC=no diff --git a/ansible-nix/files/logrotate_config/logrotate-postgres-auth.conf b/ansible-nix/files/logrotate_config/logrotate-postgres-auth.conf deleted file mode 100644 index 050210e60..000000000 --- a/ansible-nix/files/logrotate_config/logrotate-postgres-auth.conf +++ /dev/null @@ -1,8 +0,0 @@ -/var/log/postgresql/auth-failures.csv { - size 10M - rotate 5 - compress - delaycompress - notifempty - missingok -} diff --git a/ansible-nix/files/logrotate_config/logrotate-postgres-csv.conf b/ansible-nix/files/logrotate_config/logrotate-postgres-csv.conf deleted file mode 100644 index e5418e8e0..000000000 --- a/ansible-nix/files/logrotate_config/logrotate-postgres-csv.conf +++ /dev/null @@ -1,11 +0,0 @@ -/var/log/postgresql/postgresql.csv { - size 50M - rotate 9 - compress - delaycompress - notifempty - missingok - postrotate - sudo -u postgres /usr/lib/postgresql/bin/pg_ctl -D /var/lib/postgresql/data logrotate - endscript -} diff --git a/ansible-nix/files/logrotate_config/logrotate-postgres.conf b/ansible-nix/files/logrotate_config/logrotate-postgres.conf deleted file mode 100644 index c802320c4..000000000 --- a/ansible-nix/files/logrotate_config/logrotate-postgres.conf +++ /dev/null @@ -1,9 +0,0 @@ -/var/log/postgresql/postgresql.log { - size 50M - rotate 3 - copytruncate - delaycompress - compress - notifempty - missingok -} diff --git a/ansible-nix/files/logrotate_config/logrotate-walg.conf b/ansible-nix/files/logrotate_config/logrotate-walg.conf deleted file mode 100644 index 49eeb59eb..000000000 --- a/ansible-nix/files/logrotate_config/logrotate-walg.conf +++ /dev/null @@ -1,9 +0,0 @@ -/var/log/wal-g/*.log { - size 50M - rotate 3 - copytruncate - delaycompress - compress - notifempty - missingok -} diff --git a/ansible-nix/files/manifest.json b/ansible-nix/files/manifest.json deleted file mode 100644 index 3a20e76a0..000000000 --- a/ansible-nix/files/manifest.json +++ /dev/null @@ -1 +0,0 @@ -{{ vars | to_json }} diff --git a/ansible-nix/files/nginx.service.j2 b/ansible-nix/files/nginx.service.j2 deleted file mode 100644 index 872e3346a..000000000 --- a/ansible-nix/files/nginx.service.j2 +++ /dev/null @@ -1,22 +0,0 @@ -[Unit] -Description=nginx server -After=postgrest.service gotrue.service adminapi.service -Wants=postgrest.service gotrue.service adminapi.service - -[Service] -Type=forking -ExecStart=/usr/local/nginx/sbin/nginx -c /etc/nginx/nginx.conf -ExecReload=/usr/local/nginx/sbin/nginx -s reload -c /etc/nginx/nginx.conf -ExecStop=/usr/local/nginx/sbin/nginx -s quit -User=nginx -Slice=services.slice -Restart=always -RestartSec=3 -LimitNOFILE=100000 - -# Via systemd we grant the process a set of privileges to bind to 80/443 -# See http://archive.vn/36zJU -AmbientCapabilities=CAP_NET_BIND_SERVICE - -[Install] -WantedBy=multi-user.target diff --git a/ansible-nix/files/pg_egress_collect.service.j2 b/ansible-nix/files/pg_egress_collect.service.j2 deleted file mode 100644 index 7ac04f47d..000000000 --- a/ansible-nix/files/pg_egress_collect.service.j2 +++ /dev/null @@ -1,13 +0,0 @@ -[Unit] -Description=Postgres Egress Collector - -[Service] -Type=simple -ExecStart=/bin/bash -c "tcpdump -s 128 -Q out -nn -tt -vv -p -l 'tcp and (port 5432 or port 6543)' | perl /root/pg_egress_collect.pl" -User=root -Slice=services.slice -Restart=always -RestartSec=3 - -[Install] -WantedBy=multi-user.target diff --git a/ansible-nix/files/pgbouncer_config/pgbouncer.ini.j2 b/ansible-nix/files/pgbouncer_config/pgbouncer.ini.j2 deleted file mode 100644 index e4518c007..000000000 --- a/ansible-nix/files/pgbouncer_config/pgbouncer.ini.j2 +++ /dev/null @@ -1,364 +0,0 @@ -;;; -;;; PgBouncer configuration file -;;; - -;; database name = connect string -;; -;; connect string params: -;; dbname= host= port= user= password= auth_user= -;; client_encoding= datestyle= timezone= -;; pool_size= reserve_pool= max_db_connections= -;; pool_mode= connect_query= application_name= -[databases] -* = host=localhost auth_user=pgbouncer - -;; foodb over Unix socket -;foodb = - -;; redirect bardb to bazdb on localhost -;bardb = host=localhost dbname=bazdb - -;; access to dest database will go with single user -;forcedb = host=localhost port=300 user=baz password=foo client_encoding=UNICODE datestyle=ISO connect_query='SELECT 1' - -;; use custom pool sizes -;nondefaultdb = pool_size=50 reserve_pool=10 - -;; use auth_user with auth_query if user not present in auth_file -;; auth_user must exist in auth_file -; foodb = auth_user=bar - -;; fallback connect string -;* = host=testserver - -;; User-specific configuration -[users] - -;user1 = pool_mode=transaction max_user_connections=10 - -;; Configuration section -[pgbouncer] - -;;; -;;; Administrative settings -;;; - -;logfile = /var/log/pgbouncer.log -pidfile = /var/run/pgbouncer/pgbouncer.pid - -;;; -;;; Where to wait for clients -;;; - -;; IP address or * which means all IPs -listen_addr = * -listen_port = 6543 - -;; Unix socket is also used for -R. -;; On Debian it should be /var/run/postgresql -unix_socket_dir = /tmp -;unix_socket_mode = 0777 -;unix_socket_group = - -;;; -;;; TLS settings for accepting clients -;;; - -;; disable, allow, require, verify-ca, verify-full -;client_tls_sslmode = disable - -;; Path to file that contains trusted CA certs -;client_tls_ca_file = - -;; Private key and cert to present to clients. -;; Required for accepting TLS connections from clients. -;client_tls_key_file = -;client_tls_cert_file = - -;; fast, normal, secure, legacy, -;client_tls_ciphers = fast - -;; all, secure, tlsv1.0, tlsv1.1, tlsv1.2, tlsv1.3 -;client_tls_protocols = secure - -;; none, auto, legacy -;client_tls_dheparams = auto - -;; none, auto, -;client_tls_ecdhcurve = auto - -;;; -;;; TLS settings for connecting to backend databases -;;; - -;; disable, allow, require, verify-ca, verify-full -;server_tls_sslmode = disable - -;; Path to that contains trusted CA certs -;server_tls_ca_file = - -;; Private key and cert to present to backend. -;; Needed only if backend server require client cert. -;server_tls_key_file = -;server_tls_cert_file = - -;; all, secure, tlsv1.0, tlsv1.1, tlsv1.2, tlsv1.3 -;server_tls_protocols = secure - -;; fast, normal, secure, legacy, -;server_tls_ciphers = fast - -;;; -;;; Authentication settings -;;; - -;; any, trust, plain, md5, cert, hba, pam -auth_type = scram-sha-256 -auth_file = /etc/pgbouncer/userlist.txt - -;; Path to HBA-style auth config -;auth_hba_file = - -;; Query to use to fetch password from database. Result -;; must have 2 columns - username and password hash. -auth_query = SELECT * FROM pgbouncer.get_auth($1) - -;;; -;;; Users allowed into database 'pgbouncer' -;;; - -;; comma-separated list of users who are allowed to change settings -admin_users = pgbouncer - -;; comma-separated list of users who are just allowed to use SHOW command -stats_users = pgbouncer - -;;; -;;; Pooler personality questions -;;; - -;; When server connection is released back to pool: -;; session - after client disconnects (default) -;; transaction - after transaction finishes -;; statement - after statement finishes -pool_mode = transaction - -;; Query for cleaning connection immediately after releasing from -;; client. No need to put ROLLBACK here, pgbouncer does not reuse -;; connections where transaction is left open. -;server_reset_query = DISCARD ALL - -;; Whether server_reset_query should run in all pooling modes. If it -;; is off, server_reset_query is used only for session-pooling. -;server_reset_query_always = 0 - -;; Comma-separated list of parameters to ignore when given in startup -;; packet. Newer JDBC versions require the extra_float_digits here. -ignore_startup_parameters = extra_float_digits - -;; When taking idle server into use, this query is run first. -;server_check_query = select 1 - -;; If server was used more recently that this many seconds ago, -; skip the check query. Value 0 may or may not run in immediately. -;server_check_delay = 30 - -;; Close servers in session pooling mode after a RECONNECT, RELOAD, -;; etc. when they are idle instead of at the end of the session. -;server_fast_close = 0 - -;; Use as application_name on server. -;application_name_add_host = 0 - -;; Period for updating aggregated stats. -;stats_period = 60 - -;;; -;;; Connection limits -;;; - -;; Total number of clients that can connect -;max_client_conn = 100 - -;; Default pool size. 20 is good number when transaction pooling -;; is in use, in session pooling it needs to be the number of -;; max clients you want to handle at any moment -default_pool_size = 15 - -;; Minimum number of server connections to keep in pool. -;min_pool_size = 0 - -; how many additional connection to allow in case of trouble -;reserve_pool_size = 0 - -;; If a clients needs to wait more than this many seconds, use reserve -;; pool. -;reserve_pool_timeout = 5 - -;; Maximum number of server connections for a database -;max_db_connections = 0 - -;; Maximum number of server connections for a user -;max_user_connections = 0 - -;; If off, then server connections are reused in LIFO manner -;server_round_robin = 0 - -;;; -;;; Logging -;;; - -;; Syslog settings -;syslog = 0 -;syslog_facility = daemon -;syslog_ident = pgbouncer - -;; log if client connects or server connection is made -;log_connections = 1 - -;; log if and why connection was closed -;log_disconnections = 1 - -;; log error messages pooler sends to clients -;log_pooler_errors = 1 - -;; write aggregated stats into log -;log_stats = 1 - -;; Logging verbosity. Same as -v switch on command line. -;verbose = 0 - -;;; -;;; Timeouts -;;; - -;; Close server connection if its been connected longer. -;server_lifetime = 3600 - -;; Close server connection if its not been used in this time. Allows -;; to clean unnecessary connections from pool after peak. -;server_idle_timeout = 600 - -;; Cancel connection attempt if server does not answer takes longer. -;server_connect_timeout = 15 - -;; If server login failed (server_connect_timeout or auth failure) -;; then wait this many second. -;server_login_retry = 15 - -;; Dangerous. Server connection is closed if query does not return in -;; this time. Should be used to survive network problems, _not_ as -;; statement_timeout. (default: 0) -;query_timeout = 0 - -;; Dangerous. Client connection is closed if the query is not -;; assigned to a server in this time. Should be used to limit the -;; number of queued queries in case of a database or network -;; failure. (default: 120) -;query_wait_timeout = 120 - -;; Dangerous. Client connection is closed if no activity in this -;; time. Should be used to survive network problems. (default: 0) -;client_idle_timeout = 0 - -;; Disconnect clients who have not managed to log in after connecting -;; in this many seconds. -;client_login_timeout = 60 - -;; Clean automatically created database entries (via "*") if they stay -;; unused in this many seconds. -; autodb_idle_timeout = 3600 - -;; Close connections which are in "IDLE in transaction" state longer -;; than this many seconds. -;idle_transaction_timeout = 0 - -;; How long SUSPEND/-R waits for buffer flush before closing -;; connection. -;suspend_timeout = 10 - -;;; -;;; Low-level tuning options -;;; - -;; buffer for streaming packets -;pkt_buf = 4096 - -;; man 2 listen -;listen_backlog = 128 - -;; Max number pkt_buf to process in one event loop. -;sbuf_loopcnt = 5 - -;; Maximum PostgreSQL protocol packet size. -;max_packet_size = 2147483647 - -;; Set SO_REUSEPORT socket option -;so_reuseport = 0 - -;; networking options, for info: man 7 tcp - -;; Linux: Notify program about new connection only if there is also -;; data received. (Seconds to wait.) On Linux the default is 45, on -;; other OS'es 0. -;tcp_defer_accept = 0 - -;; In-kernel buffer size (Linux default: 4096) -;tcp_socket_buffer = 0 - -;; whether tcp keepalive should be turned on (0/1) -;tcp_keepalive = 1 - -;; The following options are Linux-specific. They also require -;; tcp_keepalive=1. - -;; Count of keepalive packets -;tcp_keepcnt = 0 - -;; How long the connection can be idle before sending keepalive -;; packets -;tcp_keepidle = 0 - -;; The time between individual keepalive probes -;tcp_keepintvl = 0 - -;; How long may transmitted data remain unacknowledged before TCP -;; connection is closed (in milliseconds) -;tcp_user_timeout = 0 - -;; DNS lookup caching time -;dns_max_ttl = 15 - -;; DNS zone SOA lookup period -;dns_zone_check_period = 0 - -;; DNS negative result caching time -;dns_nxdomain_ttl = 15 - -;; Custom resolv.conf file, to set custom DNS servers or other options -;; (default: empty = use OS settings) -;resolv_conf = /etc/pgbouncer/resolv.conf - -;;; -;;; Random stuff -;;; - -;; Hackish security feature. Helps against SQL injection: when PQexec -;; is disabled, multi-statement cannot be made. -;disable_pqexec = 0 - -;; Config file to use for next RELOAD/SIGHUP -;; By default contains config file from command line. -;conffile - -;; Windows service name to register as. job_name is alias for -;; service_name, used by some Skytools scripts. -;service_name = pgbouncer -;job_name = pgbouncer - -;; Read additional config from other file -;%include /etc/pgbouncer/pgbouncer-other.ini - -%include /etc/pgbouncer-custom/generated-optimizations.ini -%include /etc/pgbouncer-custom/custom-overrides.ini -%include /etc/pgbouncer-custom/ssl-config.ini diff --git a/ansible-nix/files/pgbouncer_config/pgbouncer.service.j2 b/ansible-nix/files/pgbouncer_config/pgbouncer.service.j2 deleted file mode 100644 index 1ec5ea378..000000000 --- a/ansible-nix/files/pgbouncer_config/pgbouncer.service.j2 +++ /dev/null @@ -1,20 +0,0 @@ -[Unit] -Description=connection pooler for PostgreSQL -Documentation=man:pgbouncer(1) -Documentation=https://www.pgbouncer.org/ -After=network.target -{% if supabase_internal is defined %} -Requires=database-optimizations.service -After=database-optimizations.service -{% endif %} - -[Service] -Type=notify -User=pgbouncer -ExecStart=/usr/local/bin/pgbouncer /etc/pgbouncer/pgbouncer.ini -ExecReload=/bin/kill -HUP $MAINPID -KillSignal=SIGINT -LimitNOFILE=65536 - -[Install] -WantedBy=multi-user.target diff --git a/ansible-nix/files/pgbouncer_config/pgbouncer_auth_schema.sql b/ansible-nix/files/pgbouncer_config/pgbouncer_auth_schema.sql deleted file mode 100644 index c10ce44fd..000000000 --- a/ansible-nix/files/pgbouncer_config/pgbouncer_auth_schema.sql +++ /dev/null @@ -1,20 +0,0 @@ -CREATE USER pgbouncer; - -REVOKE ALL PRIVILEGES ON SCHEMA public FROM pgbouncer; - -CREATE SCHEMA pgbouncer AUTHORIZATION pgbouncer; - -CREATE OR REPLACE FUNCTION pgbouncer.get_auth(p_usename TEXT) -RETURNS TABLE(username TEXT, password TEXT) AS -$$ -BEGIN - RAISE WARNING 'PgBouncer auth request: %', p_usename; - - RETURN QUERY - SELECT usename::TEXT, passwd::TEXT FROM pg_catalog.pg_shadow - WHERE usename = p_usename; -END; -$$ LANGUAGE plpgsql SECURITY DEFINER; - -REVOKE ALL ON FUNCTION pgbouncer.get_auth(p_usename TEXT) FROM PUBLIC; -GRANT EXECUTE ON FUNCTION pgbouncer.get_auth(p_usename TEXT) TO pgbouncer; diff --git a/ansible-nix/files/pgbouncer_config/tmpfiles.d-pgbouncer.conf.j2 b/ansible-nix/files/pgbouncer_config/tmpfiles.d-pgbouncer.conf.j2 deleted file mode 100644 index d5d2cd49d..000000000 --- a/ansible-nix/files/pgbouncer_config/tmpfiles.d-pgbouncer.conf.j2 +++ /dev/null @@ -1,2 +0,0 @@ -# Directory for PostgreSQL sockets, lockfiles and stats tempfiles -d /run/pgbouncer 2775 pgbouncer postgres - - \ No newline at end of file diff --git a/ansible-nix/files/pgsodium_getkey_readonly.sh.j2 b/ansible-nix/files/pgsodium_getkey_readonly.sh.j2 deleted file mode 100644 index e0a72733f..000000000 --- a/ansible-nix/files/pgsodium_getkey_readonly.sh.j2 +++ /dev/null @@ -1,14 +0,0 @@ -#!/bin/bash - -set -euo pipefail - -KEY_FILE=/etc/postgresql-custom/pgsodium_root.key - -# On the hosted platform, the root key is generated and managed for each project -# If for some reason the key is missing, we want to fail loudly, -# rather than generating a new one. -if [[ ! -f "${KEY_FILE}" ]]; then - echo "Key file ${KEY_FILE} does not exist." >&2 - exit 1 -fi -cat $KEY_FILE diff --git a/ansible-nix/files/pgsodium_getkey_urandom.sh.j2 b/ansible-nix/files/pgsodium_getkey_urandom.sh.j2 deleted file mode 100755 index e8039d037..000000000 --- a/ansible-nix/files/pgsodium_getkey_urandom.sh.j2 +++ /dev/null @@ -1,10 +0,0 @@ -#!/bin/bash - -set -euo pipefail - -KEY_FILE=/etc/postgresql-custom/pgsodium_root.key - -if [[ ! -f "${KEY_FILE}" ]]; then - head -c 32 /dev/urandom | od -A n -t x1 | tr -d ' \n' > "${KEY_FILE}" -fi -cat $KEY_FILE diff --git a/ansible-nix/files/postgres_exporter.service.j2 b/ansible-nix/files/postgres_exporter.service.j2 deleted file mode 100644 index 0066a76b2..000000000 --- a/ansible-nix/files/postgres_exporter.service.j2 +++ /dev/null @@ -1,14 +0,0 @@ -[Unit] -Description=Postgres Exporter - -[Service] -Type=simple -ExecStart=/opt/postgres_exporter/postgres_exporter --disable-settings-metrics --extend.query-path="/opt/postgres_exporter/queries.yml" --disable-default-metrics --no-collector.locks --no-collector.replication --no-collector.replication_slot --no-collector.stat_bgwriter --no-collector.stat_database --no-collector.stat_user_tables --no-collector.statio_user_tables --no-collector.wal -User=postgres -Group=postgres -Restart=always -RestartSec=3 -Environment="DATA_SOURCE_NAME=host=localhost dbname=postgres sslmode=disable user=supabase_admin pg_stat_statements.track=none application_name=postgres_exporter" - -[Install] -WantedBy=multi-user.target diff --git a/ansible-nix/files/postgresql_config/custom_read_replica.conf.j2 b/ansible-nix/files/postgresql_config/custom_read_replica.conf.j2 deleted file mode 100644 index 7d52f92a7..000000000 --- a/ansible-nix/files/postgresql_config/custom_read_replica.conf.j2 +++ /dev/null @@ -1,5 +0,0 @@ -# hot_standby = on -# restore_command = '/usr/bin/admin-mgr wal-fetch %f %p >> /var/log/wal-g/wal-fetch.log 2>&1' -# recovery_target_timeline = 'latest' - -# primary_conninfo = 'host=localhost port=6543 user=replication' diff --git a/ansible-nix/files/postgresql_config/custom_walg.conf.j2 b/ansible-nix/files/postgresql_config/custom_walg.conf.j2 deleted file mode 100644 index 7ef7256d8..000000000 --- a/ansible-nix/files/postgresql_config/custom_walg.conf.j2 +++ /dev/null @@ -1,21 +0,0 @@ -# - Archiving - - -#archive_mode = on -#archive_command = '/usr/bin/admin-mgr wal-push %p >> /var/log/wal-g/wal-push.log 2>&1' -#archive_timeout = 120 - - -# - Archive Recovery - - -#restore_command = '/usr/bin/admin-mgr wal-fetch %f %p >> /var/log/wal-g/wal-fetch.log 2>&1' - -# - Recovery Target - - -#recovery_target_lsn = '' -#recovery_target_time = '' -#recovery_target_action = 'promote' -#recovery_target_timeline = 'current' -#recovery_target_inclusive = off - -# - Hot Standby - -hot_standby = off diff --git a/ansible-nix/files/postgresql_config/pg_hba.conf.j2 b/ansible-nix/files/postgresql_config/pg_hba.conf.j2 deleted file mode 100755 index 9cafd4146..000000000 --- a/ansible-nix/files/postgresql_config/pg_hba.conf.j2 +++ /dev/null @@ -1,94 +0,0 @@ -# PostgreSQL Client Authentication Configuration File -# =================================================== -# -# Refer to the "Client Authentication" section in the PostgreSQL -# documentation for a complete description of this file. A short -# synopsis follows. -# -# This file controls: which hosts are allowed to connect, how clients -# are authenticated, which PostgreSQL user names they can use, which -# databases they can access. Records take one of these forms: -# -# local DATABASE USER METHOD [OPTIONS] -# host DATABASE USER ADDRESS METHOD [OPTIONS] -# hostssl DATABASE USER ADDRESS METHOD [OPTIONS] -# hostnossl DATABASE USER ADDRESS METHOD [OPTIONS] -# hostgssenc DATABASE USER ADDRESS METHOD [OPTIONS] -# hostnogssenc DATABASE USER ADDRESS METHOD [OPTIONS] -# -# (The uppercase items must be replaced by actual values.) -# -# The first field is the connection type: "local" is a Unix-domain -# socket, "host" is either a plain or SSL-encrypted TCP/IP socket, -# "hostssl" is an SSL-encrypted TCP/IP socket, and "hostnossl" is a -# non-SSL TCP/IP socket. Similarly, "hostgssenc" uses a -# GSSAPI-encrypted TCP/IP socket, while "hostnogssenc" uses a -# non-GSSAPI socket. -# -# DATABASE can be "all", "sameuser", "samerole", "replication", a -# database name, or a comma-separated list thereof. The "all" -# keyword does not match "replication". Access to replication -# must be enabled in a separate record (see example below). -# -# USER can be "all", a user name, a group name prefixed with "+", or a -# comma-separated list thereof. In both the DATABASE and USER fields -# you can also write a file name prefixed with "@" to include names -# from a separate file. -# -# ADDRESS specifies the set of hosts the record matches. It can be a -# host name, or it is made up of an IP address and a CIDR mask that is -# an integer (between 0 and 32 (IPv4) or 128 (IPv6) inclusive) that -# specifies the number of significant bits in the mask. A host name -# that starts with a dot (.) matches a suffix of the actual host name. -# Alternatively, you can write an IP address and netmask in separate -# columns to specify the set of hosts. Instead of a CIDR-address, you -# can write "samehost" to match any of the server's own IP addresses, -# or "samenet" to match any address in any subnet that the server is -# directly connected to. -# -# METHOD can be "trust", "reject", "md5", "password", "scram-sha-256", -# "gss", "sspi", "ident", "peer", "pam", "ldap", "radius" or "cert". -# Note that "password" sends passwords in clear text; "md5" or -# "scram-sha-256" are preferred since they send encrypted passwords. -# -# OPTIONS are a set of options for the authentication in the format -# NAME=VALUE. The available options depend on the different -# authentication methods -- refer to the "Client Authentication" -# section in the documentation for a list of which options are -# available for which authentication methods. -# -# Database and user names containing spaces, commas, quotes and other -# special characters must be quoted. Quoting one of the keywords -# "all", "sameuser", "samerole" or "replication" makes the name lose -# its special character, and just match a database or username with -# that name. -# -# This file is read on server startup and when the server receives a -# SIGHUP signal. If you edit the file on a running system, you have to -# SIGHUP the server for the changes to take effect, run "pg_ctl reload", -# or execute "SELECT pg_reload_conf()". -# -# Put your actual configuration here -# ---------------------------------- -# -# If you want to allow non-local connections, you need to add more -# "host" records. In that case you will also need to make PostgreSQL -# listen on a non-local interface via the listen_addresses -# configuration parameter, or via the -i or -h command line switches. - -# TYPE DATABASE USER ADDRESS METHOD - -# trust local connections -local all supabase_admin scram-sha-256 -local all all peer map=supabase_map -host all all 127.0.0.1/32 trust -host all all ::1/128 trust - -# IPv4 external connections -host all all 10.0.0.0/8 scram-sha-256 -host all all 172.16.0.0/12 scram-sha-256 -host all all 192.168.0.0/16 scram-sha-256 -host all all 0.0.0.0/0 scram-sha-256 - -# IPv6 external connections -host all all ::0/0 scram-sha-256 diff --git a/ansible-nix/files/postgresql_config/pg_ident.conf.j2 b/ansible-nix/files/postgresql_config/pg_ident.conf.j2 deleted file mode 100755 index d8891f416..000000000 --- a/ansible-nix/files/postgresql_config/pg_ident.conf.j2 +++ /dev/null @@ -1,50 +0,0 @@ -# PostgreSQL User Name Maps -# ========================= -# -# Refer to the PostgreSQL documentation, chapter "Client -# Authentication" for a complete description. A short synopsis -# follows. -# -# This file controls PostgreSQL user name mapping. It maps external -# user names to their corresponding PostgreSQL user names. Records -# are of the form: -# -# MAPNAME SYSTEM-USERNAME PG-USERNAME -# -# (The uppercase quantities must be replaced by actual values.) -# -# MAPNAME is the (otherwise freely chosen) map name that was used in -# pg_hba.conf. SYSTEM-USERNAME is the detected user name of the -# client. PG-USERNAME is the requested PostgreSQL user name. The -# existence of a record specifies that SYSTEM-USERNAME may connect as -# PG-USERNAME. -# -# If SYSTEM-USERNAME starts with a slash (/), it will be treated as a -# regular expression. Optionally this can contain a capture (a -# parenthesized subexpression). The substring matching the capture -# will be substituted for \1 (backslash-one) if present in -# PG-USERNAME. -# -# Multiple maps may be specified in this file and used by pg_hba.conf. -# -# No map names are defined in the default configuration. If all -# system user names and PostgreSQL user names are the same, you don't -# need anything in this file. -# -# This file is read on server startup and when the postmaster receives -# a SIGHUP signal. If you edit the file on a running system, you have -# to SIGHUP the postmaster for the changes to take effect. You can -# use "pg_ctl reload" to do that. - -# Put your actual configuration here -# ---------------------------------- - -# MAPNAME SYSTEM-USERNAME PG-USERNAME -supabase_map postgres postgres -supabase_map root postgres -supabase_map ubuntu postgres - -# supabase-specific users -supabase_map gotrue supabase_auth_admin -supabase_map postgrest authenticator -supabase_map adminapi postgres diff --git a/ansible-nix/files/postgresql_config/postgresql-csvlog.conf b/ansible-nix/files/postgresql_config/postgresql-csvlog.conf deleted file mode 100644 index b8d64da51..000000000 --- a/ansible-nix/files/postgresql_config/postgresql-csvlog.conf +++ /dev/null @@ -1,33 +0,0 @@ -# - Where to Log - - -log_destination = 'csvlog' # Valid values are combinations of - # stderr, csvlog, syslog, and eventlog, - # depending on platform. csvlog - # requires logging_collector to be on. - -# This is used when logging to stderr: -logging_collector = on # Enable capturing of stderr and csvlog - # into log files. Required to be on for - # csvlogs. - # (change requires restart) - -# These are only used if logging_collector is on: -log_directory = '/var/log/postgresql' # directory where log files are written, - # can be absolute or relative to PGDATA -log_filename = 'postgresql.log' # log file name pattern, - # can include strftime() escapes -log_file_mode = 0640 # creation mode for log files, - # begin with 0 to use octal notation -log_rotation_age = 0 # Automatic rotation of logfiles will - # happen after that time. 0 disables. -log_rotation_size = 0 # Automatic rotation of logfiles will - # happen after that much log output. - # 0 disables. -#log_truncate_on_rotation = off # If on, an existing log file with the - # same name as the new log file will be - # truncated rather than appended to. - # But such truncation only occurs on - # time-driven rotation, not on restarts - # or size-driven rotation. Default is - # off, meaning append to existing files - # in all cases. diff --git a/ansible-nix/files/postgresql_config/postgresql-stdout-log.conf b/ansible-nix/files/postgresql_config/postgresql-stdout-log.conf deleted file mode 100644 index 6ae4ff456..000000000 --- a/ansible-nix/files/postgresql_config/postgresql-stdout-log.conf +++ /dev/null @@ -1,4 +0,0 @@ -logging_collector = off # Enable capturing of stderr and csvlog - # into log files. Required to be on for - # csvlogs. - # (change requires restart) diff --git a/ansible-nix/files/postgresql_config/postgresql.conf.j2 b/ansible-nix/files/postgresql_config/postgresql.conf.j2 deleted file mode 100644 index fdca6643d..000000000 --- a/ansible-nix/files/postgresql_config/postgresql.conf.j2 +++ /dev/null @@ -1,776 +0,0 @@ -# ----------------------------- -# PostgreSQL configuration file -# ----------------------------- -# -# This file consists of lines of the form: -# -# name = value -# -# (The "=" is optional.) Whitespace may be used. Comments are introduced with -# "#" anywhere on a line. The complete list of parameter names and allowed -# values can be found in the PostgreSQL documentation. -# -# The commented-out settings shown in this file represent the default values. -# Re-commenting a setting is NOT sufficient to revert it to the default value; -# you need to reload the server. -# -# This file is read on server startup and when the server receives a SIGHUP -# signal. If you edit the file on a running system, you have to SIGHUP the -# server for the changes to take effect, run "pg_ctl reload", or execute -# "SELECT pg_reload_conf()". Some parameters, which are marked below, -# require a server shutdown and restart to take effect. -# -# Any parameter can also be given as a command-line option to the server, e.g., -# "postgres -c log_connections=on". Some parameters can be changed at run time -# with the "SET" SQL command. -# -# Memory units: B = bytes Time units: us = microseconds -# kB = kilobytes ms = milliseconds -# MB = megabytes s = seconds -# GB = gigabytes min = minutes -# TB = terabytes h = hours -# d = days - - -#------------------------------------------------------------------------------ -# FILE LOCATIONS -#------------------------------------------------------------------------------ - -# The default values of these variables are driven from the -D command-line -# option or PGDATA environment variable, represented here as ConfigDir. - -data_directory = '/var/lib/postgresql/data' # use data in another directory - # (change requires restart) -hba_file = '/etc/postgresql/pg_hba.conf' # host-based authentication file - # (change requires restart) -ident_file = '/etc/postgresql/pg_ident.conf' # ident configuration file - # (change requires restart) - -# If external_pid_file is not explicitly set, no extra PID file is written. -#external_pid_file = '' # write an extra PID file - # (change requires restart) - - -#------------------------------------------------------------------------------ -# CONNECTIONS AND AUTHENTICATION -#------------------------------------------------------------------------------ - -# - Connection Settings - - -listen_addresses = '*' # what IP address(es) to listen on; - # comma-separated list of addresses; - # defaults to 'localhost'; use '*' for all - # (change requires restart) -#port = 5432 # (change requires restart) -#max_connections = 100 # (change requires restart) -#superuser_reserved_connections = 3 # (change requires restart) -#unix_socket_directories = '/tmp' # comma-separated list of directories - # (change requires restart) -#unix_socket_group = '' # (change requires restart) -#unix_socket_permissions = 0777 # begin with 0 to use octal notation - # (change requires restart) -#bonjour = off # advertise server via Bonjour - # (change requires restart) -#bonjour_name = '' # defaults to the computer name - # (change requires restart) - -# - TCP settings - -# see "man tcp" for details - -#tcp_keepalives_idle = 0 # TCP_KEEPIDLE, in seconds; - # 0 selects the system default -#tcp_keepalives_interval = 0 # TCP_KEEPINTVL, in seconds; - # 0 selects the system default -#tcp_keepalives_count = 0 # TCP_KEEPCNT; - # 0 selects the system default -#tcp_user_timeout = 0 # TCP_USER_TIMEOUT, in milliseconds; - # 0 selects the system default - -#client_connection_check_interval = 0 # time between checks for client - # disconnection while running queries; - # 0 for never - -# - Authentication - - -authentication_timeout = 1min # 1s-600s -password_encryption = scram-sha-256 # scram-sha-256 or md5 -db_user_namespace = off - -# GSSAPI using Kerberos -#krb_server_keyfile = 'FILE:${sysconfdir}/krb5.keytab' -#krb_caseins_users = off - -# - SSL - - -ssl = off -ssl_ca_file = '' -ssl_cert_file = '' -ssl_crl_file = '' -ssl_crl_dir = '' -ssl_key_file = '' -ssl_ciphers = 'HIGH:MEDIUM:+3DES:!aNULL' # allowed SSL ciphers -ssl_prefer_server_ciphers = on -ssl_ecdh_curve = 'prime256v1' -ssl_min_protocol_version = 'TLSv1.2' -ssl_max_protocol_version = '' -ssl_dh_params_file = '' -ssl_passphrase_command = '' -ssl_passphrase_command_supports_reload = off - - -#------------------------------------------------------------------------------ -# RESOURCE USAGE (except WAL) -#------------------------------------------------------------------------------ - -# - Memory - - -shared_buffers = 128MB # min 128kB - # (change requires restart) -#huge_pages = try # on, off, or try - # (change requires restart) -#huge_page_size = 0 # zero for system default - # (change requires restart) -#temp_buffers = 8MB # min 800kB -#max_prepared_transactions = 0 # zero disables the feature - # (change requires restart) -# Caution: it is not advisable to set max_prepared_transactions nonzero unless -# you actively intend to use prepared transactions. -#work_mem = 4MB # min 64kB -#hash_mem_multiplier = 1.0 # 1-1000.0 multiplier on hash table work_mem -#maintenance_work_mem = 64MB # min 1MB -#autovacuum_work_mem = -1 # min 1MB, or -1 to use maintenance_work_mem -#logical_decoding_work_mem = 64MB # min 64kB -#max_stack_depth = 2MB # min 100kB -#shared_memory_type = mmap # the default is the first option - # supported by the operating system: - # mmap - # sysv - # windows - # (change requires restart) -#dynamic_shared_memory_type = posix # the default is the first option - # supported by the operating system: - # posix - # sysv - # windows - # mmap - # (change requires restart) -#min_dynamic_shared_memory = 0MB # (change requires restart) - -# - Disk - - -#temp_file_limit = -1 # limits per-process temp file space - # in kilobytes, or -1 for no limit - -# - Kernel Resources - - -#max_files_per_process = 1000 # min 64 - # (change requires restart) - -# - Cost-Based Vacuum Delay - - -#vacuum_cost_delay = 0 # 0-100 milliseconds (0 disables) -#vacuum_cost_page_hit = 1 # 0-10000 credits -#vacuum_cost_page_miss = 2 # 0-10000 credits -#vacuum_cost_page_dirty = 20 # 0-10000 credits -#vacuum_cost_limit = 200 # 1-10000 credits - -# - Background Writer - - -#bgwriter_delay = 200ms # 10-10000ms between rounds -#bgwriter_lru_maxpages = 100 # max buffers written/round, 0 disables -#bgwriter_lru_multiplier = 2.0 # 0-10.0 multiplier on buffers scanned/round -#bgwriter_flush_after = 0 # measured in pages, 0 disables - -# - Asynchronous Behavior - - -#backend_flush_after = 0 # measured in pages, 0 disables -#effective_io_concurrency = 1 # 1-1000; 0 disables prefetching -#maintenance_io_concurrency = 10 # 1-1000; 0 disables prefetching -#max_worker_processes = 8 # (change requires restart) -#max_parallel_workers_per_gather = 2 # taken from max_parallel_workers -#max_parallel_maintenance_workers = 2 # taken from max_parallel_workers -#max_parallel_workers = 8 # maximum number of max_worker_processes that - # can be used in parallel operations -#parallel_leader_participation = on -#old_snapshot_threshold = -1 # 1min-60d; -1 disables; 0 is immediate - # (change requires restart) - - -#------------------------------------------------------------------------------ -# WRITE-AHEAD LOG -#------------------------------------------------------------------------------ - -# - Settings - - -wal_level = logical # minimal, replica, or logical - # (change requires restart) -#fsync = on # flush data to disk for crash safety - # (turning this off can cause - # unrecoverable data corruption) -#synchronous_commit = on # synchronization level; - # off, local, remote_write, remote_apply, or on -#wal_sync_method = fsync # the default is the first option - # supported by the operating system: - # open_datasync - # fdatasync (default on Linux and FreeBSD) - # fsync - # fsync_writethrough - # open_sync -#full_page_writes = on # recover from partial page writes -#wal_log_hints = off # also do full page writes of non-critical updates - # (change requires restart) -#wal_compression = off # enable compression of full-page writes -#wal_init_zero = on # zero-fill new WAL files -#wal_recycle = on # recycle WAL files -#wal_buffers = -1 # min 32kB, -1 sets based on shared_buffers - # (change requires restart) -#wal_writer_delay = 200ms # 1-10000 milliseconds -#wal_writer_flush_after = 1MB # measured in pages, 0 disables -#wal_skip_threshold = 2MB - -#commit_delay = 0 # range 0-100000, in microseconds -#commit_siblings = 5 # range 1-1000 - -# - Checkpoints - - -#checkpoint_timeout = 5min # range 30s-1d -checkpoint_completion_target = 0.5 # checkpoint target duration, 0.0 - 1.0 -checkpoint_flush_after = 256kB # measured in pages, 0 disables -#checkpoint_warning = 30s # 0 disables -#max_wal_size = 1GB -#min_wal_size = 80MB - -# - Archiving - - -#archive_mode = off # enables archiving; off, on, or always - # (change requires restart) -#archive_command = '' # command to use to archive a logfile segment - # placeholders: %p = path of file to archive - # %f = file name only - # e.g. 'test ! -f /mnt/server/archivedir/%f && cp %p /mnt/server/archivedir/%f' -#archive_timeout = 0 # force a logfile segment switch after this - # number of seconds; 0 disables - -# - Archive Recovery - - -# These are only used in recovery mode. - -#restore_command = '' # command to use to restore an archived logfile segment - # placeholders: %p = path of file to restore - # %f = file name only - # e.g. 'cp /mnt/server/archivedir/%f %p' -#archive_cleanup_command = '' # command to execute at every restartpoint -#recovery_end_command = '' # command to execute at completion of recovery - -# - Recovery Target - - -# Set these only when performing a targeted recovery. - -#recovery_target = '' # 'immediate' to end recovery as soon as a - # consistent state is reached - # (change requires restart) -#recovery_target_name = '' # the named restore point to which recovery will proceed - # (change requires restart) -#recovery_target_time = '' # the time stamp up to which recovery will proceed - # (change requires restart) -#recovery_target_xid = '' # the transaction ID up to which recovery will proceed - # (change requires restart) -#recovery_target_lsn = '' # the WAL LSN up to which recovery will proceed - # (change requires restart) -#recovery_target_inclusive = on # Specifies whether to stop: - # just after the specified recovery target (on) - # just before the recovery target (off) - # (change requires restart) -#recovery_target_timeline = 'latest' # 'current', 'latest', or timeline ID - # (change requires restart) -#recovery_target_action = 'pause' # 'pause', 'promote', 'shutdown' - # (change requires restart) - - -#------------------------------------------------------------------------------ -# REPLICATION -#------------------------------------------------------------------------------ - -# - Sending Servers - - -# Set these on the primary and on any standby that will send replication data. - -max_wal_senders = 10 # max number of walsender processes - # (change requires restart) -max_replication_slots = 5 # max number of replication slots - # (change requires restart) -#wal_keep_size = 0 # in megabytes; 0 disables -max_slot_wal_keep_size = 1024 # in megabytes; -1 disables -#wal_sender_timeout = 60s # in milliseconds; 0 disables -#track_commit_timestamp = off # collect timestamp of transaction commit - # (change requires restart) - -# - Primary Server - - -# These settings are ignored on a standby server. - -#synchronous_standby_names = '' # standby servers that provide sync rep - # method to choose sync standbys, number of sync standbys, - # and comma-separated list of application_name - # from standby(s); '*' = all -#vacuum_defer_cleanup_age = 0 # number of xacts by which cleanup is delayed - -# - Standby Servers - - -# These settings are ignored on a primary server. - -#primary_conninfo = '' # connection string to sending server -#primary_slot_name = '' # replication slot on sending server -#promote_trigger_file = '' # file name whose presence ends recovery -#hot_standby = on # "off" disallows queries during recovery - # (change requires restart) -#max_standby_archive_delay = 30s # max delay before canceling queries - # when reading WAL from archive; - # -1 allows indefinite delay -#max_standby_streaming_delay = 30s # max delay before canceling queries - # when reading streaming WAL; - # -1 allows indefinite delay -#wal_receiver_create_temp_slot = off # create temp slot if primary_slot_name - # is not set -#wal_receiver_status_interval = 10s # send replies at least this often - # 0 disables -#hot_standby_feedback = off # send info from standby to prevent - # query conflicts -#wal_receiver_timeout = 60s # time that receiver waits for - # communication from primary - # in milliseconds; 0 disables -#wal_retrieve_retry_interval = 5s # time to wait before retrying to - # retrieve WAL after a failed attempt -#recovery_min_apply_delay = 0 # minimum delay for applying changes during recovery - -# - Subscribers - - -# These settings are ignored on a publisher. - -#max_logical_replication_workers = 4 # taken from max_worker_processes - # (change requires restart) -#max_sync_workers_per_subscription = 2 # taken from max_logical_replication_workers - - -#------------------------------------------------------------------------------ -# QUERY TUNING -#------------------------------------------------------------------------------ - -# - Planner Method Configuration - - -#enable_async_append = on -#enable_bitmapscan = on -#enable_gathermerge = on -#enable_hashagg = on -#enable_hashjoin = on -#enable_incremental_sort = on -#enable_indexscan = on -#enable_indexonlyscan = on -#enable_material = on -#enable_resultcache = on -#enable_mergejoin = on -#enable_nestloop = on -#enable_parallel_append = on -#enable_parallel_hash = on -#enable_partition_pruning = on -#enable_partitionwise_join = off -#enable_partitionwise_aggregate = off -#enable_seqscan = on -#enable_sort = on -#enable_tidscan = on - -# - Planner Cost Constants - - -#seq_page_cost = 1.0 # measured on an arbitrary scale -#random_page_cost = 4.0 # same scale as above -#cpu_tuple_cost = 0.01 # same scale as above -#cpu_index_tuple_cost = 0.005 # same scale as above -#cpu_operator_cost = 0.0025 # same scale as above -#parallel_setup_cost = 1000.0 # same scale as above -#parallel_tuple_cost = 0.1 # same scale as above -#min_parallel_table_scan_size = 8MB -#min_parallel_index_scan_size = 512kB -effective_cache_size = 128MB - -#jit_above_cost = 100000 # perform JIT compilation if available - # and query more expensive than this; - # -1 disables -#jit_inline_above_cost = 500000 # inline small functions if query is - # more expensive than this; -1 disables -#jit_optimize_above_cost = 500000 # use expensive JIT optimizations if - # query is more expensive than this; - # -1 disables - -# - Genetic Query Optimizer - - -#geqo = on -#geqo_threshold = 12 -#geqo_effort = 5 # range 1-10 -#geqo_pool_size = 0 # selects default based on effort -#geqo_generations = 0 # selects default based on effort -#geqo_selection_bias = 2.0 # range 1.5-2.0 -#geqo_seed = 0.0 # range 0.0-1.0 - -# - Other Planner Options - - -#default_statistics_target = 100 # range 1-10000 -#constraint_exclusion = partition # on, off, or partition -#cursor_tuple_fraction = 0.1 # range 0.0-1.0 -#from_collapse_limit = 8 -#jit = on # allow JIT compilation -#join_collapse_limit = 8 # 1 disables collapsing of explicit - # JOIN clauses -#plan_cache_mode = auto # auto, force_generic_plan or - # force_custom_plan - - -#------------------------------------------------------------------------------ -# REPORTING AND LOGGING -#------------------------------------------------------------------------------ - -include = '/etc/postgresql/logging.conf' - -# These are relevant when logging to syslog: -#syslog_facility = 'LOCAL0' -#syslog_ident = 'postgres' -#syslog_sequence_numbers = on -#syslog_split_messages = on - -# This is only relevant when logging to eventlog (Windows): -# (change requires restart) -#event_source = 'PostgreSQL' - -# - When to Log - - -#log_min_messages = warning # values in order of decreasing detail: - # debug5 - # debug4 - # debug3 - # debug2 - # debug1 - # info - # notice - # warning - # error - # log - # fatal - # panic - -#log_min_error_statement = error # values in order of decreasing detail: - # debug5 - # debug4 - # debug3 - # debug2 - # debug1 - # info - # notice - # warning - # error - # log - # fatal - # panic (effectively off) - -#log_min_duration_statement = -1 # -1 is disabled, 0 logs all statements - # and their durations, > 0 logs only - # statements running at least this number - # of milliseconds - -#log_min_duration_sample = -1 # -1 is disabled, 0 logs a sample of statements - # and their durations, > 0 logs only a sample of - # statements running at least this number - # of milliseconds; - # sample fraction is determined by log_statement_sample_rate - -#log_statement_sample_rate = 1.0 # fraction of logged statements exceeding - # log_min_duration_sample to be logged; - # 1.0 logs all such statements, 0.0 never logs - - -#log_transaction_sample_rate = 0.0 # fraction of transactions whose statements - # are logged regardless of their duration; 1.0 logs all - # statements from all transactions, 0.0 never logs - -# - What to Log - - -#debug_print_parse = off -#debug_print_rewritten = off -#debug_print_plan = off -#debug_pretty_print = on -#log_autovacuum_min_duration = -1 # log autovacuum activity; - # -1 disables, 0 logs all actions and - # their durations, > 0 logs only - # actions running at least this number - # of milliseconds. -#log_checkpoints = off -#log_connections = off -#log_disconnections = off -#log_duration = off -#log_error_verbosity = default # terse, default, or verbose messages -#log_hostname = off -log_line_prefix = '%h %m [%p] %q%u@%d ' # special values: - # %a = application name - # %u = user name - # %d = database name - # %r = remote host and port - # %h = remote host - # %b = backend type - # %p = process ID - # %P = process ID of parallel group leader - # %t = timestamp without milliseconds - # %m = timestamp with milliseconds - # %n = timestamp with milliseconds (as a Unix epoch) - # %Q = query ID (0 if none or not computed) - # %i = command tag - # %e = SQL state - # %c = session ID - # %l = session line number - # %s = session start timestamp - # %v = virtual transaction ID - # %x = transaction ID (0 if none) - # %q = stop here in non-session - # processes - # %% = '%' - # e.g. '<%u%%%d> ' -#log_lock_waits = off # log lock waits >= deadlock_timeout -#log_recovery_conflict_waits = off # log standby recovery conflict waits - # >= deadlock_timeout -#log_parameter_max_length = -1 # when logging statements, limit logged - # bind-parameter values to N bytes; - # -1 means print in full, 0 disables -#log_parameter_max_length_on_error = 0 # when logging an error, limit logged - # bind-parameter values to N bytes; - # -1 means print in full, 0 disables -log_statement = 'none' # none, ddl, mod, all -#log_replication_commands = off -#log_temp_files = -1 # log temporary files equal or larger - # than the specified size in kilobytes; - # -1 disables, 0 logs all temp files -log_timezone = 'UTC' - -#------------------------------------------------------------------------------ -# PROCESS TITLE -#------------------------------------------------------------------------------ - -cluster_name = 'main' # added to process titles if nonempty - # (change requires restart) -#update_process_title = on - - -#------------------------------------------------------------------------------ -# STATISTICS -#------------------------------------------------------------------------------ - -# - Query and Index Statistics Collector - - -#track_activities = on -#track_activity_query_size = 1024 # (change requires restart) -#track_counts = on -#track_io_timing = off -#track_wal_io_timing = off -#track_functions = none # none, pl, all -#stats_temp_directory = 'pg_stat_tmp' - - -# - Monitoring - - -#compute_query_id = auto -#log_statement_stats = off -#log_parser_stats = off -#log_planner_stats = off -#log_executor_stats = off - - -#------------------------------------------------------------------------------ -# AUTOVACUUM -#------------------------------------------------------------------------------ - -#autovacuum = on # Enable autovacuum subprocess? 'on' - # requires track_counts to also be on. -#autovacuum_max_workers = 3 # max number of autovacuum subprocesses - # (change requires restart) -#autovacuum_naptime = 1min # time between autovacuum runs -#autovacuum_vacuum_threshold = 50 # min number of row updates before - # vacuum -#autovacuum_vacuum_insert_threshold = 1000 # min number of row inserts - # before vacuum; -1 disables insert - # vacuums -#autovacuum_analyze_threshold = 50 # min number of row updates before - # analyze -#autovacuum_vacuum_scale_factor = 0.2 # fraction of table size before vacuum -#autovacuum_vacuum_insert_scale_factor = 0.2 # fraction of inserts over table - # size before insert vacuum -#autovacuum_analyze_scale_factor = 0.1 # fraction of table size before analyze -#autovacuum_freeze_max_age = 200000000 # maximum XID age before forced vacuum - # (change requires restart) -#autovacuum_multixact_freeze_max_age = 400000000 # maximum multixact age - # before forced vacuum - # (change requires restart) -#autovacuum_vacuum_cost_delay = 2ms # default vacuum cost delay for - # autovacuum, in milliseconds; - # -1 means use vacuum_cost_delay -#autovacuum_vacuum_cost_limit = -1 # default vacuum cost limit for - # autovacuum, -1 means use - # vacuum_cost_limit - - -#------------------------------------------------------------------------------ -# CLIENT CONNECTION DEFAULTS -#------------------------------------------------------------------------------ - -# - Statement Behavior - - -#client_min_messages = notice # values in order of decreasing detail: - # debug5 - # debug4 - # debug3 - # debug2 - # debug1 - # log - # notice - # warning - # error -#search_path = '"$user", public' # schema names -row_security = on -#default_table_access_method = 'heap' -#default_tablespace = '' # a tablespace name, '' uses the default -#default_toast_compression = 'pglz' # 'pglz' or 'lz4' -#temp_tablespaces = '' # a list of tablespace names, '' uses - # only default tablespace -#check_function_bodies = on -#default_transaction_isolation = 'read committed' -#default_transaction_read_only = off -#default_transaction_deferrable = off -#session_replication_role = 'origin' -#statement_timeout = 0 # in milliseconds, 0 is disabled -#lock_timeout = 0 # in milliseconds, 0 is disabled -#idle_in_transaction_session_timeout = 0 # in milliseconds, 0 is disabled -#idle_session_timeout = 0 # in milliseconds, 0 is disabled -#vacuum_freeze_table_age = 150000000 -#vacuum_freeze_min_age = 50000000 -#vacuum_failsafe_age = 1600000000 -#vacuum_multixact_freeze_table_age = 150000000 -#vacuum_multixact_freeze_min_age = 5000000 -#vacuum_multixact_failsafe_age = 1600000000 -#bytea_output = 'hex' # hex, escape -#xmlbinary = 'base64' -#xmloption = 'content' -#gin_pending_list_limit = 4MB - -# - Locale and Formatting - - -#datestyle = 'iso, mdy' -#intervalstyle = 'postgres' -timezone = 'UTC' -#timezone_abbreviations = 'Default' # Select the set of available time zone - # abbreviations. Currently, there are - # Default - # Australia (historical usage) - # India - # You can create your own file in - # share/timezonesets/. -extra_float_digits = 0 # min -15, max 3; any value >0 actually - # selects precise output mode -#client_encoding = sql_ascii # actually, defaults to database - # encoding - -# These settings are initialized by initdb, but they can be changed. -lc_messages = 'en_US.UTF-8' # locale for system error message - # strings -lc_monetary = 'en_US.UTF-8' # locale for monetary formatting -lc_numeric = 'en_US.UTF-8' # locale for number formatting -lc_time = 'en_US.UTF-8' # locale for time formatting - -# default configuration for text search -default_text_search_config = 'pg_catalog.english' - -# - Shared Library Preloading - - -#local_preload_libraries = '' -#session_preload_libraries = '' - -shared_preload_libraries = 'pg_stat_statements, pg_stat_monitor, pgaudit, plpgsql, plpgsql_check, pg_cron, pg_net, pgsodium, timescaledb, auto_explain, pg_tle' # (change requires restart) -jit_provider = 'llvmjit' # JIT library to use - -# - Other Defaults - - -#dynamic_library_path = '$libdir' -#gin_fuzzy_search_limit = 0 - -#------------------------------------------------------------------------------ -# LOCK MANAGEMENT -#------------------------------------------------------------------------------ - -#deadlock_timeout = 1s -#max_locks_per_transaction = 64 # min 10 - # (change requires restart) -#max_pred_locks_per_transaction = 64 # min 10 - # (change requires restart) -#max_pred_locks_per_relation = -2 # negative values mean - # (max_pred_locks_per_transaction - # / -max_pred_locks_per_relation) - 1 -#max_pred_locks_per_page = 2 # min 0 - - -#------------------------------------------------------------------------------ -# VERSION AND PLATFORM COMPATIBILITY -#------------------------------------------------------------------------------ - -# - Previous PostgreSQL Versions - - -#array_nulls = on -#backslash_quote = safe_encoding # on, off, or safe_encoding -#escape_string_warning = on -#lo_compat_privileges = off -#quote_all_identifiers = off -#standard_conforming_strings = on -#synchronize_seqscans = on - -# - Other Platforms and Clients - - -#transform_null_equals = off - - -#------------------------------------------------------------------------------ -# ERROR HANDLING -#------------------------------------------------------------------------------ - -#exit_on_error = off # terminate session on any error? -#restart_after_crash = on # reinitialize after backend crash? -#data_sync_retry = off # retry or panic on failure to fsync - # data? - # (change requires restart) -#recovery_init_sync_method = fsync # fsync, syncfs (Linux 5.8+) - - -#------------------------------------------------------------------------------ -# CONFIG FILE INCLUDES -#------------------------------------------------------------------------------ - -# These options allow settings to be loaded from files other than the -# default postgresql.conf. Note that these are directives, not variable -# assignments, so they can usefully be given more than once. - -#include_dir = '...' # include files ending in '.conf' from - # a directory, e.g., 'conf.d' -#include_if_exists = '...' # include file only if it exists -#include = '...' # include file - -# Automatically generated optimizations -#include = '/etc/postgresql-custom/generated-optimizations.conf' -# User-supplied custom parameters, override any automatically generated ones -#include = '/etc/postgresql-custom/custom-overrides.conf' - -# WAL-G specific configurations -#include = '/etc/postgresql-custom/wal-g.conf' - -# read replica specific configurations -include = '/etc/postgresql-custom/read-replica.conf' - -# supautils specific configurations -#include = '/etc/postgresql-custom/supautils.conf' - -#------------------------------------------------------------------------------ -# CUSTOMIZED OPTIONS -#------------------------------------------------------------------------------ - -# Add settings for extensions here diff --git a/ansible-nix/files/postgresql_config/postgresql.service.j2 b/ansible-nix/files/postgresql_config/postgresql.service.j2 deleted file mode 100644 index 41a0d0d80..000000000 --- a/ansible-nix/files/postgresql_config/postgresql.service.j2 +++ /dev/null @@ -1,24 +0,0 @@ -[Unit] -Description=PostgreSQL database server -Documentation=man:postgres(1) -{% if supabase_internal is defined %} -Requires=database-optimizations.service -After=database-optimizations.service -{% endif %} - -[Service] -Type=notify -User=postgres -ExecStart=/usr/lib/postgresql/bin/postgres -D /etc/postgresql -ExecReload=/bin/kill -HUP $MAINPID -KillMode=mixed -KillSignal=SIGINT -TimeoutStopSec=90 -TimeoutStartSec=86400 -Restart=always -RestartSec=5 -OOMScoreAdjust=-1000 -EnvironmentFile=-/etc/environment.d/postgresql.env - -[Install] -WantedBy=multi-user.target diff --git a/ansible-nix/files/postgresql_config/supautils.conf.j2 b/ansible-nix/files/postgresql_config/supautils.conf.j2 deleted file mode 100644 index bfbd590f9..000000000 --- a/ansible-nix/files/postgresql_config/supautils.conf.j2 +++ /dev/null @@ -1,12 +0,0 @@ -supautils.extensions_parameter_overrides = '{"pg_cron":{"schema":"pg_catalog"}}' -supautils.policy_grants = '{"postgres":["auth.audit_log_entries","auth.identities","auth.refresh_tokens","auth.sessions","auth.users","realtime.broadcasts","realtime.channels","realtime.presences","storage.buckets","storage.migrations","storage.objects"]}' -# full list: address_standardizer, address_standardizer_data_us, adminpack, amcheck, autoinc, bloom, btree_gin, btree_gist, citext, cube, dblink, dict_int, dict_xsyn, earthdistance, file_fdw, fuzzystrmatch, hstore, http, hypopg, index_advisor, insert_username, intagg, intarray, isn, lo, ltree, moddatetime, old_snapshot, orioledb, pageinspect, pg_buffercache, pg_cron, pg_freespacemap, pg_graphql, pg_hashids, pg_jsonschema, pg_net, pg_prewarm, pg_repack, pg_stat_monitor, pg_stat_statements, pg_surgery, pg_tle, pg_trgm, pg_visibility, pg_walinspect, pgaudit, pgcrypto, pgjwt, pgroonga, pgroonga_database, pgrouting, pgrowlocks, pgsodium, pgstattuple, pgtap, plcoffee, pljava, plls, plpgsql, plpgsql_check, plv8, postgis, postgis_raster, postgis_sfcgal, postgis_tiger_geocoder, postgis_topology, postgres_fdw, refint, rum, seg, sslinfo, supabase_vault, supautils, tablefunc, tcn, timescaledb, tsm_system_rows, tsm_system_time, unaccent, uuid-ossp, vector, wrappers, xml2 -# omitted because may be unsafe: adminpack, amcheck, file_fdw, lo, old_snapshot, pageinspect, pg_buffercache, pg_freespacemap, pg_surgery, pg_visibility -# omitted because deprecated: intagg, xml2 -supautils.privileged_extensions = 'address_standardizer, address_standardizer_data_us, autoinc, bloom, btree_gin, btree_gist, citext, cube, dblink, dict_int, dict_xsyn, earthdistance, fuzzystrmatch, hstore, http, hypopg, index_advisor, insert_username, intarray, isn, ltree, moddatetime, orioledb, pg_cron, pg_graphql, pg_hashids, pg_jsonschema, pg_net, pg_repack, pg_stat_monitor, pg_stat_statements, pg_tle, pg_trgm, pg_walinspect, pgaudit, pgcrypto, pgjwt, pg_prewarm, pgroonga, pgroonga_database, pgrouting, pgrowlocks, pgstattuple, pgsodium, pgtap, plcoffee, pljava, plls, plpgsql, plpgsql_check, plv8, postgis, postgis_raster, postgis_sfcgal, postgis_tiger_geocoder, postgis_topology, postgres_fdw, refint, rum, seg, sslinfo, supabase_vault, supautils, tablefunc, tcn, timescaledb, tsm_system_rows, tsm_system_time, unaccent, uuid-ossp, vector, wrappers' -supautils.privileged_extensions_custom_scripts_path = '/etc/postgresql-custom/extension-custom-scripts' -supautils.privileged_extensions_superuser = 'supabase_admin' -supautils.privileged_role = 'postgres' -supautils.privileged_role_allowed_configs = 'log_min_messages, pgaudit.log, pgaudit.log_catalog, pgaudit.log_client, pgaudit.log_level, pgaudit.log_relation, pgaudit.log_rows, pgaudit.log_statement, pgaudit.log_statement_once, pgaudit.role, pgrst.*, session_replication_role, track_io_timing' -supautils.reserved_memberships = 'pg_read_server_files, pg_write_server_files, pg_execute_server_program, authenticator' -supautils.reserved_roles = 'supabase_admin, supabase_auth_admin, supabase_storage_admin, supabase_read_only_user, supabase_replication_admin, dashboard_user, pgbouncer, service_role*, authenticator*, authenticated*, anon*' diff --git a/ansible-nix/files/postgresql_config/tmpfiles.postgresql.conf b/ansible-nix/files/postgresql_config/tmpfiles.postgresql.conf deleted file mode 100644 index b5ea54948..000000000 --- a/ansible-nix/files/postgresql_config/tmpfiles.postgresql.conf +++ /dev/null @@ -1,5 +0,0 @@ -# unchanged from upstream package -d /run/postgresql 2775 postgres postgres - - -# Log directory - ensure that our logging setup gets preserved -# and that vector can keep writing to a file here as well -d /var/log/postgresql 1775 postgres postgres - - diff --git a/ansible-nix/files/postgresql_extension_custom_scripts/before-create.sql b/ansible-nix/files/postgresql_extension_custom_scripts/before-create.sql deleted file mode 100644 index f2f238668..000000000 --- a/ansible-nix/files/postgresql_extension_custom_scripts/before-create.sql +++ /dev/null @@ -1,84 +0,0 @@ --- If the following are true: --- * the extension to be created is a TLE --- * the extension is created with `cascade` --- --- then we pre-`create` all nested extension dependencies which are part of --- `supautils.privileged_extensions`. This is because supautils can't intercept --- the extension creation for dependencies - it can only intercept the `create --- extension` statement. -do $$ -declare - _extname text := @extname@; - _extschema text := @extschema@; - _extversion text := @extversion@; - _extcascade bool := @extcascade@; - _r record; -begin - if not _extcascade then - return; - end if; - - if not exists (select from pg_extension where extname = 'pg_tle') then - return; - end if; - - if not exists (select from pgtle.available_extensions() where name = _extname) then - return; - end if; - - if _extversion is null then - select default_version - from pgtle.available_extensions() - where name = _extname - into _extversion; - end if; - - if _extschema is null then - select schema - from pgtle.available_extension_versions() - where name = _extname and version = _extversion - into _extschema; - end if; - - for _r in ( - with recursive available_extensions(name, default_version) as ( - select name, default_version - from pg_available_extensions - union - select name, default_version - from pgtle.available_extensions() - ) - , available_extension_versions(name, version, requires) as ( - select name, version, requires - from pg_available_extension_versions - union - select name, version, requires - from pgtle.available_extension_versions() - ) - , all_dependencies(name, dependency) as ( - select e.name, unnest(ev.requires) as dependency - from available_extensions e - join available_extension_versions ev on ev.name = e.name and ev.version = e.default_version - ) - , dependencies(name) AS ( - select unnest(requires) - from available_extension_versions - where name = _extname and version = _extversion - union - select all_dependencies.dependency - from all_dependencies - join dependencies d on d.name = all_dependencies.name - ) - select name - from dependencies - intersect - select name - from regexp_split_to_table(current_setting('supautils.privileged_extensions', true), '\s*,\s*') as t(name) - ) loop - if _extschema is null then - execute(format('create extension if not exists %I cascade', _r.name)); - else - execute(format('create extension if not exists %I schema %I cascade', _r.name, _extschema)); - end if; - end loop; -end $$; diff --git a/ansible-nix/files/postgresql_extension_custom_scripts/dblink/after-create.sql b/ansible-nix/files/postgresql_extension_custom_scripts/dblink/after-create.sql deleted file mode 100644 index 22261bc77..000000000 --- a/ansible-nix/files/postgresql_extension_custom_scripts/dblink/after-create.sql +++ /dev/null @@ -1,14 +0,0 @@ -do $$ -declare - r record; -begin - for r in (select oid, (aclexplode(proacl)).grantee from pg_proc where proname = 'dblink_connect_u') loop - continue when r.grantee = 'supabase_admin'::regrole; - execute( - format( - 'revoke all on function %s(%s) from %s;', r.oid::regproc, pg_get_function_identity_arguments(r.oid), r.grantee::regrole - ) - ); - end loop; -end -$$; diff --git a/ansible-nix/files/postgresql_extension_custom_scripts/pg_cron/after-create.sql b/ansible-nix/files/postgresql_extension_custom_scripts/pg_cron/after-create.sql deleted file mode 100644 index 6ac9d6b6e..000000000 --- a/ansible-nix/files/postgresql_extension_custom_scripts/pg_cron/after-create.sql +++ /dev/null @@ -1,13 +0,0 @@ -grant usage on schema cron to postgres with grant option; -grant all on all functions in schema cron to postgres with grant option; - -alter default privileges for user supabase_admin in schema cron grant all - on sequences to postgres with grant option; -alter default privileges for user supabase_admin in schema cron grant all - on tables to postgres with grant option; -alter default privileges for user supabase_admin in schema cron grant all - on functions to postgres with grant option; - -grant all privileges on all tables in schema cron to postgres with grant option; -revoke all on table cron.job from postgres; -grant select on table cron.job to postgres with grant option; diff --git a/ansible-nix/files/postgresql_extension_custom_scripts/pg_tle/after-create.sql b/ansible-nix/files/postgresql_extension_custom_scripts/pg_tle/after-create.sql deleted file mode 100644 index eb8aeff7e..000000000 --- a/ansible-nix/files/postgresql_extension_custom_scripts/pg_tle/after-create.sql +++ /dev/null @@ -1 +0,0 @@ -grant pgtle_admin to postgres; diff --git a/ansible-nix/files/postgresql_extension_custom_scripts/pgsodium/after-create.sql b/ansible-nix/files/postgresql_extension_custom_scripts/pgsodium/after-create.sql deleted file mode 100644 index 907c67ebf..000000000 --- a/ansible-nix/files/postgresql_extension_custom_scripts/pgsodium/after-create.sql +++ /dev/null @@ -1,3 +0,0 @@ -grant execute on function pgsodium.crypto_aead_det_decrypt(bytea, bytea, uuid, bytea) to service_role; -grant execute on function pgsodium.crypto_aead_det_encrypt(bytea, bytea, uuid, bytea) to service_role; -grant execute on function pgsodium.crypto_aead_det_keygen to service_role; diff --git a/ansible-nix/files/postgresql_extension_custom_scripts/postgis_tiger_geocoder/after-create.sql b/ansible-nix/files/postgresql_extension_custom_scripts/postgis_tiger_geocoder/after-create.sql deleted file mode 100644 index f8ec163bb..000000000 --- a/ansible-nix/files/postgresql_extension_custom_scripts/postgis_tiger_geocoder/after-create.sql +++ /dev/null @@ -1,10 +0,0 @@ --- These schemas are created by extension to house all tiger related functions, owned by supabase_admin -grant usage on schema tiger, tiger_data to postgres with grant option; --- Give postgres permission to all existing entities, also allows postgres to grant other roles -grant all on all tables in schema tiger, tiger_data to postgres with grant option; -grant all on all routines in schema tiger, tiger_data to postgres with grant option; -grant all on all sequences in schema tiger, tiger_data to postgres with grant option; --- Update default privileges so that new entities are also accessible by postgres -alter default privileges in schema tiger, tiger_data grant all on tables to postgres with grant option; -alter default privileges in schema tiger, tiger_data grant all on routines to postgres with grant option; -alter default privileges in schema tiger, tiger_data grant all on sequences to postgres with grant option; diff --git a/ansible-nix/files/postgresql_extension_custom_scripts/postgres_fdw/after-create.sql b/ansible-nix/files/postgresql_extension_custom_scripts/postgres_fdw/after-create.sql deleted file mode 100644 index 1e83ee90e..000000000 --- a/ansible-nix/files/postgresql_extension_custom_scripts/postgres_fdw/after-create.sql +++ /dev/null @@ -1,21 +0,0 @@ -do $$ -declare - is_super boolean; -begin - is_super = ( - select usesuper - from pg_user - where usename = 'postgres' - ); - - -- Need to be superuser to own FDWs, so we temporarily make postgres superuser. - if not is_super then - alter role postgres superuser; - end if; - - alter foreign data wrapper postgres_fdw owner to postgres; - - if not is_super then - alter role postgres nosuperuser; - end if; -end $$; diff --git a/ansible-nix/files/postgrest-optimizations.service.j2 b/ansible-nix/files/postgrest-optimizations.service.j2 deleted file mode 100644 index 38604b67a..000000000 --- a/ansible-nix/files/postgrest-optimizations.service.j2 +++ /dev/null @@ -1,11 +0,0 @@ -[Unit] -Description=Postgrest optimizations - -[Service] -Type=oneshot -# we don't want failures from this command to cause PG startup to fail -ExecStart=/bin/bash -c "/opt/supabase-admin-api optimize postgrest --destination-config-file-path /etc/postgrest/generated.conf ; exit 0" -User=postgrest - -[Install] -WantedBy=multi-user.target diff --git a/ansible-nix/files/postgrest.service.j2 b/ansible-nix/files/postgrest.service.j2 deleted file mode 100644 index 290f07720..000000000 --- a/ansible-nix/files/postgrest.service.j2 +++ /dev/null @@ -1,18 +0,0 @@ -[Unit] -Description=PostgREST -Requires=postgrest-optimizations.service -After=postgrest-optimizations.service - -[Service] -Type=simple -# We allow the base config (sent from the worker) to override the generated config -ExecStartPre=/etc/postgrest/merge.sh /etc/postgrest/generated.conf /etc/postgrest/base.conf -ExecStart=/opt/postgrest /etc/postgrest/merged.conf -User=postgrest -Slice=services.slice -Restart=always -RestartSec=3 -LimitNOFILE=100000 - -[Install] -WantedBy=multi-user.target diff --git a/ansible-nix/files/services.slice.j2 b/ansible-nix/files/services.slice.j2 deleted file mode 100644 index d45187fb8..000000000 --- a/ansible-nix/files/services.slice.j2 +++ /dev/null @@ -1,6 +0,0 @@ -# Used for general services grouping for easy visibility when running -# systemctl status -# See http://archive.vn/94IGa for an in depth article on systemd slices -[Unit] -Description=Slice used for PostgreSQL -Before=slices.target diff --git a/ansible-nix/files/sodium_extension.sql b/ansible-nix/files/sodium_extension.sql deleted file mode 100644 index a19cabf72..000000000 --- a/ansible-nix/files/sodium_extension.sql +++ /dev/null @@ -1,6 +0,0 @@ -create schema if not exists pgsodium; -create extension if not exists pgsodium with schema pgsodium cascade; - -grant pgsodium_keyiduser to postgres with admin option; -grant pgsodium_keyholder to postgres with admin option; -grant pgsodium_keymaker to postgres with admin option; diff --git a/ansible-nix/files/start-envoy.sh b/ansible-nix/files/start-envoy.sh deleted file mode 100644 index edd6fe09e..000000000 --- a/ansible-nix/files/start-envoy.sh +++ /dev/null @@ -1,12 +0,0 @@ -#!/usr/bin/env bash -set -eou pipefail - -if [[ $(cat /sys/module/ipv6/parameters/disable) = 1 ]]; then - sed -i -e "s/address: '::'/address: '0.0.0.0'/" -e 's/ipv4_compat: true/ipv4_compat: false/' /etc/envoy/lds.yaml -else - sed -i -e "s/address: '0.0.0.0'/address: '::'/" -e 's/ipv4_compat: false/ipv4_compat: true/' /etc/envoy/lds.yaml -fi - -# Workaround using `tee` to get `/dev/stdout` access logging to work, see: -# https://github.com/envoyproxy/envoy/issues/8297#issuecomment-620659781 -exec /opt/envoy --config-path /etc/envoy/envoy.yaml --restart-epoch "${RESTART_EPOCH}" 2>&1 | tee diff --git a/ansible-nix/files/stat_extension.sql b/ansible-nix/files/stat_extension.sql deleted file mode 100644 index 937834004..000000000 --- a/ansible-nix/files/stat_extension.sql +++ /dev/null @@ -1,2 +0,0 @@ -CREATE SCHEMA IF NOT exists extensions; -CREATE EXTENSION IF NOT EXISTS pg_stat_statements with schema extensions; diff --git a/ansible-nix/files/supabase_facts.ini b/ansible-nix/files/supabase_facts.ini deleted file mode 100644 index 44e01b4c3..000000000 --- a/ansible-nix/files/supabase_facts.ini +++ /dev/null @@ -1,2 +0,0 @@ -[general] -postgres_version=15 diff --git a/ansible-nix/files/sysstat.sysstat b/ansible-nix/files/sysstat.sysstat deleted file mode 100644 index 52b7d07d1..000000000 --- a/ansible-nix/files/sysstat.sysstat +++ /dev/null @@ -1,36 +0,0 @@ -# How long to keep log files (in days). -# Used by sa2(8) script -# If value is greater than 28, then use sadc's option -D to prevent older -# data files from being overwritten. See sadc(8) and sysstat(5) manual pages. -HISTORY=7 - -# Compress (using xz, gzip or bzip2) sa and sar files older than (in days): -COMPRESSAFTER=10 - -# Parameters for the system activity data collector (see sadc(8) manual page) -# which are used for the generation of log files. -# By default contains the `-S DISK' option responsible for generating disk -# statisitcs. Use `-S XALL' to collect all available statistics. -SADC_OPTIONS="-S DISK" - -# Directory where sa and sar files are saved. The directory must exist. -SA_DIR=/var/log/sysstat - -# Compression program to use. -ZIP="xz" - -# By default sa2 script generates yesterday's summary, since the cron job -# usually runs right after midnight. If you want sa2 to generate the summary -# of the same day (for example when cron job runs at 23:53) set this variable. -#YESTERDAY=no - -# By default sa2 script generates reports files (the so called sarDD files). -# Set this variable to false to disable reports generation. -#REPORTS=false - -# The sa1 and sa2 scripts generate system activity data and report files in -# the /var/log/sysstat directory. By default the files are created with umask 0022 -# and are therefore readable for all users. Change this variable to restrict -# the permissions on the files (e.g. use 0027 to adhere to more strict -# security standards). -UMASK=0022 diff --git a/ansible-nix/files/systemd-resolved.conf b/ansible-nix/files/systemd-resolved.conf deleted file mode 100644 index 9280d88a1..000000000 --- a/ansible-nix/files/systemd-resolved.conf +++ /dev/null @@ -1,8 +0,0 @@ -# the default is RestartSec=0. If the service fails to start because -# of a systemic issue (e.g. rare case when disk is full) it will -# quickly hit the burst limit (default of 5 failures within 10secs) -# and thereafter be placed in a failed state. By increasing the -# restart interval, we avoid that, and ensure that the service will be -# started back up once any underlying issues are resolved. -[Service] -RestartSec=3 diff --git a/ansible-nix/files/ufw.service.conf b/ansible-nix/files/ufw.service.conf deleted file mode 100644 index 83b82efc7..000000000 --- a/ansible-nix/files/ufw.service.conf +++ /dev/null @@ -1,4 +0,0 @@ -[Unit] -After=nftables.service -Requires=nftables.service -PartOf=nftables.service diff --git a/ansible-nix/files/vector.service.j2 b/ansible-nix/files/vector.service.j2 deleted file mode 100644 index 1c88baa20..000000000 --- a/ansible-nix/files/vector.service.j2 +++ /dev/null @@ -1,20 +0,0 @@ -[Unit] -Description=Vector -Documentation=https://vector.dev -After=network-online.target -Requires=network-online.target - -[Service] -User=vector -Group=vector -ExecStartPre=/usr/bin/vector validate --config-yaml /etc/vector/vector.yaml -ExecStart=/usr/bin/vector --config-yaml /etc/vector/vector.yaml -ExecReload=/usr/bin/vector validate --config-yaml /etc/vector/vector.yaml -ExecReload=/bin/kill -HUP $MAINPID -Restart=always -RestartSec=3 -AmbientCapabilities=CAP_NET_BIND_SERVICE -EnvironmentFile=-/etc/default/vector - -[Install] -WantedBy=multi-user.target diff --git a/ansible-nix/files/walg_helper_scripts/wal_change_ownership.sh b/ansible-nix/files/walg_helper_scripts/wal_change_ownership.sh deleted file mode 100644 index 3f0112d2f..000000000 --- a/ansible-nix/files/walg_helper_scripts/wal_change_ownership.sh +++ /dev/null @@ -1,42 +0,0 @@ -#! /usr/bin/env bash - -set -euo pipefail - -filename=$1 - -if [[ -z "$filename" ]]; then - echo "Nothing supplied. Exiting." - exit 1 -fi - -full_path=/tmp/wal_fetch_dir/$filename - -num_paths=$(readlink -f "$full_path" | wc -l) - -# Checks if supplied filename string contains multiple paths -# For example, "correct/path /var/lib/injected/path /var/lib/etc" -if [[ "$num_paths" -gt 1 ]]; then - echo "Multiple paths supplied. Exiting." - exit 1 -fi - -base_dir=$(readlink -f "$full_path" | cut -d'/' -f2) - -# Checks if directory/ file to be manipulated -# is indeed within the /tmp directory -# For example, "/tmp/../var/lib/postgresql/..." -# will return "var" as the value for $base_dir -if [[ "$base_dir" != "tmp" ]]; then - echo "Attempt to manipulate a file not in /tmp. Exiting." - exit 1 -fi - -# Checks if change of ownership will be applied to a file -# If not, exit -if [[ ! -f $full_path ]]; then - echo "Either file does not exist or is a directory. Exiting." - exit 1 -fi - -# once valid, proceed to change ownership -chown postgres:postgres "$full_path" diff --git a/ansible-nix/files/walg_helper_scripts/wal_fetch.sh b/ansible-nix/files/walg_helper_scripts/wal_fetch.sh deleted file mode 100644 index 33448ac95..000000000 --- a/ansible-nix/files/walg_helper_scripts/wal_fetch.sh +++ /dev/null @@ -1,12 +0,0 @@ -#! /usr/bin/env bash - -set -euo pipefail - -# Fetch the WAL file and temporarily store them in /tmp -sudo -u wal-g wal-g wal-fetch "$1" /tmp/wal_fetch_dir/"$1" --config /etc/wal-g/config.json - -# Ensure WAL file is owned by the postgres Linux user -sudo -u root /root/wal_change_ownership.sh "$1" - -# Move file to its final destination -mv /tmp/wal_fetch_dir/"$1" /var/lib/postgresql/data/"$2" diff --git a/ansible-nix/manifest-playbook.yml b/ansible-nix/manifest-playbook.yml deleted file mode 100644 index 93f0e15c5..000000000 --- a/ansible-nix/manifest-playbook.yml +++ /dev/null @@ -1,91 +0,0 @@ -- hosts: localhost - gather_facts: no - - vars_files: - - ./vars.yml - - tasks: - - name: Write out image manifest - action: template src=files/manifest.json dest=./image-manifest-{{ ami_release_version }}.json - - - name: Upload image manifest - shell: | - aws s3 cp ./image-manifest-{{ ami_release_version }}.json s3://{{ internal_artifacts_bucket }}/manifests/postgres-{{ ami_release_version }}/software-manifest.json - - # upload software artifacts of interest - # Generally - download, extract, repack as xz archive, upload - # currently, we upload gotrue, adminapi, postgrest - - name: gotrue - download commit archive - get_url: - url: "https://github.com/supabase/gotrue/releases/download/v{{ gotrue_release }}/auth-v{{ gotrue_release }}-arm64.tar.gz" - dest: /tmp/gotrue.tar.gz - checksum: "{{ gotrue_release_checksum }}" - timeout: 60 - - - name: gotrue - create /tmp/gotrue - file: - path: /tmp/gotrue - state: directory - mode: 0775 - - - name: gotrue - unpack archive in /tmp/gotrue - unarchive: - remote_src: yes - src: /tmp/gotrue.tar.gz - dest: /tmp/gotrue - - - name: gotrue - pack archive - shell: | - cd /tmp && tar -cJf gotrue-v{{ gotrue_release }}-arm64.tar.xz gotrue - - - name: PostgREST - download ubuntu binary archive (arm) - get_url: - url: "https://github.com/PostgREST/postgrest/releases/download/v{{ postgrest_release }}/postgrest-v{{ postgrest_release }}-ubuntu-aarch64.tar.xz" - dest: /tmp/postgrest-{{ postgrest_release }}-arm64.tar.xz - checksum: "{{ postgrest_arm_release_checksum }}" - timeout: 60 - - - name: Download adminapi archive - get_url: - url: "https://supabase-public-artifacts-bucket.s3.amazonaws.com/supabase-admin-api/v{{ adminapi_release }}/supabase-admin-api_{{ adminapi_release }}_linux_arm64.tar.gz" - dest: "/tmp/adminapi.tar.gz" - timeout: 90 - - - name: adminapi - unpack archive in /tmp - unarchive: - remote_src: yes - src: /tmp/adminapi.tar.gz - dest: /tmp - - - name: adminapi - pack archive - shell: | - cd /tmp && tar -cJf supabase-admin-api-{{ adminapi_release }}-arm64.tar.xz supabase-admin-api - - - name: Download admin-mgr archive - get_url: - url: "https://supabase-public-artifacts-bucket.s3.amazonaws.com/admin-mgr/v{{ adminmgr_release }}/admin-mgr_{{ adminmgr_release }}_linux_arm64.tar.gz" - dest: "/tmp/admin-mgr.tar.gz" - timeout: 90 - - - name: admin-mgr - unpack archive in /tmp - unarchive: - remote_src: yes - src: /tmp/admin-mgr.tar.gz - dest: /tmp - - - name: admin-mgr - pack archive - shell: | - cd /tmp && tar -cJf admin-mgr-{{ adminmgr_release }}-arm64.tar.xz admin-mgr - - - name: upload archives - shell: | - aws s3 cp /tmp/{{ item.file }} s3://{{ internal_artifacts_bucket }}/upgrades/{{ item.service }}/{{ item.file }} - with_items: - - service: gotrue - file: gotrue-v{{ gotrue_release }}-arm64.tar.xz - - service: postgrest - file: postgrest-{{ postgrest_release }}-arm64.tar.xz - - service: supabase-admin-api - file: supabase-admin-api-{{ adminapi_release }}-arm64.tar.xz - - service: admin-mgr - file: admin-mgr-{{ adminmgr_release }}-arm64.tar.xz diff --git a/ansible-nix/playbook.yml b/ansible-nix/playbook.yml deleted file mode 100644 index c1bb3b898..000000000 --- a/ansible-nix/playbook.yml +++ /dev/null @@ -1,120 +0,0 @@ -- hosts: all - become: yes - - pre_tasks: - - import_tasks: tasks/setup-system.yml - - vars_files: - - ./vars.yml - - vars: - sql_files: - - { - source: "pgbouncer_config/pgbouncer_auth_schema.sql", - dest: "00-schema.sql", - } - - { source: "stat_extension.sql", dest: "01-extension.sql" } - - environment: - PATH: /usr/lib/postgresql/bin:{{ ansible_env.PATH }} - - tasks: - - set_fact: - supabase_internal: true - tags: - - install-supabase-internal - - - set_fact: - parallel_jobs: 16 - - - name: Prepare machine for Postgres installation - import_tasks: tasks/setup-postgres.yml - - - name: Install PgBouncer - import_tasks: tasks/setup-pgbouncer.yml - tags: - - install-pgbouncer - - install-supabase-internal - - - name: Install WAL-G - import_tasks: tasks/setup-wal-g.yml - - - name: Install Gotrue - import_tasks: tasks/setup-gotrue.yml - tags: - - install-gotrue - - install-supabase-internal - - - name: Install PostgREST - import_tasks: tasks/setup-postgrest.yml - tags: - - install-postgrest - - install-supabase-internal - - - name: Install Envoy - import_tasks: tasks/setup-envoy.yml - tags: - - install-supabase-internal - - - name: Install Kong - import_tasks: tasks/setup-kong.yml - tags: - - install-supabase-internal - - - name: Install nginx - import_tasks: tasks/setup-nginx.yml - tags: - - install-supabase-internal - - - name: Install Supabase specific content - import_tasks: tasks/setup-supabase-internal.yml - tags: - - install-supabase-internal - - - name: Adjust APT update intervals - copy: - src: files/apt_periodic - dest: /etc/apt/apt.conf.d/10periodic - - - name: Finalize AMI - import_tasks: tasks/finalize-ami.yml - tags: - - install-supabase-internal - - - name: Enhance fail2ban - import_tasks: tasks/setup-fail2ban.yml - - # Install EC2 instance connect - # Only for AWS images - - name: install EC2 instance connect - become: yes - apt: - pkg: - - ec2-instance-connect - tags: - - aws-only - - # Install this at the end to prevent it from kicking in during the apt process, causing conflicts - - name: Install security tools - become: yes - apt: - pkg: - - unattended-upgrades - update_cache: yes - cache_valid_time: 3600 - - - name: Clean out build dependencies - import_tasks: tasks/clean-build-dependencies.yml - - - name: Check if postgres user is part of users group - shell: "id -nG postgres | grep -qw users" - register: check_user_group - ignore_errors: yes - become: yes - args: - executable: /bin/bash - - - name: Print result to Ansible log output - debug: - msg: "The postgres user is {{ 'not ' if check_user_group.rc != 0 else '' }}part of the users group" - diff --git a/ansible-nix/tasks/clean-build-dependencies.yml b/ansible-nix/tasks/clean-build-dependencies.yml deleted file mode 100644 index 43ec05179..000000000 --- a/ansible-nix/tasks/clean-build-dependencies.yml +++ /dev/null @@ -1,21 +0,0 @@ -- name: Remove build dependencies - apt: - pkg: - - bison - - build-essential - - clang-11 - - cmake - - cpp - - flex - - g++ - - g++-10 - - g++-9 - - gcc-10 - - make - - manpages - - manpages-dev - - ninja-build - - patch - - python2 - state: absent - autoremove: yes diff --git a/ansible-nix/tasks/finalize-ami.yml b/ansible-nix/tasks/finalize-ami.yml deleted file mode 100644 index 81a89abeb..000000000 --- a/ansible-nix/tasks/finalize-ami.yml +++ /dev/null @@ -1,72 +0,0 @@ -- name: PG logging conf - template: - src: files/postgresql_config/postgresql-csvlog.conf - dest: /etc/postgresql/logging.conf - group: postgres - -- name: UFW - Allow SSH connections - ufw: - rule: allow - name: OpenSSH - -- name: UFW - Allow connections to postgreSQL (5432) - ufw: - rule: allow - port: "5432" - -- name: UFW - Allow connections to postgreSQL (6543) - ufw: - rule: allow - port: "6543" - tags: - - install-pgbouncer - -- name: UFW - Allow connections to http (80) - ufw: - rule: allow - port: http - tags: - - install-supabase-internal - -- name: UFW - Allow connections to https (443) - ufw: - rule: allow - port: https - tags: - - install-supabase-internal - -- name: UFW - Deny all other incoming traffic by default - ufw: - state: enabled - policy: deny - direction: incoming - -- name: Move logrotate files to /etc/logrotate.d/ - copy: - src: "files/logrotate_config/{{ item.file }}" - dest: "/etc/logrotate.d/{{ item.file }}" - mode: "0700" - owner: root - loop: - - { file: "logrotate-postgres-csv.conf" } - - { file: "logrotate-postgres.conf" } - - { file: "logrotate-walg.conf" } - - { file: "logrotate-postgres-auth.conf" } - -- name: Ensure default Postgres logrotate config is removed - file: - path: /etc/logrotate.d/postgresql-common - state: absent - -- name: Disable cron access - copy: - src: files/cron.deny - dest: /etc/cron.deny - -- name: Configure logrotation to run every hour - shell: - cmd: | - cp /usr/lib/systemd/system/logrotate.timer /etc/systemd/system/logrotate.timer - sed -i -e 's;daily;*:0/5;' /etc/systemd/system/logrotate.timer - systemctl reenable logrotate.timer - become: yes diff --git a/ansible-nix/tasks/internal/admin-api.yml b/ansible-nix/tasks/internal/admin-api.yml deleted file mode 100644 index cea0109fd..000000000 --- a/ansible-nix/tasks/internal/admin-api.yml +++ /dev/null @@ -1,92 +0,0 @@ -- name: adminapi - system user - user: - name: adminapi - groups: root,admin,envoy,kong,pgbouncer,postgres,postgrest,systemd-journal,vector,wal-g - append: yes - -- name: Move shell scripts to /root dir - copy: - src: "files/admin_api_scripts/{{ item.file }}" - dest: "/root/{{ item.file }}" - mode: "0700" - owner: root - loop: - - { file: "grow_fs.sh" } - - { file: "manage_readonly_mode.sh" } - - { file: "pg_egress_collect.pl" } - -- name: give adminapi user permissions - copy: - src: files/adminapi.sudoers.conf - dest: /etc/sudoers.d/adminapi - mode: "0644" - -- name: perms for adminapi - shell: | - chmod g+w /etc - -- name: Setting arch (x86) - set_fact: - arch: "x86" - when: platform == "amd64" - -- name: Setting arch (arm) - set_fact: - arch: "arm64" - when: platform == "arm64" - -- name: Download adminapi archive - get_url: - url: "https://supabase-public-artifacts-bucket.s3.amazonaws.com/supabase-admin-api/v{{ adminapi_release }}/supabase-admin-api_{{ adminapi_release }}_linux_{{ arch }}.tar.gz" - dest: "/tmp/adminapi.tar.gz" - timeout: 90 - -- name: adminapi - unpack archive in /opt - unarchive: - remote_src: yes - src: /tmp/adminapi.tar.gz - dest: /opt - owner: adminapi - -- name: adminapi - config dir - file: - path: /etc/adminapi - owner: adminapi - state: directory - -- name: adminapi - pg_upgrade scripts dir - file: - path: /etc/adminapi/pg_upgrade_scripts - owner: adminapi - state: directory - -- name: Move shell scripts to /etc/adminapi/pg_upgrade_scripts/ - copy: - src: "files/admin_api_scripts/pg_upgrade_scripts/{{ item.file }}" - dest: "/etc/adminapi/pg_upgrade_scripts/{{ item.file }}" - mode: "0755" - owner: adminapi - loop: - - { file: "check.sh" } - - { file: "complete.sh" } - - { file: "initiate.sh" } - - { file: "prepare.sh" } - - { file: "pgsodium_getkey.sh" } - - { file: "common.sh" } - -- name: adminapi - create service file - template: - src: files/adminapi.service.j2 - dest: /etc/systemd/system/adminapi.service - -- name: UFW - Allow connections to adminapi ports - ufw: - rule: allow - port: "8085" - -- name: adminapi - reload systemd - systemd: - daemon_reload: yes - -- name: adminapi - grant extra priviliges to user - shell: chmod 775 /etc && chmod 775 /etc/kong diff --git a/ansible-nix/tasks/internal/admin-mgr.yml b/ansible-nix/tasks/internal/admin-mgr.yml deleted file mode 100644 index 073b8661f..000000000 --- a/ansible-nix/tasks/internal/admin-mgr.yml +++ /dev/null @@ -1,22 +0,0 @@ -- name: Setting arch (x86) - set_fact: - arch: "amd64" - when: platform == "amd64" - -- name: Setting arch (arm) - set_fact: - arch: "arm64" - when: platform == "arm64" - -- name: Download admin-mgr archive - get_url: - url: "https://supabase-public-artifacts-bucket.s3.amazonaws.com/admin-mgr/v{{ adminmgr_release }}/admin-mgr_{{ adminmgr_release }}_linux_{{ arch }}.tar.gz" - dest: "/tmp/admin-mgr.tar.gz" - timeout: 90 - -- name: admin-mgr - unpack archive in /usr/bin/ - unarchive: - remote_src: yes - src: /tmp/admin-mgr.tar.gz - dest: /usr/bin/ - owner: root diff --git a/ansible-nix/tasks/internal/pg_egress_collect.yml b/ansible-nix/tasks/internal/pg_egress_collect.yml deleted file mode 100644 index be9fefe02..000000000 --- a/ansible-nix/tasks/internal/pg_egress_collect.yml +++ /dev/null @@ -1,15 +0,0 @@ -- name: pg_egress_collect - install tcpdump and perl async lib - apt: - pkg: - - tcpdump - - libio-async-perl - -- name: pg_egress_collect - create service file - template: - src: files/pg_egress_collect.service.j2 - dest: /etc/systemd/system/pg_egress_collect.service - -- name: pg_egress_collect - reload systemd - systemd: - daemon_reload: yes - diff --git a/ansible-nix/tasks/internal/postgres-exporter.yml b/ansible-nix/tasks/internal/postgres-exporter.yml deleted file mode 100644 index 0292157b2..000000000 --- a/ansible-nix/tasks/internal/postgres-exporter.yml +++ /dev/null @@ -1,48 +0,0 @@ -- name: UFW - Allow connections to exporter for prometheus - ufw: - rule: allow - port: "9187" - -- name: create directories - systemd unit - file: - state: directory - path: /etc/systemd/system/postgres_exporter.service.d - owner: root - mode: '0700' - become: yes - -- name: create directories - service files - file: - state: directory - path: /opt/postgres_exporter - owner: postgres - group: postgres - mode: '0775' - become: yes - -- name: download postgres exporter - get_url: - url: "https://github.com/prometheus-community/postgres_exporter/releases/download/v{{ postgres_exporter_release }}/postgres_exporter-{{ postgres_exporter_release }}.linux-{{ platform }}.tar.gz" - dest: /tmp/postgres_exporter.tar.gz - checksum: "{{ postgres_exporter_release_checksum[platform] }}" - timeout: 60 - -- name: expand postgres exporter - unarchive: - remote_src: yes - src: /tmp/postgres_exporter.tar.gz - dest: /opt/postgres_exporter - extra_opts: [--strip-components=1] - become: yes - -- name: exporter create a service - template: - src: files/postgres_exporter.service.j2 - dest: /etc/systemd/system/postgres_exporter.service - -- name: exporter ensure service is present - systemd: - enabled: no - name: postgres_exporter - daemon_reload: yes - state: stopped diff --git a/ansible-nix/tasks/internal/setup-ansible-pull.yml b/ansible-nix/tasks/internal/setup-ansible-pull.yml deleted file mode 100644 index 7cce74a8c..000000000 --- a/ansible-nix/tasks/internal/setup-ansible-pull.yml +++ /dev/null @@ -1,29 +0,0 @@ -- name: install ansible - shell: - cmd: | - apt install -y software-properties-common - add-apt-repository --yes --update ppa:ansible/ansible - apt install -y ansible - sed -i -e 's/#callback_whitelist.*/callback_whitelist = profile_tasks/' /etc/ansible/ansible.cfg - -- name: ansible pull systemd units - copy: - src: files/{{ item }} - dest: /etc/systemd/system/{{ item }} - with_items: - - ansible-pull.service - - ansible-pull.timer - -- name: create facts dir - file: - path: /etc/ansible/facts.d - state: directory - -- name: ansible facts - copy: - src: files/supabase_facts.ini - dest: /etc/ansible/facts.d/supabase.fact - -- name: reload systemd - systemd: - daemon_reload: yes diff --git a/ansible-nix/tasks/internal/setup-nftables.yml b/ansible-nix/tasks/internal/setup-nftables.yml deleted file mode 100644 index fc8d0235a..000000000 --- a/ansible-nix/tasks/internal/setup-nftables.yml +++ /dev/null @@ -1,34 +0,0 @@ -- name: nftables overrides - file: - state: directory - path: /etc/nftables - owner: adminapi - -- name: nftables empty config - file: - state: touch - path: /etc/nftables/supabase_managed.conf - owner: adminapi - -- name: include managed config - shell: | - cat >> "/etc/nftables.conf" << EOF - table inet supabase_managed { } - include "/etc/nftables/supabase_managed.conf"; - - EOF - -- name: ufw overrides dir - file: - state: directory - path: /etc/systemd/system/ufw.service.d - owner: root - -- name: Custom systemd overrides - copy: - src: files/ufw.service.conf - dest: /etc/systemd/system/ufw.service.d/overrides.conf - -- name: reload systemd - systemd: - daemon_reload: yes diff --git a/ansible-nix/tasks/internal/supautils.yml b/ansible-nix/tasks/internal/supautils.yml deleted file mode 100644 index 33811b5ac..000000000 --- a/ansible-nix/tasks/internal/supautils.yml +++ /dev/null @@ -1,77 +0,0 @@ -# supautils -- name: supautils - download & install dependencies - apt: - pkg: - - build-essential - - clang-11 - update_cache: yes - cache_valid_time: 3600 - -- name: supautils - download latest release - get_url: - url: "https://github.com/supabase/supautils/archive/refs/tags/v{{ supautils_release }}.tar.gz" - dest: /tmp/supautils-{{ supautils_release }}.tar.gz - checksum: "{{ supautils_release_checksum }}" - timeout: 60 - -- name: supautils - unpack archive - unarchive: - remote_src: yes - src: /tmp/supautils-{{ supautils_release }}.tar.gz - dest: /tmp - become: yes - -- name: supautils - build - make: - chdir: /tmp/supautils-{{ supautils_release }} - become: yes - -- name: supautils - install - make: - chdir: /tmp/supautils-{{ supautils_release }} - target: install - become: yes - -- name: supautils - add supautils to session_preload_libraries - become: yes - replace: - path: /etc/postgresql/postgresql.conf - regexp: "#session_preload_libraries = ''" - replace: session_preload_libraries = 'supautils' - -- name: supautils - write custom supautils.conf - template: - src: "files/postgresql_config/supautils.conf.j2" - dest: /etc/postgresql-custom/supautils.conf - mode: 0664 - owner: postgres - group: postgres - -- name: supautils - copy extension custom scripts - copy: - src: files/postgresql_extension_custom_scripts/ - dest: /etc/postgresql-custom/extension-custom-scripts - become: yes - -- name: supautils - chown extension custom scripts - file: - mode: 0775 - owner: postgres - group: postgres - path: /etc/postgresql-custom/extension-custom-scripts - recurse: yes - become: yes - -- name: supautils - include /etc/postgresql-custom/supautils.conf in postgresql.conf - become: yes - replace: - path: /etc/postgresql/postgresql.conf - regexp: "#include = '/etc/postgresql-custom/supautils.conf'" - replace: "include = '/etc/postgresql-custom/supautils.conf'" - -- name: supautils - remove build dependencies - apt: - pkg: - - build-essential - - clang-11 - state: absent diff --git a/ansible-nix/tasks/setup-envoy.yml b/ansible-nix/tasks/setup-envoy.yml deleted file mode 100644 index 9843b5546..000000000 --- a/ansible-nix/tasks/setup-envoy.yml +++ /dev/null @@ -1,60 +0,0 @@ -- name: Envoy - system user - ansible.builtin.user: - name: envoy - -- name: Envoy - download binary - ansible.builtin.get_url: - checksum: "{{ envoy_release_checksum }}" - dest: /opt/envoy - group: envoy - mode: u+x - owner: envoy - # yamllint disable-line rule:line-length - url: "https://github.com/envoyproxy/envoy/releases/download/v{{ envoy_release }}/envoy-{{ envoy_release }}-linux-aarch_64" - -- name: Envoy - download hot restarter script - ansible.builtin.get_url: - checksum: "{{ envoy_hot_restarter_release_checksum }}" - dest: /opt/envoy-hot-restarter.py - group: envoy - mode: u+x - owner: envoy - # yamllint disable-line rule:line-length - url: https://raw.githubusercontent.com/envoyproxy/envoy/v{{ envoy_release }}/restarter/hot-restarter.py - -- name: Envoy - bump up ulimit - community.general.pam_limits: - domain: envoy - limit_item: nofile - limit_type: soft - value: 4096 - -- name: Envoy - create script to start envoy - ansible.builtin.copy: - dest: /opt/start-envoy.sh - group: envoy - mode: u+x - owner: envoy - src: files/start-envoy.sh - -- name: Envoy - create configuration files - ansible.builtin.copy: - dest: /etc/envoy/ - directory_mode: u=rwx,g=rwx,o=rx - group: envoy - mode: u=rw,g=rw,o=r - owner: envoy - src: files/envoy_config/ - -- name: Envoy - create service file - ansible.builtin.copy: - dest: /etc/systemd/system/envoy.service - mode: u=rw,g=r,o=r - src: files/envoy.service - -- name: Envoy - disable service - ansible.builtin.systemd: - daemon_reload: true - enabled: false - name: envoy - state: stopped diff --git a/ansible-nix/tasks/setup-extensions.yml b/ansible-nix/tasks/setup-extensions.yml deleted file mode 100644 index 0fb92c151..000000000 --- a/ansible-nix/tasks/setup-extensions.yml +++ /dev/null @@ -1,94 +0,0 @@ -- name: Install plv8 - import_tasks: tasks/postgres-extensions/13-plv8.yml - -- name: Install pg_jsonschema - import_tasks: tasks/postgres-extensions/22-pg_jsonschema.yml - -- name: Install postgis - import_tasks: tasks/postgres-extensions/01-postgis.yml - -- name: Install pgrouting - import_tasks: tasks/postgres-extensions/02-pgrouting.yml - -- name: Install pgtap - import_tasks: tasks/postgres-extensions/03-pgtap.yml - -- name: Install pg_cron - import_tasks: tasks/postgres-extensions/04-pg_cron.yml - -- name: Install pgaudit - import_tasks: tasks/postgres-extensions/05-pgaudit.yml - -- name: Install pgjwt - import_tasks: tasks/postgres-extensions/06-pgjwt.yml - -- name: Install pgsql-http - import_tasks: tasks/postgres-extensions/07-pgsql-http.yml - -- name: Install plpgsql_check - import_tasks: tasks/postgres-extensions/08-plpgsql_check.yml - -- name: Install pg-safeupdate - import_tasks: tasks/postgres-extensions/09-pg-safeupdate.yml - -- name: Install timescaledb - import_tasks: tasks/postgres-extensions/10-timescaledb.yml - -- name: Install wal2json - import_tasks: tasks/postgres-extensions/11-wal2json.yml - -- name: Install pljava - import_tasks: tasks/postgres-extensions/12-pljava.yml - tags: - - legacy-incompatible - -- name: Install pg_plan_filter - import_tasks: tasks/postgres-extensions/14-pg_plan_filter.yml - -- name: Install pg_net - import_tasks: tasks/postgres-extensions/15-pg_net.yml - -- name: Install rum - import_tasks: tasks/postgres-extensions/16-rum.yml - -- name: Install pg_hashids - import_tasks: tasks/postgres-extensions/17-pg_hashids.yml - -- name: Install pgsodium - import_tasks: tasks/postgres-extensions/18-pgsodium.yml - -- name: Install pg_graphql - import_tasks: tasks/postgres-extensions/19-pg_graphql.yml - tags: - - legacy-incompatible - -- name: Install pg_stat_monitor - import_tasks: tasks/postgres-extensions/20-pg_stat_monitor.yml - -- name: Install auto_explain - import_tasks: tasks/postgres-extensions/21-auto_explain.yml - -- name: Install vault - import_tasks: tasks/postgres-extensions/23-vault.yml - -- name: Install PGroonga - import_tasks: tasks/postgres-extensions/24-pgroonga.yml - -- name: Install wrappers - import_tasks: tasks/postgres-extensions/25-wrappers.yml - -- name: Install hypopg - import_tasks: tasks/postgres-extensions/26-hypopg.yml - -- name: Install pg_repack - import_tasks: tasks/postgres-extensions/27-pg_repack.yml - -- name: Install pgvector - import_tasks: tasks/postgres-extensions/28-pgvector.yml - -- name: Install Trusted Language Extensions - import_tasks: tasks/postgres-extensions/29-pg_tle.yml - -- name: Verify async task status - import_tasks: tasks/postgres-extensions/99-finish_async_tasks.yml - when: async_mode diff --git a/ansible-nix/tasks/setup-fail2ban.yml b/ansible-nix/tasks/setup-fail2ban.yml deleted file mode 100644 index e1cec2d92..000000000 --- a/ansible-nix/tasks/setup-fail2ban.yml +++ /dev/null @@ -1,70 +0,0 @@ -# set default bantime to 1 hour -- name: extend bantime - become: yes - replace: - path: /etc/fail2ban/jail.conf - regexp: bantime = 10m - replace: bantime = 3600 - -- name: Configure journald - copy: - src: files/fail2ban_config/jail-ssh.conf - dest: /etc/fail2ban/jail.d/sshd.local - -- name: configure fail2ban to use nftables - copy: - src: files/fail2ban_config/jail.local - dest: /etc/fail2ban/jail.local - -# postgresql -- name: import jail.d/postgresql.conf - template: - src: files/fail2ban_config/jail-postgresql.conf.j2 - dest: /etc/fail2ban/jail.d/postgresql.conf - become: yes - -- name: import filter.d/postgresql.conf - template: - src: files/fail2ban_config/filter-postgresql.conf.j2 - dest: /etc/fail2ban/filter.d/postgresql.conf - become: yes - -- name: create overrides dir - file: - state: directory - owner: root - group: root - path: /etc/systemd/system/fail2ban.service.d - mode: '0700' - -- name: Custom systemd overrides - copy: - src: files/fail2ban_config/fail2ban.service.conf - dest: /etc/systemd/system/fail2ban.service.d/overrides.conf - -- name: add in supabase specific ignore filters - lineinfile: - path: /etc/fail2ban/filter.d/postgresql.conf - state: present - line: "{{ item.line }}" - loop: - - { line: ' ^.*,.*,.*,.*,":.*password authentication failed for user ""supabase_admin".*$' } - - { line: ' ^.*,.*,.*,.*,":.*password authentication failed for user ""supabase_auth_admin".*$' } - - { line: ' ^.*,.*,.*,.*,":.*password authentication failed for user ""supabase_storage_admin".*$' } - - { line: ' ^.*,.*,.*,.*,":.*password authentication failed for user ""authenticator".*$' } - - { line: ' ^.*,.*,.*,.*,":.*password authentication failed for user ""pgbouncer".*$' } - become: yes - tags: - - install-supabase-internal - -# Restart -- name: fail2ban - restart - systemd: - name: fail2ban - state: restarted - -- name: fail2ban - disable service - systemd: - name: fail2ban - enabled: no - daemon_reload: yes diff --git a/ansible-nix/tasks/setup-gotrue.yml b/ansible-nix/tasks/setup-gotrue.yml deleted file mode 100644 index 2a70caa4d..000000000 --- a/ansible-nix/tasks/setup-gotrue.yml +++ /dev/null @@ -1,54 +0,0 @@ -- name: UFW - Allow connections to GoTrue metrics exporter - ufw: - rule: allow - port: "9122" - -# use this user for the Gotrue build and for running the service -- name: Gotrue - system user - user: name=gotrue - -- name: Setting arch (x86) - set_fact: - arch: "x86" - when: platform == "amd64" - -- name: Setting arch (arm) - set_fact: - arch: "arm64" - when: platform == "arm64" - -- name: gotrue - download commit archive - get_url: - url: "https://github.com/supabase/gotrue/releases/download/v{{ gotrue_release }}/auth-v{{ gotrue_release }}-{{ arch }}.tar.gz" - dest: /tmp/gotrue.tar.gz - checksum: "{{ gotrue_release_checksum }}" - -- name: gotrue - create /opt/gotrue - file: - path: /opt/gotrue - state: directory - owner: gotrue - mode: 0775 - -- name: gotrue - unpack archive in /opt/gotrue - unarchive: - remote_src: yes - src: /tmp/gotrue.tar.gz - dest: /opt/gotrue - owner: gotrue - -# libpq is a C library that enables user programs to communicate with -# the PostgreSQL database server. -- name: gotrue - system dependencies - apt: - pkg: - - libpq-dev - -- name: gotrue - create service file - template: - src: files/gotrue.service.j2 - dest: /etc/systemd/system/gotrue.service - -- name: gotrue - reload systemd - systemd: - daemon_reload: yes diff --git a/ansible-nix/tasks/setup-kong.yml b/ansible-nix/tasks/setup-kong.yml deleted file mode 100644 index b34f96e78..000000000 --- a/ansible-nix/tasks/setup-kong.yml +++ /dev/null @@ -1,62 +0,0 @@ -- name: Kong - system user - user: name=kong - -# Kong installation steps from http://archive.vn/3HRQx -- name: Kong - system dependencies - apt: - pkg: - - openssl - - libpcre3 - - procps - - perl - -- name: Kong - download deb package - get_url: - url: "https://packages.konghq.com/public/gateway-28/deb/ubuntu/pool/{{ kong_release_target }}/main/k/ko/kong_2.8.1/{{ kong_deb }}" - dest: /tmp/kong.deb - checksum: "{{ kong_deb_checksum }}" - -- name: Kong - deb installation - apt: deb=file:///tmp/kong.deb - -- name: Kong - ensure it is NOT autoremoved - shell: | - set -e - apt-mark manual kong zlib1g* - -- name: Kong - configuration - template: - src: files/kong_config/kong.conf.j2 - dest: /etc/kong/kong.conf - -- name: Kong - hand over ownership of /usr/local/kong to user kong - file: - path: /usr/local/kong - recurse: yes - owner: kong - -# [warn] ulimit is currently set to "1024". For better performance set it to at least -# "4096" using "ulimit -n" -- name: Kong - bump up ulimit - pam_limits: - limit_item: nofile - limit_type: soft - domain: kong - value: "4096" - -- name: Kong - create env file - template: - src: files/kong_config/kong.env.j2 - dest: /etc/kong/kong.env - -- name: Kong - create service file - template: - src: files/kong_config/kong.service.j2 - dest: /etc/systemd/system/kong.service - -- name: Kong - disable service - systemd: - enabled: no - name: kong - state: stopped - daemon_reload: yes diff --git a/ansible-nix/tasks/setup-migrations.yml b/ansible-nix/tasks/setup-migrations.yml deleted file mode 100644 index 570f7763c..000000000 --- a/ansible-nix/tasks/setup-migrations.yml +++ /dev/null @@ -1,13 +0,0 @@ -- name: Run migrate.sh script - shell: ./migrate.sh - register: retval - when: ebssurrogate_mode - args: - chdir: /tmp/migrations/db - failed_when: retval.rc != 0 - -- name: Create /root/MIGRATION-AMI file - file: - path: "/root/MIGRATION-AMI" - state: touch - when: ebssurrogate_mode diff --git a/ansible-nix/tasks/setup-nginx.yml b/ansible-nix/tasks/setup-nginx.yml deleted file mode 100644 index 77fb7707a..000000000 --- a/ansible-nix/tasks/setup-nginx.yml +++ /dev/null @@ -1,82 +0,0 @@ -- name: nginx - system user - user: name=nginx - -# Kong installation steps from http://archive.vn/3HRQx -- name: nginx - system dependencies - apt: - pkg: - - openssl - - libpcre3-dev - - libssl-dev - - zlib1g-dev - -- name: nginx - download source - get_url: - url: "https://nginx.org/download/nginx-{{ nginx_release }}.tar.gz" - dest: /tmp/nginx-{{ nginx_release }}.tar.gz - checksum: "{{ nginx_release_checksum }}" - -- name: nginx - unpack archive - unarchive: - remote_src: yes - src: /tmp/nginx-{{ nginx_release }}.tar.gz - dest: /tmp - -- name: nginx - configure - shell: - chdir: /tmp/nginx-{{ nginx_release }} - cmd: | - set -e - - ./configure \ - --prefix=/usr/local/nginx \ - --conf-path=/etc/nginx/nginx.conf \ - --with-http_ssl_module \ - --with-http_realip_module \ - --with-threads - become: yes - -- name: nginx - build - community.general.make: - target: build - chdir: /tmp/nginx-{{ nginx_release }} - jobs: "{{ parallel_jobs | default(omit) }}" - become: yes - -- name: nginx - install - make: - chdir: /tmp/nginx-{{ nginx_release }} - target: install - become: yes - -- name: nginx - hand over ownership of /usr/local/nginx to user nginx - file: - path: /usr/local/nginx - recurse: yes - owner: nginx - -- name: nginx - hand over ownership of /etc/nginx to user nginx - file: - path: /etc/nginx - recurse: yes - owner: nginx - -# [warn] ulimit is currently set to "1024". For better performance set it to at least -# "4096" using "ulimit -n" -- name: nginx - bump up ulimit - pam_limits: - limit_item: nofile - limit_type: soft - domain: nginx - value: "4096" - -- name: nginx - create service file - template: - src: files/nginx.service.j2 - dest: /etc/systemd/system/nginx.service - -# Keep it dormant for the timebeing - -# - name: nginx - reload systemd -# systemd: -# daemon_reload: yes diff --git a/ansible-nix/tasks/setup-pgbouncer.yml b/ansible-nix/tasks/setup-pgbouncer.yml deleted file mode 100644 index 4381ba24d..000000000 --- a/ansible-nix/tasks/setup-pgbouncer.yml +++ /dev/null @@ -1,135 +0,0 @@ -# PgBouncer -- name: PgBouncer - download & install dependencies - apt: - pkg: - - build-essential - - libssl-dev - - pkg-config - - libevent-dev - - libsystemd-dev - update_cache: yes - cache_valid_time: 3600 - -- name: PgBouncer - download latest release - get_url: - url: "https://www.pgbouncer.org/downloads/files/{{ pgbouncer_release }}/pgbouncer-{{ pgbouncer_release }}.tar.gz" - dest: /tmp/pgbouncer-{{ pgbouncer_release }}.tar.gz - checksum: "{{ pgbouncer_release_checksum }}" - timeout: 60 - -- name: PgBouncer - unpack archive - unarchive: - remote_src: yes - src: /tmp/pgbouncer-{{ pgbouncer_release }}.tar.gz - dest: /tmp - become: yes - -- name: PgBouncer - configure - shell: - cmd: "./configure --prefix=/usr/local --with-systemd" - chdir: /tmp/pgbouncer-{{ pgbouncer_release }} - become: yes - -- name: PgBouncer - build - make: - chdir: /tmp/pgbouncer-{{ pgbouncer_release }} - become: yes - -- name: PgBouncer - install - make: - chdir: /tmp/pgbouncer-{{ pgbouncer_release }} - target: install - become: yes - -- name: Create pgbouncer user - user: - name: pgbouncer - shell: /bin/false - comment: PgBouncer user - groups: postgres,ssl-cert - -- name: PgBouncer - create a directory if it does not exist - file: - path: /etc/pgbouncer - state: directory - owner: pgbouncer - group: pgbouncer - mode: '0700' - -- name: PgBouncer - create a directory if it does not exist - file: - state: directory - owner: pgbouncer - group: pgbouncer - path: '{{ item }}' - mode: '0775' - with_items: - - '/etc/pgbouncer-custom' - -- name: create placeholder config files - file: - path: '/etc/pgbouncer-custom/{{ item }}' - state: touch - owner: pgbouncer - group: pgbouncer - mode: 0664 - with_items: - - 'generated-optimizations.ini' - - 'custom-overrides.ini' - - 'ssl-config.ini' - -- name: PgBouncer - adjust pgbouncer.ini - copy: - src: files/pgbouncer_config/pgbouncer.ini.j2 - dest: /etc/pgbouncer/pgbouncer.ini - owner: pgbouncer - mode: '0700' - -- name: PgBouncer - create a directory if it does not exist - file: - path: /etc/pgbouncer/userlist.txt - state: touch - owner: pgbouncer - mode: '0700' - -- name: import /etc/tmpfiles.d/pgbouncer.conf - template: - src: files/pgbouncer_config/tmpfiles.d-pgbouncer.conf.j2 - dest: /etc/tmpfiles.d/pgbouncer.conf - become: yes - -- name: PgBouncer - By default allow ssl connections. - become: yes - copy: - dest: /etc/pgbouncer-custom/ssl-config.ini - content: | - client_tls_sslmode = allow - -- name: Grant pg_hba and pgbouncer grp perm for adminapi updates - shell: | - chmod g+w /etc/postgresql/pg_hba.conf - chmod g+w /etc/pgbouncer-custom/ssl-config.ini - -# Add fail2ban filter -- name: import jail.d/pgbouncer.conf - template: - src: files/fail2ban_config/jail-pgbouncer.conf.j2 - dest: /etc/fail2ban/jail.d/pgbouncer.conf - become: yes - -- name: import filter.d/pgbouncer.conf - template: - src: files/fail2ban_config/filter-pgbouncer.conf.j2 - dest: /etc/fail2ban/filter.d/pgbouncer.conf - become: yes - -# Add systemd file for PgBouncer -- name: PgBouncer - import postgresql.service - template: - src: files/pgbouncer_config/pgbouncer.service.j2 - dest: /etc/systemd/system/pgbouncer.service - become: yes - -- name: PgBouncer - reload systemd - systemd: - daemon_reload: yes diff --git a/ansible-nix/tasks/setup-postgres.yml b/ansible-nix/tasks/setup-postgres.yml deleted file mode 100644 index 6677f470d..000000000 --- a/ansible-nix/tasks/setup-postgres.yml +++ /dev/null @@ -1,139 +0,0 @@ -- name: create ssl-cert group - group: - name: ssl-cert - state: present - -# the old method of installing from debian creates this group, but we must create it explicitly -# for the nix built version - -- name: create postgres group - group: - name: postgres - state: present - -- name: create postgres user - shell: adduser --system --home /var/lib/postgresql --no-create-home --shell /bin/bash --group --gecos "PostgreSQL administrator" postgres - args: - executable: /bin/bash - become: yes - -- name: add postgres user to postgres group - shell: usermod -a -G ssl-cert postgres - args: - executable: /bin/bash - become: yes - -- name: Create relevant directories - file: - path: '{{ item }}' - recurse: yes - state: directory - owner: postgres - group: postgres - with_items: - - '/var/log/postgresql' - - '/var/lib/postgresql' - -- name: Allow adminapi to write custom config - file: - path: '{{ item }}' - recurse: yes - state: directory - owner: postgres - group: postgres - mode: 0775 - with_items: - - '/etc/postgresql' - - '/etc/postgresql-custom' - -- name: create placeholder config files - file: - path: '/etc/postgresql-custom/{{ item }}' - state: touch - owner: postgres - group: postgres - mode: 0664 - with_items: - - 'generated-optimizations.conf' - - 'custom-overrides.conf' - -- name: locale-gen - command: sudo locale-gen en_US.UTF-8 - -- name: Make sure .bashrc exists - file: - path: /var/lib/postgresql/.bashrc - state: touch - owner: postgres - group: postgres - - -- name: Add LOCALE_ARCHIVE to .bashrc - lineinfile: - dest: "/var/lib/postgresql/.bashrc" - line: 'export LOCALE_ARCHIVE=/usr/lib/locale/locale-archive' - create: yes - become: yes - - -- name: Add LANG items to .bashrc - lineinfile: - dest: "/var/lib/postgresql/.bashrc" - line: "{{ item }}" - - loop: - - 'export LANG="en_US.UTF-8"' - - 'export LANGUAGE="en_US.UTF-8"' - - 'export LC_ALL="en_US.UTF-8"' - - 'export LANG="en_US.UTF-8"' - - 'export LC_CTYPE="en_US.UTF-8"' - become: yes - - -# Move Postgres configuration files into /etc/postgresql -# Add postgresql.conf -- name: import postgresql.conf - template: - src: files/postgresql_config/postgresql.conf.j2 - dest: /etc/postgresql/postgresql.conf - group: postgres - -# Add pg_hba.conf -- name: import pg_hba.conf - template: - src: files/postgresql_config/pg_hba.conf.j2 - dest: /etc/postgresql/pg_hba.conf - group: postgres - -# Add pg_ident.conf -- name: import pg_ident.conf - template: - src: files/postgresql_config/pg_ident.conf.j2 - dest: /etc/postgresql/pg_ident.conf - group: postgres - -# Add custom config for read replicas set up -- name: Move custom read-replica.conf file to /etc/postgresql-custom/read-replica.conf - template: - src: "files/postgresql_config/custom_read_replica.conf.j2" - dest: /etc/postgresql-custom/read-replica.conf - mode: 0664 - owner: postgres - group: postgres - -# # Install extensions before init -# (samrose) moved to tasks/stage2/setup-extensions.yml -# now called from stage2/stage2-setup-postgres.yml - - -# init DB -- name: Create directory on data volume - file: - path: '{{ item }}' - recurse: yes - state: directory - owner: postgres - group: postgres - mode: 0750 - with_items: - - "/data/pgdata" diff --git a/ansible-nix/tasks/setup-postgrest.yml b/ansible-nix/tasks/setup-postgrest.yml deleted file mode 100644 index 57b76e1ee..000000000 --- a/ansible-nix/tasks/setup-postgrest.yml +++ /dev/null @@ -1,84 +0,0 @@ -- name: PostgREST - system user - user: name=postgrest - -# libpq is a C library that enables user programs to communicate with -# the PostgreSQL database server. -- name: PostgREST - system dependencies - apt: - pkg: - - libpq5 - - libnuma-dev - -- name: postgis - ensure dependencies do not get autoremoved - shell: | - set -e - apt-mark manual libnuma* - apt-mark auto libnuma*-dev - -- name: PostgREST - download ubuntu binary archive (arm) - get_url: - url: "https://github.com/PostgREST/postgrest/releases/download/v{{ postgrest_release }}/postgrest-v{{ postgrest_release }}-ubuntu-aarch64.tar.xz" - dest: /tmp/postgrest.tar.xz - checksum: "{{ postgrest_arm_release_checksum }}" - timeout: 60 - when: platform == "arm64" - -- name: PostgREST - download ubuntu binary archive (x86) - get_url: - url: "https://github.com/PostgREST/postgrest/releases/download/v{{ postgrest_release }}/postgrest-v{{ postgrest_release }}-linux-static-x64.tar.xz" - dest: /tmp/postgrest.tar.xz - checksum: "{{ postgrest_x86_release_checksum }}" - timeout: 60 - when: platform == "amd64" - -- name: PostgREST - unpack archive in /opt - unarchive: - remote_src: yes - src: /tmp/postgrest.tar.xz - dest: /opt - owner: postgrest - mode: '0755' - -- name: create directories - file: - state: directory - owner: postgrest - group: postgrest - mode: '0775' - path: /etc/postgrest - -- name: empty files - file: - state: touch - owner: postgrest - group: postgrest - path: /etc/postgrest/{{ item }} - with_items: - - base.conf - - generated.conf - -- name: create conf merging script - copy: - content: | - #! /usr/bin/env bash - set -euo pipefail - set -x - - cd "$(dirname "$0")" - cat $@ > merged.conf - dest: /etc/postgrest/merge.sh - mode: 0750 - owner: postgrest - group: postgrest - -- name: PostgREST - create service files - template: - src: files/{{ item }}.j2 - dest: /etc/systemd/system/{{ item }} - with_items: - - postgrest.service - - postgrest-optimizations.service - -- name: PostgREST - reload systemd - systemd: - daemon_reload: yes diff --git a/ansible-nix/tasks/setup-supabase-internal.yml b/ansible-nix/tasks/setup-supabase-internal.yml deleted file mode 100644 index 849c76954..000000000 --- a/ansible-nix/tasks/setup-supabase-internal.yml +++ /dev/null @@ -1,108 +0,0 @@ -- name: AWS CLI dep - apt: - pkg: - - unzip - - jq - install_recommends: no - -- name: AWS CLI (arm) - get_url: - url: "https://awscli.amazonaws.com/awscli-exe-linux-aarch64-{{ aws_cli_release }}.zip" - dest: "/tmp/awscliv2.zip" - timeout: 60 - when: platform == "arm64" - -- name: AWS CLI (x86) - get_url: - url: "https://awscli.amazonaws.com/awscli-exe-linux-x86_64-{{ aws_cli_release }}.zip" - dest: "/tmp/awscliv2.zip" - timeout: 60 - when: platform == "amd64" - -- name: AWS CLI - expand - unarchive: - remote_src: yes - src: "/tmp/awscliv2.zip" - dest: "/tmp" - -- name: AWS CLI - install - shell: "/tmp/aws/install --update" - become: true - -- name: AWS CLI - configure ipv6 support for s3 - shell: | - aws configure set default.s3.use_dualstack_endpoint true - -- name: install Vector for logging - become: yes - apt: - deb: "{{ vector_x86_deb }}" - when: platform == "amd64" - -- name: install Vector for logging - become: yes - apt: - deb: "{{ vector_arm_deb }}" - when: platform == "arm64" - -- name: add Vector to postgres group - become: yes - shell: - cmd: | - usermod -a -G postgres vector - -- name: create service files for Vector - template: - src: files/vector.service.j2 - dest: /etc/systemd/system/vector.service - -- name: configure tmpfiles for postgres - overwrites upstream package - template: - src: files/postgresql_config/tmpfiles.postgresql.conf - dest: /etc/tmpfiles.d/postgresql-common.conf - -- name: fix permissions for vector config to be managed - shell: - cmd: | - chown -R vector:vector /etc/vector - chmod 0775 /etc/vector - -- name: vector - reload systemd - systemd: - daemon_reload: yes - -- name: Create checkpoints dir - become: yes - file: - path: /var/lib/vector - state: directory - owner: vector - -- name: Include file for generated optimizations in postgresql.conf - become: yes - replace: - path: /etc/postgresql/postgresql.conf - regexp: "#include = '/etc/postgresql-custom/generated-optimizations.conf'" - replace: "include = '/etc/postgresql-custom/generated-optimizations.conf'" - -- name: Include file for custom overrides in postgresql.conf - become: yes - replace: - path: /etc/postgresql/postgresql.conf - regexp: "#include = '/etc/postgresql-custom/custom-overrides.conf'" - replace: "include = '/etc/postgresql-custom/custom-overrides.conf'" - -- name: Install Postgres exporter - import_tasks: internal/postgres-exporter.yml - -- name: Install admin-mgr - import_tasks: internal/admin-mgr.yml - -- name: Install adminapi - import_tasks: internal/admin-api.yml - -- name: Init nftabless - import_tasks: internal/setup-nftables.yml - -- name: Install pg_egress_collect - import_tasks: internal/pg_egress_collect.yml diff --git a/ansible-nix/tasks/setup-system.yml b/ansible-nix/tasks/setup-system.yml deleted file mode 100644 index 860d75cc2..000000000 --- a/ansible-nix/tasks/setup-system.yml +++ /dev/null @@ -1,154 +0,0 @@ -- name: System - apt update and apt upgrade - apt: update_cache=yes upgrade=yes - when: not ebssurrogate_mode - # SEE http://archive.vn/DKJjs#parameter-upgrade - -- name: Install required security updates - apt: - pkg: - - tzdata - - linux-libc-dev - -# SEE https://github.com/georchestra/ansible/issues/55#issuecomment-588313638 -# Without this, a similar error is faced -- name: Install Ansible dependencies - apt: - pkg: - - acl - -- name: Install security tools - apt: - pkg: - - nftables - - fail2ban - update_cache: yes - cache_valid_time: 3600 - -- name: Use nftables backend - shell: | - update-alternatives --set iptables /usr/sbin/iptables-nft - update-alternatives --set ip6tables /usr/sbin/ip6tables-nft - update-alternatives --set arptables /usr/sbin/arptables-nft - update-alternatives --set ebtables /usr/sbin/ebtables-nft - systemctl restart ufw - -- name: Create Sysstat log directory - file: - path: /var/log/sysstat - state: directory - -- name: Install other useful tools - apt: - pkg: - - bwm-ng - - htop - - net-tools - - ngrep - - sysstat - - vim-tiny - update_cache: yes - -- name: Configure sysstat - copy: - src: files/sysstat.sysstat - dest: /etc/sysstat/sysstat - -- name: Configure default sysstat - copy: - src: files/default.sysstat - dest: /etc/default/sysstat - - -- name: Adjust APT update intervals - copy: - src: files/apt_periodic - dest: /etc/apt/apt.conf.d/10periodic - -# Find platform architecture and set as a variable -- name: finding platform architecture - shell: if [ $(uname -m) = "aarch64" ]; then echo "arm64"; else echo "amd64"; fi - register: platform_output - tags: - - update - - update-only -- set_fact: - platform: "{{ platform_output.stdout }}" - tags: - - update - - update-only - -- name: create overrides dir - file: - state: directory - owner: root - group: root - path: /etc/systemd/system/systemd-resolved.service.d - mode: '0700' - -- name: Custom systemd overrides for resolved - copy: - src: files/systemd-resolved.conf - dest: /etc/systemd/system/systemd-resolved.service.d/override.conf - -- name: System - Create services.slice - template: - src: files/services.slice.j2 - dest: /etc/systemd/system/services.slice - when: not ebssurrogate_mode - -- name: System - systemd reload - systemd: daemon_reload=yes - -- name: Configure journald - copy: - src: files/journald.conf - dest: /etc/systemd/journald.conf - -- name: reload systemd-journald - systemd: - name: systemd-journald - state: restarted - -- name: Configure logind - copy: - src: files/logind.conf - dest: /etc/systemd/logind.conf - -- name: reload systemd-logind - systemd: - name: systemd-logind - state: restarted - -- name: enable timestamps for shell history - copy: - content: | - export HISTTIMEFORMAT='%d/%m/%y %T ' - dest: /etc/profile.d/09-history-timestamps.sh - mode: 0644 - owner: root - group: root - -- name: set hosts file - copy: - content: | - 127.0.0.1 localhost - ::1 localhost - dest: /etc/hosts - mode: 0644 - owner: root - group: root - -#Set Sysctl params for restarting the OS on oom after 10 -- name: Set vm.panic_on_oom=1 - ansible.builtin.sysctl: - name: vm.panic_on_oom - value: '1' - state: present - reload: yes - -- name: Set kernel.panic=10 - ansible.builtin.sysctl: - name: kernel.panic - value: '10' - state: present - reload: yes diff --git a/ansible-nix/tasks/setup-wal-g.yml b/ansible-nix/tasks/setup-wal-g.yml deleted file mode 100644 index a36b77a6d..000000000 --- a/ansible-nix/tasks/setup-wal-g.yml +++ /dev/null @@ -1,130 +0,0 @@ -# Downloading dependencies -- name: wal-g dependencies - become: yes - apt: - pkg: - - libbrotli-dev - - liblzo2-dev - - libsodium-dev - - cmake - -# install go dependency for WAL-G -- name: wal-g go dependency - get_url: - url: "https://golang.org/dl/go{{ golang_version }}.linux-{{ platform }}.tar.gz" - dest: /tmp - checksum: "{{ golang_version_checksum[platform] }}" - timeout: 60 - -- name: unpack go archive - unarchive: - remote_src: yes - src: "/tmp/go{{ golang_version }}.linux-{{ platform }}.tar.gz" - dest: /usr/local - -# Download WAL-G -- name: wal-g - download latest version - git: - repo: https://github.com/wal-g/wal-g.git - dest: /tmp/wal-g - version: "v{{ wal_g_release }}" - become: yes - -- name: wal-g - pg_clean - make: - chdir: /tmp/wal-g - target: pg_clean - params: - GOBIN: "/usr/local/bin" - PATH: "{{ ansible_env.PATH }}:/usr/local/go/bin" - USE_LIBSODIUM: true - become: yes - ignore_errors: yes - -- name: wal-g - deps - make: - chdir: /tmp/wal-g - target: deps - params: - GOBIN: "/usr/local/bin" - PATH: "{{ ansible_env.PATH }}:/usr/local/go/bin" - USE_LIBSODIUM: true - become: yes - ignore_errors: yes - -- name: wal-g - build and install - community.general.make: - chdir: /tmp/wal-g - target: pg_install - jobs: "{{ parallel_jobs | default(omit) }}" - params: - GOBIN: "/usr/local/bin" - PATH: "{{ ansible_env.PATH }}:/usr/local/go/bin" - USE_LIBSODIUM: true - become: yes - -- name: Create wal-g group - group: - name: wal-g - state: present - -- name: Create wal-g user - user: - name: wal-g - shell: /bin/false - comment: WAL-G user - group: wal-g - groups: wal-g, postgres - -- name: Create a config directory owned by wal-g - file: - path: /etc/wal-g - state: directory - owner: wal-g - group: wal-g - mode: '0770' - -- name: Create /etc/wal-g/config.json - file: - path: /etc/wal-g/config.json - state: touch - owner: wal-g - group: wal-g - mode: '0664' - -- name: Move custom wal-g.conf file to /etc/postgresql-custom/wal-g.conf - template: - src: "files/postgresql_config/custom_walg.conf.j2" - dest: /etc/postgresql-custom/wal-g.conf - mode: 0664 - owner: postgres - group: postgres - -- name: Add script to be run for restore_command - template: - src: "files/walg_helper_scripts/wal_fetch.sh" - dest: /var/lib/postgresql/wal_fetch.sh - mode: 0500 - owner: postgres - group: postgres - -- name: Add helper script for wal_fetch.sh - template: - src: "files/walg_helper_scripts/wal_change_ownership.sh" - dest: /root/wal_change_ownership.sh - mode: 0700 - owner: root - -- name: Include /etc/postgresql-custom/wal-g.conf in postgresql.conf - become: yes - replace: - path: /etc/postgresql/postgresql.conf - regexp: "#include = '/etc/postgresql-custom/wal-g.conf'" - replace: "include = '/etc/postgresql-custom/wal-g.conf'" - -# Clean up Go -- name: Uninstall Go - become: yes - file: - path: /usr/local/go - state: absent diff --git a/ansible-nix/tasks/stage2/optimizations.yml b/ansible-nix/tasks/stage2/optimizations.yml deleted file mode 100644 index 77ecb3697..000000000 --- a/ansible-nix/tasks/stage2/optimizations.yml +++ /dev/null @@ -1,27 +0,0 @@ -- name: ensure services are stopped and disabled for first boot - systemd: - enabled: no - name: '{{ item }}' - state: stopped - with_items: - - postgresql - - pgbouncer - - fail2ban - - motd-news - - vector - -- name: Remove snapd - apt: - state: absent - pkg: - - snapd - -- name: disable man-db - become: yes - file: - state: absent - path: "/etc/cron.daily/{{ item }}" - with_items: - - man-db - - popularity-contest - - ubuntu-advantage-tools diff --git a/ansible-nix/tasks/stage2/playbook.yml b/ansible-nix/tasks/stage2/playbook.yml deleted file mode 100644 index 022e8e9b4..000000000 --- a/ansible-nix/tasks/stage2/playbook.yml +++ /dev/null @@ -1,79 +0,0 @@ -- hosts: localhost - become: yes - - vars: - sql_files: - - "/tmp/ansible-playbook/files/pgbouncer_config/pgbouncer_auth_schema.sql" - - "/tmp/ansible-playbook/files/stat_extension.sql" - - - tasks: - - set_fact: - supabase_internal: true - tags: - - install-supabase-internal - - - set_fact: - parallel_jobs: 16 - - - name: stat unit test file copy - copy: - src: /tmp/unit-tests/unit-test-01.sql - dest: /var/lib/postgresql/unit-test-01.sql - # state: present - owner: postgres - group: postgres - mode: '0644' - - - name: locale-gen - command: sudo locale-gen en_US.UTF-8 - - # - name: Ensure en_US.UTF-8 locale is enabled - # shell: | - # echo "LC_ALL=en_US.UTF-8" >> /etc/environment - # echo "en_US.UTF-8 UTF-8" >> /etc/locale.gen - # echo "LANG=en_US.UTF-8" > /etc/locale.conf - # locale-gen en_US.UTF-8 - # become: yes - - - name: check locales - command: locale -a - register: locales - - - name: Install Postgres from nix binary cache - import_tasks: stage2-setup-postgres.yml - - - name: First boot optimizations - import_tasks: optimizations.yml - - - name: Run unit tests - import_tasks: test-image.yml - tags: - - unit-tests - - - name: Check if postgres user is part of users group - shell: "id -nG postgres | grep -qw users" - register: check_user_group - ignore_errors: yes - become: yes - args: - executable: /bin/bash - - - name: Print result to Ansible log output - debug: - msg: "The postgres user is {{ 'not ' if check_user_group.rc != 0 else '' }}part of the users group" - - - name: Install osquery from nixpkgs binary cache - become: yes - shell: | - sudo -u ubuntu bash -c ". /nix/var/nix/profiles/default/etc/profile.d/nix-daemon.sh && nix profile install nixpkgs#osquery" - - - name: Run osquery permission checks - become: yes - shell: | - sudo -u ubuntu bash -c ". /nix/var/nix/profiles/default/etc/profile.d/nix-daemon.sh && /usr/bin/python3 /tmp/ansible-playbook/files/permission_check.py" - - - name: Remove osquery - become: yes - shell: | - sudo -u ubuntu bash -c ". /nix/var/nix/profiles/default/etc/profile.d/nix-daemon.sh && nix profile remove osquery" diff --git a/ansible-nix/tasks/stage2/setup-extensions.yml b/ansible-nix/tasks/stage2/setup-extensions.yml deleted file mode 100644 index 6cc1038f7..000000000 --- a/ansible-nix/tasks/stage2/setup-extensions.yml +++ /dev/null @@ -1,70 +0,0 @@ -# - name: pljava - libjvm.so location in postgresql.conf -# become: yes -# lineinfile: -# path: /etc/postgresql/postgresql.conf -# state: present -# line: pljava.libjvm_location = '/var/lib/postgresql/.nix-profile/lib/openjdk/lib/server/libjvm.so' -# It was decided to leave pljava disabled at https://github.com/supabase/postgres/pull/690 therefore removing this task - -- name: pg_cron - set cron.database_name - become: yes - lineinfile: - path: /etc/postgresql/postgresql.conf - state: present - line: cron.database_name = 'postgres' - -- set_fact: - pg_bindir: "/usr/lib/postgresql/bin" - -- name: pgsodium - set pgsodium.getkey_script - become: yes - lineinfile: - path: /etc/postgresql/postgresql.conf - state: present - # script is expected to be placed by finalization tasks for different target platforms - line: pgsodium.getkey_script= '{{ pg_bindir }}/pgsodium_getkey.sh' - -- name: auto_explain - set auto_explain.log_min_duration - become: yes - lineinfile: - path: /etc/postgresql/postgresql.conf - state: present - line: auto_explain.log_min_duration = 10s - -# supautils -- name: supautils - add supautils to session_preload_libraries - become: yes - replace: - path: /etc/postgresql/postgresql.conf - regexp: "#session_preload_libraries = ''" - replace: session_preload_libraries = 'supautils' - -- name: supautils - write custom supautils.conf - template: - src: "/tmp/ansible-playbook/files/postgresql_config/supautils.conf.j2" - dest: /etc/postgresql-custom/supautils.conf - mode: 0664 - owner: postgres - group: postgres - -- name: supautils - copy extension custom scripts - copy: - src: /tmp/ansible-playbook/files/postgresql_extension_custom_scripts/ - dest: /etc/postgresql-custom/extension-custom-scripts - become: yes - -- name: supautils - chown extension custom scripts - file: - mode: 0775 - owner: postgres - group: postgres - path: /etc/postgresql-custom/extension-custom-scripts - recurse: yes - become: yes - -- name: supautils - include /etc/postgresql-custom/supautils.conf in postgresql.conf - become: yes - replace: - path: /etc/postgresql/postgresql.conf - regexp: "#include = '/etc/postgresql-custom/supautils.conf'" - replace: "include = '/etc/postgresql-custom/supautils.conf'" diff --git a/ansible-nix/tasks/stage2/setup-migrations.yml b/ansible-nix/tasks/stage2/setup-migrations.yml deleted file mode 100644 index d69fba024..000000000 --- a/ansible-nix/tasks/stage2/setup-migrations.yml +++ /dev/null @@ -1,13 +0,0 @@ -- name: Run migrate.sh script - shell: . /nix/var/nix/profiles/default/etc/profile.d/nix-daemon.sh && ./migrate.sh - register: retval - args: - chdir: /tmp/migrations/db - become: yes - become_user: postgres - failed_when: retval.rc != 0 - -- name: Create /root/MIGRATION-AMI file - file: - path: "/root/MIGRATION-AMI" - state: touch diff --git a/ansible-nix/tasks/stage2/test-image.yml b/ansible-nix/tasks/stage2/test-image.yml deleted file mode 100644 index e6a7bc249..000000000 --- a/ansible-nix/tasks/stage2/test-image.yml +++ /dev/null @@ -1,104 +0,0 @@ -- name: Temporarily disable PG Sodium references in config - become: yes - become_user: postgres - shell: - cmd: sed -i.bak -e "s/pg_net,\ pgsodium,\ timescaledb/pg_net,\ timescaledb/g" -e "s/pgsodium.getkey_script=/#pgsodium.getkey_script=/g" /etc/postgresql/postgresql.conf - -- name: Start Postgres Database to load all extensions. - become: yes - become_user: postgres - shell: source /var/lib/postgresql/.bashrc && /usr/lib/postgresql/bin/pg_ctl -D /var/lib/postgresql/data start "-o -c config_file=/etc/postgresql/postgresql.conf" - args: - executable: /bin/bash - environment: - LANG: en_US.UTF-8 - LANGUAGE: en_US.UTF-8 - LC_ALL: en_US.UTF-8 - LC_CTYPE: en_US.UTF-8 - LOCALE_ARCHIVE: /usr/lib/locale/locale-archive - - -- name: check contents of unit test file - become: yes - become_user: postgres - shell: cat /var/lib/postgresql/unit-test-01.sql && ls -l /var/lib/postgresql/unit-test-01.sql - -- name: verify postgres server is running - become: yes - become_user: postgres - shell: psql -U postgres -h localhost -c "SELECT version();" - register: pg_isready - failed_when: pg_isready.rc != 0 - args: - executable: /bin/bash - environment: - LANG: en_US.UTF-8 - LANGUAGE: en_US.UTF-8 - LC_ALL: en_US.UTF-8 - LC_CTYPE: en_US.UTF-8 - LOCALE_ARCHIVE: /usr/lib/locale/locale-archive - PATH: /var/lib/postgresql/.nix-profile/bin:$PATH - -- name: Run Unit tests (with filename unit-test-*) on Postgres Database - become: yes - become_user: postgres - shell: source /var/lib/postgresql/.bashrc && /var/lib/postgresql/.nix-profile/bin/pg_prove -U postgres -h localhost -d postgres -f /var/lib/postgresql/unit-test-01.sql - register: retval - failed_when: retval.rc != 0 - args: - executable: /bin/bash - environment: - LANG: en_US.UTF-8 - LANGUAGE: en_US.UTF-8 - LC_ALL: en_US.UTF-8 - LC_CTYPE: en_US.UTF-8 - LOCALE_ARCHIVE: /usr/lib/locale/locale-archive - PATH: /var/lib/postgresql/.nix-profile/bin:$PATH - -- name: Run migrations tests - shell: /var/lib/postgresql/.nix-profile/bin/pg_prove -U supabase_admin -h localhost -d postgres -v tests/test.sql - register: retval - failed_when: retval.rc != 0 - args: - executable: /bin/bash - chdir: /tmp/migrations - environment: - LANG: en_US.UTF-8 - LANGUAGE: en_US.UTF-8 - LC_ALL: en_US.UTF-8 - LC_CTYPE: en_US.UTF-8 - LOCALE_ARCHIVE: /usr/lib/locale/locale-archive - PATH: /var/lib/postgresql/.nix-profile/bin:$PATH - -- name: Re-enable PG Sodium references in config - become: yes - become_user: postgres - shell: - cmd: mv /etc/postgresql/postgresql.conf.bak /etc/postgresql/postgresql.conf - -- name: Reset db stats - become: yes - become_user: postgres - shell: | - source /var/lib/postgresql/.bashrc && \ - /usr/lib/postgresql/bin/psql --no-password --no-psqlrc -d postgres -h localhost -U supabase_admin -c 'SELECT pg_stat_statements_reset(); SELECT pg_stat_reset();' - args: - executable: /bin/bash - environment: - LANG: en_US.UTF-8 - LANGUAGE: en_US.UTF-8 - LC_ALL: en_US.UTF-8 - LC_CTYPE: en_US.UTF-8 - LOCALE_ARCHIVE: /usr/lib/locale/locale-archive - -# - name: remove pg_prove -- name: Remove pg_prove - become: yes - shell: | - sudo -u postgres bash -c ". /nix/var/nix/profiles/default/etc/profile.d/nix-daemon.sh && nix profile remove pg_prove" - -- name: Stop Postgres Database - become: yes - become_user: postgres - shell: - cmd: /usr/lib/postgresql/bin/pg_ctl -D /var/lib/postgresql/data stop diff --git a/ansible-nix/files/permission_check.py b/ansible/files/permission_check.py similarity index 100% rename from ansible-nix/files/permission_check.py rename to ansible/files/permission_check.py diff --git a/ansible/files/postgresql_config/postgresql.service.j2 b/ansible/files/postgresql_config/postgresql.service.j2 index 88cf62c81..8e5318cba 100644 --- a/ansible/files/postgresql_config/postgresql.service.j2 +++ b/ansible/files/postgresql_config/postgresql.service.j2 @@ -19,6 +19,7 @@ TimeoutStartSec=86400 Restart=always RestartSec=5 OOMScoreAdjust=-1000 +EnvironmentFile=-/etc/environment.d/postgresql.env [Install] WantedBy=multi-user.target diff --git a/ansible/playbook.yml b/ansible/playbook.yml index 16a689f52..01e36e9dc 100644 --- a/ansible/playbook.yml +++ b/ansible/playbook.yml @@ -3,7 +3,6 @@ pre_tasks: - import_tasks: tasks/setup-system.yml - vars_files: - ./vars.yml @@ -14,7 +13,7 @@ dest: "00-schema.sql", } - { source: "stat_extension.sql", dest: "01-extension.sql" } - + environment: PATH: /usr/lib/postgresql/bin:{{ ansible_env.PATH }} @@ -35,70 +34,75 @@ tags: - install-pgbouncer - install-supabase-internal + when: debpkg_mode or nixpkg_mode - name: Install WAL-G import_tasks: tasks/setup-wal-g.yml + when: debpkg_mode or nixpkg_mode - name: Install Gotrue import_tasks: tasks/setup-gotrue.yml tags: - install-gotrue - install-supabase-internal - + when: debpkg_mode or nixpkg_mode + - name: Install PostgREST import_tasks: tasks/setup-postgrest.yml tags: - install-postgrest - install-supabase-internal + when: debpkg_mode or nixpkg_mode - name: Install Envoy import_tasks: tasks/setup-envoy.yml tags: - install-supabase-internal + when: debpkg_mode or nixpkg_mode - name: Install Kong import_tasks: tasks/setup-kong.yml tags: - install-supabase-internal + when: debpkg_mode or nixpkg_mode - name: Install nginx import_tasks: tasks/setup-nginx.yml tags: - install-supabase-internal + when: debpkg_mode or nixpkg_mode - name: Install Supabase specific content import_tasks: tasks/setup-supabase-internal.yml tags: - install-supabase-internal + when: debpkg_mode or nixpkg_mode - name: Fix IPv6 NDisc issues import_tasks: tasks/fix_ipv6_ndisc.yml tags: - install-supabase-internal - - - name: Start Postgres Database - systemd: - name: postgresql - state: started - when: not ebssurrogate_mode + when: debpkg_mode or nixpkg_mode - name: Start Postgres Database without Systemd become: yes become_user: postgres shell: cmd: /usr/lib/postgresql/bin/pg_ctl -D /var/lib/postgresql/data start - when: ebssurrogate_mode + when: debpkg_mode - name: Adjust APT update intervals copy: src: files/apt_periodic dest: /etc/apt/apt.conf.d/10periodic - + when: debpkg_mode or nixpkg_mode + - name: Transfer init SQL files copy: src: files/{{ item.source }} dest: /tmp/{{ item.dest }} loop: "{{ sql_files }}" + when: debpkg_mode or stage2_nix - name: Execute init SQL files become: yes @@ -106,25 +110,30 @@ shell: cmd: /usr/lib/postgresql/bin/psql -f /tmp/{{ item.dest }} loop: "{{ sql_files }}" + when: debpkg_mode or stage2_nix - name: Delete SQL scripts file: path: /tmp/{{ item.dest }} state: absent loop: "{{ sql_files }}" + when: debpkg_mode or stage2_nix - name: First boot optimizations import_tasks: tasks/internal/optimizations.yml tags: - install-supabase-internal - + when: debpkg_mode or stage2_nix + - name: Finalize AMI import_tasks: tasks/finalize-ami.yml tags: - install-supabase-internal - + when: debpkg_mode or nixpkg_mode + - name: Enhance fail2ban import_tasks: tasks/setup-fail2ban.yml + when: debpkg_mode or nixpkg_mode # Install EC2 instance connect # Only for AWS images @@ -153,26 +162,47 @@ become_user: postgres shell: cmd: /usr/lib/postgresql/bin/pg_ctl -D /var/lib/postgresql/data restart -o "-c shared_preload_libraries='pg_tle'" - when: ebssurrogate_mode + when: debpkg_mode - name: Run migrations import_tasks: tasks/setup-migrations.yml tags: - migrations + when: debpkg_mode or stage2_nix - name: Stop Postgres Database without Systemd become: yes become_user: postgres shell: cmd: /usr/lib/postgresql/bin/pg_ctl -D /var/lib/postgresql/data stop - when: ebssurrogate_mode + when: debpkg_mode - name: Run unit tests import_tasks: tasks/test-image.yml tags: - unit-tests + when: debpkg_mode or stage2_nix - name: Collect Postgres binaries import_tasks: tasks/internal/collect-pg-binaries.yml tags: - collect-binaries + when: debpkg_mode + + - name: Install osquery from nixpkgs binary cache + become: yes + shell: | + sudo -u ubuntu bash -c ". /nix/var/nix/profiles/default/etc/profile.d/nix-daemon.sh && nix profile install nixpkgs#osquery" + when: stage2_nix + + - name: Run osquery permission checks + become: yes + shell: | + sudo -u ubuntu bash -c ". /nix/var/nix/profiles/default/etc/profile.d/nix-daemon.sh && /usr/bin/python3 /tmp/ansible-playbook/ansible/files/permission_check.py" + when: stage2_nix + + - name: Remove osquery + become: yes + shell: | + sudo -u ubuntu bash -c ". /nix/var/nix/profiles/default/etc/profile.d/nix-daemon.sh && nix profile remove osquery" + when: stage2_nix diff --git a/ansible/tasks/finalize-ami.yml b/ansible/tasks/finalize-ami.yml index 9818f2add..7f0de3ac8 100644 --- a/ansible/tasks/finalize-ami.yml +++ b/ansible/tasks/finalize-ami.yml @@ -78,3 +78,4 @@ owner: postgres group: postgres mode: 0700 + when: debpkg_mode or stage2_nix diff --git a/ansible/tasks/internal/optimizations.yml b/ansible/tasks/internal/optimizations.yml index 895acccd9..157c35123 100644 --- a/ansible/tasks/internal/optimizations.yml +++ b/ansible/tasks/internal/optimizations.yml @@ -1,39 +1,29 @@ -- name: ensure services are stopped - community.general.snap: - name: amazon-ssm-agent - state: absent - failed_when: not ebssurrogate_mode - -- name: ensure services are stopped and disabled for first boot +- name: ensure services are stopped and disabled for first boot debian build systemd: enabled: no name: '{{ item }}' state: stopped with_items: - - snapd - postgresql - pgbouncer - fail2ban - motd-news - vector - failed_when: not ebssurrogate_mode - -- name: Remove snapd - apt: - state: absent - pkg: - - snapd - failed_when: not ebssurrogate_mode + - lvm2-monitor + when: debpkg_mode -- name: ensure services are stopped and disabled for first boot +- name: ensure services are stopped and disabled for first boot nix build systemd: enabled: no name: '{{ item }}' state: stopped - masked: yes with_items: - - lvm2-monitor - failed_when: not ebssurrogate_mode + - postgresql + - pgbouncer + - fail2ban + - motd-news + - vector + when: stage2_nix - name: disable man-db become: yes @@ -44,4 +34,4 @@ - man-db - popularity-contest - ubuntu-advantage-tools - failed_when: not ebssurrogate_mode + when: debpkg_mode or stage2_nix diff --git a/ansible/tasks/setup-docker.yml b/ansible/tasks/setup-docker.yml index 42f4f3b3f..7b37f70cc 100644 --- a/ansible/tasks/setup-docker.yml +++ b/ansible/tasks/setup-docker.yml @@ -2,6 +2,7 @@ copy: src: files/extensions/ dest: /tmp/extensions/ + when: debpkg_mode # Builtin apt module does not support wildcard for deb paths - name: Install extensions @@ -9,12 +10,16 @@ set -e apt-get update apt-get install -y --no-install-recommends /tmp/extensions/*.deb + when: debpkg_mode - name: pgsodium - determine postgres bin directory shell: pg_config --bindir register: pg_bindir_output + when: debpkg_mode + - set_fact: pg_bindir: "{{ pg_bindir_output.stdout }}" + when: debpkg_mode - name: pgsodium - set pgsodium.getkey_script become: yes @@ -23,6 +28,7 @@ state: present # script is expected to be placed by finalization tasks for different target platforms line: pgsodium.getkey_script= '{{ pg_bindir }}/pgsodium_getkey.sh' + when: debpkg_mode # supautils - name: supautils - add supautils to session_preload_libraries @@ -31,6 +37,7 @@ path: /etc/postgresql/postgresql.conf regexp: "#session_preload_libraries = ''" replace: session_preload_libraries = 'supautils' + when: debpkg_mode or stage2_nix - name: supautils - write custom supautils.conf template: @@ -39,12 +46,14 @@ mode: 0664 owner: postgres group: postgres + when: debpkg_mode or stage2_nix - name: supautils - copy extension custom scripts copy: src: files/postgresql_extension_custom_scripts/ dest: /etc/postgresql-custom/extension-custom-scripts become: yes + when: debpkg_mode or stage2_nix - name: supautils - chown extension custom scripts file: @@ -54,6 +63,7 @@ path: /etc/postgresql-custom/extension-custom-scripts recurse: yes become: yes + when: debpkg_mode or stage2_nix - name: supautils - include /etc/postgresql-custom/supautils.conf in postgresql.conf become: yes @@ -61,8 +71,10 @@ path: /etc/postgresql/postgresql.conf regexp: "#include = '/etc/postgresql-custom/supautils.conf'" replace: "include = '/etc/postgresql-custom/supautils.conf'" + when: debpkg_mode or stage2_nix - name: Cleanup - extension packages file: path: /tmp/extensions state: absent + when: debpkg_mode diff --git a/ansible/tasks/setup-fail2ban.yml b/ansible/tasks/setup-fail2ban.yml index e1cec2d92..1f6065d32 100644 --- a/ansible/tasks/setup-fail2ban.yml +++ b/ansible/tasks/setup-fail2ban.yml @@ -5,16 +5,19 @@ path: /etc/fail2ban/jail.conf regexp: bantime = 10m replace: bantime = 3600 + when: debpkg_mode or nixpkg_mode - name: Configure journald copy: src: files/fail2ban_config/jail-ssh.conf dest: /etc/fail2ban/jail.d/sshd.local + when: debpkg_mode or nixpkg_mode - name: configure fail2ban to use nftables copy: src: files/fail2ban_config/jail.local dest: /etc/fail2ban/jail.local + when: debpkg_mode or nixpkg_mode # postgresql - name: import jail.d/postgresql.conf @@ -22,12 +25,14 @@ src: files/fail2ban_config/jail-postgresql.conf.j2 dest: /etc/fail2ban/jail.d/postgresql.conf become: yes + when: debpkg_mode or nixpkg_mode - name: import filter.d/postgresql.conf template: src: files/fail2ban_config/filter-postgresql.conf.j2 dest: /etc/fail2ban/filter.d/postgresql.conf become: yes + when: debpkg_mode or nixpkg_mode - name: create overrides dir file: @@ -36,11 +41,13 @@ group: root path: /etc/systemd/system/fail2ban.service.d mode: '0700' + when: debpkg_mode or nixpkg_mode - name: Custom systemd overrides copy: src: files/fail2ban_config/fail2ban.service.conf dest: /etc/systemd/system/fail2ban.service.d/overrides.conf + when: debpkg_mode or nixpkg_mode - name: add in supabase specific ignore filters lineinfile: @@ -56,15 +63,18 @@ become: yes tags: - install-supabase-internal + when: debpkg_mode or nixpkg_mode # Restart - name: fail2ban - restart systemd: name: fail2ban state: restarted + when: debpkg_mode or nixpkg_mode - name: fail2ban - disable service systemd: name: fail2ban enabled: no daemon_reload: yes + when: debpkg_mode or nixpkg_mode \ No newline at end of file diff --git a/ansible/tasks/setup-migrations.yml b/ansible/tasks/setup-migrations.yml index 570f7763c..6eea6844b 100644 --- a/ansible/tasks/setup-migrations.yml +++ b/ansible/tasks/setup-migrations.yml @@ -1,7 +1,7 @@ - name: Run migrate.sh script shell: ./migrate.sh register: retval - when: ebssurrogate_mode + when: debpkg_mode or stage2_nix args: chdir: /tmp/migrations/db failed_when: retval.rc != 0 @@ -10,4 +10,4 @@ file: path: "/root/MIGRATION-AMI" state: touch - when: ebssurrogate_mode + when: debpkg_mode or stage2_nix diff --git a/ansible/tasks/setup-postgres.yml b/ansible/tasks/setup-postgres.yml index c84142928..ef84c92c8 100644 --- a/ansible/tasks/setup-postgres.yml +++ b/ansible/tasks/setup-postgres.yml @@ -2,39 +2,83 @@ copy: src: files/postgres/ dest: /tmp/build/ + when: debpkg_mode - name: Postgres - add PPA apt_repository: repo: "deb [ trusted=yes ] file:///tmp/build ./" state: present + when: debpkg_mode - name: Postgres - install commons apt: name: postgresql-common install_recommends: no + when: debpkg_mode - name: Do not create main cluster shell: cmd: sed -ri 's/#(create_main_cluster) .*$/\1 = false/' /etc/postgresql-common/createcluster.conf + when: debpkg_mode - name: Postgres - install server apt: name: postgresql-{{ postgresql_major }}={{ postgresql_release }}-1.pgdg20.04+1 install_recommends: no + when: debpkg_mode - name: Postgres - remove PPA apt_repository: repo: "deb [ trusted=yes ] file:///tmp/build ./" state: absent + when: debpkg_mode - name: Postgres - cleanup package file: path: /tmp/build state: absent + when: debpkg_mode + +- name: locale-gen + command: sudo locale-gen en_US.UTF-8 + when: stage2_nix + +- name: update-locale + command: sudo update-locale + when: stage2_nix - name: Create symlink to /usr/lib/postgresql/bin shell: cmd: ln -s /usr/lib/postgresql/{{ postgresql_major }}/bin /usr/lib/postgresql/bin + when: debpkg_mode + +- name: create ssl-cert group + group: + name: ssl-cert + state: present + when: nixpkg_mode +# the old method of installing from debian creates this group, but we must create it explicitly +# for the nix built version + +- name: create postgres group + group: + name: postgres + state: present + when: nixpkg_mode + +- name: create postgres user + shell: adduser --system --home /var/lib/postgresql --no-create-home --shell /bin/bash --group --gecos "PostgreSQL administrator" postgres + args: + executable: /bin/bash + become: yes + when: nixpkg_mode + +- name: add postgres user to postgres group + shell: usermod -a -G ssl-cert postgres + args: + executable: /bin/bash + become: yes + when: nixpkg_mode - name: Create relevant directories file: @@ -47,6 +91,7 @@ - '/home/postgres' - '/var/log/postgresql' - '/var/lib/postgresql' + when: debpkg_mode or nixpkg_mode - name: Allow adminapi to write custom config file: @@ -59,6 +104,7 @@ with_items: - '/etc/postgresql' - '/etc/postgresql-custom' + when: debpkg_mode or nixpkg_mode - name: create placeholder config files file: @@ -70,6 +116,7 @@ with_items: - 'generated-optimizations.conf' - 'custom-overrides.conf' + when: debpkg_mode or nixpkg_mode # Move Postgres configuration files into /etc/postgresql # Add postgresql.conf @@ -78,6 +125,7 @@ src: files/postgresql_config/postgresql.conf.j2 dest: /etc/postgresql/postgresql.conf group: postgres + when: debpkg_mode or nixpkg_mode # Add pg_hba.conf - name: import pg_hba.conf @@ -85,6 +133,7 @@ src: files/postgresql_config/pg_hba.conf.j2 dest: /etc/postgresql/pg_hba.conf group: postgres + when: debpkg_mode or nixpkg_mode # Add pg_ident.conf - name: import pg_ident.conf @@ -92,6 +141,7 @@ src: files/postgresql_config/pg_ident.conf.j2 dest: /etc/postgresql/pg_ident.conf group: postgres + when: debpkg_mode or nixpkg_mode # Add custom config for read replicas set up - name: Move custom read-replica.conf file to /etc/postgresql-custom/read-replica.conf @@ -101,10 +151,17 @@ mode: 0664 owner: postgres group: postgres + when: debpkg_mode or nixpkg_mode # Install extensions before init - name: Install Postgres extensions import_tasks: tasks/setup-docker.yml + when: debpkg_mode or stage2_nix + +#stage 2 postgres tasks +- name: stage2 postgres tasks + import_tasks: tasks/stage2-setup-postgres.yml + when: stage2_nix # init DB - name: Create directory on data volume @@ -117,6 +174,7 @@ mode: 0750 with_items: - "/data/pgdata" + when: debpkg_mode or nixpkg_mode - name: Link database data_dir to data volume directory file: @@ -124,26 +182,60 @@ path: "/var/lib/postgresql/data" state: link force: yes + when: debpkg_mode or nixpkg_mode - name: Initialize the database become: yes become_user: postgres - shell: - cmd: /usr/lib/postgresql/bin/pg_ctl -D /var/lib/postgresql/data initdb -o "--allow-group-access" + shell: /usr/lib/postgresql/bin/pg_ctl -D /var/lib/postgresql/data initdb -o "--allow-group-access" + vars: + ansible_command_timeout: 60 + when: debpkg_mode + +- name: Initialize the database stage2_nix + become: yes + become_user: postgres + shell: source /var/lib/postgresql/.bashrc && /usr/lib/postgresql/bin/pg_ctl -D /var/lib/postgresql/data initdb -o "--allow-group-access" + args: + executable: /bin/bash + environment: + LANG: en_US.UTF-8 + LANGUAGE: en_US.UTF-8 + LC_ALL: en_US.UTF-8 + LC_CTYPE: en_US.UTF-8 + LOCALE_ARCHIVE: /usr/lib/locale/locale-archive vars: ansible_command_timeout: 60 # Circumvents the following error: # "Timeout (12s) waiting for privilege escalation prompt" + when: stage2_nix - name: copy PG systemd unit template: src: files/postgresql_config/postgresql.service.j2 dest: /etc/systemd/system/postgresql.service + when: debpkg_mode or stage2_nix - name: copy optimizations systemd unit template: src: files/database-optimizations.service.j2 dest: /etc/systemd/system/database-optimizations.service + when: debpkg_mode or stage2_nix + +- name: Restart Postgres Database without Systemd + become: yes + become_user: postgres + shell: | + source /var/lib/postgresql/.bashrc + /usr/lib/postgresql/bin/pg_ctl -D /var/lib/postgresql/data start + environment: + LANG: en_US.UTF-8 + LANGUAGE: en_US.UTF-8 + LC_ALL: en_US.UTF-8 + LC_CTYPE: en_US.UTF-8 + LOCALE_ARCHIVE: /usr/lib/locale/locale-archive + when: stage2_nix + # Reload - name: System - systemd reload @@ -151,3 +243,33 @@ enabled: yes name: postgresql daemon_reload: yes + when: debpkg_mode or stage2_nix + +- name: Make sure .bashrc exists + file: + path: /var/lib/postgresql/.bashrc + state: touch + owner: postgres + group: postgres + when: nixpkg_mode + +- name: Add LOCALE_ARCHIVE to .bashrc + lineinfile: + dest: "/var/lib/postgresql/.bashrc" + line: 'export LOCALE_ARCHIVE=/usr/lib/locale/locale-archive' + create: yes + become: yes + when: nixpkg_mode + +- name: Add LANG items to .bashrc + lineinfile: + dest: "/var/lib/postgresql/.bashrc" + line: "{{ item }}" + loop: + - 'export LANG="en_US.UTF-8"' + - 'export LANGUAGE="en_US.UTF-8"' + - 'export LC_ALL="en_US.UTF-8"' + - 'export LANG="en_US.UTF-8"' + - 'export LC_CTYPE="en_US.UTF-8"' + become: yes + when: nixpkg_mode diff --git a/ansible/tasks/setup-system.yml b/ansible/tasks/setup-system.yml index 860d75cc2..d18c19130 100644 --- a/ansible/tasks/setup-system.yml +++ b/ansible/tasks/setup-system.yml @@ -1,6 +1,6 @@ - name: System - apt update and apt upgrade apt: update_cache=yes upgrade=yes - when: not ebssurrogate_mode + when: debpkg_mode or nixpkg_mode # SEE http://archive.vn/DKJjs#parameter-upgrade - name: Install required security updates @@ -8,13 +8,14 @@ pkg: - tzdata - linux-libc-dev - + when: debpkg_mode or nixpkg_mode # SEE https://github.com/georchestra/ansible/issues/55#issuecomment-588313638 # Without this, a similar error is faced - name: Install Ansible dependencies apt: pkg: - acl + when: debpkg_mode or nixpkg_mode - name: Install security tools apt: @@ -23,6 +24,7 @@ - fail2ban update_cache: yes cache_valid_time: 3600 + when: debpkg_mode or nixpkg_mode - name: Use nftables backend shell: | @@ -31,11 +33,13 @@ update-alternatives --set arptables /usr/sbin/arptables-nft update-alternatives --set ebtables /usr/sbin/ebtables-nft systemctl restart ufw + when: debpkg_mode or nixpkg_mode - name: Create Sysstat log directory file: path: /var/log/sysstat state: directory + when: debpkg_mode or nixpkg_mode - name: Install other useful tools apt: @@ -47,22 +51,26 @@ - sysstat - vim-tiny update_cache: yes + when: debpkg_mode or nixpkg_mode - name: Configure sysstat copy: src: files/sysstat.sysstat dest: /etc/sysstat/sysstat + when: debpkg_mode or nixpkg_mode - name: Configure default sysstat copy: src: files/default.sysstat dest: /etc/default/sysstat + when: debpkg_mode or nixpkg_mode - name: Adjust APT update intervals copy: src: files/apt_periodic dest: /etc/apt/apt.conf.d/10periodic + when: debpkg_mode or nixpkg_mode # Find platform architecture and set as a variable - name: finding platform architecture @@ -76,6 +84,7 @@ tags: - update - update-only + when: debpkg_mode or nixpkg_mode or stage2_nix - name: create overrides dir file: @@ -84,40 +93,48 @@ group: root path: /etc/systemd/system/systemd-resolved.service.d mode: '0700' + when: debpkg_mode or nixpkg_mode - name: Custom systemd overrides for resolved copy: src: files/systemd-resolved.conf dest: /etc/systemd/system/systemd-resolved.service.d/override.conf + when: debpkg_mode or nixpkg_mode - name: System - Create services.slice template: src: files/services.slice.j2 dest: /etc/systemd/system/services.slice - when: not ebssurrogate_mode + when: debpkg_mode or nixpkg_mode + - name: System - systemd reload systemd: daemon_reload=yes + when: debpkg_mode or nixpkg_mode - name: Configure journald copy: src: files/journald.conf dest: /etc/systemd/journald.conf + when: debpkg_mode or nixpkg_mode - name: reload systemd-journald systemd: name: systemd-journald state: restarted + when: debpkg_mode or nixpkg_mode - name: Configure logind copy: src: files/logind.conf dest: /etc/systemd/logind.conf + when: debpkg_mode or nixpkg_mode - name: reload systemd-logind systemd: name: systemd-logind state: restarted + when: debpkg_mode or nixpkg_mode - name: enable timestamps for shell history copy: @@ -127,6 +144,7 @@ mode: 0644 owner: root group: root + when: debpkg_mode or nixpkg_mode - name: set hosts file copy: @@ -137,6 +155,7 @@ mode: 0644 owner: root group: root + when: debpkg_mode or stage2_nix #Set Sysctl params for restarting the OS on oom after 10 - name: Set vm.panic_on_oom=1 @@ -145,6 +164,7 @@ value: '1' state: present reload: yes + when: debpkg_mode or nixpkg_mode - name: Set kernel.panic=10 ansible.builtin.sysctl: @@ -152,3 +172,4 @@ value: '10' state: present reload: yes + when: debpkg_mode or nixpkg_mode diff --git a/ansible-nix/tasks/stage2/stage2-setup-postgres.yml b/ansible/tasks/stage2-setup-postgres.yml similarity index 69% rename from ansible-nix/tasks/stage2/stage2-setup-postgres.yml rename to ansible/tasks/stage2-setup-postgres.yml index 261e550bc..c5e1b3fbb 100644 --- a/ansible-nix/tasks/stage2/stage2-setup-postgres.yml +++ b/ansible/tasks/stage2-setup-postgres.yml @@ -8,11 +8,13 @@ shell: | sudo -u postgres bash -c ". /nix/var/nix/profiles/default/etc/profile.d/nix-daemon.sh && nix profile install github:supabase/postgres/sam/2-stage-ami-nix#psql_15/bin" #TODO (samrose) switch pg_prove sourcing to develop branch once PR is merged + when: stage2_nix - name: Install pg_prove from nix binary cache become: yes shell: | sudo -u postgres bash -c ". /nix/var/nix/profiles/default/etc/profile.d/nix-daemon.sh && nix profile install github:supabase/postgres/sam/2-stage-ami-nix#pg_prove" + when: stage2_nix - name: Set ownership and permissions for /etc/ssl/private become: yes @@ -21,6 +23,7 @@ owner: root group: postgres mode: '0750' + when: stage2_nix - name: Set permissions for postgresql.env become: yes @@ -29,6 +32,7 @@ owner: postgres group: postgres mode: '0644' + when: stage2_nix - name: Ensure /usr/lib/postgresql/bin directory exists file: @@ -36,7 +40,7 @@ state: directory owner: postgres group: postgres - + when: stage2_nix - name: Ensure /usr/lib/postgresql/share directory exists file: @@ -44,6 +48,7 @@ state: directory owner: postgres group: postgres + when: stage2_nix - name: Ensure /usr/lib/postgresql/share/contrib directory exists file: @@ -51,6 +56,7 @@ state: directory owner: postgres group: postgres + when: stage2_nix - name: Ensure /usr/lib/postgresql/share/timezonesets directory exists file: @@ -58,6 +64,7 @@ state: directory owner: postgres group: postgres + when: stage2_nix - name: Ensure /usr/lib/postgresql/share/tsearch_data directory exists file: @@ -65,6 +72,7 @@ state: directory owner: postgres group: postgres + when: stage2_nix - name: Ensure /usr/lib/postgresql/share/extension directory exists file: @@ -72,6 +80,7 @@ state: directory owner: postgres group: postgres + when: stage2_nix # - name: Ensure /usr/lib/postgresql/share/postgresql/pljava directory exists # file: @@ -79,15 +88,17 @@ # state: directory # owner: postgres # group: postgres +# when: stage2_nix # It was decided to leave pljava disabled at https://github.com/supabase/postgres/pull/690 therefore removing this task - name: import pgsodium_getkey script template: - src: /tmp/ansible-playbook/files/pgsodium_getkey_readonly.sh.j2 + src: /tmp/ansible-playbook/ansible/files/pgsodium_getkey_readonly.sh.j2 dest: "/usr/lib/postgresql/bin/pgsodium_getkey.sh" owner: postgres group: postgres mode: 0700 + when: stage2_nix - name: Create symbolic links from /var/lib/postgresql/.nix-profile/bin to /usr/lib/postgresql/bin file: @@ -97,20 +108,21 @@ with_fileglob: - "/var/lib/postgresql/.nix-profile/bin/*" become: yes + when: stage2_nix - name: Check if /usr/bin/pg_config exists stat: path: /usr/bin/pg_config register: pg_config_stat + when: stage2_nix - name: Remove existing /usr/bin/pg_config if it is not a symlink file: path: /usr/bin/pg_config state: absent - when: pg_config_stat.stat.exists and not pg_config_stat.stat.islnk + when: pg_config_stat.stat.exists and not pg_config_stat.stat.islnk and stage2_nix become: yes - - name: Create symbolic links from /var/lib/postgresql/.nix-profile/bin to /usr/bin file: src: "{{ item }}" @@ -119,6 +131,7 @@ with_fileglob: - "/var/lib/postgresql/.nix-profile/bin/*" become: yes + when: stage2_nix - name: Ensure postgres user has ownership of symlink file: @@ -128,6 +141,8 @@ with_fileglob: - "/var/lib/postgresql/.nix-profile/bin/*" become: yes + when: stage2_nix + # - name: Create symbolic links from /var/lib/postgresql/.nix-profile/share/pljava to /usr/lib/postgresql/share/postgresql/pljava # file: # src: "{{ item }}" @@ -146,6 +161,7 @@ with_fileglob: - "/var/lib/postgresql/.nix-profile/share/postgresql/*" become: yes + when: stage2_nix - name: Create symbolic links from /var/lib/postgresql/.nix-profile/share/postgresql/extension to /usr/lib/postgresql/share/postgresql/extension file: @@ -155,12 +171,14 @@ with_fileglob: - "/var/lib/postgresql/.nix-profile/share/postgresql/extension/*" become: yes + when: stage2_nix - name: create destination directory file: path: /usr/lib/postgresql/share/postgresql/contrib/ state: directory recurse: yes + when: stage2_nix - name: Recursively create symbolic links and set permissions for the contrib/postgis-* dir shell: > @@ -168,6 +186,7 @@ sudo find /var/lib/postgresql/.nix-profile/share/postgresql/contrib/ -mindepth 1 -type d -exec sh -c 'for dir do sudo ln -s "$dir" "/usr/lib/postgresql/share/postgresql/contrib/$(basename "$dir")"; done' sh {} + \ && chown -R postgres:postgres "/usr/lib/postgresql/share/postgresql/contrib/" become: yes + when: stage2_nix - name: Create symbolic links from /var/lib/postgresql/.nix-profile/share/postgresql/timezonesets to /usr/lib/postgresql/share/postgresql/timeszonesets file: @@ -177,6 +196,7 @@ with_fileglob: - "/var/lib/postgresql/.nix-profile/share/postgresql/timezonesets/*" become: yes + when: stage2_nix - name: Create symbolic links from /var/lib/postgresql/.nix-profile/share/postgresql/tsearch_data to /usr/lib/postgresql/share/postgresql/tsearch_data file: @@ -186,110 +206,17 @@ with_fileglob: - "/var/lib/postgresql/.nix-profile/share/postgresql/tsearch_data/*" become: yes + when: stage2_nix +- set_fact: + pg_bindir: "/usr/lib/postgresql/bin" + when: stage2_nix -#Install configure before init -- name: Install Postgres extensions - import_tasks: setup-extensions.yml - -- name: Link database data_dir to data volume directory - file: - src: "/data/pgdata" - path: "/var/lib/postgresql/data" - state: link - force: yes - owner: postgres - group: postgres - -- name: Initialize the database - become: yes - become_user: postgres - shell: source /var/lib/postgresql/.bashrc && /usr/lib/postgresql/bin/pg_ctl -D /var/lib/postgresql/data initdb -o "--allow-group-access" - args: - executable: /bin/bash - environment: - LANG: en_US.UTF-8 - LANGUAGE: en_US.UTF-8 - LC_ALL: en_US.UTF-8 - LC_CTYPE: en_US.UTF-8 - LOCALE_ARCHIVE: /usr/lib/locale/locale-archive - vars: - ansible_command_timeout: 60 - # Circumvents the following error: - # "Timeout (12s) waiting for privilege escalation prompt" - -- name: copy PG systemd unit - template: - src: /tmp/ansible-playbook/files/postgresql_config/postgresql.service.j2 - dest: /etc/systemd/system/postgresql.service - -- name: copy optimizations systemd unit - template: - src: /tmp/ansible-playbook/files/database-optimizations.service.j2 - dest: /etc/systemd/system/database-optimizations.service - -- name: Restart Postgres Database without Systemd - become: yes - become_user: postgres - shell: | - source /var/lib/postgresql/.bashrc - /usr/lib/postgresql/bin/pg_ctl -D /var/lib/postgresql/data start - environment: - LANG: en_US.UTF-8 - LANGUAGE: en_US.UTF-8 - LC_ALL: en_US.UTF-8 - LC_CTYPE: en_US.UTF-8 - LOCALE_ARCHIVE: /usr/lib/locale/locale-archive - -- name: Execute init SQL files - become: yes - become_user: postgres - shell: - cmd: /usr/lib/postgresql/bin/psql -f {{ item }} - loop: "{{ sql_files }}" - -- name: Delete SQL scripts - file: - path: "{{ item }}" - state: absent - loop: "{{ sql_files }}" - -- name: Restart Postgres Database without Systemd - become: yes - become_user: postgres - shell: | - source /var/lib/postgresql/.bashrc && \ - /usr/lib/postgresql/bin/pg_ctl -D /var/lib/postgresql/data restart -o "-c shared_preload_libraries='pg_tle'" - args: - executable: /bin/bash - environment: - LANG: en_US.UTF-8 - LANGUAGE: en_US.UTF-8 - LC_ALL: en_US.UTF-8 - LC_CTYPE: en_US.UTF-8 - LOCALE_ARCHIVE: /usr/lib/locale/locale-archive - -- name: Run migrations - import_tasks: setup-migrations.yml - tags: - - migrations - - -# # # Reload -- name: System - systemd reload - systemd: - enabled: yes - name: postgresql - daemon_reload: yes - -- name: Stop Postgres with systemd - systemd: - state: stopped - name: postgresql - - -- name: Stop Postgres Database without systemd +- name: pgsodium - set pgsodium.getkey_script become: yes - become_user: postgres - shell: - cmd: /usr/lib/postgresql/bin/pg_ctl -D /var/lib/postgresql/data stop + lineinfile: + path: /etc/postgresql/postgresql.conf + state: present + # script is expected to be placed by finalization tasks for different target platforms + line: pgsodium.getkey_script= '{{ pg_bindir }}/pgsodium_getkey.sh' + when: stage2_nix diff --git a/ansible/tasks/test-image.yml b/ansible/tasks/test-image.yml index cd92a27d6..d6e8223f7 100644 --- a/ansible/tasks/test-image.yml +++ b/ansible/tasks/test-image.yml @@ -2,32 +2,61 @@ apt: pkg: - libtap-parser-sourcehandler-pgtap-perl + when: debpkg_mode - name: Temporarily disable PG Sodium references in config become: yes become_user: postgres shell: cmd: sed -i.bak -e "s/pg_net,\ pgsodium,\ timescaledb/pg_net,\ timescaledb/g" -e "s/pgsodium.getkey_script=/#pgsodium.getkey_script=/g" /etc/postgresql/postgresql.conf - when: ebssurrogate_mode + when: debpkg_mode or stage2_nix - name: Start Postgres Database to load all extensions. become: yes become_user: postgres shell: cmd: /usr/lib/postgresql/bin/pg_ctl -D /var/lib/postgresql/data start "-o -c config_file=/etc/postgresql/postgresql.conf" - when: ebssurrogate_mode + when: debpkg_mode + +- name: Stop Postgres Database in stage 2 + become: yes + become_user: postgres + shell: source /var/lib/postgresql/.bashrc && /usr/lib/postgresql/bin/pg_ctl -D /var/lib/postgresql/data stop + args: + executable: /bin/bash + environment: + LANG: en_US.UTF-8 + LANGUAGE: en_US.UTF-8 + LC_ALL: en_US.UTF-8 + LC_CTYPE: en_US.UTF-8 + LOCALE_ARCHIVE: /usr/lib/locale/locale-archive + when: stage2_nix + +- name: Start Postgres Database to load all extensions. + become: yes + become_user: postgres + shell: source /var/lib/postgresql/.bashrc && /usr/lib/postgresql/bin/pg_ctl -D /var/lib/postgresql/data start "-o -c config_file=/etc/postgresql/postgresql.conf" + args: + executable: /bin/bash + environment: + LANG: en_US.UTF-8 + LANGUAGE: en_US.UTF-8 + LC_ALL: en_US.UTF-8 + LC_CTYPE: en_US.UTF-8 + LOCALE_ARCHIVE: /usr/lib/locale/locale-archive + when: stage2_nix - name: Run Unit tests (with filename unit-test-*) on Postgres Database shell: /usr/bin/pg_prove -U postgres -h localhost -d postgres -v /tmp/unit-tests/unit-test-*.sql register: retval failed_when: retval.rc != 0 - when: ebssurrogate_mode + when: debpkg_mode or stage2_nix - name: Run migrations tests shell: /usr/bin/pg_prove -U supabase_admin -h localhost -d postgres -v tests/test.sql register: retval failed_when: retval.rc != 0 - when: ebssurrogate_mode + when: debpkg_mode or stage2_nix args: chdir: /tmp/migrations @@ -36,11 +65,11 @@ become_user: postgres shell: cmd: mv /etc/postgresql/postgresql.conf.bak /etc/postgresql/postgresql.conf - when: ebssurrogate_mode + when: debpkg_mode or stage2_nix - name: Reset db stats shell: /usr/lib/postgresql/bin/psql --no-password --no-psqlrc -d postgres -h localhost -U supabase_admin -c 'SELECT pg_stat_statements_reset(); SELECT pg_stat_reset();' - when: ebssurrogate_mode + when: debpkg_mode or stage2_nix - name: remove pg_prove apt: @@ -48,10 +77,11 @@ - libtap-parser-sourcehandler-pgtap-perl state: absent autoremove: yes + when: debpkg_mode - name: Stop Postgres Database become: yes become_user: postgres shell: cmd: /usr/lib/postgresql/bin/pg_ctl -D /var/lib/postgresql/data stop - when: ebssurrogate_mode + when: debpkg_mode or stage2_nix diff --git a/ebssurrogate/scripts/surrogate-bootstrap-nix.sh b/ebssurrogate/scripts/surrogate-bootstrap-nix.sh index 0daa6e517..5bb021d96 100755 --- a/ebssurrogate/scripts/surrogate-bootstrap-nix.sh +++ b/ebssurrogate/scripts/surrogate-bootstrap-nix.sh @@ -214,7 +214,7 @@ EOF # Run Ansible playbook #export ANSIBLE_LOG_PATH=/tmp/ansible.log && export ANSIBLE_DEBUG=True && export ANSIBLE_REMOTE_TEMP=/mnt/tmp export ANSIBLE_LOG_PATH=/tmp/ansible.log && export ANSIBLE_REMOTE_TEMP=/mnt/tmp - ansible-playbook -c chroot -i '/mnt,' /tmp/ansible-playbook/ansible-nix/playbook.yml $ARGS + ansible-playbook -c chroot -i '/mnt,' /tmp/ansible-playbook/ansible/playbook.yml --extra-vars '{"nixpkg_mode": true, "debpkg_mode": false, "stage2_nix": false}' $ARGS } function update_systemd_services { diff --git a/ebssurrogate/scripts/surrogate-bootstrap.sh b/ebssurrogate/scripts/surrogate-bootstrap.sh index a24e1d35e..54eb98fb5 100755 --- a/ebssurrogate/scripts/surrogate-bootstrap.sh +++ b/ebssurrogate/scripts/surrogate-bootstrap.sh @@ -214,7 +214,7 @@ EOF # Run Ansible playbook #export ANSIBLE_LOG_PATH=/tmp/ansible.log && export ANSIBLE_DEBUG=True && export ANSIBLE_REMOTE_TEMP=/mnt/tmp export ANSIBLE_LOG_PATH=/tmp/ansible.log && export ANSIBLE_REMOTE_TEMP=/mnt/tmp - ansible-playbook -c chroot -i '/mnt,' /tmp/ansible-playbook/ansible/playbook.yml $ARGS + ansible-playbook -c chroot -i '/mnt,' /tmp/ansible-playbook/ansible/playbook.yml --extra-vars '{"debpkg_mode": true, "nixpkg_mode": false, "stage2_nix": false}' $ARGS } function update_systemd_services { diff --git a/scripts/nix-provision.sh b/scripts/nix-provision.sh index 1b7804e78..43682412a 100644 --- a/scripts/nix-provision.sh +++ b/scripts/nix-provision.sh @@ -30,10 +30,10 @@ sudo tee /etc/ansible/ansible.cfg < str: ) def is_healthy(host) -> bool: - cmd = host.run("sudo -u postgres /var/lib/postgresql/.nix-profile/bin/pg_isready -U postgres") + cmd = host.run("sudo -u postgres /usr/bin/pg_isready -U postgres") if cmd.failed is True: logger.warning("pg not ready") return False From 02f1f4f66146bff167930a51f674a8e23041e543 Mon Sep 17 00:00:00 2001 From: samrose Date: Thu, 18 Jul 2024 11:34:44 -0400 Subject: [PATCH 40/45] Sam/timescale and wrappers (#1052) * fix: was using the wrong sha256 hash for version * chore: updating wrappers version * itests: make sure we run the current commit on psql bundle test --------- Co-authored-by: Sam Rose --- .github/workflows/testinfra-nix.yml | 2 +- ansible/tasks/stage2-setup-postgres.yml | 2 +- common-nix.vars.pkr.hcl | 2 +- nix/ext/timescaledb.nix | 2 +- nix/ext/wrappers/default.nix | 4 ++-- scripts/nix-provision.sh | 14 ++++++++------ stage2-nix-psql.pkr.hcl | 7 +++++++ 7 files changed, 21 insertions(+), 12 deletions(-) diff --git a/.github/workflows/testinfra-nix.yml b/.github/workflows/testinfra-nix.yml index 7a3e4eea0..a0a94fe41 100644 --- a/.github/workflows/testinfra-nix.yml +++ b/.github/workflows/testinfra-nix.yml @@ -47,7 +47,7 @@ jobs: run: | packer init stage2-nix-psql.pkr.hcl GIT_SHA=${{github.sha}} - packer build -var "git-head-version=${GIT_SHA}" -var "packer-execution-id=${GITHUB_RUN_ID}" -var-file="development-arm.vars.pkr.hcl" -var-file="common-nix.vars.pkr.hcl" -var "postgres-version=ci-ami-test" -var "region=ap-southeast-1" -var 'ami_regions=["ap-southeast-1"]' -var "force-deregister=true" stage2-nix-psql.pkr.hcl + packer build -var "git-head-version=${GIT_SHA}" -var "packer-execution-id=${GITHUB_RUN_ID}" -var-file="development-arm.vars.pkr.hcl" -var-file="common-nix.vars.pkr.hcl" -var "postgres-version=ci-ami-test" -var "region=ap-southeast-1" -var 'ami_regions=["ap-southeast-1"]' -var "force-deregister=true" -var "git_sha=${GITHUB_SHA}" stage2-nix-psql.pkr.hcl - name: Run tests timeout-minutes: 10 diff --git a/ansible/tasks/stage2-setup-postgres.yml b/ansible/tasks/stage2-setup-postgres.yml index c5e1b3fbb..911e1eae5 100644 --- a/ansible/tasks/stage2-setup-postgres.yml +++ b/ansible/tasks/stage2-setup-postgres.yml @@ -6,7 +6,7 @@ - name: Install Postgres from nix binary cache become: yes shell: | - sudo -u postgres bash -c ". /nix/var/nix/profiles/default/etc/profile.d/nix-daemon.sh && nix profile install github:supabase/postgres/sam/2-stage-ami-nix#psql_15/bin" + sudo -u postgres bash -c ". /nix/var/nix/profiles/default/etc/profile.d/nix-daemon.sh && nix profile install github:supabase/postgres/{{ git_commit_sha }}#psql_15/bin" #TODO (samrose) switch pg_prove sourcing to develop branch once PR is merged when: stage2_nix diff --git a/common-nix.vars.pkr.hcl b/common-nix.vars.pkr.hcl index ce914fc26..a7da699b5 100644 --- a/common-nix.vars.pkr.hcl +++ b/common-nix.vars.pkr.hcl @@ -1 +1 @@ -postgres-version = "15.6.1.90-nix-staged" +postgres-version = "15.6.1.91-nix-staged" diff --git a/nix/ext/timescaledb.nix b/nix/ext/timescaledb.nix index d5bb60423..4c3f2ef1e 100644 --- a/nix/ext/timescaledb.nix +++ b/nix/ext/timescaledb.nix @@ -11,7 +11,7 @@ stdenv.mkDerivation rec { owner = "timescale"; repo = "timescaledb"; rev = version; - hash = "sha256-gJViEWHtIczvIiQKuvvuwCfWJMxAYoBhCHhD75no6r0="; + hash = "sha256-fvVSxDiGZAewyuQ2vZDb0I6tmlDXl6trjZp8+qDBtb8="; }; cmakeFlags = [ "-DSEND_TELEMETRY_DEFAULT=OFF" "-DREGRESS_CHECKS=OFF" "-DTAP_CHECKS=OFF" ] diff --git a/nix/ext/wrappers/default.nix b/nix/ext/wrappers/default.nix index 845bf64b6..c68641659 100644 --- a/nix/ext/wrappers/default.nix +++ b/nix/ext/wrappers/default.nix @@ -11,14 +11,14 @@ buildPgrxExtension_0_11_3 rec { pname = "supabase-wrappers"; - version = "0.3.1"; + version = "0.4.1"; inherit postgresql; src = fetchFromGitHub { owner = "supabase"; repo = "wrappers"; rev = "v${version}"; - hash = "sha256-ZwTw0USJC/F/ZW5usX7p0CB8p2YzeUb6OLiMF3D1+J4="; + hash = "sha256-AU9Y43qEMcIBVBThu+Aor1HCtfFIg+CdkzK9IxVdkzM="; }; nativeBuildInputs = [ pkg-config cargo ]; diff --git a/scripts/nix-provision.sh b/scripts/nix-provision.sh index 43682412a..223e84926 100644 --- a/scripts/nix-provision.sh +++ b/scripts/nix-provision.sh @@ -25,15 +25,17 @@ function install_nix() { function execute_stage2_playbook { - -sudo tee /etc/ansible/ansible.cfg < Date: Thu, 18 Jul 2024 14:41:53 -0400 Subject: [PATCH 41/45] fix: locale gen and ami deregister on any testinfra run (#1055) * fix: locale gen and ami deregister on any testinfra run * fix: use more manual approach --------- Co-authored-by: Sam Rose --- .github/workflows/testinfra-nix.yml | 21 +++++++++++++++++++++ ansible/tasks/setup-postgres.yml | 14 +++++++++++++- 2 files changed, 34 insertions(+), 1 deletion(-) diff --git a/.github/workflows/testinfra-nix.yml b/.github/workflows/testinfra-nix.yml index a0a94fe41..cd6a903f6 100644 --- a/.github/workflows/testinfra-nix.yml +++ b/.github/workflows/testinfra-nix.yml @@ -65,3 +65,24 @@ jobs: if: ${{ always() }} run: | aws ec2 --region ap-southeast-1 describe-instances --filters "Name=tag:testinfra-run-id,Values=${GITHUB_RUN_ID}" --query "Reservations[].Instances[].InstanceId" --output text | xargs -n 1 -I {} aws ec2 terminate-instances --region ap-southeast-1 --instance-ids {} || true + + - name: Cleanup AMIs + if: always() + run: | + # Define AMI name patterns + STAGE1_AMI_NAME="supabase-postgres-ci-ami-test-stage-1" + STAGE2_AMI_NAME="supabase-postgres-ci-ami-test-nix" + + # Function to deregister AMIs by name pattern + deregister_ami_by_name() { + local ami_name_pattern=$1 + local ami_ids=$(aws ec2 describe-images --region ap-southeast-1 --owners self --filters "Name=name,Values=${ami_name_pattern}" --query 'Images[*].ImageId' --output text) + for ami_id in $ami_ids; do + echo "Deregistering AMI: $ami_id" + aws ec2 deregister-image --region ap-southeast-1 --image-id $ami_id + done + } + + # Deregister AMIs + deregister_ami_by_name "$STAGE1_AMI_NAME" + deregister_ami_by_name "$STAGE2_AMI_NAME" \ No newline at end of file diff --git a/ansible/tasks/setup-postgres.yml b/ansible/tasks/setup-postgres.yml index ef84c92c8..c1cf1983e 100644 --- a/ansible/tasks/setup-postgres.yml +++ b/ansible/tasks/setup-postgres.yml @@ -39,8 +39,20 @@ state: absent when: debpkg_mode +- name: install locales + apt: + name: locales + state: present + become: yes + when: stage2_nix + +- name: configure locales + command: echo "C.UTF-8 UTF-8" > /etc/locale.gen && echo "en_US.UTF-8 UTF-8" >> /etc/locale.gen + become: yes + when: stage2_nix + - name: locale-gen - command: sudo locale-gen en_US.UTF-8 + command: sudo locale-gen when: stage2_nix - name: update-locale From 16cd5c9e5a110bfe7ac0601248ec69827df7c0a9 Mon Sep 17 00:00:00 2001 From: Paul Cioanca Date: Fri, 19 Jul 2024 18:48:56 +0300 Subject: [PATCH 42/45] chore: update pg_upgrade initiate.sh to support nix-based upgrades (#1057) --- .../pg_upgrade_scripts/complete.sh | 10 ++- .../pg_upgrade_scripts/initiate.sh | 88 +++++++++++++++---- 2 files changed, 80 insertions(+), 18 deletions(-) diff --git a/ansible/files/admin_api_scripts/pg_upgrade_scripts/complete.sh b/ansible/files/admin_api_scripts/pg_upgrade_scripts/complete.sh index 1975709e7..d67d623d1 100755 --- a/ansible/files/admin_api_scripts/pg_upgrade_scripts/complete.sh +++ b/ansible/files/admin_api_scripts/pg_upgrade_scripts/complete.sh @@ -161,12 +161,20 @@ function apply_auth_scheme_updates { function start_vacuum_analyze { echo "complete" > /tmp/pg-upgrade-status - su -c 'vacuumdb --all --analyze-in-stages' -s "$SHELL" postgres + if ! command -v nix &> /dev/null; then + su -c 'vacuumdb --all --analyze-in-stages' -s "$SHELL" postgres + else + su -c '. /nix/var/nix/profiles/default/etc/profile.d/nix-daemon.sh && vacuumdb --all --analyze-in-stages' -s "$SHELL" postgres + fi echo "Upgrade job completed" } trap cleanup ERR +echo "C.UTF-8 UTF-8" > /etc/locale.gen +echo "en_US.UTF-8 UTF-8" >> /etc/locale.gen +locale-gen + if [ -z "$IS_CI" ]; then complete_pg_upgrade >> $LOG_FILE 2>&1 & else diff --git a/ansible/files/admin_api_scripts/pg_upgrade_scripts/initiate.sh b/ansible/files/admin_api_scripts/pg_upgrade_scripts/initiate.sh index 1b7329ded..5c16682ae 100755 --- a/ansible/files/admin_api_scripts/pg_upgrade_scripts/initiate.sh +++ b/ansible/files/admin_api_scripts/pg_upgrade_scripts/initiate.sh @@ -29,10 +29,13 @@ SCRIPT_DIR=$(dirname -- "$0";) source "$SCRIPT_DIR/common.sh" IS_CI=${IS_CI:-} -LOG_FILE="/var/log/pg-upgrade-initiate.log" +IS_LOCAL_UPGRADE=${IS_LOCAL_UPGRADE:-} +IS_NIX_UPGRADE=${IS_NIX_UPGRADE:-} +IS_NIX_BASED_SYSTEM="false" PGVERSION=$1 MOUNT_POINT="/data_migration" +LOG_FILE="/var/log/pg-upgrade-initiate.log" POST_UPGRADE_EXTENSION_SCRIPT="/tmp/pg_upgrade/pg_upgrade_extensions.sql" OLD_PGVERSION=$(run_sql -A -t -c "SHOW server_version;") @@ -41,6 +44,15 @@ POSTGRES_CONFIG_PATH="/etc/postgresql/postgresql.conf" PGBINOLD="/usr/lib/postgresql/bin" PGLIBOLD="/usr/lib/postgresql/lib" +PG_UPGRADE_BIN_DIR="/tmp/pg_upgrade_bin/$PGVERSION" + +if [ -L "$PGBINOLD/pg_upgrade" ]; then + BINARY_PATH=$(readlink -f "$PGBINOLD/pg_upgrade") + if [[ "$BINARY_PATH" == *"nix"* ]]; then + IS_NIX_BASED_SYSTEM="true" + fi +fi + # If upgrading from older major PG versions, disable specific extensions if [[ "$OLD_PGVERSION" =~ ^14.* ]]; then EXTENSIONS_TO_DISABLE+=("${PG14_EXTENSIONS_TO_DISABLE[@]}") @@ -107,7 +119,7 @@ cleanup() { echo "Removing SUPERUSER grant from postgres" run_sql -c "ALTER USER postgres WITH NOSUPERUSER;" - if [ -z "$IS_CI" ]; then + if [ -z "$IS_CI" ] && [ -z "$IS_LOCAL_UPGRADE" ]; then echo "Unmounting data disk from ${MOUNT_POINT}" umount $MOUNT_POINT fi @@ -175,18 +187,50 @@ function initiate_upgrade { PGDATAOLD=$(cat "$POSTGRES_CONFIG_PATH" | grep data_directory | sed "s/data_directory = '\(.*\)'.*/\1/") PGDATANEW="$MOUNT_POINT/pgdata" - PG_UPGRADE_BIN_DIR="/tmp/pg_upgrade_bin/$PGVERSION" - PGBINNEW="$PG_UPGRADE_BIN_DIR/bin" - PGLIBNEW="$PG_UPGRADE_BIN_DIR/lib" - PGSHARENEW="$PG_UPGRADE_BIN_DIR/share" # running upgrade using at least 1 cpu core WORKERS=$(nproc | awk '{ print ($1 == 1 ? 1 : $1 - 1) }') + + # To make nix-based upgrades work for testing, create a pg binaries tarball with the following contents: + # - nix_flake_version - a7189a68ed4ea78c1e73991b5f271043636cf074 + # Where the value is the commit hash of the nix flake that contains the binaries + + if [ -n "$IS_LOCAL_UPGRADE" ]; then + mkdir -p "$PG_UPGRADE_BIN_DIR" + mkdir -p /tmp/persistent/ + echo "a7189a68ed4ea78c1e73991b5f271043636cf074" > "$PG_UPGRADE_BIN_DIR/nix_flake_version" + tar -czf "/tmp/persistent/pg_upgrade_bin.tar.gz" -C "/tmp/pg_upgrade_bin" . + rm -rf /tmp/pg_upgrade_bin/ + fi echo "1. Extracting pg_upgrade binaries" mkdir -p "/tmp/pg_upgrade_bin" tar zxf "/tmp/persistent/pg_upgrade_bin.tar.gz" -C "/tmp/pg_upgrade_bin" + PGSHARENEW="$PG_UPGRADE_BIN_DIR/share" + + if [ -f "$PG_UPGRADE_BIN_DIR/nix_flake_version" ]; then + IS_NIX_UPGRADE="true" + NIX_FLAKE_VERSION=$(cat "$PG_UPGRADE_BIN_DIR/nix_flake_version") + + if [ "$IS_NIX_BASED_SYSTEM" = "false" ]; then + echo "1.1. Nix is not installed; installing." + + curl --proto '=https' --tlsv1.2 -sSf -L https://install.determinate.systems/nix | sh -s -- install --no-confirm \ + --extra-conf "substituters = https://cache.nixos.org https://nix-postgres-artifacts.s3.amazonaws.com" \ + --extra-conf "trusted-public-keys = nix-postgres-artifacts:dGZlQOvKcNEjvT7QEAJbcV6b6uk7VF/hWMjhYleiaLI=% cache.nixos.org-1:6NCHdD59X431o0gWypbMrAURkbJ16ZPMQFGspcDShjY=" + fi + + echo "1.2. Installing flake revision: $NIX_FLAKE_VERSION" + # shellcheck disable=SC1091 + source /nix/var/nix/profiles/default/etc/profile.d/nix-daemon.sh + PG_UPGRADE_BIN_DIR=$(nix build "github:supabase/postgres/${NIX_FLAKE_VERSION}#psql_15/bin" --no-link --print-out-paths --extra-experimental-features nix-command --extra-experimental-features flakes) + PGSHARENEW="$PG_UPGRADE_BIN_DIR/share/postgresql" + fi + + PGBINNEW="$PG_UPGRADE_BIN_DIR/bin" + PGLIBNEW="$PG_UPGRADE_BIN_DIR/lib" + # copy upgrade-specific pgsodium_getkey script into the share dir chmod +x "$SCRIPT_DIR/pgsodium_getkey.sh" mkdir -p "$PGSHARENEW/extension" @@ -220,7 +264,7 @@ function initiate_upgrade { locale-gen fi - if [ -z "$IS_CI" ]; then + if [ -z "$IS_CI" ] && [ -z "$IS_LOCAL_UPGRADE" ]; then # awk NF==3 prints lines with exactly 3 fields, which are the block devices currently not mounted anywhere # excluding nvme0 since it is the root disk echo "5. Determining block device to mount" @@ -254,13 +298,17 @@ function initiate_upgrade { echo "8. Granting SUPERUSER to postgres user" run_sql -c "ALTER USER postgres WITH SUPERUSER;" - if [ -d "/usr/share/postgresql/${PGVERSION}" ]; then - mv "/usr/share/postgresql/${PGVERSION}" "/usr/share/postgresql/${PGVERSION}.bak" - fi - ln -s "$PGSHARENEW" "/usr/share/postgresql/${PGVERSION}" + if [ -z "$IS_NIX_UPGRADE" ]; then + if [ -d "/usr/share/postgresql/${PGVERSION}" ]; then + mv "/usr/share/postgresql/${PGVERSION}" "/usr/share/postgresql/${PGVERSION}.bak" + fi + + ln -s "$PGSHARENEW" "/usr/share/postgresql/${PGVERSION}" + cp --remove-destination "$PGLIBNEW"/*.control "$PGSHARENEW/extension/" + cp --remove-destination "$PGLIBNEW"/*.sql "$PGSHARENEW/extension/" - cp --remove-destination "$PGLIBNEW"/*.control "$PGSHARENEW/extension/" - cp --remove-destination "$PGLIBNEW"/*.sql "$PGSHARENEW/extension/" + export LD_LIBRARY_PATH="${PGLIBNEW}" + fi # This is a workaround for older versions of wrappers which don't have the expected # naming scheme, containing the version in their library's file name @@ -287,8 +335,6 @@ function initiate_upgrade { fi fi - export LD_LIBRARY_PATH="${PGLIBNEW}" - echo "9. Creating new data directory, initializing database" chown -R postgres:postgres "$MOUNT_POINT/" rm -rf "${PGDATANEW:?}/" @@ -308,6 +354,10 @@ function initiate_upgrade { EOF ) + if [ "$IS_NIX_BASED_SYSTEM" = "true" ]; then + UPGRADE_COMMAND=". /nix/var/nix/profiles/default/etc/profile.d/nix-daemon.sh && $UPGRADE_COMMAND" + fi + su -c "$UPGRADE_COMMAND --check" -s "$SHELL" postgres echo "10. Stopping postgres; running pg_upgrade" @@ -324,7 +374,11 @@ EOF CI_stop_postgres fi - su -c "$UPGRADE_COMMAND" -s "$SHELL" postgres + if [ "$IS_NIX_BASED_SYSTEM" = "true" ]; then + LC_ALL=en_US.UTF-8 LC_CTYPE=en_US.UTF-8 LANGUAGE=en_US.UTF-8 LANG=en_US.UTF-8 LOCALE_ARCHIVE=/usr/lib/locale/locale-archive su -pc "$UPGRADE_COMMAND" -s "$SHELL" postgres + else + su -c "$UPGRADE_COMMAND" -s "$SHELL" postgres + fi # copying custom configurations echo "11. Copying custom configurations" @@ -349,7 +403,7 @@ EOF trap cleanup ERR echo "running" > /tmp/pg-upgrade-status -if [ -z "$IS_CI" ]; then +if [ -z "$IS_CI" ] && [ -z "$IS_LOCAL_UPGRADE" ]; then initiate_upgrade >> "$LOG_FILE" 2>&1 & echo "Upgrade initiate job completed" else From 2edcf2d880607cf9bbf91dbd3ec0b6bc10d73f62 Mon Sep 17 00:00:00 2001 From: Paul Cioanca Date: Fri, 19 Jul 2024 18:49:14 +0300 Subject: [PATCH 43/45] chore: package nix flake revision in pg_upgrade binaries tarball when building the nix AMI (#1058) --- .github/workflows/ami-release-nix.yml | 18 +++- .../publish-nix-pgupgrade-scripts.yml | 94 +++++++++++++++++++ 2 files changed, 110 insertions(+), 2 deletions(-) create mode 100644 .github/workflows/publish-nix-pgupgrade-scripts.yml diff --git a/.github/workflows/ami-release-nix.yml b/.github/workflows/ami-release-nix.yml index da61c9e2a..12c97a68d 100644 --- a/.github/workflows/ami-release-nix.yml +++ b/.github/workflows/ami-release-nix.yml @@ -61,6 +61,15 @@ jobs: VERSION=$(sed -e 's/postgres-version = "\(.*\)"/\1/g' common-nix.vars.pkr.hcl) echo "version=$VERSION" >> "$GITHUB_OUTPUT" + - name: Create nix flake revision tarball + run: | + GIT_SHA=${{github.sha}} + MAJOR_VERSION=$(echo "${{ steps.process_release_version.outputs.version }}" | cut -d. -f1) + + mkdir -p "/tmp/pg_upgrade_bin/${MAJOR_VERSION}" + echo "$GIT_SHA" >> "/tmp/pg_upgrade_bin/${MAJOR_VERSION}/nix_flake_version" + tar -czf "/tmp/pg_binaries.tar.gz" -C "/tmp/pg_upgrade_bin" . + - name: configure aws credentials - staging uses: aws-actions/configure-aws-credentials@v4 with: @@ -75,6 +84,9 @@ jobs: -e "internal_artifacts_bucket=${{ secrets.ARTIFACTS_BUCKET }}" \ manifest-playbook.yml + - name: Upload nix flake revision to s3 staging + run: | + aws s3 cp /tmp/pg_binaries.tar.gz s3://${{ secrets.ARTIFACTS_BUCKET }}/upgrades/postgres/supabase-postgres-${{ steps.process_release_version.outputs.version }}/20.04.tar.gz #Our self hosted github runner already has permissions to publish images #but they're limited to only that; @@ -95,8 +107,10 @@ jobs: -e "internal_artifacts_bucket=${{ secrets.PROD_ARTIFACTS_BUCKET }}" \ manifest-playbook.yml - - + - name: Upload nix flake revision to s3 prod + run: | + aws s3 cp /tmp/pg_binaries.tar.gz s3://${{ secrets.PROD_ARTIFACTS_BUCKET }}/upgrades/postgres/supabase-postgres-${{ steps.process_release_version.outputs.version }}/20.04.tar.gz + - name: Create release uses: softprops/action-gh-release@v1 with: diff --git a/.github/workflows/publish-nix-pgupgrade-scripts.yml b/.github/workflows/publish-nix-pgupgrade-scripts.yml new file mode 100644 index 000000000..7272da0df --- /dev/null +++ b/.github/workflows/publish-nix-pgupgrade-scripts.yml @@ -0,0 +1,94 @@ +name: Publish pg_upgrade_scripts + +on: + push: + branches: + - develop + - sam/nix-and-conventional-ami + paths: + - '.github/workflows/publish-pgupgrade-scripts.yml' + - 'common-nix.vars.pkr.hcl' + workflow_dispatch: + +permissions: + id-token: write + +jobs: + publish-staging: + runs-on: ubuntu-latest + + steps: + - name: Checkout Repo + uses: actions/checkout@v3 + + - name: Grab release version + id: process_release_version + run: | + VERSION=$(grep 'postgres-version' common-nix.vars.pkr.hcl | sed -e 's/postgres-version = "\(.*\)"/\1/g') + echo "version=$VERSION" >> "$GITHUB_OUTPUT" + + - name: Create a tarball containing pg_upgrade scripts + run: | + mkdir -p /tmp/pg_upgrade_scripts + cp -r ansible/files/admin_api_scripts/pg_upgrade_scripts/* /tmp/pg_upgrade_scripts + tar -czvf /tmp/pg_upgrade_scripts.tar.gz -C /tmp/ pg_upgrade_scripts + + - name: configure aws credentials - staging + uses: aws-actions/configure-aws-credentials@v1 + with: + role-to-assume: ${{ secrets.DEV_AWS_ROLE }} + aws-region: "us-east-1" + + - name: Upload pg_upgrade scripts to s3 staging + run: | + aws s3 cp /tmp/pg_upgrade_scripts.tar.gz s3://${{ secrets.ARTIFACTS_BUCKET }}/upgrades/postgres/supabase-postgres-${{ steps.process_release_version.outputs.version }}/pg_upgrade_scripts.tar.gz + + - name: Slack Notification on Failure + if: ${{ failure() }} + uses: rtCamp/action-slack-notify@v2 + env: + SLACK_WEBHOOK: ${{ secrets.SLACK_NOTIFICATIONS_WEBHOOK }} + SLACK_USERNAME: 'gha-failures-notifier' + SLACK_COLOR: 'danger' + SLACK_MESSAGE: 'Publishing pg_upgrade scripts failed' + SLACK_FOOTER: '' + + publish-prod: + runs-on: ubuntu-latest + if: github.ref_name == 'develop' + + steps: + - name: Checkout Repo + uses: actions/checkout@v3 + + - name: Grab release version + id: process_release_version + run: | + VERSION=$(grep 'postgres-version' common-nix.vars.pkr.hcl | sed -e 's/postgres-version = "\(.*\)"/\1/g') + echo "version=$VERSION" >> "$GITHUB_OUTPUT" + + - name: Create a tarball containing pg_upgrade scripts + run: | + mkdir -p /tmp/pg_upgrade_scripts + cp -r ansible/files/admin_api_scripts/pg_upgrade_scripts/* /tmp/pg_upgrade_scripts + tar -czvf /tmp/pg_upgrade_scripts.tar.gz -C /tmp/ pg_upgrade_scripts + + - name: configure aws credentials - prod + uses: aws-actions/configure-aws-credentials@v1 + with: + role-to-assume: ${{ secrets.PROD_AWS_ROLE }} + aws-region: "us-east-1" + + - name: Upload pg_upgrade scripts to s3 prod + run: | + aws s3 cp /tmp/pg_upgrade_scripts.tar.gz s3://${{ secrets.PROD_ARTIFACTS_BUCKET }}/upgrades/postgres/supabase-postgres-${{ steps.process_release_version.outputs.version }}/pg_upgrade_scripts.tar.gz + + - name: Slack Notification on Failure + if: ${{ failure() }} + uses: rtCamp/action-slack-notify@v2 + env: + SLACK_WEBHOOK: ${{ secrets.SLACK_NOTIFICATIONS_WEBHOOK }} + SLACK_USERNAME: 'gha-failures-notifier' + SLACK_COLOR: 'danger' + SLACK_MESSAGE: 'Publishing pg_upgrade scripts failed' + SLACK_FOOTER: '' From 0c05f2c6d18a0a6373b53d3be38c4d7578babab4 Mon Sep 17 00:00:00 2001 From: Sam Rose Date: Fri, 19 Jul 2024 12:47:02 -0400 Subject: [PATCH 44/45] chore: activate release workflow --- .github/workflows/ami-release-nix.yml | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/.github/workflows/ami-release-nix.yml b/.github/workflows/ami-release-nix.yml index 12c97a68d..d500af738 100644 --- a/.github/workflows/ami-release-nix.yml +++ b/.github/workflows/ami-release-nix.yml @@ -1,11 +1,12 @@ name: Release AMI Nix on: - # push: - # branches: - # - sam/nix-and-conventional-ami - # - '.github/workflows/ami-release-nix.yml' - # - 'common-nix.vars.pkr.hcl' + push: + branches: + - develop + paths: + - '.github/workflows/ami-release-nix.yml' + - 'common-nix.vars.pkr.hcl' workflow_dispatch: jobs: From 055afd8564976c2d2e1e239e632f0949c44157b1 Mon Sep 17 00:00:00 2001 From: Sam Rose Date: Fri, 19 Jul 2024 12:48:08 -0400 Subject: [PATCH 45/45] chore: bump version --- common-nix.vars.pkr.hcl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common-nix.vars.pkr.hcl b/common-nix.vars.pkr.hcl index a7da699b5..f1d6f4089 100644 --- a/common-nix.vars.pkr.hcl +++ b/common-nix.vars.pkr.hcl @@ -1 +1 @@ -postgres-version = "15.6.1.91-nix-staged" +postgres-version = "15.6.1.96-nix-staged"