Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 19 additions & 0 deletions .github/workflows/ami-release-nix.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ on:
- flake.lock
- flake.nix
- nix/packages/build-ami.nix
- nix/**
workflow_dispatch:

permissions:
Expand Down Expand Up @@ -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_PROFILE_PATH=$(nix eval --raw ".#update-profile.outPath")
jq -n --arg sys "$SYSTEM" --arg path "$UPDATE_PROFILE_PATH" '{($sys): $path}' > /tmp/update-profile-catalog.json
aws s3 cp /tmp/update-profile-catalog.json \
"s3://${{ secrets.SHARED_AWS_ARTIFACTS_BUCKET }}/nix-catalog/${GIT_SHA}-update-profile-${SYSTEM}.json" \
--content-type "application/json"

- name: Create release
uses: softprops/action-gh-release@a06a81a03ee405af7f2048a818ed3f03bbf83c7b # v2.5.0
with:
Expand Down
11 changes: 11 additions & 0 deletions ansible/tasks/stage2-setup-postgres.yml
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,17 @@
nix-env --set {{ postgres_env_path.stdout }}
"

- name: Resolve update-profile 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-profile
register: update_profile_path

- name: Install update-profile
ansible.builtin.shell: |
. /nix/var/nix/profiles/default/etc/profile.d/nix-daemon.sh &&
nix-env --profile /nix/var/nix/profiles/update-profile --set {{ update_profile_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"
Expand Down
29 changes: 29 additions & 0 deletions nix/ext/tests/update-profile.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
{ self, pkgs }:
let
system = pkgs.pkgsLinux.stdenv.hostPlatform.system;
update-profile = self.packages.${system}.update-profile;
site-env-17 = self.packages.${system}."site-env-17";
in
pkgs.testers.runNixOSTest {
name = "update-profile";
nodes.machine =
{ ... }:
{
environment.systemPackages = [
update-profile
site-env-17
];
};
testScript = ''
machine.succeed("echo '{\"${system}\": \"${site-env-17}\"}' > /tmp/catalog.json")
# sha is only needed to fetch from S3 — omitted here since UPDATE_PROFILE_CATALOG bypasses that
machine.succeed("UPDATE_PROFILE_CATALOG=/tmp/catalog.json update-profile site-env-17")
machine.succeed("[ \"$(readlink -f /nix/var/nix/profiles/site-env-17)\" = \"${site-env-17}\" ]")

# idempotent: same catalog again is a no-op success
machine.succeed("UPDATE_PROFILE_CATALOG=/tmp/catalog.json update-profile site-env-17")

# wrong profile for the resolved path: must refuse
machine.fail("UPDATE_PROFILE_CATALOG=/tmp/catalog.json update-profile site-env-15")
'';
}
12 changes: 6 additions & 6 deletions nix/packages/extension-catalog.nix
Original file line number Diff line number Diff line change
Expand Up @@ -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"
''
)
Expand Down Expand Up @@ -148,17 +148,17 @@

# 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";
update-site-extensions = pkgs.writeShellApplication {
name = "update-site-extensions";
runtimeInputs = [
self'.packages.site-extensions-resolve
pkgs.nix
];
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
'';
};
Expand Down
45 changes: 42 additions & 3 deletions nix/packages/site-env.nix
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# These are envs (package sets per pg major version) deployed to instances
# at /nix/var/nix/profiles/site and updated regularly.
# at /nix/var/nix/profiles/<env-name> and updated regularly.
{
perSystem =
{
Expand Down Expand Up @@ -28,9 +28,48 @@
lib.optionals pkgs.stdenv.isLinux [ self'.packages.gatekeeper ]
);
};

# Given a profile name (e.g. site-env-17, postgres-env-17) and a git sha,
# fetches that name's catalog entry and flips /nix/var/nix/profiles/<name>
# to it. Generic across any single-package catalog entry named <name>-<system>.json.
# Assumes `aws` is provided by the environment (AMIs already install AWS CLI v2).
update-profile = pkgs.writeShellApplication {
name = "update-profile";
runtimeInputs = [
pkgs.jq
pkgs.nix
];
text = ''
profile_name="''${1:?Usage: $0 <profile> <git-sha>}"
system="$(uname -m)-linux"
profile_path="/nix/var/nix/profiles/''${profile_name}"

catalog="''${UPDATE_PROFILE_CATALOG:-}"
if [[ -z "$catalog" ]]; then
sha="''${2:?Usage: $0 <profile> <git-sha>}"
catalog="/tmp/''${profile_name}-catalog-''${sha}-''${system}.json"
aws s3 cp "s3://supabase-internal-artifacts/nix-catalog/''${sha}-''${profile_name}-''${system}.json" \
"$catalog" --region ap-southeast-1
fi

path="$(jq -er --arg s "$system" '.[$s]' "$catalog")"
[[ "$(basename "$path")" == *"-''${profile_name}" ]] || {
echo "error: resolved path $path is not tagged for profile $profile_name" >&2
exit 1
}

[[ "$(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"
'';
};
in
{
packages = siteEnvs;
legacyPackages = siteEnvs;
packages = siteEnvs // {
inherit update-profile;
};
legacyPackages = siteEnvs // {
inherit update-profile;
};
};
}
Loading