supabase-postgres.git / summary / log / commit / refs

commit    156a6d77f4bfddfe5efd17abf2883d17ed4d29cd
Author:   Tom Ashley <tom.ashley@gmail.com>
Commit:   GitHub <noreply@github.com>
Date:     Wed Jun 12 10:23:10 2024 +0000

    feat: delegated-init support for Fly projects (#997)
    
    * feat: delegated-init support for Fly projects
    
    * chore: add a salt minion config
    
    * chore: always extract the archive to /
    
    * chore: extract newer archive only based on touch time in GHA
    
    * chore: track salt version in aio, not always latest
    
    * chore: bump image version


common.vars.pkr.hcl | 2 +- docker/all-in-one/Dockerfile | 16 +++++ docker/all-in-one/entrypoint.sh | 127 ++++++++++++++++++++++++++------------ docker/all-in-one/etc/salt/minion | 71 +++++++++++++++++++++ 4 files changed, 174 insertions(+), 42 deletions(-) diff --git a/common.vars.pkr.hcl b/common.vars.pkr.hcl index a298571f..7a23eb91 100644 --- a/common.vars.pkr.hcl +++ b/common.vars.pkr.hcl @@ -1 +1 @@ -postgres-version = "15.1.1.61" +postgres-version = "15.1.1.62" diff --git a/docker/all-in-one/Dockerfile b/docker/all-in-one/Dockerfile index e7e92e6c..b0dbb202 100644 --- a/docker/all-in-one/Dockerfile +++ b/docker/all-in-one/Dockerfile @@ -154,6 +154,22 @@ RUN apt-get update && apt-get install -y --no-install-recommends \ && mkdir -p /dist \ && mkdir -p /data/opt && chmod go+rwx /data/opt +#################### +# Install salt +#################### +ENV DEBIAN_FRONTEND noninteractive +ENV SALT_VERSION 3006 + +# Install one-dir salt +RUN mkdir /etc/apt/keyrings \ + && curl -fsSL -o /etc/apt/keyrings/salt-archive-keyring-2023.gpg https://repo.saltproject.io/salt/py3/ubuntu/20.04/arm64/SALT-PROJECT-GPG-PUBKEY-2023.gpg \ + && echo "deb [signed-by=/etc/apt/keyrings/salt-archive-keyring-2023.gpg arch=arm64] https://repo.saltproject.io/salt/py3/ubuntu/20.04/arm64/$SALT_VERSION focal main" | tee /etc/apt/sources.list.d/salt.list \ + && apt-get clean && apt-get update \ + && apt-get install -y salt-minion + +ADD docker/all-in-one/etc/salt/minion /etc/salt/minion + + # Copy single binary dependencies COPY --from=pgrst /bin/postgrest /dist/ COPY --from=gotrue /usr/local/bin/auth /dist/gotrue diff --git a/docker/all-in-one/entrypoint.sh b/docker/all-in-one/entrypoint.sh index 48311a41..67d46af4 100755 --- a/docker/all-in-one/entrypoint.sh +++ b/docker/all-in-one/entrypoint.sh @@ -1,6 +1,8 @@ #!/bin/bash set -eou pipefail +START_TIME=$(date +%s%N) + PG_CONF=/etc/postgresql/postgresql.conf SUPERVISOR_CONF=/etc/supervisor/supervisord.conf @@ -9,6 +11,16 @@ export CONFIGURED_FLAG_PATH=${CONFIGURED_FLAG_PATH:-$DATA_VOLUME_MOUNTPOINT/mach export MAX_IDLE_TIME_MINUTES=${MAX_IDLE_TIME_MINUTES:-5} +function calculate_duration { + local start_time=$1 + local end_time=$2 + + local duration=$((end_time - start_time)) + local milliseconds=$((duration / 1000000)) + + echo "$milliseconds" +} + # Ref: https://gist.github.com/sj26/88e1c6584397bb7c13bd11108a579746 function retry { # Pass 0 for unlimited retries @@ -53,12 +65,12 @@ function enable_swap { } function push_lsn_checkpoint_file { - if [ "${PLATFORM_DEPLOYMENT:-}" != "true" ]; then - echo "Skipping push of LSN checkpoint file" - return - fi + if [ "${PLATFORM_DEPLOYMENT:-}" != "true" ]; then + echo "Skipping push of LSN checkpoint file" + return + fi - /usr/bin/admin-mgr lsn-checkpoint-push --immediately || echo "Failed to push LSN checkpoint" + /usr/bin/admin-mgr lsn-checkpoint-push --immediately || echo "Failed to push LSN checkpoint" } function graceful_shutdown { @@ -71,46 +83,33 @@ function graceful_shutdown { } function enable_autoshutdown { - sed -i "s/autostart=.*/autostart=true/" /etc/supervisor/base-services/supa-shutdown.conf + sed -i "s/autostart=.*/autostart=true/" /etc/supervisor/base-services/supa-shutdown.conf } function enable_lsn_checkpoint_push { - sed -i "s/autostart=.*/autostart=true/" /etc/supervisor/base-services/lsn-checkpoint-push.conf - sed -i "s/autorestart=.*/autorestart=true/" /etc/supervisor/base-services/lsn-checkpoint-push.conf + sed -i "s/autostart=.*/autostart=true/" /etc/supervisor/base-services/lsn-checkpoint-push.conf + sed -i "s/autorestart=.*/autorestart=true/" /etc/supervisor/base-services/lsn-checkpoint-push.conf } function disable_fail2ban { - sed -i "s/command=.*/command=sleep 5/" /etc/supervisor/services/fail2ban.conf sed -i "s/autostart=.*/autostart=false/" /etc/supervisor/services/fail2ban.conf sed -i "s/autorestart=.*/autorestart=false/" /etc/supervisor/services/fail2ban.conf } -function disable_gotrue { - sed -i "s/command=.*/command=sleep 5/" /etc/supervisor/services/gotrue.conf - sed -i "s/autostart=.*/autostart=false/" /etc/supervisor/services/gotrue.conf - sed -i "s/autorestart=.*/autorestart=false/" /etc/supervisor/services/gotrue.conf -} - -function disable_pgbouncer { - sed -i "s/command=.*/command=sleep 5/" /etc/supervisor/services/pgbouncer.conf - sed -i "s/autostart=.*/autostart=false/" /etc/supervisor/services/pgbouncer.conf - sed -i "s/autorestart=.*/autorestart=false/" /etc/supervisor/services/pgbouncer.conf -} - function setup_postgres { tar -xzvf "$INIT_PAYLOAD_PATH" -C / ./etc/postgresql.schema.sql mv /etc/postgresql.schema.sql /docker-entrypoint-initdb.d/migrations/99-schema.sql tar -xzvf "$INIT_PAYLOAD_PATH" -C / ./etc/postgresql-custom/pgsodium_root.key - echo "include = '/etc/postgresql-custom/postgresql-platform-defaults.conf'" >> $PG_CONF + echo "include = '/etc/postgresql-custom/postgresql-platform-defaults.conf'" >>$PG_CONF # TODO (darora): walg enablement is temporarily performed here until changes from https://github.com/supabase/postgres/pull/639 get picked up # other things will still be needed in the future (auth_delay config) sed -i \ - -e "s|#include = '/etc/postgresql-custom/wal-g.conf'|include = '/etc/postgresql-custom/wal-g.conf'|g" \ - -e "s|shared_preload_libraries = '\(.*\)'|shared_preload_libraries = '\1, auth_delay'|" \ - -e "/# Automatically generated optimizations/i auth_delay.milliseconds = '3000'" \ - "${PG_CONF}" + -e "s|#include = '/etc/postgresql-custom/wal-g.conf'|include = '/etc/postgresql-custom/wal-g.conf'|g" \ + -e "s|shared_preload_libraries = '\(.*\)'|shared_preload_libraries = '\1, auth_delay'|" \ + -e "/# Automatically generated optimizations/i auth_delay.milliseconds = '3000'" \ + "${PG_CONF}" # Setup ssl certs mkdir -p /etc/ssl/certs/postgres @@ -169,6 +168,8 @@ function setup_postgres { chmod g+rx "/etc/wal-g" chmod g+rx "${WALG_CONF_DIR}" fi + DURATION=$(calculate_duration "$START_TIME" "$(date +%s%N)") + echo "E: Execution time to setting up postgresql: $DURATION milliseconds" } function setup_credentials { @@ -178,6 +179,8 @@ function setup_credentials { export SERVICE_ROLE_KEY=${SERVICE_ROLE_KEY:-$(jq -r '.["service_key"]' /tmp/init.json)} export ADMIN_API_KEY=${ADMIN_API_KEY:-$(jq -r '.["supabase_admin_key"]' /tmp/init.json)} export JWT_SECRET=${JWT_SECRET:-$(jq -r '.["jwt_secret"]' /tmp/init.json)} + DURATION=$(calculate_duration "$START_TIME" "$(date +%s%N)") + echo "E: Execution time to setting up credentials: $DURATION milliseconds" } function report_health { @@ -193,9 +196,9 @@ function report_health { } function run_prelaunch_hooks { - if [ -f "/etc/postgresql-custom/supautils.conf" ]; then - sed -i -e 's/dblink, //' "/etc/postgresql-custom/supautils.conf" - fi + if [ -f "/etc/postgresql-custom/supautils.conf" ]; then + sed -i -e 's/dblink, //' "/etc/postgresql-custom/supautils.conf" + fi } function start_supervisor { @@ -206,19 +209,57 @@ function start_supervisor { /usr/bin/supervisord -c $SUPERVISOR_CONF } +DELEGATED_ARCHIVE_PATH=/data/delegated-init.tar.gz +DELEGATED_ENTRY_PATH=/data/delegated-entry.sh + +function fetch_and_execute_delegated_payload { + curl -s --time-cond $DELEGATED_ARCHIVE_PATH -o $DELEGATED_ARCHIVE_PATH "$DELEGATED_INIT_LOCATION" + + if [ ! -f $DELEGATED_ARCHIVE_PATH ]; then + echo "No delegated payload found, bailing" + return + fi + + # only extract a valid archive + if tar -tzf "$DELEGATED_ARCHIVE_PATH" &>/dev/null; then + TAR_MTIME_EPOCH=$(tar -tvzf "$DELEGATED_ARCHIVE_PATH" data/delegated-entry.sh | awk '{print $4, $5}' | xargs -I {} date -d {} +%s) + + if [ -f $DELEGATED_ENTRY_PATH ]; then + FILE_MTIME_EPOCH=$(stat -c %Y "$DELEGATED_ENTRY_PATH") + + if [ "$TAR_MTIME_EPOCH" -gt "$FILE_MTIME_EPOCH" ]; then + tar -xvzf "$DELEGATED_ARCHIVE_PATH" -C / + else + echo "TAR archive is not newer, skipping extraction" + fi + else + tar -xvzf "$DELEGATED_ARCHIVE_PATH" -C / + fi + else + echo "Invalid TAR archive" + return + fi + + # Run our delegated entry script here + if [ -f "$DELEGATED_ENTRY_PATH" ]; then + chmod +x $DELEGATED_ENTRY_PATH + bash -c "$DELEGATED_ENTRY_PATH $START_TIME" + fi +} + # Increase max number of open connections ulimit -n 65536 # Update pgsodium root key if [ "${PGSODIUM_ROOT_KEY:-}" ]; then - echo "${PGSODIUM_ROOT_KEY}" > /etc/postgresql-custom/pgsodium_root.key + echo "${PGSODIUM_ROOT_KEY}" >/etc/postgresql-custom/pgsodium_root.key fi # Update pgdata directory if [ "${PGDATA_REAL:-}" ]; then - mkdir -p "${PGDATA_REAL}" - chown -R postgres:postgres "${PGDATA_REAL}" - chmod -R g+rx "${PGDATA_REAL}" + mkdir -p "${PGDATA_REAL}" + chown -R postgres:postgres "${PGDATA_REAL}" + chmod -R g+rx "${PGDATA_REAL}" fi if [ "${PGDATA:-}" ]; then @@ -239,7 +280,7 @@ export INIT_PAYLOAD_PATH=${INIT_PAYLOAD_PATH:-/tmp/payload.tar.gz} if [ "${INIT_PAYLOAD_PRESIGNED_URL:-}" ]; then curl -fsSL "$INIT_PAYLOAD_PRESIGNED_URL" -o "/tmp/payload.tar.gz" || true - if [ -f "/tmp/payload.tar.gz" ] && [ "/tmp/payload.tar.gz" != "$INIT_PAYLOAD_PATH" ] ; then + if [ -f "/tmp/payload.tar.gz" ] && [ "/tmp/payload.tar.gz" != "$INIT_PAYLOAD_PATH" ]; then mv "/tmp/payload.tar.gz" "$INIT_PAYLOAD_PATH" fi fi @@ -298,11 +339,8 @@ if [ "${FAIL2BAN_DISABLED:-}" == "true" ]; then fi if [ "${GOTRUE_DISABLED:-}" == "true" ]; then - disable_gotrue -fi - -if [ "${PGBOUNCER_DISABLED:-}" == "true" ]; then - disable_pgbouncer + sed -i "s/autostart=.*/autostart=false/" /etc/supervisor/services/gotrue.conf + sed -i "s/autorestart=.*/autorestart=false/" /etc/supervisor/services/gotrue.conf fi if [ "${PLATFORM_DEPLOYMENT:-}" == "true" ]; then @@ -316,5 +354,12 @@ fi touch "$CONFIGURED_FLAG_PATH" run_prelaunch_hooks -start_supervisor -push_lsn_checkpoint_file + +if [ -n "${DELEGATED_INIT_LOCATION:-}" ]; then + fetch_and_execute_delegated_payload +else + DURATION=$(calculate_duration "$START_TIME" "$(date +%s%N)") + echo "E: Execution time to starting supervisor: $DURATION milliseconds" + start_supervisor + push_lsn_checkpoint_file +fi diff --git a/docker/all-in-one/etc/salt/minion b/docker/all-in-one/etc/salt/minion new file mode 100644 index 00000000..1dbdd31a --- /dev/null +++ b/docker/all-in-one/etc/salt/minion @@ -0,0 +1,71 @@ +# Minions can connect to multiple masters simultaneously (all masters +# are "hot"), or can be configured to failover if a master becomes +# unavailable. Multiple hot masters are configured by setting this +# value to "str". Failover masters can be requested by setting +# to "failover". MAKE SURE TO SET master_alive_interval if you are +# using failover. +# Setting master_type to 'disable' lets you have a running minion (with engines and +# beacons) without a master connection +master_type: disable + +# The minion can locally cache the return data from jobs sent to it, this +# can be a good way to keep track of jobs the minion has executed +# (on the minion side). By default this feature is disabled, to enable, set +# cache_jobs to True. +cache_jobs: True + +# The minion can take a while to start up when lspci and/or dmidecode is used +# to populate the grains for the minion. Set this to False if you do not need +# GPU hardware grains for your minion. +enable_gpu_grains: False + +# Backup files that are replaced by file.managed and file.recurse under +# 'cachedir'/file_backup relative to their original location and appended +# with a timestamp. The only valid setting is "minion". Disabled by default. +# +# Alternatively this can be specified for each file in state files: +# /etc/ssh/sshd_config: +# file.managed: +# - source: salt://ssh/sshd_config +# - backup: minion +# +backup_mode: minion + +##### File Directory Settings ##### +########################################## +# The Salt Minion can redirect all file server operations to a local directory, +# this allows for the same state tree that is on the master to be used if +# copied completely onto the minion. This is a literal copy of the settings on +# the master but used to reference a local directory on the minion. + +# Set the file client. The client defaults to looking on the master server for +# files, but can be directed to look at the local file directory setting +# defined below by setting it to "local". Setting a local file_client runs the +# minion in masterless mode. +file_client: local + +# The file directory works on environments passed to the minion, each environment +# can have multiple root directories, the subdirectories in the multiple file +# roots cannot match, otherwise the downloaded files will not be able to be +# reliably ensured. A base environment is required to house the top file. +# Example: +# file_roots: +# base: +# - /srv/salt/ +# dev: +# - /srv/salt/dev/services +# - /srv/salt/dev/states +# prod: +# - /srv/salt/prod/services +# - /srv/salt/prod/states +# +file_roots: + base: + - /opt/salt/state + +# The Salt pillar is searched for locally if file_client is set to local. If +# this is the case, and pillar data is defined, then the pillar_roots need to +# also be configured on the minion: +pillar_roots: + base: + - /opt/salt/pillar [parent: 438a454e1ecd]