From fbce703c0a489913a5b1bd6117b39a3a7a43f65e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A1rton=20Boros?= Date: Fri, 16 Oct 2026 15:03:59 +0300 Subject: [PATCH 01/12] refactor(ami): share provisioning steps between qemu and ami builds Move the Nix install, playbook run, Nix GC and report steps that qemu-bootstrap-nix.sh and nix-provision.sh duplicated into provision-common.sh. Both Packer builds upload it to /tmp. Refs: MPG-1383 Co-Authored-By: Claude Sonnet 5.5 --- ebssurrogate/scripts/nix-provision.sh | 65 ++----------------- ebssurrogate/scripts/provision-common.sh | 71 ++++++++++++++++++++ ebssurrogate/scripts/qemu-bootstrap-nix.sh | 75 ++-------------------- qemu.pkr.hcl | 5 ++ stage2-nix-psql.pkr.hcl | 5 ++ 5 files changed, 91 insertions(+), 130 deletions(-) create mode 100644 ebssurrogate/scripts/provision-common.sh diff --git a/ebssurrogate/scripts/nix-provision.sh b/ebssurrogate/scripts/nix-provision.sh index e8470fc635..17b24ecff9 100755 --- a/ebssurrogate/scripts/nix-provision.sh +++ b/ebssurrogate/scripts/nix-provision.sh @@ -5,94 +5,39 @@ set -o errexit set -o pipefail set -o xtrace +# shellcheck source=/dev/null +source /tmp/provision-common.sh + exec 1>&2 function setup_apt { export DEBIAN_FRONTEND=noninteractive } -function cleanup_apt { - apt-get clean - apt-get autoremove --purge --yes - rm -rf /var/lib/apt/lists/* -} - -function update_and_upgrade_apt { - apt-get update --yes - apt-get dist-upgrade --yes -} - function install_packages { apt-get install -y ansible ansible-galaxy collection install community.general } -function install_nix() { - curl -L https://releases.nixos.org/nix/nix-2.34.6/install | sh -s -- --yes --daemon --nix-extra-conf-file <( - cat <<-EOF - extra-experimental-features = nix-command flakes - extra-substituters = https://nix-postgres-artifacts.s3.amazonaws.com - extra-trusted-public-keys = nix-postgres-artifacts:dGZlQOvKcNEjvT7QEAJbcV6b6uk7VF/hWMjhYleiaLI= - EOF - ) - - #shellcheck disable=SC1091 - . /nix/var/nix/profiles/default/etc/profile.d/nix-daemon.sh - nix --version -} - function execute_stage2_playbook { echo "POSTGRES_MAJOR_VERSION: $POSTGRES_MAJOR_VERSION" echo "GIT_SHA: $GIT_SHA" - mkdir -p /etc/ansible - tee /etc/ansible/ansible.cfg <<-EOF - [defaults] - callbacks_enabled = timer, profile_tasks, profile_roles - EOF - sed -i 's/- hosts: all/- hosts: localhost/' /tmp/ansible-playbook/ansible/playbook.yml - - # Run Ansible playbook - export ANSIBLE_LOG_PATH=/tmp/ansible.log - export ANSIBLE_REMOTE_TEMP=/tmp # shellcheck disable=SC2086 - ansible-playbook /tmp/ansible-playbook/ansible/playbook.yml \ - --extra-vars '{"stage2":true, "qemu":false}' \ - --extra-vars "git_commit_sha=$GIT_SHA" \ - --extra-vars "psql_version=psql_$POSTGRES_MAJOR_VERSION" \ - --extra-vars "postgresql_version=postgresql_$POSTGRES_MAJOR_VERSION" \ - --extra-vars "postgresql_major_version=$POSTGRES_MAJOR_VERSION" \ - $ARGS + run_playbook /tmp/ansible-playbook/ansible/playbook.yml /tmp true false $ARGS } function cleanup_packages { apt-get remove --purge --yes ansible } -function cleanup_nix { - nix-collect-garbage -d - nix-store --optimise -v -} - -function report_packages { - # shellcheck disable=SC2016 - dpkg-query -W -f='${Package}\t${Version}\t${Architecture}\n' | LC_COLLATE=C.UTF-8 sort - find /nix/store -maxdepth 1 | LC_COLLATE=C.UTF-8 sort -t- -k2 -} - -function report_disk_usage { - read -r dub _ < <(du -sx -B1 /) - read -r duh _ < <(du -sx -h /) - printf '::notice::disk_usage bytes=%s human=%s\n' "$dub" "$duh" | tee -a /tmp/ansible.log -} - setup_apt update_and_upgrade_apt install_packages install_nix execute_stage2_playbook cleanup_packages -cleanup_nix +clean_nix update_and_upgrade_apt cleanup_apt report_packages diff --git a/ebssurrogate/scripts/provision-common.sh b/ebssurrogate/scripts/provision-common.sh new file mode 100644 index 0000000000..bc46b0aecf --- /dev/null +++ b/ebssurrogate/scripts/provision-common.sh @@ -0,0 +1,71 @@ +# shellcheck shell=bash + +function update_and_upgrade_apt { + apt-get update --yes + apt-get dist-upgrade --yes +} + +function cleanup_apt { + apt-get clean + apt-get autoremove --purge --yes + rm -rf /var/lib/apt/lists/* +} + +function install_nix() { + curl -L https://releases.nixos.org/nix/nix-2.34.6/install | sh -s -- --yes --daemon --nix-extra-conf-file <( + cat <<-EOF + extra-experimental-features = nix-command flakes + extra-substituters = https://nix-postgres-artifacts.s3.amazonaws.com + extra-trusted-public-keys = nix-postgres-artifacts:dGZlQOvKcNEjvT7QEAJbcV6b6uk7VF/hWMjhYleiaLI= + EOF + ) + + # shellcheck disable=SC1091 + . /nix/var/nix/profiles/default/etc/profile.d/nix-daemon.sh + nix --version +} + +function run_playbook { + local playbook=$1 remote_tmp=$2 stage2=$3 qemu=$4 + shift 4 + + local sha_args=() + if [[ $stage2 == true ]]; then + sha_args=(--extra-vars "git_commit_sha=$GIT_SHA") + fi + + mkdir -p /etc/ansible + tee /etc/ansible/ansible.cfg <<-EOF + [defaults] + callbacks_enabled = timer, profile_tasks, profile_roles + EOF + sed -i 's/- hosts: all/- hosts: localhost/' "$playbook" + + export ANSIBLE_LOG_PATH=/tmp/ansible.log + export ANSIBLE_REMOTE_TEMP=$remote_tmp + + ansible-playbook "$playbook" \ + --extra-vars "{\"stage2\":$stage2,\"qemu\":$qemu}" \ + "${sha_args[@]}" \ + --extra-vars "psql_version=psql_$POSTGRES_MAJOR_VERSION" \ + --extra-vars "postgresql_version=postgresql_$POSTGRES_MAJOR_VERSION" \ + --extra-vars "postgresql_major_version=$POSTGRES_MAJOR_VERSION" \ + "$@" +} + +function clean_nix { + nix-collect-garbage -d + nix-store --optimise -v +} + +function report_packages { + # shellcheck disable=SC2016 + dpkg-query -W -f='${Package}\t${Version}\t${Architecture}\n' | LC_COLLATE=C.UTF-8 sort + find /nix/store -maxdepth 1 | LC_COLLATE=C.UTF-8 sort -t- -k2 +} + +function report_disk_usage { + read -r dub _ < <(du -sx -B1 /) + read -r duh _ < <(du -sx -h /) + printf '::notice::disk_usage bytes=%s human=%s\n' "$dub" "$duh" | tee -a /tmp/ansible.log +} diff --git a/ebssurrogate/scripts/qemu-bootstrap-nix.sh b/ebssurrogate/scripts/qemu-bootstrap-nix.sh index c064454b0d..a645e8e1ec 100755 --- a/ebssurrogate/scripts/qemu-bootstrap-nix.sh +++ b/ebssurrogate/scripts/qemu-bootstrap-nix.sh @@ -4,6 +4,9 @@ set -o errexit set -o pipefail set -o xtrace +# shellcheck source=/dev/null +source /tmp/provision-common.sh + ################# # stage1 things # ################# @@ -42,17 +45,6 @@ function setup_apt { sed -i "s|$defmirror|& $ubumirror|" /etc/apt/sources.list.d/ubuntu.sources } -function cleanup_apt { - apt-get clean - apt-get autoremove --purge --yes - rm -rf /var/lib/apt/lists/* -} - -function update_and_upgrade_apt { - apt-get update --yes - apt-get dist-upgrade --yes -} - function waitfor_boot_finished { # Wait for cloudinit on the surrogate to complete before making progress while [[ ! -f /var/lib/cloud/instance/boot-finished ]]; do @@ -81,21 +73,8 @@ function install_packages { } function execute_playbook { - sed -i 's/- hosts: all/- hosts: localhost/' ansible/playbook.yml - - mkdir -p /etc/ansible - tee /etc/ansible/ansible.cfg <<-EOF - [defaults] - callbacks_enabled = timer, profile_tasks, profile_roles - EOF - - # Run Ansible playbook - export ANSIBLE_LOG_PATH=/tmp/ansible.log && export ANSIBLE_REMOTE_TEMP=/mnt/tmp - ansible-playbook ./ansible/playbook.yml --extra-vars '{"stage2": false, "qemu": true}' \ - --extra-vars "postgresql_version=postgresql_$POSTGRES_MAJOR_VERSION" \ - --extra-vars "postgresql_major_version=$POSTGRES_MAJOR_VERSION" \ + run_playbook ./ansible/playbook.yml /mnt/tmp false true \ --extra-vars "postgresql_major=$POSTGRES_MAJOR_VERSION" \ - --extra-vars "psql_version=psql_$POSTGRES_MAJOR_VERSION" \ --extra-vars @./ansible/qemu-vars.yaml } @@ -129,36 +108,9 @@ function setup_locale { # stage2 things # ################# -function install_nix() { - curl -L https://releases.nixos.org/nix/nix-2.34.6/install | sh -s -- --yes --daemon --nix-extra-conf-file <( - cat <<-EOF - extra-experimental-features = nix-command flakes - extra-substituters = https://nix-postgres-artifacts.s3.amazonaws.com - extra-trusted-public-keys = nix-postgres-artifacts:dGZlQOvKcNEjvT7QEAJbcV6b6uk7VF/hWMjhYleiaLI= - EOF - ) - - # shellcheck disable=SC1091 - . /nix/var/nix/profiles/default/etc/profile.d/nix-daemon.sh - nix --version -} - function execute_stage2_playbook { - mkdir -p /etc/ansible - tee /etc/ansible/ansible.cfg <<-EOF - [defaults] - callbacks_enabled = timer, profile_tasks, profile_roles - EOF - - # Run Ansible playbook - export ANSIBLE_LOG_PATH=/tmp/ansible.log && export ANSIBLE_REMOTE_TEMP=/tmp - ansible-playbook ./ansible/playbook.yml \ - --extra-vars '{"stage2": true, "qemu": true}' \ - --extra-vars "git_commit_sha=$GIT_SHA" \ - --extra-vars "postgresql_version=postgresql_$POSTGRES_MAJOR_VERSION" \ - --extra-vars "postgresql_major_version=$POSTGRES_MAJOR_VERSION" \ + run_playbook ./ansible/playbook.yml /tmp true true \ --extra-vars "postgresql_major=$POSTGRES_MAJOR_VERSION" \ - --extra-vars "psql_version=psql_$POSTGRES_MAJOR_VERSION" \ --extra-vars @./ansible/qemu-vars.yaml } @@ -227,23 +179,6 @@ function clean_system { fi } -function clean_nix { - nix-collect-garbage -d - nix-store --optimise -v -} - -function report_packages { - # shellcheck disable=SC2016 - dpkg-query -W -f='${Package}\t${Version}\t${Architecture}\n' | LC_COLLATE=C.UTF-8 sort - find /nix/store -maxdepth 1 | LC_COLLATE=C.UTF-8 sort -t- -k2 -} - -function report_disk_usage { - read -r dub _ < <(du -sx -B1 /) - read -r duh _ < <(du -sx -h /) - printf '::notice::disk_usage bytes=%s human=%s\n' "$dub" "$duh" | tee -a /tmp/ansible.log -} - ################# # stage1 things # ################# diff --git a/qemu.pkr.hcl b/qemu.pkr.hcl index ab854240f0..feb1232cde 100644 --- a/qemu.pkr.hcl +++ b/qemu.pkr.hcl @@ -106,6 +106,11 @@ build { destination = "/tmp/cleanup-qemu.sh" } + provisioner "file" { + source = "ebssurrogate/scripts/provision-common.sh" + destination = "/tmp/provision-common.sh" + } + provisioner "shell" { environment_vars = [ "GIT_SHA=${var.git_sha}", diff --git a/stage2-nix-psql.pkr.hcl b/stage2-nix-psql.pkr.hcl index 7278ccd2bf..0a8590bb8e 100644 --- a/stage2-nix-psql.pkr.hcl +++ b/stage2-nix-psql.pkr.hcl @@ -137,6 +137,11 @@ build { destination = "/tmp/ansible-playbook" } + provisioner "file" { + source = "ebssurrogate/scripts/provision-common.sh" + destination = "/tmp/provision-common.sh" + } + provisioner "shell" { environment_vars = [ "GIT_SHA=${var.git_sha}", From b1d068bb777d33a65c6d51739941afcf843349f7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A1rton=20Boros?= Date: Fri, 16 Oct 2026 15:26:19 +0300 Subject: [PATCH 02/12] refactor(ami): share stage 1 and cleanup steps between builds Move locale, postgres env, sshd password auth and the image cleanup tail into provision-common.sh. The AMI chroot scripts get the library copied into /mnt/tmp. Refs: MPG-1383 Co-Authored-By: Claude Sonnet 5.5 --- amazon-amd64-nix.pkr.hcl | 5 ++ amazon-arm64-nix.pkr.hcl | 5 ++ ebssurrogate/scripts/chroot-bootstrap-nix.sh | 35 +-------- ebssurrogate/scripts/cleanup-qemu.sh | 34 +++------ ebssurrogate/scripts/cleanup.sh | 33 +++------ ebssurrogate/scripts/provision-common.sh | 71 +++++++++++++++++++ ebssurrogate/scripts/qemu-bootstrap-nix.sh | 31 +------- .../scripts/surrogate-bootstrap-nix.sh | 2 + 8 files changed, 103 insertions(+), 113 deletions(-) diff --git a/amazon-amd64-nix.pkr.hcl b/amazon-amd64-nix.pkr.hcl index 9d2d2fd2eb..a3e4cf014a 100644 --- a/amazon-amd64-nix.pkr.hcl +++ b/amazon-amd64-nix.pkr.hcl @@ -188,6 +188,11 @@ build { destination = "/tmp/70-ec2-nvme-devices.rules" } + provisioner "file" { + source = "ebssurrogate/scripts/provision-common.sh" + destination = "/tmp/provision-common.sh" + } + provisioner "file" { source = "ebssurrogate/scripts/chroot-bootstrap-nix.sh" destination = "/tmp/chroot-bootstrap-nix.sh" diff --git a/amazon-arm64-nix.pkr.hcl b/amazon-arm64-nix.pkr.hcl index 74fc2755a8..03d98a44ba 100644 --- a/amazon-arm64-nix.pkr.hcl +++ b/amazon-arm64-nix.pkr.hcl @@ -188,6 +188,11 @@ build { destination = "/tmp/70-ec2-nvme-devices.rules" } + provisioner "file" { + source = "ebssurrogate/scripts/provision-common.sh" + destination = "/tmp/provision-common.sh" + } + provisioner "file" { source = "ebssurrogate/scripts/chroot-bootstrap-nix.sh" destination = "/tmp/chroot-bootstrap-nix.sh" diff --git a/ebssurrogate/scripts/chroot-bootstrap-nix.sh b/ebssurrogate/scripts/chroot-bootstrap-nix.sh index 1c0e2cfa2d..cd696aade2 100755 --- a/ebssurrogate/scripts/chroot-bootstrap-nix.sh +++ b/ebssurrogate/scripts/chroot-bootstrap-nix.sh @@ -8,6 +8,9 @@ set -o errexit set -o pipefail set -o xtrace +# shellcheck source=/dev/null +source /tmp/provision-common.sh + function setup_apt { export DEBIAN_FRONTEND=noninteractive } @@ -92,31 +95,6 @@ function install_initial_packages { fi } -function setup_locale { - cat >>/etc/locale.gen <<-EOF - en_US.UTF-8 UTF-8 - EOF - cat >/etc/default/locale <<-EOF - 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 - mkdir -p /etc/environment.d - - # Define the contents of the PostgreSQL environment file - tee /etc/environment.d/postgresql.env >/dev/null <<-EOF - 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 setup_apparmor { # Copy apparmor profiles cp -rv /tmp/apparmor_profiles/* /etc/apparmor.d/ @@ -179,13 +157,6 @@ function setup_eth0_interface { chmod 600 /etc/netplan/eth0.yaml } -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 } diff --git a/ebssurrogate/scripts/cleanup-qemu.sh b/ebssurrogate/scripts/cleanup-qemu.sh index 9c79a981cd..512c98c3cc 100755 --- a/ebssurrogate/scripts/cleanup-qemu.sh +++ b/ebssurrogate/scripts/cleanup-qemu.sh @@ -6,13 +6,13 @@ set -ex +# shellcheck source=/dev/null +source /tmp/provision-common.sh + # Ensure /tmp exists and has the proper permissions before # checking for security updates # https://github.com/digitalocean/marketplace-partners/issues/94 -if [[ ! -d /tmp ]]; then - mkdir /tmp -fi -chmod 1777 /tmp +ensure_tmp_dir # Cleanup more packages packages=( @@ -117,31 +117,13 @@ systemctl disable getty@tty1.service systemctl mask getty@tty1.service systemctl mask graphical.target -rm -rf /tmp/* /var/tmp/* -history -c -cat /dev/null >/root/.bash_history -unset HISTFILE +scrub_history journalctl --rotate journalctl --vacuum-time=1s -find /var/log -mtime -1 -type f -exec truncate -s 0 {} \; -rm -rf /var/log/*.gz /var/log/*.[0-9] /var/log/*-???????? -rm -rf /var/lib/cloud/instances/* -rm -f /root/.ssh/authorized_keys /etc/ssh/*key* -touch /etc/ssh/revoked_keys -chmod 600 /etc/ssh/revoked_keys - -cat /dev/null >/var/log/lastlog -cat /dev/null >/var/log/wtmp +scrub_logs_and_keys -dd if=/dev/zero of=/zerofile & -PID=$! -while [ -d /proc/$PID ]; do - printf "." - sleep 5 -done -sync -rm /zerofile -sync +zero_free_space +empty_login_records fstrim / diff --git a/ebssurrogate/scripts/cleanup.sh b/ebssurrogate/scripts/cleanup.sh index f9a103fb02..6e33b5f507 100755 --- a/ebssurrogate/scripts/cleanup.sh +++ b/ebssurrogate/scripts/cleanup.sh @@ -6,13 +6,13 @@ set -ex +# shellcheck source=/dev/null +source /tmp/provision-common.sh + # Ensure /tmp exists and has the proper permissions before # checking for security updates # https://github.com/digitalocean/marketplace-partners/issues/94 -if [[ ! -d /tmp ]]; then - mkdir /tmp -fi -chmod 1777 /tmp +ensure_tmp_dir # Cleanup more packages packages=( @@ -39,16 +39,8 @@ apt-get --yes autoclean apt-get --yes update apt-get --yes upgrade -rm -rf /tmp/* /var/tmp/* -history -c -cat /dev/null >/root/.bash_history -unset HISTFILE -find /var/log -mtime -1 -type f -exec truncate -s 0 {} \; -rm -rf /var/log/*.gz /var/log/*.[0-9] /var/log/*-???????? -rm -rf /var/lib/cloud/instances/* -rm -f /root/.ssh/authorized_keys /etc/ssh/*key* -touch /etc/ssh/revoked_keys -chmod 600 /etc/ssh/revoked_keys +scrub_history +scrub_logs_and_keys # Securely erase the unused portion of the filesystem cat <<-EOF @@ -59,14 +51,5 @@ cat <<-EOF Beginning secure erase now EOF -dd if=/dev/zero of=/zerofile & -PID=$! -while [ -d /proc/$PID ]; do - printf "." - sleep 5 -done -sync -rm /zerofile -sync -cat /dev/null >/var/log/lastlog -cat /dev/null >/var/log/wtmp +zero_free_space +empty_login_records diff --git a/ebssurrogate/scripts/provision-common.sh b/ebssurrogate/scripts/provision-common.sh index bc46b0aecf..190e4106a6 100644 --- a/ebssurrogate/scripts/provision-common.sh +++ b/ebssurrogate/scripts/provision-common.sh @@ -69,3 +69,74 @@ function report_disk_usage { read -r duh _ < <(du -sx -h /) printf '::notice::disk_usage bytes=%s human=%s\n' "$dub" "$duh" | tee -a /tmp/ansible.log } + +function setup_locale { + cat >>/etc/locale.gen <<-EOF + en_US.UTF-8 UTF-8 + EOF + cat >/etc/default/locale <<-EOF + LANG="C.UTF-8" + LC_CTYPE="C.UTF-8" + EOF + locale-gen en_US.UTF-8 +} + +function setup_postgesql_env { + mkdir -p /etc/environment.d + + tee /etc/environment.d/postgresql.env >/dev/null <<-EOF + 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 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 ensure_tmp_dir { + # https://github.com/digitalocean/marketplace-partners/issues/94 + if [[ ! -d /tmp ]]; then + mkdir /tmp + fi + chmod 1777 /tmp +} + +function scrub_history { + rm -rf /tmp/* /var/tmp/* + history -c + cat /dev/null >/root/.bash_history + unset HISTFILE +} + +function scrub_logs_and_keys { + find /var/log -mtime -1 -type f -exec truncate -s 0 {} \; + rm -rf /var/log/*.gz /var/log/*.[0-9] /var/log/*-???????? + rm -rf /var/lib/cloud/instances/* + rm -f /root/.ssh/authorized_keys /etc/ssh/*key* + touch /etc/ssh/revoked_keys + chmod 600 /etc/ssh/revoked_keys +} + +function zero_free_space { + dd if=/dev/zero of=/zerofile & + PID=$! + while [ -d /proc/$PID ]; do + printf "." + sleep 5 + done + sync + rm /zerofile + sync +} + +function empty_login_records { + cat /dev/null >/var/log/lastlog + cat /dev/null >/var/log/wtmp +} diff --git a/ebssurrogate/scripts/qemu-bootstrap-nix.sh b/ebssurrogate/scripts/qemu-bootstrap-nix.sh index a645e8e1ec..4c19ba11f1 100755 --- a/ebssurrogate/scripts/qemu-bootstrap-nix.sh +++ b/ebssurrogate/scripts/qemu-bootstrap-nix.sh @@ -78,32 +78,6 @@ function execute_playbook { --extra-vars @./ansible/qemu-vars.yaml } -function setup_postgesql_env { - # Create the directory if it doesn't exist - mkdir -p /etc/environment.d - - # Define the contents of the PostgreSQL environment file - tee /etc/environment.d/postgresql.env >/dev/null <<-EOF - 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 setup_locale { - cat >>/etc/locale.gen <<-EOF - en_US.UTF-8 UTF-8 - EOF - - cat >/etc/default/locale <<-EOF - LANG="C.UTF-8" - LC_CTYPE="C.UTF-8" - EOF - locale-gen en_US.UTF-8 -} - ################# # stage2 things # ################# @@ -168,10 +142,7 @@ function clean_system { # Ensure that PasswordAuthentication is off # From chroot-boostrap-nix.sh - 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 + disable_sshd_passwd_auth if ! grep -qE "^PasswordAuthentication\s+no" /etc/ssh/sshd_config; then echo "ERROR: PasswordAuthentication is not disabled in sshd_config" diff --git a/ebssurrogate/scripts/surrogate-bootstrap-nix.sh b/ebssurrogate/scripts/surrogate-bootstrap-nix.sh index 2f43a5a458..6717540c48 100755 --- a/ebssurrogate/scripts/surrogate-bootstrap-nix.sh +++ b/ebssurrogate/scripts/surrogate-bootstrap-nix.sh @@ -207,6 +207,7 @@ function setup_chroot_environment { cp -r /tmp/migrations /mnt/tmp/ # Copy the bootstrap script into place and execute inside chroot + cp /tmp/provision-common.sh /mnt/tmp/provision-common.sh 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 @@ -270,6 +271,7 @@ function update_systemd_services { function clean_system { # Copy cleanup scripts + cp -v /tmp/provision-common.sh /mnt/tmp cp -v /tmp/cleanup.sh /mnt/tmp chmod +x /mnt/tmp/cleanup.sh chroot /mnt /tmp/cleanup.sh From 760221396663158b8f4d86edb60451486c5b2cc6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A1rton=20Boros?= Date: Fri, 16 Oct 2026 15:29:44 +0300 Subject: [PATCH 03/12] fix(ami): set vector-readable wal-g log modes on the ami Share the image log setup between both builds. The AMI now ships /var/log/wal-g as 0310 and pitr.log as 0340, matching QEMU and the salt vector formula, so vector can read pitr.log without salt. Refs: MPG-1383 Co-Authored-By: Claude Sonnet 5.5 --- ebssurrogate/scripts/provision-common.sh | 29 +++++++++++++++++ ebssurrogate/scripts/qemu-bootstrap-nix.sh | 26 +--------------- .../scripts/surrogate-bootstrap-nix.sh | 31 +------------------ 3 files changed, 31 insertions(+), 55 deletions(-) diff --git a/ebssurrogate/scripts/provision-common.sh b/ebssurrogate/scripts/provision-common.sh index 190e4106a6..a204b63587 100644 --- a/ebssurrogate/scripts/provision-common.sh +++ b/ebssurrogate/scripts/provision-common.sh @@ -140,3 +140,32 @@ function empty_login_records { cat /dev/null >/var/log/lastlog cat /dev/null >/var/log/wtmp } + +function setup_image_logs { + local root=${1:-} run=() + if [[ -n $root ]]; then + run=(chroot "$root") + fi + + rm -rf "$root"/var/log/* + # https://github.com/fail2ban/fail2ban/issues/1593 + touch "$root/var/log/auth.log" + + touch "$root/var/log/pgbouncer.log" + "${run[@]}" chown pgbouncer:postgres /var/log/pgbouncer.log + + mkdir -p "$root/var/log/postgresql" + "${run[@]}" chown postgres:postgres /var/log/postgresql + + mkdir "$root/var/log/wal-g" + touch "$root"/var/log/wal-g/{backup-push.log,backup-fetch.log,wal-push.log,wal-fetch.log,pitr.log} + + mkdir "$root/var/log/sysstat" + + "${run[@]}" chown -R postgres:postgres /var/log/wal-g + # vector reads pitr.log; modes match the salt vector formula + "${run[@]}" chmod -R 0310 /var/log/wal-g + "${run[@]}" chmod 0340 /var/log/wal-g/pitr.log + + mkdir "$root/var/log/audit" +} diff --git a/ebssurrogate/scripts/qemu-bootstrap-nix.sh b/ebssurrogate/scripts/qemu-bootstrap-nix.sh index 4c19ba11f1..f378d04f8e 100755 --- a/ebssurrogate/scripts/qemu-bootstrap-nix.sh +++ b/ebssurrogate/scripts/qemu-bootstrap-nix.sh @@ -104,31 +104,7 @@ function clean_system { chmod +x /tmp/cleanup-qemu.sh /tmp/cleanup-qemu.sh - # Cleanup logs - rm -rf /var/log/* - # https://github.com/fail2ban/fail2ban/issues/1593 - touch /var/log/auth.log - - touch /var/log/pgbouncer.log - chown pgbouncer:postgres /var/log/pgbouncer.log - - # Setup postgresql logs - mkdir -p /var/log/postgresql - chown postgres:postgres /var/log/postgresql - # Setup wal-g logs - mkdir /var/log/wal-g - touch /var/log/wal-g/{backup-push.log,backup-fetch.log,wal-push.log,wal-fetch.log,pitr.log} - - # Creatre Sysstat directory for SAR - mkdir /var/log/sysstat - - chown -R postgres:postgres /var/log/wal-g - # moving up fixes from init scripts - chmod -R 0310 /var/log/wal-g - chmod 0340 /var/log/wal-g/pitr.log - - # audit logs directory for apparmor - mkdir /var/log/audit + setup_image_logs # unwanted files rm -rf /root/.cache diff --git a/ebssurrogate/scripts/surrogate-bootstrap-nix.sh b/ebssurrogate/scripts/surrogate-bootstrap-nix.sh index 6717540c48..1d8bbd5d63 100755 --- a/ebssurrogate/scripts/surrogate-bootstrap-nix.sh +++ b/ebssurrogate/scripts/surrogate-bootstrap-nix.sh @@ -276,36 +276,7 @@ function clean_system { chmod +x /mnt/tmp/cleanup.sh chroot /mnt /tmp/cleanup.sh - # Cleanup logs - rm -rf /mnt/var/log/* - # https://github.com/fail2ban/fail2ban/issues/1593 - touch /mnt/var/log/auth.log - - touch /mnt/var/log/pgbouncer.log - if [[ -f /usr/bin/chown ]]; then - chroot /mnt /usr/bin/chown pgbouncer:postgres /var/log/pgbouncer.log - fi - - # Setup postgresql logs - mkdir -p /mnt/var/log/postgresql - if [[ -f /usr/bin/chown ]]; then - chroot /mnt /usr/bin/chown postgres:postgres /var/log/postgresql - fi - - # Setup wal-g logs - mkdir /mnt/var/log/wal-g - touch /mnt/var/log/wal-g/{backup-push.log,backup-fetch.log,wal-push.log,wal-fetch.log,pitr.log} - - #Creatre Sysstat directory for SAR - mkdir /mnt/var/log/sysstat - - if [[ -f /usr/bin/chown ]]; then - chroot /mnt /usr/bin/chown -R postgres:postgres /var/log/wal-g - chroot /mnt /usr/bin/chmod -R 0300 /var/log/wal-g - fi - - # audit logs directory for apparmor - mkdir /mnt/var/log/audit + setup_image_logs /mnt # unwanted files rm -rf /mnt/var/lib/apt/lists/* From c4eebdcb71930324476f8c70c5a5070e1bbd2d89 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A1rton=20Boros?= Date: Tue, 20 Oct 2026 03:57:16 +0300 Subject: [PATCH 04/12] fix(ami): source the shared script in the surrogate bootstrap clean_system calls setup_image_logs, which lives in provision-common.sh. The surrogate script copied the library into the chroot but never sourced it on the host. Refs: MPG-1383 Co-Authored-By: Claude Sonnet 5.5 --- ebssurrogate/scripts/surrogate-bootstrap-nix.sh | 3 +++ 1 file changed, 3 insertions(+) diff --git a/ebssurrogate/scripts/surrogate-bootstrap-nix.sh b/ebssurrogate/scripts/surrogate-bootstrap-nix.sh index 1d8bbd5d63..8ea5887865 100755 --- a/ebssurrogate/scripts/surrogate-bootstrap-nix.sh +++ b/ebssurrogate/scripts/surrogate-bootstrap-nix.sh @@ -10,6 +10,9 @@ set -o errexit set -o pipefail set -o xtrace +# shellcheck source=/dev/null +source /tmp/provision-common.sh + exec 1>&2 function setup_apt { From b2684a16424c230026240d5b1381c30235ce129a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A1rton=20Boros?= Date: Tue, 20 Oct 2026 03:57:39 +0300 Subject: [PATCH 05/12] refactor(ami): share the ansible install and drop qemu-vars Add install_ansible to provision-common.sh for all three bootstrap scripts. Delete ansible/qemu-vars.yaml: it set a var the templates never read, so the QEMU splay was always the vars.yml default. Refs: MPG-1383 Co-Authored-By: Claude Sonnet 5.5 --- ansible/qemu-vars.yaml | 1 - ebssurrogate/scripts/nix-provision.sh | 7 +------ ebssurrogate/scripts/provision-common.sh | 5 +++++ ebssurrogate/scripts/qemu-bootstrap-nix.sh | 9 +++------ ebssurrogate/scripts/surrogate-bootstrap-nix.sh | 3 +-- 5 files changed, 10 insertions(+), 15 deletions(-) delete mode 100644 ansible/qemu-vars.yaml diff --git a/ansible/qemu-vars.yaml b/ansible/qemu-vars.yaml deleted file mode 100644 index ad06a2a014..0000000000 --- a/ansible/qemu-vars.yaml +++ /dev/null @@ -1 +0,0 @@ -supabase_admin_agent_splay_secs: 2h diff --git a/ebssurrogate/scripts/nix-provision.sh b/ebssurrogate/scripts/nix-provision.sh index 17b24ecff9..a4f3749691 100755 --- a/ebssurrogate/scripts/nix-provision.sh +++ b/ebssurrogate/scripts/nix-provision.sh @@ -14,11 +14,6 @@ function setup_apt { export DEBIAN_FRONTEND=noninteractive } -function install_packages { - apt-get install -y ansible - ansible-galaxy collection install community.general -} - function execute_stage2_playbook { echo "POSTGRES_MAJOR_VERSION: $POSTGRES_MAJOR_VERSION" echo "GIT_SHA: $GIT_SHA" @@ -33,7 +28,7 @@ function cleanup_packages { setup_apt update_and_upgrade_apt -install_packages +install_ansible install_nix execute_stage2_playbook cleanup_packages diff --git a/ebssurrogate/scripts/provision-common.sh b/ebssurrogate/scripts/provision-common.sh index a204b63587..0bc09a1054 100644 --- a/ebssurrogate/scripts/provision-common.sh +++ b/ebssurrogate/scripts/provision-common.sh @@ -11,6 +11,11 @@ function cleanup_apt { rm -rf /var/lib/apt/lists/* } +function install_ansible { + apt-get install --yes ansible + ansible-galaxy collection install community.general +} + function install_nix() { curl -L https://releases.nixos.org/nix/nix-2.34.6/install | sh -s -- --yes --daemon --nix-extra-conf-file <( cat <<-EOF diff --git a/ebssurrogate/scripts/qemu-bootstrap-nix.sh b/ebssurrogate/scripts/qemu-bootstrap-nix.sh index f378d04f8e..80dba19736 100755 --- a/ebssurrogate/scripts/qemu-bootstrap-nix.sh +++ b/ebssurrogate/scripts/qemu-bootstrap-nix.sh @@ -55,7 +55,6 @@ function waitfor_boot_finished { function install_packages { packages=( - ansible arptables e2fsprogs ebtables @@ -69,13 +68,12 @@ function install_packages { ufw ) apt-get install --yes "${packages[@]}" - ansible-galaxy collection install community.general + install_ansible } function execute_playbook { run_playbook ./ansible/playbook.yml /mnt/tmp false true \ - --extra-vars "postgresql_major=$POSTGRES_MAJOR_VERSION" \ - --extra-vars @./ansible/qemu-vars.yaml + --extra-vars "postgresql_major=$POSTGRES_MAJOR_VERSION" } ################# @@ -84,8 +82,7 @@ function execute_playbook { function execute_stage2_playbook { run_playbook ./ansible/playbook.yml /tmp true true \ - --extra-vars "postgresql_major=$POSTGRES_MAJOR_VERSION" \ - --extra-vars @./ansible/qemu-vars.yaml + --extra-vars "postgresql_major=$POSTGRES_MAJOR_VERSION" } function clean_legacy_things { diff --git a/ebssurrogate/scripts/surrogate-bootstrap-nix.sh b/ebssurrogate/scripts/surrogate-bootstrap-nix.sh index 8ea5887865..dcf905c8fb 100755 --- a/ebssurrogate/scripts/surrogate-bootstrap-nix.sh +++ b/ebssurrogate/scripts/surrogate-bootstrap-nix.sh @@ -63,14 +63,13 @@ function waitfor_boot_finished { function install_packages { packages=( - ansible debootstrap e2fsprogs gdisk nvme-cli ) apt-get install --yes "${packages[@]}" - ansible-galaxy collection install community.general + install_ansible } # Partition the new root EBS volume From 649be9a0e54f0ea8e95ab28bf6b510abae4ce9e2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A1rton=20Boros?= Date: Tue, 20 Oct 2026 05:44:29 +0300 Subject: [PATCH 06/12] refactor(ami): run the ami stage 1 playbook through run_playbook run_playbook takes the inventory host and connection as arguments, so the chroot run shares it with the local runs. Drop the sed that rewrote the playbook hosts line and use -i localhost, -c local instead. Refs: MPG-1383 Co-Authored-By: Claude Sonnet 5.5 --- ebssurrogate/scripts/nix-provision.sh | 2 +- ebssurrogate/scripts/provision-common.sh | 7 +++---- ebssurrogate/scripts/qemu-bootstrap-nix.sh | 4 ++-- ebssurrogate/scripts/surrogate-bootstrap-nix.sh | 17 ++--------------- 4 files changed, 8 insertions(+), 22 deletions(-) diff --git a/ebssurrogate/scripts/nix-provision.sh b/ebssurrogate/scripts/nix-provision.sh index a4f3749691..9d152bdd45 100755 --- a/ebssurrogate/scripts/nix-provision.sh +++ b/ebssurrogate/scripts/nix-provision.sh @@ -19,7 +19,7 @@ function execute_stage2_playbook { echo "GIT_SHA: $GIT_SHA" # shellcheck disable=SC2086 - run_playbook /tmp/ansible-playbook/ansible/playbook.yml /tmp true false $ARGS + run_playbook /tmp/ansible-playbook/ansible/playbook.yml /tmp true false localhost local $ARGS } function cleanup_packages { diff --git a/ebssurrogate/scripts/provision-common.sh b/ebssurrogate/scripts/provision-common.sh index 0bc09a1054..60109217b9 100644 --- a/ebssurrogate/scripts/provision-common.sh +++ b/ebssurrogate/scripts/provision-common.sh @@ -31,8 +31,8 @@ function install_nix() { } function run_playbook { - local playbook=$1 remote_tmp=$2 stage2=$3 qemu=$4 - shift 4 + local playbook=$1 remote_tmp=$2 stage2=$3 qemu=$4 host=$5 connection=$6 + shift 6 local sha_args=() if [[ $stage2 == true ]]; then @@ -44,12 +44,11 @@ function run_playbook { [defaults] callbacks_enabled = timer, profile_tasks, profile_roles EOF - sed -i 's/- hosts: all/- hosts: localhost/' "$playbook" export ANSIBLE_LOG_PATH=/tmp/ansible.log export ANSIBLE_REMOTE_TEMP=$remote_tmp - ansible-playbook "$playbook" \ + ansible-playbook -c "$connection" -i "$host," "$playbook" \ --extra-vars "{\"stage2\":$stage2,\"qemu\":$qemu}" \ "${sha_args[@]}" \ --extra-vars "psql_version=psql_$POSTGRES_MAJOR_VERSION" \ diff --git a/ebssurrogate/scripts/qemu-bootstrap-nix.sh b/ebssurrogate/scripts/qemu-bootstrap-nix.sh index 80dba19736..37e3077890 100755 --- a/ebssurrogate/scripts/qemu-bootstrap-nix.sh +++ b/ebssurrogate/scripts/qemu-bootstrap-nix.sh @@ -72,7 +72,7 @@ function install_packages { } function execute_playbook { - run_playbook ./ansible/playbook.yml /mnt/tmp false true \ + run_playbook ./ansible/playbook.yml /mnt/tmp false true localhost local \ --extra-vars "postgresql_major=$POSTGRES_MAJOR_VERSION" } @@ -81,7 +81,7 @@ function execute_playbook { ################# function execute_stage2_playbook { - run_playbook ./ansible/playbook.yml /tmp true true \ + run_playbook ./ansible/playbook.yml /tmp true true localhost local \ --extra-vars "postgresql_major=$POSTGRES_MAJOR_VERSION" } diff --git a/ebssurrogate/scripts/surrogate-bootstrap-nix.sh b/ebssurrogate/scripts/surrogate-bootstrap-nix.sh index dcf905c8fb..bda3ebed31 100755 --- a/ebssurrogate/scripts/surrogate-bootstrap-nix.sh +++ b/ebssurrogate/scripts/surrogate-bootstrap-nix.sh @@ -237,23 +237,10 @@ function setup_chroot_environment { } function execute_playbook { - mkdir -p /etc/ansible - tee /etc/ansible/ansible.cfg <<-EOF - [defaults] - callbacks_enabled = timer, profile_tasks, profile_roles - pipelining = True - EOF - - # Run Ansible playbook - # export ANSIBLE_DEBUG=True - export ANSIBLE_LOG_PATH=/tmp/ansible.log - export ANSIBLE_REMOTE_TEMP=/mnt/tmp + export ANSIBLE_PIPELINING=True # shellcheck disable=SC2086 - ansible-playbook -c chroot -i '/mnt,' /tmp/ansible-playbook/ansible/playbook.yml \ - --extra-vars '{"stage2":false, "qemu":false} ' \ - --extra-vars "psql_version=psql_$POSTGRES_MAJOR_VERSION" \ - $ARGS + run_playbook /tmp/ansible-playbook/ansible/playbook.yml /mnt/tmp false false /mnt chroot $ARGS } function update_systemd_services { From 7345f60fb5fdbcf2a69217fffac341ada8ad9d65 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A1rton=20Boros?= Date: Tue, 20 Oct 2026 05:52:13 +0300 Subject: [PATCH 07/12] refactor(ami): stop shadowing library functions in the chroot scripts Drop the update_and_upgrade_apt copies that matched the library. Rename the chroot cleanup_apt and report_packages, which differ from the library versions, to clean_apt_cache and report_chroot_packages. Refs: MPG-1383 Co-Authored-By: Claude Sonnet 5.5 --- ebssurrogate/scripts/chroot-bootstrap-nix.sh | 9 ++------- ebssurrogate/scripts/surrogate-bootstrap-nix.sh | 9 ++------- 2 files changed, 4 insertions(+), 14 deletions(-) diff --git a/ebssurrogate/scripts/chroot-bootstrap-nix.sh b/ebssurrogate/scripts/chroot-bootstrap-nix.sh index cd696aade2..b61402d4e7 100755 --- a/ebssurrogate/scripts/chroot-bootstrap-nix.sh +++ b/ebssurrogate/scripts/chroot-bootstrap-nix.sh @@ -15,16 +15,11 @@ function setup_apt { export DEBIAN_FRONTEND=noninteractive } -function cleanup_apt { +function clean_apt_cache { apt-get clean apt-get autoremove --purge --yes } -function update_and_upgrade_apt { - apt-get update --yes - apt-get dist-upgrade --yes -} - function install_initial_packages { local packages=( e2fsprogs @@ -198,5 +193,5 @@ set_default_target setup_eth0_interface disable_sshd_passwd_auth disable_fsck -cleanup_apt +clean_apt_cache enable_services diff --git a/ebssurrogate/scripts/surrogate-bootstrap-nix.sh b/ebssurrogate/scripts/surrogate-bootstrap-nix.sh index bda3ebed31..f1328fa5eb 100755 --- a/ebssurrogate/scripts/surrogate-bootstrap-nix.sh +++ b/ebssurrogate/scripts/surrogate-bootstrap-nix.sh @@ -49,11 +49,6 @@ function setup_apt { sed -i "s|$defmirror|& $ubumirror|" /etc/apt/sources.list.d/ubuntu.sources } -function update_and_upgrade_apt { - apt-get update --yes - apt-get dist-upgrade --yes -} - function waitfor_boot_finished { while [[ ! -f /var/lib/cloud/instance/boot-finished ]]; do echo 'Waiting for cloud-init...' @@ -275,7 +270,7 @@ function clean_system { rm -rf /mnt/usr/share/doc } -function report_packages { +function report_chroot_packages { # shellcheck disable=SC2016 chroot /mnt dpkg-query -W -f='${Package}\t${Version}\t${Architecture}\n' | LC_COLLATE=C.UTF-8 sort } @@ -317,5 +312,5 @@ setup_chroot_environment execute_playbook update_systemd_services clean_system -report_packages +report_chroot_packages umount_reset_mappings From ea017f75df2678f33c2d26ec2b90b78a894f5ce7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A1rton=20Boros?= Date: Tue, 20 Oct 2026 06:39:12 +0300 Subject: [PATCH 08/12] refactor(ami): share apt setup, boot wait and file cleanup Move the apt mirror fallback, DEBIAN_FRONTEND export, cloud-init wait and the unwanted-files removal into provision-common.sh. Mark only zlib1g-dev for autoremove on QEMU. Refs: MPG-1383 Co-Authored-By: Claude Sonnet 5.5 --- ebssurrogate/scripts/chroot-bootstrap-nix.sh | 4 -- ebssurrogate/scripts/nix-provision.sh | 4 -- ebssurrogate/scripts/provision-common.sh | 51 +++++++++++++++++++ ebssurrogate/scripts/qemu-bootstrap-nix.sh | 50 ++---------------- .../scripts/surrogate-bootstrap-nix.sh | 47 +---------------- 5 files changed, 56 insertions(+), 100 deletions(-) diff --git a/ebssurrogate/scripts/chroot-bootstrap-nix.sh b/ebssurrogate/scripts/chroot-bootstrap-nix.sh index b61402d4e7..42e30839c5 100755 --- a/ebssurrogate/scripts/chroot-bootstrap-nix.sh +++ b/ebssurrogate/scripts/chroot-bootstrap-nix.sh @@ -11,10 +11,6 @@ set -o xtrace # shellcheck source=/dev/null source /tmp/provision-common.sh -function setup_apt { - export DEBIAN_FRONTEND=noninteractive -} - function clean_apt_cache { apt-get clean apt-get autoremove --purge --yes diff --git a/ebssurrogate/scripts/nix-provision.sh b/ebssurrogate/scripts/nix-provision.sh index 9d152bdd45..6adb0f5531 100755 --- a/ebssurrogate/scripts/nix-provision.sh +++ b/ebssurrogate/scripts/nix-provision.sh @@ -10,10 +10,6 @@ source /tmp/provision-common.sh exec 1>&2 -function setup_apt { - export DEBIAN_FRONTEND=noninteractive -} - function execute_stage2_playbook { echo "POSTGRES_MAJOR_VERSION: $POSTGRES_MAJOR_VERSION" echo "GIT_SHA: $GIT_SHA" diff --git a/ebssurrogate/scripts/provision-common.sh b/ebssurrogate/scripts/provision-common.sh index 60109217b9..ae6ab5f115 100644 --- a/ebssurrogate/scripts/provision-common.sh +++ b/ebssurrogate/scripts/provision-common.sh @@ -173,3 +173,54 @@ function setup_image_logs { mkdir "$root/var/log/audit" } + +function setup_apt { + export DEBIAN_FRONTEND=noninteractive +} + +function add_apt_mirror_fallback { + # This function assumes deb822 formatted sources are in use, which is the case in both qemu and aws images + # In aws cloud-init creates a sources file with regional mirrors for "default" Suites but keeps ubuntu for security suite + # So we grab the first (only) URI from security and append it to non-security's URI + # This ends up giving us fastest mirror for installs and falls back to ubuntu if there's an issue + # + # Note: Ubuntu amd64 mirrors have different hostnames for security vs non but aarch64 are the same, hence the amd64 specific line + + # ensure deb822 format sources are in use + tail -n+1 /etc/apt/sources.list /etc/apt/sources.list.d/ubuntu.sources >&2 + + local sources defmirror ubumirror + sources=$(grep -e '^URIs\s*:' -e '^Suites\s*:' /etc/apt/sources.list.d/ubuntu.sources) + defmirror=$(grep -B1 "$CODENAME-updates" <<<"$sources" | awk '/URIs/ {print $2}') + ubumirror=$(grep -B1 "$CODENAME-security" <<<"$sources" | awk '/URIs/ {print $2}') + if [[ $ARCH == amd64 ]]; then + # amd64 hosts use security.ubuntu.com for security but archive.ubuntu.com for everything else + ubumirror=${ubumirror/security/archive} + fi + + if [[ $ubumirror == "$defmirror" ]]; then + # Only using one mirror so nothing to add as fallback, not running in AWS maybe? + return + fi + + if grep -q "^URIs:.*$defmirror.*$ubumirror" /etc/apt/sources.list.d/ubuntu.sources; then + echo "Ubuntu upstream is already a fallback, this is unexpected and needs source changes" >&2 + exit 1 + fi + sed -i "s|$defmirror|& $ubumirror|" /etc/apt/sources.list.d/ubuntu.sources +} + +function waitfor_boot_finished { + while [[ ! -f /var/lib/cloud/instance/boot-finished ]]; do + echo 'Waiting for cloud-init...' + sleep 1 + done +} + +function remove_unwanted_files { + local root=${1:-} + + rm -rf "$root"/root/.cache + rm -rf "$root"/root/.vpython* + rm -rf "$root"/root/go +} diff --git a/ebssurrogate/scripts/qemu-bootstrap-nix.sh b/ebssurrogate/scripts/qemu-bootstrap-nix.sh index 37e3077890..7f2dbe047b 100755 --- a/ebssurrogate/scripts/qemu-bootstrap-nix.sh +++ b/ebssurrogate/scripts/qemu-bootstrap-nix.sh @@ -11,48 +11,6 @@ source /tmp/provision-common.sh # stage1 things # ################# -function setup_apt { - export DEBIAN_FRONTEND=noninteractive - - # This function assumes deb822 formatted sources are in use, which is the case in both qemu and aws images - # In aws cloud-init creates a sources file with regional mirrors for "default" Suites but keeps ubuntu for security suite - # So we grab the first (only) URI from security and append it to non-security's URI - # This ends up giving us fastest mirror for installs and falls back to ubuntu if there's an issue - # - # Note: Ubuntu amd64 mirrors have different hostnames for security vs non but aarch64 are the same, hence the amd64 specific line - - # ensure deb822 format sources are in use - tail -n+1 /etc/apt/sources.list /etc/apt/sources.list.d/ubuntu.sources >&2 - - local sources defmirror ubumirror - sources=$(grep -e '^URIs\s*:' -e '^Suites\s*:' /etc/apt/sources.list.d/ubuntu.sources) - defmirror=$(grep -B1 "$CODENAME-updates" <<<"$sources" | awk '/URIs/ {print $2}') - ubumirror=$(grep -B1 "$CODENAME-security" <<<"$sources" | awk '/URIs/ {print $2}') - if [[ $ARCH == amd64 ]]; then - # amd64 hosts use security.ubuntu.com for security but archive.ubuntu.com for everything else - ubumirror=${ubumirror/security/archive} - fi - - if [[ $ubumirror == "$defmirror" ]]; then - # Only using one mirror so nothing to add as fallback, not running in AWS maybe? - return - fi - - if grep -q "^URIs:.*$defmirror.*$ubumirror" /etc/apt/sources.list.d/ubuntu.sources; then - echo "Ubuntu upstream is already a fallback, this is unexpected and needs source changes" >&2 - exit 1 - fi - sed -i "s|$defmirror|& $ubumirror|" /etc/apt/sources.list.d/ubuntu.sources -} - -function waitfor_boot_finished { - # 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 { packages=( arptables @@ -87,7 +45,7 @@ function execute_stage2_playbook { function clean_legacy_things { # removes things that are bundled for legacy reasons, but we can start without for our newer artifacts - apt-mark auto zlib1g* # TODO (darora): need to make sure that there aren't other things that still need this + apt-mark auto zlib1g-dev apt-get purge --yes kong } @@ -103,10 +61,7 @@ function clean_system { setup_image_logs - # unwanted files - rm -rf /root/.cache - rm -rf /root/.vpython* - rm -rf /root/go + remove_unwanted_files rm -rf /mnt/usr/share/doc # remove passwords in user-data-cloudimg.img (required for Packer login) @@ -135,6 +90,7 @@ CODENAME=$(source /etc/os-release && echo "$VERSION_CODENAME") waitfor_boot_finished setup_apt +add_apt_mirror_fallback update_and_upgrade_apt install_packages setup_postgesql_env diff --git a/ebssurrogate/scripts/surrogate-bootstrap-nix.sh b/ebssurrogate/scripts/surrogate-bootstrap-nix.sh index f1328fa5eb..e40dc2cafc 100755 --- a/ebssurrogate/scripts/surrogate-bootstrap-nix.sh +++ b/ebssurrogate/scripts/surrogate-bootstrap-nix.sh @@ -15,47 +15,6 @@ source /tmp/provision-common.sh exec 1>&2 -function setup_apt { - export DEBIAN_FRONTEND=noninteractive - - # This function assumes deb822 formatted sources are in use, which is the case in both qemu and aws images - # In aws cloud-init creates a sources file with regional mirrors for "default" Suites but keeps ubuntu for security suite - # So we grab the first (only) URI from security and append it to non-security's URI - # This ends up giving us fastest mirror for installs and falls back to ubuntu if there's an issue - # - # Note: Ubuntu amd64 mirrors have different hostnames for security vs non but aarch64 are the same, hence the amd64 specific line - - # ensure deb822 format sources are in use - tail -n+1 /etc/apt/sources.list /etc/apt/sources.list.d/ubuntu.sources >&2 - - local sources defmirror ubumirror - sources=$(grep -e '^URIs\s*:' -e '^Suites\s*:' /etc/apt/sources.list.d/ubuntu.sources) - defmirror=$(grep -B1 "$CODENAME-updates" <<<"$sources" | awk '/URIs/ {print $2}') - ubumirror=$(grep -B1 "$CODENAME-security" <<<"$sources" | awk '/URIs/ {print $2}') - if [[ $ARCH == amd64 ]]; then - # amd64 hosts use security.ubuntu.com for security but archive.ubuntu.com for everything else - ubumirror=${ubumirror/security/archive} - fi - - if [[ $ubumirror == "$defmirror" ]]; then - # Only using one mirror so nothing to add as fallback, not running in AWS maybe? - return - fi - - if grep -q "^URIs:.*$defmirror.*$ubumirror" /etc/apt/sources.list.d/ubuntu.sources; then - echo "Ubuntu upstream is already a fallback, this is unexpected and needs source changes" >&2 - exit 1 - fi - sed -i "s|$defmirror|& $ubumirror|" /etc/apt/sources.list.d/ubuntu.sources -} - -function waitfor_boot_finished { - while [[ ! -f /var/lib/cloud/instance/boot-finished ]]; do - echo 'Waiting for cloud-init...' - sleep 1 - done -} - function install_packages { packages=( debootstrap @@ -262,11 +221,8 @@ function clean_system { setup_image_logs /mnt - # unwanted files rm -rf /mnt/var/lib/apt/lists/* - rm -rf /mnt/root/.cache - rm -rf /mnt/root/.vpython* - rm -rf /mnt/root/go + remove_unwanted_files /mnt rm -rf /mnt/usr/share/doc } @@ -303,6 +259,7 @@ CODENAME=$(source /etc/os-release && echo "$VERSION_CODENAME") waitfor_boot_finished setup_apt +add_apt_mirror_fallback update_and_upgrade_apt install_packages device_partition_mappings From be9c8d5896b8e6013b272d0bae833d54d2e68b4a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A1rton=20Boros?= Date: Tue, 20 Oct 2026 19:51:50 +0300 Subject: [PATCH 09/12] fix(ami): remove /usr/share/doc on qemu and drop libgcc-8-dev purge The qemu doc removal used an /mnt path and did nothing on the live VM. Do it in remove_unwanted_files for both targets. noble has no libgcc-8-dev, so drop it from the aarch64 purge list. Refs: MPG-1383 Co-Authored-By: Claude Sonnet 5.5 --- ebssurrogate/scripts/cleanup-qemu.sh | 4 ---- ebssurrogate/scripts/provision-common.sh | 1 + ebssurrogate/scripts/qemu-bootstrap-nix.sh | 1 - ebssurrogate/scripts/surrogate-bootstrap-nix.sh | 1 - 4 files changed, 1 insertion(+), 6 deletions(-) diff --git a/ebssurrogate/scripts/cleanup-qemu.sh b/ebssurrogate/scripts/cleanup-qemu.sh index 512c98c3cc..fea46c6b7b 100755 --- a/ebssurrogate/scripts/cleanup-qemu.sh +++ b/ebssurrogate/scripts/cleanup-qemu.sh @@ -101,10 +101,6 @@ packages=( xfsprogs ) -if [[ $(uname -m) == aarch64 ]]; then - packages+=(libgcc-8-dev) -fi - apt-mark manual libevent-2.1-7t64 apt-get --yes remove --purge "${packages[@]}" apt-get --yes autoremove diff --git a/ebssurrogate/scripts/provision-common.sh b/ebssurrogate/scripts/provision-common.sh index ae6ab5f115..e5e4694bc5 100644 --- a/ebssurrogate/scripts/provision-common.sh +++ b/ebssurrogate/scripts/provision-common.sh @@ -223,4 +223,5 @@ function remove_unwanted_files { rm -rf "$root"/root/.cache rm -rf "$root"/root/.vpython* rm -rf "$root"/root/go + rm -rf "$root"/usr/share/doc } diff --git a/ebssurrogate/scripts/qemu-bootstrap-nix.sh b/ebssurrogate/scripts/qemu-bootstrap-nix.sh index 7f2dbe047b..611399169e 100755 --- a/ebssurrogate/scripts/qemu-bootstrap-nix.sh +++ b/ebssurrogate/scripts/qemu-bootstrap-nix.sh @@ -62,7 +62,6 @@ function clean_system { setup_image_logs remove_unwanted_files - rm -rf /mnt/usr/share/doc # remove passwords in user-data-cloudimg.img (required for Packer login) usermod -p '*' ubuntu diff --git a/ebssurrogate/scripts/surrogate-bootstrap-nix.sh b/ebssurrogate/scripts/surrogate-bootstrap-nix.sh index e40dc2cafc..f65910f898 100755 --- a/ebssurrogate/scripts/surrogate-bootstrap-nix.sh +++ b/ebssurrogate/scripts/surrogate-bootstrap-nix.sh @@ -223,7 +223,6 @@ function clean_system { rm -rf /mnt/var/lib/apt/lists/* remove_unwanted_files /mnt - rm -rf /mnt/usr/share/doc } function report_chroot_packages { From adc598b886f6fc1b3059e881a501830147fc08a5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A1rton=20Boros?= Date: Tue, 20 Oct 2026 19:52:12 +0300 Subject: [PATCH 10/12] refactor(ami): share the package purge between cleanup scripts Add purge_packages to provision-common.sh with the build leftovers both targets remove and the shared autoremove, autoclean and upgrade tail. cleanup-qemu.sh passes its extra names. The purge sets are unchanged. Refs: MPG-1383 Co-Authored-By: Claude Sonnet 5.5 --- ebssurrogate/scripts/cleanup-qemu.sh | 20 +------------------ ebssurrogate/scripts/cleanup.sh | 25 +----------------------- ebssurrogate/scripts/provision-common.sh | 25 ++++++++++++++++++++++++ 3 files changed, 27 insertions(+), 43 deletions(-) diff --git a/ebssurrogate/scripts/cleanup-qemu.sh b/ebssurrogate/scripts/cleanup-qemu.sh index fea46c6b7b..1cc1f8b433 100755 --- a/ebssurrogate/scripts/cleanup-qemu.sh +++ b/ebssurrogate/scripts/cleanup-qemu.sh @@ -16,13 +16,9 @@ ensure_tmp_dir # Cleanup more packages packages=( - ansible ansible-core apport appstream - autoconf - automake - autotools-dev bash-completion bcache-tools bind9-dnsutils @@ -31,11 +27,8 @@ packages=( bolt btrfs-progs byobu - cmake-data command-not-found console-setup - cpp-10 - cpp-9 distro-info eject 'fonts-dejavu*' @@ -44,19 +37,12 @@ packages=( ftp fwupd gawk - gcc-10 - gcc-9 gdisk - git - git-man gnupg keyboard-configuration libc6-dev - libcgal-dev libclang-cpp18 libevent-dev - libgcc-9-dev - libicu-dev libicu74 libpcre3-dev libssl-dev @@ -102,11 +88,7 @@ packages=( ) apt-mark manual libevent-2.1-7t64 -apt-get --yes remove --purge "${packages[@]}" -apt-get --yes autoremove -apt-get --yes autoclean -apt-get --yes update -apt-get --yes upgrade +purge_packages "${packages[@]}" systemctl set-default multi-user.target systemctl disable getty@tty1.service diff --git a/ebssurrogate/scripts/cleanup.sh b/ebssurrogate/scripts/cleanup.sh index 6e33b5f507..1454c990d3 100755 --- a/ebssurrogate/scripts/cleanup.sh +++ b/ebssurrogate/scripts/cleanup.sh @@ -14,30 +14,7 @@ source /tmp/provision-common.sh # https://github.com/digitalocean/marketplace-partners/issues/94 ensure_tmp_dir -# Cleanup more packages -packages=( - ansible - ansible - autoconf - automake - autotools-dev - cmake-data - cpp-10 - cpp-9 - gcc-10 - gcc-9 - git - git-man - libcgal-dev - libgcc-9-dev - libicu-dev -) - -apt-get --yes remove --purge "${packages[@]}" -apt-get --yes autoremove -apt-get --yes autoclean -apt-get --yes update -apt-get --yes upgrade +purge_packages scrub_history scrub_logs_and_keys diff --git a/ebssurrogate/scripts/provision-common.sh b/ebssurrogate/scripts/provision-common.sh index e5e4694bc5..959620f8f8 100644 --- a/ebssurrogate/scripts/provision-common.sh +++ b/ebssurrogate/scripts/provision-common.sh @@ -225,3 +225,28 @@ function remove_unwanted_files { rm -rf "$root"/root/go rm -rf "$root"/usr/share/doc } + +function purge_packages { + local common=( + ansible + autoconf + automake + autotools-dev + cmake-data + cpp-10 + cpp-9 + gcc-10 + gcc-9 + git + git-man + libcgal-dev + libgcc-9-dev + libicu-dev + ) + + apt-get --yes remove --purge "${common[@]}" "$@" + apt-get --yes autoremove + apt-get --yes autoclean + apt-get --yes update + apt-get --yes upgrade +} From fd7aa1ae88bc2be2d2a4b4cc045f7a589813a777 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A1rton=20Boros?= Date: Wed, 21 Oct 2026 03:32:20 +0300 Subject: [PATCH 11/12] refactor(ansible): move qemu-specific values into per-target vars Load ansible/vars/aws.yml or qemu.yml from the playbook. The UID and GID pins, the supascan baseline prefix and the differing values in the adminapi, gotrue, postgres_exporter and admin-agent templates now come from vars. Rendered templates and pins are unchanged for both targets. Refs: MPG-1383 Co-Authored-By: Claude Sonnet 5.5 --- ansible/files/adminapi.service.j2 | 6 +-- ansible/files/gotrue.service.j2 | 13 ++----- ansible/files/postgres_exporter.service.j2 | 3 +- .../supabase-admin-agent_salt.service.j2 | 12 ++---- .../supabase-admin-agent_salt.timer.j2 | 16 +++----- ansible/playbook.yml | 3 +- ansible/tasks/internal/admin-api.yml | 2 +- .../tasks/internal/supabase-admin-agent.yml | 2 +- ansible/tasks/setup-envoy.yml | 2 +- ansible/tasks/setup-gotrue.yml | 2 +- ansible/tasks/setup-kong.yml | 2 +- ansible/tasks/setup-pgbouncer.yml | 2 +- ansible/tasks/setup-postgrest.yml | 2 +- ansible/tasks/setup-supabase-internal.yml | 2 +- ansible/tasks/setup-system.yml | 4 +- ansible/vars/aws.yml | 34 +++++++++++++++++ ansible/vars/qemu.yml | 37 +++++++++++++++++++ 17 files changed, 99 insertions(+), 45 deletions(-) create mode 100644 ansible/vars/aws.yml create mode 100644 ansible/vars/qemu.yml diff --git a/ansible/files/adminapi.service.j2 b/ansible/files/adminapi.service.j2 index 4e956703a5..9bd2a20e73 100644 --- a/ansible/files/adminapi.service.j2 +++ b/ansible/files/adminapi.service.j2 @@ -14,9 +14,9 @@ Restart=always RestartSec=3 TimeoutStopSec=10 Environment="AWS_USE_DUALSTACK_ENDPOINT=true" -{% if qemu %} -Environment="AWS_SDK_LOAD_CONFIG=true" -{% endif %} +{% for env in adminapi_extra_env %} +Environment="{{ env }}" +{% endfor %} StandardOutput=journal StandardError=journal diff --git a/ansible/files/gotrue.service.j2 b/ansible/files/gotrue.service.j2 index 4105e92c66..cac17f6233 100644 --- a/ansible/files/gotrue.service.j2 +++ b/ansible/files/gotrue.service.j2 @@ -90,15 +90,10 @@ Environment=GOTRUE_RELOADING_POLLER_ENABLED=false # ensures only 1 reload operation occurs during a burst of config updates. Environment=GOTRUE_RELOADING_GRACE_PERIOD_INTERVAL=2s -{% if qemu %} -# v3 does not use filesystem notifications for config reloads. -Environment=GOTRUE_RELOADING_NOTIFY_ENABLED=false -{% else %} -# v2 currently relies on notify support, so we will enable it until both v2 / v3 -# have migrated to strictly use signals across all projects. The default is true -# in gotrue but we will set it defensively here. -Environment=GOTRUE_RELOADING_NOTIFY_ENABLED=true -{% endif %} +{% for line in gotrue_reloading_notify_comment %} +# {{ line }} +{% endfor %} +Environment=GOTRUE_RELOADING_NOTIFY_ENABLED={{ gotrue_reloading_notify_enabled | lower }} Slice=services.slice diff --git a/ansible/files/postgres_exporter.service.j2 b/ansible/files/postgres_exporter.service.j2 index 3dc57ef093..4e55f9689d 100644 --- a/ansible/files/postgres_exporter.service.j2 +++ b/ansible/files/postgres_exporter.service.j2 @@ -6,8 +6,7 @@ StartLimitBurst=0 [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 --collector.database_wraparound {% if qemu %}--no-collector.database {% endif %} - +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 --collector.database_wraparound{% for flag in postgres_exporter_extra_flags %} {{ flag }}{% endfor %} User=postgres Group=postgres Restart=always diff --git a/ansible/files/supabase_admin_agent_config/supabase-admin-agent_salt.service.j2 b/ansible/files/supabase_admin_agent_config/supabase-admin-agent_salt.service.j2 index d5647c8865..922042accd 100644 --- a/ansible/files/supabase_admin_agent_config/supabase-admin-agent_salt.service.j2 +++ b/ansible/files/supabase_admin_agent_config/supabase-admin-agent_salt.service.j2 @@ -6,15 +6,9 @@ Requires=local-fs.target [Service] Type=oneshot -{% if qemu %} -ExecStart=/opt/supabase-admin-agent/supabase-admin-agent --config /opt/supabase-admin-agent/config.yaml salt --apply --store-result --targets-key targetsv3-main.yaml -User=root -Group=root -{% else %} -ExecStart=/opt/supabase-admin-agent/supabase-admin-agent --config /opt/supabase-admin-agent/config.yaml salt --apply --store-result -User=supabase-admin-agent -Group=supabase-admin-agent -{% endif %} +ExecStart=/opt/supabase-admin-agent/supabase-admin-agent --config /opt/supabase-admin-agent/config.yaml {{ supabase_admin_agent_salt.args }} +User={{ supabase_admin_agent_salt.user }} +Group={{ supabase_admin_agent_salt.group }} StandardOutput=journal StandardError=journal StateDirectory=supabase-admin-agent diff --git a/ansible/files/supabase_admin_agent_config/supabase-admin-agent_salt.timer.j2 b/ansible/files/supabase_admin_agent_config/supabase-admin-agent_salt.timer.j2 index 52a4a81558..3b605cb63f 100644 --- a/ansible/files/supabase_admin_agent_config/supabase-admin-agent_salt.timer.j2 +++ b/ansible/files/supabase_admin_agent_config/supabase-admin-agent_salt.timer.j2 @@ -3,19 +3,13 @@ Description=Run Supabase supabase-admin-agent salt on a schedule Requires=supabase-admin-agent_salt.service [Timer] -{# We're using a significantly lower frequency for triggering this agent on qemu images for the moment. Once we've performed additional validations re: the aggregate impact of running it more frequently, the frequency can be increased. #} -{% if qemu %} -OnCalendar=*-*-* 0,6,12,18:00:00 +OnCalendar={{ supabase_admin_agent_timer.on_calendar }} RandomizedDelaySec={{ supabase_admin_agent_splay }} -AccuracySec=1h -OnBootSec=5m -Persistent=true -{% else %} -OnCalendar=*:0/10 -RandomizedDelaySec={{ supabase_admin_agent_splay }} -AccuracySec=1s -Persistent=true +AccuracySec={{ supabase_admin_agent_timer.accuracy_sec }} +{% if supabase_admin_agent_timer.on_boot_sec %} +OnBootSec={{ supabase_admin_agent_timer.on_boot_sec }} {% endif %} +Persistent=true [Install] WantedBy=timers.target diff --git a/ansible/playbook.yml b/ansible/playbook.yml index c4b6fa8020..747cd6f57b 100644 --- a/ansible/playbook.yml +++ b/ansible/playbook.yml @@ -6,6 +6,7 @@ vars_files: - ./vars.yml + - "./vars/{{ 'qemu' if qemu else 'aws' }}.yml" # Set facts only in here, never in any tasks. # This avoids redefining/duplicates or different values (buggy) @@ -180,7 +181,7 @@ - name: Run supascan baseline validation when: stage2 shell: >- - baseline={{ 'ami' if not qemu else 'qemu' }}-build-{{ platform }} + baseline={{ supascan_baseline_prefix }}-build-{{ platform }} nix shell github:supabase/postgres/{{ git_commit_sha }}#supascan --command /tmp/ansible-playbook/ansible/files/supascan_ami.sh /tmp/ansible-playbook/audit-specs/baselines/$baseline diff --git a/ansible/tasks/internal/admin-api.yml b/ansible/tasks/internal/admin-api.yml index dcdc68a393..2c26caf58a 100644 --- a/ansible/tasks/internal/admin-api.yml +++ b/ansible/tasks/internal/admin-api.yml @@ -7,7 +7,7 @@ - name: adminapi - system user ansible.builtin.user: name: adminapi - uid: "{{ 1006 if not qemu else 1007 }}" + uid: "{{ uids.adminapi }}" group: adminapi groups: admin,envoy,gotrue,kong,pgbouncer,postgres,postgrest,root,systemd-journal,vector,wal-g diff --git a/ansible/tasks/internal/supabase-admin-agent.yml b/ansible/tasks/internal/supabase-admin-agent.yml index fb32321749..b94952121e 100644 --- a/ansible/tasks/internal/supabase-admin-agent.yml +++ b/ansible/tasks/internal/supabase-admin-agent.yml @@ -1,7 +1,7 @@ - name: supabase-admin-agent - system group ansible.builtin.group: name: supabase-admin-agent - gid: "{{ 987 if not qemu else 988 }}" + gid: "{{ gids.supabase_admin_agent }}" system: yes - name: supabase-admin-agent - system user diff --git a/ansible/tasks/setup-envoy.yml b/ansible/tasks/setup-envoy.yml index 588b2bfb94..b6d697cc18 100644 --- a/ansible/tasks/setup-envoy.yml +++ b/ansible/tasks/setup-envoy.yml @@ -7,7 +7,7 @@ - name: Envoy - user ansible.builtin.user: name: envoy - uid: "{{ 1003 if not qemu else 1004 }}" + uid: "{{ uids.envoy }}" group: envoy state: present diff --git a/ansible/tasks/setup-gotrue.yml b/ansible/tasks/setup-gotrue.yml index b3378de4d4..e126543628 100644 --- a/ansible/tasks/setup-gotrue.yml +++ b/ansible/tasks/setup-gotrue.yml @@ -13,7 +13,7 @@ - name: Gotrue - system user ansible.builtin.user: name: gotrue - uid: "{{ 1001 if not qemu else 1002 }}" + uid: "{{ uids.gotrue }}" group: gotrue state: present diff --git a/ansible/tasks/setup-kong.yml b/ansible/tasks/setup-kong.yml index f904fef365..3dd5a0e826 100644 --- a/ansible/tasks/setup-kong.yml +++ b/ansible/tasks/setup-kong.yml @@ -7,7 +7,7 @@ - name: Kong - user ansible.builtin.user: name: kong - uid: "{{ 1004 if not qemu else 1005 }}" + uid: "{{ uids.kong }}" group: kong state: present diff --git a/ansible/tasks/setup-pgbouncer.yml b/ansible/tasks/setup-pgbouncer.yml index d76aa46b8e..fe4b45d216 100644 --- a/ansible/tasks/setup-pgbouncer.yml +++ b/ansible/tasks/setup-pgbouncer.yml @@ -8,7 +8,7 @@ - name: Create pgbouncer user ansible.builtin.user: name: 'pgbouncer' - uid: "{{ 1000 if not qemu else 1001 }}" + uid: "{{ uids.pgbouncer }}" comment: 'PgBouncer user' group: pgbouncer groups: 'postgres,ssl-cert' diff --git a/ansible/tasks/setup-postgrest.yml b/ansible/tasks/setup-postgrest.yml index a6ad947896..f6aaadbf91 100644 --- a/ansible/tasks/setup-postgrest.yml +++ b/ansible/tasks/setup-postgrest.yml @@ -7,7 +7,7 @@ - name: PostgREST - user ansible.builtin.user: name: postgrest - uid: "{{ 1002 if not qemu else 1003 }}" + uid: "{{ uids.postgrest }}" group: postgrest state: present diff --git a/ansible/tasks/setup-supabase-internal.yml b/ansible/tasks/setup-supabase-internal.yml index 871cbf6fc4..8c8e9ec7ad 100644 --- a/ansible/tasks/setup-supabase-internal.yml +++ b/ansible/tasks/setup-supabase-internal.yml @@ -23,7 +23,7 @@ - name: add vector system group ansible.builtin.group: name: vector - gid: "{{ 989 if not qemu else 990 }}" + gid: "{{ gids.vector }}" system: yes - name: add vector system user diff --git a/ansible/tasks/setup-system.yml b/ansible/tasks/setup-system.yml index 666e7a2c45..57e5130924 100644 --- a/ansible/tasks/setup-system.yml +++ b/ansible/tasks/setup-system.yml @@ -4,7 +4,7 @@ - name: Create ubuntu primary group ansible.builtin.group: name: ubuntu - gid: "{{ 1014 if not qemu else 1000 }}" + gid: "{{ gids.ubuntu }}" state: present - name: Create ubuntu user supplementary groups # noqa: explicit-identity-id @@ -19,7 +19,7 @@ - name: Create ubuntu user ansible.builtin.user: name: ubuntu - uid: "{{ 1007 if not qemu else 1000 }}" + uid: "{{ uids.ubuntu }}" group: ubuntu groups: - adm diff --git a/ansible/vars/aws.yml b/ansible/vars/aws.yml new file mode 100644 index 0000000000..b75c6a96d6 --- /dev/null +++ b/ansible/vars/aws.yml @@ -0,0 +1,34 @@ +--- +uids: + pgbouncer: 1000 + gotrue: 1001 + postgrest: 1002 + envoy: 1003 + kong: 1004 + adminapi: 1006 + ubuntu: 1007 +gids: + ubuntu: 1014 + vector: 989 + supabase_admin_agent: 987 + +supascan_baseline_prefix: ami + +adminapi_extra_env: [] + +gotrue_reloading_notify_enabled: true +gotrue_reloading_notify_comment: + - v2 currently relies on notify support, so we will enable it until both v2 / v3 + - have migrated to strictly use signals across all projects. The default is true + - in gotrue but we will set it defensively here. + +postgres_exporter_extra_flags: [] + +supabase_admin_agent_salt: + args: salt --apply --store-result + user: supabase-admin-agent + group: supabase-admin-agent +supabase_admin_agent_timer: + on_calendar: "*:0/10" + accuracy_sec: 1s + on_boot_sec: "" diff --git a/ansible/vars/qemu.yml b/ansible/vars/qemu.yml new file mode 100644 index 0000000000..686a97fd90 --- /dev/null +++ b/ansible/vars/qemu.yml @@ -0,0 +1,37 @@ +--- +uids: + pgbouncer: 1001 + gotrue: 1002 + postgrest: 1003 + envoy: 1004 + kong: 1005 + adminapi: 1007 + ubuntu: 1000 +gids: + ubuntu: 1000 + vector: 990 + supabase_admin_agent: 988 + +supascan_baseline_prefix: qemu + +adminapi_extra_env: + - AWS_SDK_LOAD_CONFIG=true + +gotrue_reloading_notify_enabled: false +gotrue_reloading_notify_comment: + - v3 does not use filesystem notifications for config reloads. + +postgres_exporter_extra_flags: + - --no-collector.database + +supabase_admin_agent_salt: + args: salt --apply --store-result --targets-key targetsv3-main.yaml + user: root + group: root +# We're using a significantly lower frequency for triggering this agent on qemu +# images for the moment. Once we've performed additional validations re: the +# aggregate impact of running it more frequently, the frequency can be increased. +supabase_admin_agent_timer: + on_calendar: "*-*-* 0,6,12,18:00:00" + accuracy_sec: 1h + on_boot_sec: 5m From 197597500722c9f97d62bce4924851ac97ba3683 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A1rton=20Boros?= Date: Sun, 25 Oct 2026 21:02:59 +0200 Subject: [PATCH 12/12] fix(ami): mark zlib1g and zlib1g-dev auto on qemu Restore both packages to the base image state after the Kong purge. setup-kong.yml marks them manual, and the previous change left zlib1g manual. Refs: MPG-1383 Co-Authored-By: Claude Sonnet 5.5 --- packer/scripts/qemu-bootstrap-nix.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packer/scripts/qemu-bootstrap-nix.sh b/packer/scripts/qemu-bootstrap-nix.sh index e811a4bc07..f0ae094bbc 100755 --- a/packer/scripts/qemu-bootstrap-nix.sh +++ b/packer/scripts/qemu-bootstrap-nix.sh @@ -43,7 +43,7 @@ function execute_stage2_playbook { function clean_legacy_things { # removes things that are bundled for legacy reasons, but we can start without for our newer artifacts - apt-mark auto zlib1g-dev + apt-mark auto zlib1g zlib1g-dev apt-get purge --yes kong }