diff --git a/.github/workflows/ami-release-nix.yml b/.github/workflows/ami-release-nix.yml index 773aee018c..998a121f83 100644 --- a/.github/workflows/ami-release-nix.yml +++ b/.github/workflows/ami-release-nix.yml @@ -11,6 +11,7 @@ on: - flake.lock - flake.nix - nix/packages/build-ami.nix + - nix/** workflow_dispatch: permissions: @@ -203,6 +204,24 @@ jobs: echo "Catalog uploaded to ${CATALOG_S3}" + - name: Update site-env catalogs + run: | + GIT_SHA="${{ steps.resolve-git-sha.outputs.sha }}" + SYSTEM=$(nix eval --impure --raw --expr 'builtins.currentSystem') + + SITE_ENV_NAME="site-env-${POSTGRES_MAJOR_VERSION}" + SITE_ENV_PATH=$(nix eval --raw ".#${SITE_ENV_NAME}.outPath") + jq -n --arg sys "$SYSTEM" --arg path "$SITE_ENV_PATH" '{($sys): $path}' > /tmp/site-env-catalog.json + aws s3 cp /tmp/site-env-catalog.json \ + "s3://${{ secrets.SHARED_AWS_ARTIFACTS_BUCKET }}/nix-catalog/${GIT_SHA}-${SITE_ENV_NAME}-${SYSTEM}.json" \ + --content-type "application/json" + + UPDATE_SITE_PATH=$(nix eval --raw ".#update-site.outPath") + jq -n --arg sys "$SYSTEM" --arg path "$UPDATE_SITE_PATH" '{($sys): $path}' > /tmp/update-site-catalog.json + aws s3 cp /tmp/update-site-catalog.json \ + "s3://${{ secrets.SHARED_AWS_ARTIFACTS_BUCKET }}/nix-catalog/${GIT_SHA}-update-site-${SYSTEM}.json" \ + --content-type "application/json" + - name: Create release uses: softprops/action-gh-release@a06a81a03ee405af7f2048a818ed3f03bbf83c7b # v2.5.0 with: diff --git a/ansible/files/postgresql_config/postgresql.conf.j2 b/ansible/files/postgresql_config/postgresql.conf.j2 index 154ec13416..4aa75eda95 100644 --- a/ansible/files/postgresql_config/postgresql.conf.j2 +++ b/ansible/files/postgresql_config/postgresql.conf.j2 @@ -692,7 +692,7 @@ jit_provider = 'llvmjit' # JIT library to use # - Other Defaults - -#dynamic_library_path = '$libdir' +dynamic_library_path = '/nix/var/nix/profiles/site/lib:$libdir' #gin_fuzzy_search_limit = 0 #------------------------------------------------------------------------------ diff --git a/ansible/tasks/stage2-setup-postgres.yml b/ansible/tasks/stage2-setup-postgres.yml index d4823238a7..1c8073199d 100644 --- a/ansible/tasks/stage2-setup-postgres.yml +++ b/ansible/tasks/stage2-setup-postgres.yml @@ -77,6 +77,28 @@ nix-env --set {{ postgres_env_path.stdout }} " + - name: Resolve site env store path + ansible.builtin.shell: | + . /nix/var/nix/profiles/default/etc/profile.d/nix-daemon.sh && + nix build --no-link --print-out-paths github:supabase/postgres/{{ git_commit_sha }}#site-env-{{ postgresql_major_version }} + register: site_env_path + + - name: Install site env from nix binary cache + ansible.builtin.shell: | + . /nix/var/nix/profiles/default/etc/profile.d/nix-daemon.sh && + nix-env --profile /nix/var/nix/profiles/site --set {{ site_env_path.stdout }} + + - name: Resolve update-site store path + ansible.builtin.shell: | + . /nix/var/nix/profiles/default/etc/profile.d/nix-daemon.sh && + nix build --no-link --print-out-paths github:supabase/postgres/{{ git_commit_sha }}#update-site + register: update_site_path + + - name: Install update-site + ansible.builtin.shell: | + . /nix/var/nix/profiles/default/etc/profile.d/nix-daemon.sh && + nix-env --profile /nix/var/nix/profiles/update-site --set {{ update_site_path.stdout }} + - name: Install supascan for baseline validation ansible.builtin.shell: | sudo -u ubuntu bash -c ". /nix/var/nix/profiles/default/etc/profile.d/nix-daemon.sh && nix profile install github:supabase/postgres/{{ git_commit_sha }}#supascan" diff --git a/nix/checks.nix b/nix/checks.nix index 3fdd5ba2c0..215dbed73e 100644 --- a/nix/checks.nix +++ b/nix/checks.nix @@ -939,6 +939,50 @@ wal-g-3 ; devShell = self'.devShells.default; + site = + let + system = pkgs.pkgsLinux.stdenv.hostPlatform.system; + update-profile = self.packages.${system}.update-profile; + site-env-17 = self.packages.${system}."site-env-17"; + psql_17 = self.legacyPackages.${system}."psql_17".bin; + pgConf = pkgs.writeText "postgresql-test.conf" '' + dynamic_library_path = '/nix/var/nix/profiles/site/lib:$libdir' + session_preload_libraries = 'supautils' + listen_addresses = 'localhost' + unix_socket_directories = '/tmp' + ''; + in + pkgs.testers.runNixOSTest { + name = "site"; + nodes.machine = + { ... }: + { + environment.systemPackages = [ + update-profile + site-env-17 + ]; + users.users.postgres = { + isSystemUser = true; + group = "postgres"; + shell = pkgs.bash; + }; + users.groups.postgres = { }; + }; + testScript = '' + machine.succeed("update-profile site ${site-env-17}") + machine.succeed("[ \"$(readlink -f /nix/var/nix/profiles/site)\" = \"${site-env-17}\" ]") + + # idempotent + machine.succeed("update-profile site ${site-env-17}") + + # postgres can load supautils via the site profile's dynamic_library_path + machine.succeed("install -d -o postgres -g postgres /tmp/pgdata") + machine.succeed("su postgres -c '${psql_17}/bin/initdb -D /tmp/pgdata'") + machine.succeed("install -o postgres -g postgres ${pgConf} /tmp/pgdata/postgresql.conf") + machine.succeed("su postgres -c '${psql_17}/bin/pg_ctl -D /tmp/pgdata -l /tmp/pg.log start'") + machine.succeed("su postgres -c '${psql_17}/bin/psql -h localhost -d postgres -c \"select 1\"'") + ''; + }; } // (import ./ext/tests { inherit self; diff --git a/nix/packages/extension-catalog.nix b/nix/packages/extension-catalog.nix index d8d5591216..d4724b27d9 100644 --- a/nix/packages/extension-catalog.nix +++ b/nix/packages/extension-catalog.nix @@ -110,8 +110,8 @@ makeWrapper ${self'.packages.site-extensions-resolve}/bin/site-extensions-resolve \ "$out/bin/site-extensions-resolve" \ --set PG_EXTENSIONS_CATALOG "$out/share/pg-extensions-catalog.json" - makeWrapper ${self'.packages.site-extensions-update}/bin/site-extensions-update \ - "$out/bin/site-extensions-update" \ + makeWrapper ${self'.packages.update-site-extensions}/bin/update-site-extensions \ + "$out/bin/update-site-extensions" \ --set PG_EXTENSIONS_CATALOG "$out/share/pg-extensions-catalog.json" '' ) @@ -146,19 +146,16 @@ ''; }; - # Takes manifest json as argument. - # Downloads paths and installs them as an env into the profile, replacing all existing ones. - site-extensions-update = pkgs.writeShellApplication { - name = "site-extensions-update"; - runtimeInputs = [ - self'.packages.site-extensions-resolve - pkgs.nix - ]; + # Downloads the manifest's paths and installs them as the profile's env, replacing all existing ones. + # nix comes from the environment. + update-site-extensions = pkgs.writeShellApplication { + name = "update-site-extensions"; + runtimeInputs = [ self'.packages.site-extensions-resolve ]; text = '' manifest="''${1:?Usage: $0 path-to/pg-extensions.json}" - profile="''${NIX_PROFILE:-/nix/var/nix/profiles/site-extensions}" + profile="/nix/var/nix/profiles/site-extensions" readarray -t paths < <(site-extensions-resolve "$manifest") - nix-store -r --option stalled-download-timeout 120 "''${paths[@]}" >/dev/null + nix-store --realise --option stalled-download-timeout 120 "''${paths[@]}" >/dev/null nix-env --profile "$profile" --install "''${paths[@]}" --remove-all ''; }; diff --git a/nix/packages/site-env.nix b/nix/packages/site-env.nix index 4fa580e99a..e3e945033c 100644 --- a/nix/packages/site-env.nix +++ b/nix/packages/site-env.nix @@ -1,5 +1,4 @@ # These are envs (package sets per pg major version) deployed to instances -# at /nix/var/nix/profiles/site and updated regularly. { perSystem = { @@ -14,6 +13,7 @@ pkgs.buildEnv { name = "site-env-${version}"; paths = [ self'.legacyPackages."psql_${version}".exts.supautils ] ++ extraPaths; + postBuild = "echo site-env-${version} > $out/site-env-name"; }; siteEnvs = { @@ -28,9 +28,50 @@ lib.optionals pkgs.stdenv.isLinux [ self'.packages.gatekeeper ] ); }; + + # Set the named nix profile to the provided nix store path. + # aws and nix come from the environment. + update-profile = pkgs.writeShellApplication { + name = "update-profile"; + text = '' + profile_name="''${1:?Usage: $0 }" + path="''${2:?Usage: $0 }" + profile_path="/nix/var/nix/profiles/''${profile_name}" + + [[ "$(readlink -f "$profile_path")" == "$path" ]] && exit 0 + nix-store --realise --option stalled-download-timeout 120 "$path" >/dev/null + nix-env --profile "$profile_path" --set "$path" + ''; + }; + + # Fetch catalog and update site profile from given postgres repo hash. + # aws and nix come from the environment. + update-site = pkgs.writeShellApplication { + name = "update-site"; + runtimeInputs = [ + pkgs.jq + update-profile + ]; + text = '' + sha="''${1:?Usage: $0 }" + system="$(uname -m)-linux" + variant="$(cat /nix/var/nix/profiles/site/site-env-name)" + catalog="/tmp/''${variant}-catalog-''${sha}-''${system}.json" + + aws s3 cp "s3://supabase-internal-artifacts/nix-catalog/''${sha}-''${variant}-''${system}.json" \ + "$catalog" --region ap-southeast-1 + path="$(jq -er --arg s "$system" '.[$s]' "$catalog")" + + update-profile site "$path" + ''; + }; in { - packages = siteEnvs; - legacyPackages = siteEnvs; + packages = siteEnvs // { + inherit update-profile update-site; + }; + legacyPackages = siteEnvs // { + inherit update-profile update-site; + }; }; }