diff --git a/Dockerfile-17 b/Dockerfile-17 index 0dc465bdc..178f093c9 100644 --- a/Dockerfile-17 +++ b/Dockerfile-17 @@ -1,215 +1,132 @@ # syntax=docker/dockerfile:1.6 -ARG postgresql_major=17-orioledb -ARG postgresql_release=${postgresql_major}.1 - -# Bump default build arg to build a package from source -# Bump vars.yml to specify runtime package version -ARG sfcgal_release=1.3.10 -ARG postgis_release=3.3.2 -ARG pgrouting_release=3.4.1 -ARG pgtap_release=1.2.0 -ARG pg_cron_release=1.6.2 -ARG pgaudit_release=1.7.0 -ARG pgjwt_release=9742dab1b2f297ad3811120db7b21451bca2d3c9 -ARG pgsql_http_release=1.5.0 -ARG plpgsql_check_release=2.2.5 -ARG pg_safeupdate_release=1.4 -ARG timescaledb_release=2.9.1 -ARG wal2json_release=2_5 -ARG pljava_release=1.6.4 -ARG plv8_release=3.1.5 -ARG pg_plan_filter_release=5081a7b5cb890876e67d8e7486b6a64c38c9a492 -ARG pg_net_release=0.7.1 -ARG rum_release=1.3.13 -ARG pg_hashids_release=cd0e1b31d52b394a0df64079406a14a4f7387cd6 -ARG libsodium_release=1.0.18 -ARG pgsodium_release=3.1.6 -ARG pg_graphql_release=1.5.11 -ARG pg_stat_monitor_release=1.1.1 -ARG pg_jsonschema_release=0.1.4 -ARG pg_repack_release=1.4.8 -ARG vault_release=0.2.8 -ARG groonga_release=12.0.8 -ARG pgroonga_release=2.4.0 -ARG wrappers_release=0.5.7 -ARG hypopg_release=1.3.1 -ARG pgvector_release=0.4.0 -ARG pg_tle_release=1.3.2 -ARG index_advisor_release=0.2.0 -ARG supautils_release=2.2.0 -ARG wal_g_release=3.0.5 - -FROM ubuntu:noble as base - -# Create reusable apt mirror fallback function -RUN echo '#!/bin/bash\n\ -apt_update_with_fallback() {\n\ - local sources_file="/etc/apt/sources.list.d/ubuntu.sources"\n\ - local max_attempts=2\n\ - local attempt=1\n\ - local mirrors="archive.ubuntu.com us.archive.ubuntu.com"\n\ - \n\ - for mirror in $mirrors; do\n\ - echo "========================================="\n\ - echo "Attempting apt-get update with mirror: ${mirror}"\n\ - echo "Attempt ${attempt} of ${max_attempts}"\n\ - echo "========================================="\n\ - \n\ - if [ -f "${sources_file}" ]; then\n\ - sed -i "s|http://[^/]*/ubuntu/|http://${mirror}/ubuntu/|g" "${sources_file}"\n\ - fi\n\ - \n\ - if timeout 300 apt-get update 2>&1; then\n\ - echo "========================================="\n\ - echo "✓ Successfully updated apt cache using mirror: ${mirror}"\n\ - echo "========================================="\n\ - return 0\n\ - else\n\ - local exit_code=$?\n\ - echo "========================================="\n\ - echo "✗ Failed to update using mirror: ${mirror}"\n\ - echo "Exit code: ${exit_code}"\n\ - echo "========================================="\n\ - \n\ - apt-get clean\n\ - rm -rf /var/lib/apt/lists/*\n\ - \n\ - if [ ${attempt} -lt ${max_attempts} ]; then\n\ - local sleep_time=$((attempt * 5))\n\ - echo "Waiting ${sleep_time} seconds before trying next mirror..."\n\ - sleep ${sleep_time}\n\ - fi\n\ - fi\n\ - \n\ - attempt=$((attempt + 1))\n\ - done\n\ - \n\ - echo "========================================="\n\ - echo "ERROR: All mirror tiers failed after ${max_attempts} attempts"\n\ - echo "========================================="\n\ - return 1\n\ -}' > /usr/local/bin/apt-update-fallback.sh && chmod +x /usr/local/bin/apt-update-fallback.sh - -RUN bash -c 'source /usr/local/bin/apt-update-fallback.sh && apt_update_with_fallback' && apt install -y \ +# Alpine-based slim PostgreSQL image with Nix extensions + +#################### +# Stage 1: Nix builder +#################### +FROM alpine:3.21 AS nix-builder + +# Install dependencies for nix installer (coreutils for GNU cp, sudo for installer) +RUN apk add --no-cache \ + bash \ + coreutils \ curl \ - gnupg \ - lsb-release \ - software-properties-common \ - wget \ + shadow \ sudo \ - tree \ - && apt clean + xz +# Create users (Alpine syntax) +RUN addgroup -S postgres && \ + adduser -S -h /var/lib/postgresql -s /bin/bash -G postgres postgres && \ + addgroup -S wal-g && \ + adduser -S -s /bin/bash -G wal-g wal-g -RUN adduser --system --home /var/lib/postgresql --no-create-home --shell /bin/bash --group --gecos "PostgreSQL administrator" postgres -RUN adduser --system --no-create-home --shell /bin/bash --group wal-g +# Create nix config RUN cat < /tmp/extra-nix.conf 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 + +# Install nix RUN curl -L https://releases.nixos.org/nix/nix-2.32.2/install | sh -s -- --daemon --no-channel-add --yes --nix-extra-conf-file /tmp/extra-nix.conf ENV PATH="${PATH}:/nix/var/nix/profiles/default/bin" -COPY . /nixpg - WORKDIR /nixpg +COPY . . -RUN nix profile add path:.#psql_17/bin +# Build PostgreSQL with extensions +RUN nix profile add path:.#psql_17_slim/bin RUN nix store gc -WORKDIR / - - -RUN mkdir -p /usr/lib/postgresql/bin \ - /usr/lib/postgresql/share/postgresql \ - /usr/share/postgresql \ - /var/lib/postgresql \ - && chown -R postgres:postgres /usr/lib/postgresql \ - && chown -R postgres:postgres /var/lib/postgresql \ - && chown -R postgres:postgres /usr/share/postgresql - -# Create symbolic links -RUN ln -s /nix/var/nix/profiles/default/bin/* /usr/lib/postgresql/bin/ \ - && ln -s /nix/var/nix/profiles/default/bin/* /usr/bin/ \ - && chown -R postgres:postgres /usr/bin - -# Create symbolic links for PostgreSQL shares -RUN ln -s /nix/var/nix/profiles/default/share/postgresql/* /usr/lib/postgresql/share/postgresql/ -RUN ln -s /nix/var/nix/profiles/default/share/postgresql/* /usr/share/postgresql/ -RUN chown -R postgres:postgres /usr/lib/postgresql/share/postgresql/ -RUN chown -R postgres:postgres /usr/share/postgresql/ - -RUN tree /nix > /tmp/tree.txt && cat /tmp/tree.txt && cat /tmp/tree.txt >&2 - -RUN chown -R postgres:postgres /usr/lib/postgresql - -RUN ln -sf /usr/lib/postgresql/share/postgresql/timezonesets /usr/share/postgresql/timezonesets +# Build groonga and copy plugins +RUN nix profile add path:.#supabase-groonga && \ + mkdir -p /tmp/groonga-plugins && \ + cp -r /nix/var/nix/profiles/default/lib/groonga/plugins /tmp/groonga-plugins/ +RUN nix store gc -RUN bash -c 'source /usr/local/bin/apt-update-fallback.sh && apt_update_with_fallback' && \ - apt-get install -y --no-install-recommends tzdata +#################### +# Stage 2: Gosu builder +#################### +FROM alpine:3.21 AS gosu-builder -RUN ln -fs /usr/share/zoneinfo/Etc/UTC /etc/localtime && \ - dpkg-reconfigure --frontend noninteractive tzdata +ARG TARGETARCH +ARG GOSU_VERSION=1.16 -RUN bash -c 'source /usr/local/bin/apt-update-fallback.sh && apt_update_with_fallback' && \ - apt-get install -y --no-install-recommends \ - build-essential \ - checkinstall \ - cmake +RUN apk add --no-cache gnupg curl -ENV PGDATA=/var/lib/postgresql/data +# Download and verify gosu +RUN curl -fsSL "https://github.com/tianon/gosu/releases/download/${GOSU_VERSION}/gosu-${TARGETARCH}" -o /usr/local/bin/gosu && \ + curl -fsSL "https://github.com/tianon/gosu/releases/download/${GOSU_VERSION}/gosu-${TARGETARCH}.asc" -o /usr/local/bin/gosu.asc && \ + GNUPGHOME="$(mktemp -d)" && \ + export GNUPGHOME && \ + gpg --batch --keyserver hkps://keys.openpgp.org --recv-keys B42F6819007F00F88E364FD4036A9C25BF357DD4 && \ + gpg --batch --verify /usr/local/bin/gosu.asc /usr/local/bin/gosu && \ + rm -rf "$GNUPGHOME" /usr/local/bin/gosu.asc && \ + chmod +x /usr/local/bin/gosu -WORKDIR / #################### -# setup-groonga +# Stage 3: Final production image #################### -FROM base as groonga +FROM alpine:3.21 AS production -WORKDIR /nixpg - -RUN nix profile add path:.#supabase-groonga && \ - mkdir -p /tmp/groonga-plugins && \ - cp -r /nix/var/nix/profiles/default/lib/groonga/plugins /tmp/groonga-plugins/ +# Install minimal runtime dependencies +RUN apk add --no-cache \ + bash \ + curl \ + shadow \ + su-exec \ + tzdata \ + musl-locales \ + musl-locales-lang \ + && rm -rf /var/cache/apk/* + +# Create postgres user/group +RUN addgroup -S postgres && \ + adduser -S -G postgres -h /var/lib/postgresql -s /bin/bash postgres && \ + addgroup -S wal-g && \ + adduser -S -G wal-g -s /bin/bash wal-g && \ + adduser postgres wal-g + +# Copy Nix store and profiles from builder (profile already created by nix profile install) +COPY --from=nix-builder /nix /nix + +# Copy groonga plugins +COPY --from=nix-builder /tmp/groonga-plugins/plugins /usr/lib/groonga/plugins + +# Copy gosu +COPY --from=gosu-builder /usr/local/bin/gosu /usr/local/bin/gosu + +# Setup PostgreSQL directories +RUN mkdir -p /usr/lib/postgresql/bin \ + /usr/lib/postgresql/share/postgresql \ + /usr/share/postgresql \ + /var/lib/postgresql/data \ + /var/run/postgresql \ + && chown -R postgres:postgres /usr/lib/postgresql \ + && chown -R postgres:postgres /var/lib/postgresql \ + && chown -R postgres:postgres /usr/share/postgresql \ + && chown -R postgres:postgres /var/run/postgresql -RUN nix store gc +# Create symbolic links for binaries +RUN for f in /nix/var/nix/profiles/default/bin/*; do \ + ln -sf "$f" /usr/lib/postgresql/bin/ 2>/dev/null || true; \ + ln -sf "$f" /usr/bin/ 2>/dev/null || true; \ + done -WORKDIR / -# #################### -# # Download gosu for easy step-down from root -# #################### -FROM base as gosu -ARG TARGETARCH -# Install dependencies -RUN bash -c 'source /usr/local/bin/apt-update-fallback.sh && apt_update_with_fallback' && apt-get install -y --no-install-recommends \ - gnupg \ - ca-certificates \ - && rm -rf /var/lib/apt/lists/* -# Download binary -ARG GOSU_VERSION=1.16 -ARG GOSU_GPG_KEY=B42F6819007F00F88E364FD4036A9C25BF357DD4 -ADD https://github.com/tianon/gosu/releases/download/$GOSU_VERSION/gosu-$TARGETARCH \ - /usr/local/bin/gosu -ADD https://github.com/tianon/gosu/releases/download/$GOSU_VERSION/gosu-$TARGETARCH.asc \ - /usr/local/bin/gosu.asc -# Verify checksum -RUN gpg --batch --keyserver hkps://keys.openpgp.org --recv-keys $GOSU_GPG_KEY && \ - gpg --batch --verify /usr/local/bin/gosu.asc /usr/local/bin/gosu && \ - gpgconf --kill all && \ - chmod +x /usr/local/bin/gosu +# Create symbolic links for PostgreSQL shares +RUN ln -sf /nix/var/nix/profiles/default/share/postgresql/* /usr/lib/postgresql/share/postgresql/ 2>/dev/null || true && \ + ln -sf /nix/var/nix/profiles/default/share/postgresql/* /usr/share/postgresql/ 2>/dev/null || true && \ + ln -sf /usr/lib/postgresql/share/postgresql/timezonesets /usr/share/postgresql/timezonesets 2>/dev/null || true -# #################### -# # Build final image -# #################### -FROM gosu as production -RUN id postgres || (echo "postgres user does not exist" && exit 1) -# # Setup extensions -COPY --from=groonga /tmp/groonga-plugins/plugins /usr/lib/groonga/plugins +# Set permissions +RUN chown -R postgres:postgres /usr/lib/postgresql && \ + chown -R postgres:postgres /usr/share/postgresql -# # Initialise configs +# Setup configs COPY --chown=postgres:postgres ansible/files/postgresql_config/postgresql.conf.j2 /etc/postgresql/postgresql.conf COPY --chown=postgres:postgres ansible/files/postgresql_config/pg_hba.conf.j2 /etc/postgresql/pg_hba.conf COPY --chown=postgres:postgres ansible/files/postgresql_config/pg_ident.conf.j2 /etc/postgresql/pg_ident.conf @@ -221,60 +138,50 @@ COPY --chown=postgres:postgres ansible/files/pgsodium_getkey_urandom.sh.j2 /usr/ COPY --chown=postgres:postgres ansible/files/walg_helper_scripts/wal_fetch.sh /home/postgres/wal_fetch.sh COPY ansible/files/walg_helper_scripts/wal_change_ownership.sh /root/wal_change_ownership.sh +# Configure PostgreSQL settings RUN sed -i \ -e "s|#session_preload_libraries = ''|session_preload_libraries = 'supautils'|g" \ -e "s|#include = '/etc/postgresql-custom/supautils.conf'|include = '/etc/postgresql-custom/supautils.conf'|g" \ /etc/postgresql/postgresql.conf && \ echo "pgsodium.getkey_script= '/usr/lib/postgresql/bin/pgsodium_getkey.sh'" >> /etc/postgresql/postgresql.conf && \ echo "vault.getkey_script= '/usr/lib/postgresql/bin/pgsodium_getkey.sh'" >> /etc/postgresql/postgresql.conf && \ - usermod -aG postgres wal-g && \ chown -R postgres:postgres /etc/postgresql-custom - # Remove items from postgresql.conf -RUN sed -i 's/ timescaledb,//g;' "/etc/postgresql/postgresql.conf" - #as of pg 16.4 + this db_user_namespace totally deprecated and will break the server if setting is present -RUN sed -i 's/db_user_namespace = off/#db_user_namespace = off/g;' "/etc/postgresql/postgresql.conf" -RUN sed -i 's/ timescaledb,//g; s/ plv8,//g' "/etc/postgresql-custom/supautils.conf" +# Remove timescaledb and plv8 references (not in pg17) +RUN sed -i 's/ timescaledb,//g;' "/etc/postgresql/postgresql.conf" && \ + sed -i 's/db_user_namespace = off/#db_user_namespace = off/g;' "/etc/postgresql/postgresql.conf" && \ + sed -i 's/ timescaledb,//g; s/ plv8,//g' "/etc/postgresql-custom/supautils.conf" - - -# # Include schema migrations +# Include schema migrations COPY migrations/db /docker-entrypoint-initdb.d/ COPY ansible/files/pgbouncer_config/pgbouncer_auth_schema.sql /docker-entrypoint-initdb.d/init-scripts/00-schema.sql COPY ansible/files/stat_extension.sql /docker-entrypoint-initdb.d/migrations/00-extension.sql -# # Add upstream entrypoint script pinned for now to last tested version -COPY --from=gosu /usr/local/bin/gosu /usr/local/bin/gosu +# Add entrypoint script ADD --chmod=0755 \ https://github.com/docker-library/postgres/raw/889f9447cd2dfe21cccfbe9bb7945e3b037e02d8/17/bullseye/docker-entrypoint.sh \ /usr/local/bin/docker-entrypoint.sh -RUN mkdir -p /var/run/postgresql && chown postgres:postgres /var/run/postgresql - -ENTRYPOINT ["docker-entrypoint.sh"] - -HEALTHCHECK --interval=2s --timeout=2s --retries=10 CMD pg_isready -U postgres -h localhost -STOPSIGNAL SIGINT -EXPOSE 5432 +# Setup pgsodium key script +RUN mkdir -p /usr/share/postgresql/extension/ && \ + ln -s /usr/lib/postgresql/bin/pgsodium_getkey.sh /usr/share/postgresql/extension/pgsodium_getkey && \ + chmod +x /usr/lib/postgresql/bin/pgsodium_getkey.sh +# Environment variables +ENV PATH="/nix/var/nix/profiles/default/bin:/usr/lib/postgresql/bin:${PATH}" +ENV PGDATA=/var/lib/postgresql/data ENV POSTGRES_HOST=/var/run/postgresql ENV POSTGRES_USER=supabase_admin ENV POSTGRES_DB=postgres ENV POSTGRES_INITDB_ARGS="--allow-group-access --locale-provider=icu --encoding=UTF-8 --icu-locale=en_US.UTF-8" -RUN bash -c 'source /usr/local/bin/apt-update-fallback.sh && apt_update_with_fallback' && apt-get install -y --no-install-recommends \ - locales \ - && rm -rf /var/lib/apt/lists/* && \ - localedef -i en_US -c -f UTF-8 -A /usr/share/locale/locale.alias en_US.UTF-8 \ - && localedef -i C -c -f UTF-8 -A /usr/share/locale/locale.alias C.UTF-8 -RUN echo "C.UTF-8 UTF-8" > /etc/locale.gen && echo "en_US.UTF-8 UTF-8" >> /etc/locale.gen && locale-gen -ENV LANG en_US.UTF-8 -ENV LANGUAGE en_US:en -ENV LC_ALL en_US.UTF-8 -ENV LOCALE_ARCHIVE /usr/lib/locale/locale-archive -RUN mkdir -p /usr/share/postgresql/extension/ && \ - ln -s /usr/lib/postgresql/bin/pgsodium_getkey.sh /usr/share/postgresql/extension/pgsodium_getkey && \ - chmod +x /usr/lib/postgresql/bin/pgsodium_getkey.sh - +ENV LANG=en_US.UTF-8 +ENV LANGUAGE=en_US:en +ENV LC_ALL=en_US.UTF-8 ENV GRN_PLUGINS_DIR=/usr/lib/groonga/plugins +ENTRYPOINT ["docker-entrypoint.sh"] +HEALTHCHECK --interval=2s --timeout=2s --retries=10 CMD pg_isready -U postgres -h localhost +STOPSIGNAL SIGINT +EXPOSE 5432 + CMD ["postgres", "-D", "/etc/postgresql"] diff --git a/docs/plans/2026-01-21-psql-slim-latest-only.md b/docs/plans/2026-01-21-psql-slim-latest-only.md new file mode 100644 index 000000000..9654b2009 --- /dev/null +++ b/docs/plans/2026-01-21-psql-slim-latest-only.md @@ -0,0 +1,536 @@ +# PostgreSQL Slim Image (Latest Extensions Only) Implementation Plan + +> **For Claude:** REQUIRED SUB-SKILL: Use superpowers:executing-plans to implement this plan task-by-task. + +**Goal:** Create a new `psql_17_slim/bin` flake output that includes only the latest version of each PostgreSQL extension, reducing image size by ~40-60%. + +**Architecture:** Add a `latestOnly` parameter to extension nix files. When true, only build the latest version instead of all versions. Create new `makePostgresBinSlim` function in postgres.nix that passes this parameter. + +**Tech Stack:** Nix, flake-parts + +**Estimated size reduction:** ~700MB+ (wrappers alone has 13 versions → 1) + +--- + +## Task 1: Update postgres.nix to Support Slim Builds + +**Files:** +- Modify: `nix/packages/postgres.nix` + +**Step 1: Add latestOnly parameter to extCallPackage** + +In `makeOurPostgresPkgs`, modify the `extCallPackage` call to accept a `latestOnly` parameter: + +```nix +# Around line 94, modify makeOurPostgresPkgs to accept latestOnly parameter +makeOurPostgresPkgs = + version: + { latestOnly ? false }: + let + postgresql = getPostgresqlPackage version; + extensionsToUse = + if (builtins.elem version [ "orioledb-17" ]) then + orioledbExtensions + else if (builtins.elem version [ "17" ]) then + dbExtensions17 + else + ourExtensions; + extCallPackage = pkgs.lib.callPackageWith ( + pkgs + // { + inherit postgresql latestOnly; + switch-ext-version = extCallPackage ./switch-ext-version.nix { }; + overlayfs-on-package = extCallPackage ./overlayfs-on-package.nix { }; + } + ); + in + map (path: extCallPackage path { }) extensionsToUse; +``` + +**Step 2: Update makePostgresBin to accept latestOnly** + +```nix +# Around line 143, modify makePostgresBin +makePostgresBin = + version: + { latestOnly ? false }: + let + postgresql = getPostgresqlPackage version; + postgres-pkgs = makeOurPostgresPkgs version { inherit latestOnly; }; + ourExts = map (ext: { + name = ext.name; + version = ext.version; + }) postgres-pkgs; + + pgbin = postgresql.withPackages (_ps: postgres-pkgs); + in + pkgs.symlinkJoin { + inherit (pgbin) name version; + paths = [ + pgbin + (makeReceipt pgbin ourExts) + ]; + }; +``` + +**Step 3: Update makePostgres to accept latestOnly** + +```nix +# Around line 172, modify makePostgres +makePostgres = + version: + { latestOnly ? false }: + lib.recurseIntoAttrs { + bin = makePostgresBin version { inherit latestOnly; }; + exts = makeOurPostgresPkgsSet version; + }; +``` + +**Step 4: Add slim packages to basePackages** + +```nix +# Around line 178 +basePackages = { + psql_15 = makePostgres "15" { }; + psql_17 = makePostgres "17" { }; + psql_orioledb-17 = makePostgres "orioledb-17" { }; +}; + +slimPackages = { + psql_17_slim = makePostgres "17" { latestOnly = true; }; +}; +``` + +**Step 5: Update binPackages to include slim variants** + +```nix +# Around line 183 +binPackages = lib.mapAttrs' (name: value: { + name = "${name}/bin"; + value = value.bin; +}) (basePackages // slimPackages); +``` + +**Step 6: Commit** + +```bash +git add nix/packages/postgres.nix +git commit -m "feat(nix): add latestOnly parameter support to postgres.nix" +``` + +--- + +## Task 2: Update pgvector.nix (Template Pattern) + +**Files:** +- Modify: `nix/ext/pgvector.nix` + +This is the template pattern that will be applied to all multi-version extensions. + +**Step 1: Add latestOnly parameter to function signature** + +```nix +# Line 1-7, add latestOnly parameter +{ + pkgs, + lib, + stdenv, + fetchFromGitHub, + postgresql, + latestOnly ? false, +}: +``` + +**Step 2: Modify version selection to respect latestOnly** + +```nix +# After line 21 (after latestVersion = lib.last versions;) +# Replace: +# packages = builtins.attrValues ( +# lib.mapAttrs (name: value: build name value.hash) supportedVersions +# ); +# With: +versionsToUse = if latestOnly + then { "${latestVersion}" = supportedVersions.${latestVersion}; } + else supportedVersions; +packages = builtins.attrValues ( + lib.mapAttrs (name: value: build name value.hash) versionsToUse +); +versionsBuilt = if latestOnly then [ latestVersion ] else versions; +numberOfVersionsBuilt = builtins.length versionsBuilt; +``` + +**Step 3: Update passthru to reflect actual versions built** + +```nix +# Around line 85-91, update passthru +passthru = { + versions = versionsBuilt; + numberOfVersions = numberOfVersionsBuilt; + inherit pname latestOnly; + version = if latestOnly + then latestVersion + else "multi-" + lib.concatStringsSep "-" (map (v: lib.replaceStrings [ "." ] [ "-" ] v) versions); + pgRegressTestName = "pgvector"; +}; +``` + +**Step 4: Commit** + +```bash +git add nix/ext/pgvector.nix +git commit -m "feat(ext): add latestOnly support to pgvector" +``` + +--- + +## Task 3: Update wrappers/default.nix + +**Files:** +- Modify: `nix/ext/wrappers/default.nix` + +This is the most complex extension with migration SQL files. Since we don't need migrations for slim, simplify significantly. + +**Step 1: Add latestOnly parameter** + +```nix +# Line 1-12, add latestOnly parameter +{ + lib, + stdenv, + callPackages, + fetchFromGitHub, + openssl, + pkg-config, + postgresql, + buildEnv, + rust-bin, + git, + latestOnly ? false, +}: +``` + +**Step 2: Modify version selection** + +```nix +# After line 208 (after latestVersion = lib.last versions;) +versionsToUse = if latestOnly + then lib.filterAttrs (n: _: n == latestVersion) supportedVersions + else supportedVersions; +versionsBuilt = if latestOnly then [ latestVersion ] else versions; +numberOfVersionsBuilt = builtins.length versionsBuilt; + +# Update packagesAttrSet to use versionsToUse +packagesAttrSet = lib.mapAttrs' (name: value: { + name = lib.replaceStrings [ "." ] [ "_" ] name; + value = build name value.hash value.rust value.pgrx; +}) versionsToUse; +``` + +**Step 3: Simplify postBuild for latestOnly** + +```nix +# Around line 229, modify postBuild to skip migrations when latestOnly +postBuild = '' + create_control_files() { + { + echo "default_version = '${latestVersion}'" + cat $out/share/postgresql/extension/${pname}--${latestVersion}.control + } > $out/share/postgresql/extension/${pname}.control + } + + create_lib_files() { + ln -sfn ${pname}-${latestVersion}${postgresql.dlSuffix} $out/lib/${pname}${postgresql.dlSuffix} + ${lib.optionalString (!latestOnly) '' + # Create symlinks for all previously packaged versions to main library + for v in ${lib.concatStringsSep " " previouslyPackagedVersions}; do + ln -sfn $out/lib/${pname}${postgresql.dlSuffix} $out/lib/${pname}-$v${postgresql.dlSuffix} + done + ''} + } + + ${lib.optionalString (!latestOnly) '' + create_migration_sql_files() { + # ... existing migration logic ... + } + ''} + + create_control_files + create_lib_files + ${lib.optionalString (!latestOnly) "create_migration_sql_files"} + + # Verify library count matches expected + ${if latestOnly then '' + (test "$(ls -A $out/lib/${pname}*${postgresql.dlSuffix} | wc -l)" = "2") + '' else '' + (test "$(ls -A $out/lib/${pname}*${postgresql.dlSuffix} | wc -l)" = "${ + toString (numberOfVersions + numberOfPreviouslyPackagedVersions + 1) + }") + ''} +''; +``` + +**Step 4: Update passthru** + +```nix +passthru = { + versions = versionsBuilt; + numberOfVersions = numberOfVersionsBuilt; + pname = "${pname}"; + inherit latestOnly; + version = if latestOnly + then latestVersion + else "multi-" + lib.concatStringsSep "-" (map (v: lib.replaceStrings [ "." ] [ "-" ] v) versions); + packages = packagesAttrSet // { + recurseForDerivations = true; + }; +}; +``` + +**Step 5: Commit** + +```bash +git add nix/ext/wrappers/default.nix +git commit -m "feat(ext): add latestOnly support to wrappers" +``` + +--- + +## Task 4: Update pg_graphql/default.nix + +**Files:** +- Modify: `nix/ext/pg_graphql/default.nix` + +**Step 1: Add latestOnly parameter and modify version selection** + +Apply the same pattern as pgvector: +1. Add `latestOnly ? false` to function parameters +2. Create `versionsToUse` filtered by latestOnly +3. Update packages list to use versionsToUse +4. Update passthru + +**Step 2: Commit** + +```bash +git add nix/ext/pg_graphql/default.nix +git commit -m "feat(ext): add latestOnly support to pg_graphql" +``` + +--- + +## Task 5: Update pg_net.nix + +**Files:** +- Modify: `nix/ext/pg_net.nix` + +Apply the same pattern as pgvector. + +**Step 1: Add latestOnly parameter and modify version selection** + +**Step 2: Update library count check for latestOnly** + +```nix +# In postBuild, update the check +${if latestOnly then '' + (test "$(ls -A $out/lib/${pname}*${postgresql.dlSuffix} | wc -l)" = "2") +'' else '' + (test "$(ls -A $out/lib/${pname}*${postgresql.dlSuffix} | wc -l)" = "${ + toString (numberOfVersions + 1) + }") +''} +``` + +**Step 3: Commit** + +```bash +git add nix/ext/pg_net.nix +git commit -m "feat(ext): add latestOnly support to pg_net" +``` + +--- + +## Task 6: Update pgsodium.nix + +**Files:** +- Modify: `nix/ext/pgsodium.nix` + +Apply the same pattern as pgvector. + +**Commit:** +```bash +git add nix/ext/pgsodium.nix +git commit -m "feat(ext): add latestOnly support to pgsodium" +``` + +--- + +## Task 7: Update pgaudit.nix + +**Files:** +- Modify: `nix/ext/pgaudit.nix` + +Apply the same pattern as pgvector. + +**Commit:** +```bash +git add nix/ext/pgaudit.nix +git commit -m "feat(ext): add latestOnly support to pgaudit" +``` + +--- + +## Task 8: Update pg_jsonschema/default.nix + +**Files:** +- Modify: `nix/ext/pg_jsonschema/default.nix` + +Apply the same pattern as pgvector. + +**Commit:** +```bash +git add nix/ext/pg_jsonschema/default.nix +git commit -m "feat(ext): add latestOnly support to pg_jsonschema" +``` + +--- + +## Task 9: Update Remaining Multi-Version Extensions + +Apply the same pattern to these extensions (4 or fewer versions each): + +**Files:** +- `nix/ext/pg_cron/default.nix` +- `nix/ext/pg_repack.nix` +- `nix/ext/pg_tle.nix` +- `nix/ext/plv8/default.nix` +- `nix/ext/pgsql-http.nix` +- `nix/ext/hypopg.nix` +- `nix/ext/pgmq/default.nix` +- `nix/ext/pgroonga/default.nix` +- `nix/ext/pgrouting/default.nix` +- `nix/ext/vault.nix` +- `nix/ext/rum.nix` +- `nix/ext/postgis.nix` +- `nix/ext/supautils.nix` + +For single-version extensions, just add the parameter with no-op behavior: +```nix +latestOnly ? false, # unused, for API compatibility +``` + +**Commit:** +```bash +git add nix/ext/ +git commit -m "feat(ext): add latestOnly support to remaining extensions" +``` + +--- + +## Task 10: Update Dockerfile-17 to Use Slim Package + +**Files:** +- Modify: `Dockerfile-17` + +**Step 1: Change nix profile add command** + +Find the line: +```dockerfile +RUN nix profile add path:.#psql_17/bin +``` + +Change to: +```dockerfile +RUN nix profile add path:.#psql_17_slim/bin +``` + +**Step 2: Commit** + +```bash +git add Dockerfile-17 +git commit -m "feat(docker): use psql_17_slim for smaller image size" +``` + +--- + +## Task 11: Test and Verify + +**Step 1: Build the slim package** + +```bash +nix build .#psql_17_slim/bin +``` + +Expected: Build succeeds with only latest versions. + +**Step 2: Verify extension count** + +```bash +ls -la result/lib/*.so | wc -l +``` + +Expected: Significantly fewer .so files than full build. + +**Step 3: Verify receipt.json** + +```bash +cat result/receipt.json | jq '.extensions | length' +``` + +Expected: Same number of extensions, but each with single version. + +**Step 4: Build Docker image and compare size** + +```bash +nix run .#image-size-analyzer -- --image Dockerfile-17 +``` + +Expected: Total size reduced by 40-60%. + +**Step 5: Commit any fixes** + +--- + +## Task 12: Update Documentation + +**Files:** +- Modify: `nix/docs/image-size-analyzer-usage.md` + +Add section explaining the slim vs full packages: + +```markdown +## Package Variants + +### Full Package (`psql_17/bin`) +Includes all versions of each extension for migration support. +Use for: Production databases that need `ALTER EXTENSION ... UPDATE`. + +### Slim Package (`psql_17_slim/bin`) +Includes only the latest version of each extension. +Use for: CI/CD, testing, new deployments without migration needs. +Typical size savings: 40-60% smaller. +``` + +**Commit:** +```bash +git add nix/docs/ +git commit -m "docs: document slim vs full package variants" +``` + +--- + +## Summary + +| Task | Files Modified | Estimated Savings | +|------|---------------|-------------------| +| 1 | postgres.nix | - | +| 2 | pgvector.nix | ~100MB | +| 3 | wrappers/default.nix | ~700MB | +| 4 | pg_graphql/default.nix | ~200MB | +| 5 | pg_net.nix | ~150MB | +| 6 | pgsodium.nix | ~50MB | +| 7 | pgaudit.nix | ~30MB | +| 8 | pg_jsonschema/default.nix | ~30MB | +| 9 | Remaining extensions | ~100MB | +| 10 | Dockerfile-17 | - | + +**Total estimated savings: 1.2-1.5 GB** diff --git a/nix/apps.nix b/nix/apps.nix index acf42910c..46fc12500 100644 --- a/nix/apps.nix +++ b/nix/apps.nix @@ -21,6 +21,7 @@ pg-restore = mkApp "pg-restore" "pg-restore"; local-infra-bootstrap = mkApp "local-infra-bootstrap" "local-infra-bootstrap"; dbmate-tool = mkApp "dbmate-tool" "dbmate-tool"; + image-size-analyzer = mkApp "image-size-analyzer" "image-size-analyzer"; update-readme = mkApp "update-readme" "update-readme"; show-commands = mkApp "show-commands" "show-commands"; build-test-ami = mkApp "build-test-ami" "build-test-ami"; diff --git a/nix/checks.nix b/nix/checks.nix index 6e68c734e..fbfedddf9 100644 --- a/nix/checks.nix +++ b/nix/checks.nix @@ -28,6 +28,10 @@ # deadnix: skip makeCheckHarness = pgpkg: + # legacyPkgName: the name used in legacyPackages (e.g., "psql_17" or "psql_17_slim") + { + legacyPkgName ? null, + }: let pg_prove = pkgs.perlPackages.TAPParserSourceHandlerpgTAP; inherit (self'.packages) pg_regress; @@ -87,11 +91,23 @@ in builtins.trace "Major version result: ${result}" result; + # Determine the legacy package name for selecting extensions + effectiveLegacyPkgName = if legacyPkgName != null then legacyPkgName else "psql_${majorVersion}"; + # Select the appropriate pgroonga package for this PostgreSQL version - pgroonga = self'.legacyPackages."psql_${majorVersion}".exts.pgroonga; + pgroonga = self'.legacyPackages.${effectiveLegacyPkgName}.exts.pgroonga; + # Use different ports to allow parallel test runs + # slim packages get their own ports to avoid conflicts + isSlim = lib.hasSuffix "_slim" effectiveLegacyPkgName; pgPort = - if (majorVersion == "17") then + if (majorVersion == "17" && isSlim) then + "5538" + else if (majorVersion == "15" && isSlim) then + "5539" + else if (majorVersion == "orioledb-17" && isSlim) then + "5540" + else if (majorVersion == "17") then "5535" else if (majorVersion == "15") then "5536" @@ -424,13 +440,28 @@ in { psql_15 = pkgs.runCommand "run-check-harness-psql-15" { } ( - lib.getExe (makeCheckHarness self'.packages."psql_15/bin") + lib.getExe (makeCheckHarness self'.packages."psql_15/bin" { legacyPkgName = "psql_15"; }) ); psql_17 = pkgs.runCommand "run-check-harness-psql-17" { } ( - lib.getExe (makeCheckHarness self'.packages."psql_17/bin") + lib.getExe (makeCheckHarness self'.packages."psql_17/bin" { legacyPkgName = "psql_17"; }) ); psql_orioledb-17 = pkgs.runCommand "run-check-harness-psql-orioledb-17" { } ( - lib.getExe (makeCheckHarness self'.packages."psql_orioledb-17/bin") + lib.getExe ( + makeCheckHarness self'.packages."psql_orioledb-17/bin" { legacyPkgName = "psql_orioledb-17"; } + ) + ); + psql_15_slim = pkgs.runCommand "run-check-harness-psql-15-slim" { } ( + lib.getExe (makeCheckHarness self'.packages."psql_15_slim/bin" { legacyPkgName = "psql_15_slim"; }) + ); + psql_17_slim = pkgs.runCommand "run-check-harness-psql-17-slim" { } ( + lib.getExe (makeCheckHarness self'.packages."psql_17_slim/bin" { legacyPkgName = "psql_17_slim"; }) + ); + psql_orioledb-17_slim = pkgs.runCommand "run-check-harness-psql-orioledb-17-slim" { } ( + lib.getExe ( + makeCheckHarness self'.packages."psql_orioledb-17_slim/bin" { + legacyPkgName = "psql_orioledb-17_slim"; + } + ) ); inherit (self'.packages) wal-g-2 diff --git a/nix/docs/image-size-analyzer-usage.md b/nix/docs/image-size-analyzer-usage.md new file mode 100644 index 000000000..dc5845b06 --- /dev/null +++ b/nix/docs/image-size-analyzer-usage.md @@ -0,0 +1,269 @@ +# Image Size Analyzer - Usage Guide + +A tool to analyze Docker image sizes for Supabase Postgres images, providing breakdowns by layers, directories, Nix packages, and APT packages. + +## Local Usage + +### Prerequisites + +- Nix with flakes enabled +- Docker daemon running + +### Basic Commands + +```bash +# Analyze all images (Dockerfile-15, Dockerfile-17, Dockerfile-orioledb-17) +# This will build all images first, then analyze them +nix run .#image-size-analyzer + +# Analyze a specific image +nix run .#image-size-analyzer -- --image Dockerfile-17 + +# Analyze multiple specific images +nix run .#image-size-analyzer -- --image Dockerfile-15 --image Dockerfile-17 + +# Skip building (analyze existing images) +# Images must already exist with the -analyze tag suffix +nix run .#image-size-analyzer -- --no-build + +# Output as JSON instead of TUI +nix run .#image-size-analyzer -- --json + +# Combine flags +nix run .#image-size-analyzer -- --image Dockerfile-17 --json --no-build +``` + +### Understanding the Output + +The TUI output shows four sections per image: + +1. **Total Size** - Overall image size +2. **Layers** - Top 10 Docker layers by size, showing which Dockerfile instructions add the most +3. **Directories** - Top 10 directories by size inside the image +4. **Nix Packages** - Top 15 Nix store packages by size (e.g., postgresql, postgis, extensions) +5. **APT Packages** - Top 15 Debian packages by size + +### Example Workflow + +```bash +# 1. Make changes to reduce image size (e.g., remove an extension) + +# 2. Build and analyze the specific image you changed +nix run .#image-size-analyzer -- --image Dockerfile-17 + +# 3. Compare with JSON output for precise numbers +nix run .#image-size-analyzer -- --image Dockerfile-17 --json > before.json + +# 4. Make more changes, then compare +nix run .#image-size-analyzer -- --image Dockerfile-17 --json > after.json +diff before.json after.json +``` + +--- + +## CI Usage + +### GitHub Actions Example + +```yaml +name: Image Size Analysis + +on: + pull_request: + paths: + - 'docker/**' + - 'nix/**' + workflow_dispatch: + +jobs: + analyze-image-size: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - name: Install Nix + uses: cachix/install-nix-action@v27 + with: + extra_nix_config: | + extra-substituters = https://nix-postgres-artifacts.s3.amazonaws.com + extra-trusted-public-keys = nix-postgres-artifacts:dGZlQOvKcNEjvT7QEAJbcV6b6uk7VF/hWMjhYleiaLI= + + - name: Analyze image sizes + run: | + nix run .#image-size-analyzer -- --json > image-sizes.json + + - name: Upload size report + uses: actions/upload-artifact@v4 + with: + name: image-size-report + path: image-sizes.json + + - name: Comment PR with sizes + if: github.event_name == 'pull_request' + uses: actions/github-script@v7 + with: + script: | + const fs = require('fs'); + const report = JSON.parse(fs.readFileSync('image-sizes.json', 'utf8')); + + let comment = '## Docker Image Size Report\n\n'; + for (const image of report.images) { + const sizeGB = (image.total_size_bytes / 1073741824).toFixed(2); + comment += `### ${image.dockerfile}: ${sizeGB} GB\n\n`; + + comment += '**Top 5 Nix Packages:**\n'; + for (const pkg of image.nix_packages.slice(0, 5)) { + const sizeMB = (pkg.size_bytes / 1048576).toFixed(1); + comment += `- ${pkg.name}: ${sizeMB} MB\n`; + } + comment += '\n'; + } + + github.rest.issues.createComment({ + issue_number: context.issue.number, + owner: context.repo.owner, + repo: context.repo.repo, + body: comment + }); +``` + +### Size Threshold Check + +Add a job that fails if images exceed a size threshold: + +```yaml + check-size-threshold: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - name: Install Nix + uses: cachix/install-nix-action@v27 + with: + extra_nix_config: | + extra-substituters = https://nix-postgres-artifacts.s3.amazonaws.com + extra-trusted-public-keys = nix-postgres-artifacts:dGZlQOvKcNEjvT7QEAJbcV6b6uk7VF/hWMjhYleiaLI= + + - name: Check image sizes + run: | + nix run .#image-size-analyzer -- --json > sizes.json + + # Set threshold (2.5 GB in bytes) + THRESHOLD=2684354560 + + # Check each image + for dockerfile in Dockerfile-15 Dockerfile-17 Dockerfile-orioledb-17; do + size=$(jq -r ".images[] | select(.dockerfile == \"$dockerfile\") | .total_size_bytes" sizes.json) + if [ "$size" -gt "$THRESHOLD" ]; then + echo "ERROR: $dockerfile exceeds size threshold" + echo " Size: $((size / 1048576)) MB" + echo " Threshold: $((THRESHOLD / 1048576)) MB" + exit 1 + fi + echo "OK: $dockerfile = $((size / 1048576)) MB" + done +``` + +### Size Regression Check + +Compare against a baseline to catch size regressions: + +```yaml + check-size-regression: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + with: + fetch-depth: 0 # Need full history for base branch + + - name: Install Nix + uses: cachix/install-nix-action@v27 + with: + extra_nix_config: | + extra-substituters = https://nix-postgres-artifacts.s3.amazonaws.com + extra-trusted-public-keys = nix-postgres-artifacts:dGZlQOvKcNEjvT7QEAJbcV6b6uk7VF/hWMjhYleiaLI= + + - name: Analyze PR branch + run: | + nix run .#image-size-analyzer -- --image Dockerfile-17 --json > pr-sizes.json + + - name: Analyze base branch + run: | + git checkout ${{ github.base_ref }} + nix run .#image-size-analyzer -- --image Dockerfile-17 --json > base-sizes.json + git checkout - + + - name: Compare sizes + run: | + PR_SIZE=$(jq -r '.images[0].total_size_bytes' pr-sizes.json) + BASE_SIZE=$(jq -r '.images[0].total_size_bytes' base-sizes.json) + + DIFF=$((PR_SIZE - BASE_SIZE)) + DIFF_MB=$((DIFF / 1048576)) + + # Allow up to 50MB increase + MAX_INCREASE=52428800 + + if [ "$DIFF" -gt "$MAX_INCREASE" ]; then + echo "ERROR: Image size increased by ${DIFF_MB}MB (max allowed: 50MB)" + echo "Base: $((BASE_SIZE / 1048576))MB" + echo "PR: $((PR_SIZE / 1048576))MB" + exit 1 + fi + + echo "Size change: ${DIFF_MB}MB" +``` + +--- + +## JSON Output Schema + +```json +{ + "images": [ + { + "dockerfile": "Dockerfile-17", + "total_size_bytes": 1954000000, + "layers": [ + { + "index": 0, + "size_bytes": 890000000, + "command": "COPY /nix/store /nix/store" + } + ], + "directories": [ + { + "path": "/nix/store", + "size_bytes": 1200000000 + } + ], + "nix_packages": [ + { + "name": "postgresql-17.6", + "size_bytes": 152000000 + } + ], + "apt_packages": [ + { + "name": "libc6", + "size_bytes": 12500000 + } + ] + } + ] +} +``` + +--- + +## Tips + +1. **Use `--no-build` for iteration** - Once you've built an image, use `--no-build` to quickly re-analyze without rebuilding. + +2. **Focus on Nix packages** - Most of the image size comes from `/nix/store/`. The Nix packages breakdown helps identify which extensions or dependencies are largest. + +3. **Check layers for optimization opportunities** - If a layer is unexpectedly large, investigate the corresponding Dockerfile instruction. + +4. **Use JSON for automation** - The JSON output is stable and can be parsed with `jq` for scripting and CI integration. + +5. **Compare before/after** - Always capture baseline sizes before making changes so you can measure the impact. diff --git a/nix/ext/hypopg.nix b/nix/ext/hypopg.nix index 92784a8de..b3e880a1b 100644 --- a/nix/ext/hypopg.nix +++ b/nix/ext/hypopg.nix @@ -4,6 +4,7 @@ buildEnv, fetchFromGitHub, postgresql, + latestOnly ? false, }: let @@ -14,7 +15,13 @@ let ) allVersions; versions = lib.naturalSort (lib.attrNames supportedVersions); latestVersion = lib.last versions; - numberOfVersions = builtins.length versions; + versionsToUse = + if latestOnly then + { "${latestVersion}" = supportedVersions.${latestVersion}; } + else + supportedVersions; + versionsBuilt = if latestOnly then [ latestVersion ] else versions; + numberOfVersionsBuilt = builtins.length versionsBuilt; build = version: hash: stdenv.mkDerivation rec { @@ -66,9 +73,7 @@ let inherit (postgresql.meta) platforms; }; }; - packages = builtins.attrValues ( - lib.mapAttrs (name: value: build name value.hash) supportedVersions - ); + packages = builtins.attrValues (lib.mapAttrs (name: value: build name value.hash) versionsToUse); in buildEnv { name = pname; @@ -81,14 +86,19 @@ buildEnv { # checks (set -x test "$(ls -A $out/lib/${pname}*${postgresql.dlSuffix} | wc -l)" = "${ - toString (numberOfVersions + 1) + toString (numberOfVersionsBuilt + 1) }" ) ''; passthru = { - inherit versions numberOfVersions pname; + versions = versionsBuilt; + numberOfVersions = numberOfVersionsBuilt; + inherit pname latestOnly; version = - "multi-" + lib.concatStringsSep "-" (map (v: lib.replaceStrings [ "." ] [ "-" ] v) versions); + if latestOnly then + latestVersion + else + "multi-" + lib.concatStringsSep "-" (map (v: lib.replaceStrings [ "." ] [ "-" ] v) versions); }; } diff --git a/nix/ext/index_advisor.nix b/nix/ext/index_advisor.nix index 85a23bfd0..3130d4bcc 100644 --- a/nix/ext/index_advisor.nix +++ b/nix/ext/index_advisor.nix @@ -5,6 +5,7 @@ fetchFromGitHub, postgresql, callPackage, + latestOnly ? false, }: let @@ -15,7 +16,13 @@ let ) allVersions; versions = lib.naturalSort (lib.attrNames supportedVersions); latestVersion = lib.last versions; - numberOfVersions = builtins.length versions; + versionsToUse = + if latestOnly then + { "${latestVersion}" = supportedVersions.${latestVersion}; } + else + supportedVersions; + versionsBuilt = if latestOnly then [ latestVersion ] else versions; + numberOfVersionsBuilt = builtins.length versionsBuilt; build = version: hash: stdenv.mkDerivation rec { @@ -64,9 +71,7 @@ let inherit (postgresql.meta) platforms; }; }; - packages = builtins.attrValues ( - lib.mapAttrs (name: value: build name value.hash) supportedVersions - ); + packages = builtins.attrValues (lib.mapAttrs (name: value: build name value.hash) versionsToUse); in pkgs.buildEnv { name = pname; @@ -78,8 +83,13 @@ pkgs.buildEnv { ]; passthru = { - inherit versions numberOfVersions pname; + versions = versionsBuilt; + numberOfVersions = numberOfVersionsBuilt; + inherit pname latestOnly; version = - "multi-" + lib.concatStringsSep "-" (map (v: lib.replaceStrings [ "." ] [ "-" ] v) versions); + if latestOnly then + latestVersion + else + "multi-" + lib.concatStringsSep "-" (map (v: lib.replaceStrings [ "." ] [ "-" ] v) versions); }; } diff --git a/nix/ext/pg-safeupdate.nix b/nix/ext/pg-safeupdate.nix index ee31f4371..97921c9c6 100644 --- a/nix/ext/pg-safeupdate.nix +++ b/nix/ext/pg-safeupdate.nix @@ -5,6 +5,7 @@ fetchFromGitHub, postgresql, makeWrapper, + latestOnly ? false, }: let @@ -49,10 +50,14 @@ let ) allVersions; versions = lib.naturalSort (lib.attrNames supportedVersions); latestVersion = lib.last versions; - numberOfVersions = builtins.length versions; - packages = builtins.attrValues ( - lib.mapAttrs (name: value: build name value.hash) supportedVersions - ); + versionsToUse = + if latestOnly then + { "${latestVersion}" = supportedVersions.${latestVersion}; } + else + supportedVersions; + versionsBuilt = if latestOnly then [ latestVersion ] else versions; + numberOfVersionsBuilt = builtins.length versionsBuilt; + packages = builtins.attrValues (lib.mapAttrs (name: value: build name value.hash) versionsToUse); in pkgs.buildEnv { name = pname; @@ -68,18 +73,23 @@ pkgs.buildEnv { # checks (set -x test "$(ls -A $out/lib/${pname}*${postgresql.dlSuffix} | wc -l)" = "${ - toString (numberOfVersions + 1) + toString (numberOfVersionsBuilt + 1) }" ) ''; passthru = { - inherit versions numberOfVersions pname; + versions = versionsBuilt; + numberOfVersions = numberOfVersionsBuilt; + inherit pname latestOnly; defaultSettings = { shared_preload_libraries = [ "safeupdate" ]; }; pgRegressTestName = "pg-safeupdate"; version = - "multi-" + lib.concatStringsSep "-" (map (v: lib.replaceStrings [ "." ] [ "-" ] v) versions); + if latestOnly then + latestVersion + else + "multi-" + lib.concatStringsSep "-" (map (v: lib.replaceStrings [ "." ] [ "-" ] v) versions); }; } diff --git a/nix/ext/pg_cron/default.nix b/nix/ext/pg_cron/default.nix index cec9d8ec4..a823fa450 100644 --- a/nix/ext/pg_cron/default.nix +++ b/nix/ext/pg_cron/default.nix @@ -6,6 +6,7 @@ buildEnv, makeWrapper, switch-ext-version, + latestOnly ? false, }: let pname = "pg_cron"; @@ -15,7 +16,13 @@ let ) allVersions; versions = lib.naturalSort (lib.attrNames supportedVersions); latestVersion = lib.last versions; - numberOfVersions = builtins.length versions; + versionsToUse = + if latestOnly then + { "${latestVersion}" = supportedVersions.${latestVersion}; } + else + supportedVersions; + versionsBuilt = if latestOnly then [ latestVersion ] else versions; + numberOfVersionsBuilt = builtins.length versionsBuilt; build = version: versionData: stdenv.mkDerivation rec { @@ -71,7 +78,7 @@ let license = licenses.postgresql; }; }; - packages = builtins.attrValues (lib.mapAttrs (name: value: build name value) supportedVersions); + packages = builtins.attrValues (lib.mapAttrs (name: value: build name value) versionsToUse); in buildEnv { name = pname; @@ -93,7 +100,7 @@ buildEnv { # checks (set -x test "$(ls -A $out/lib/${pname}*${postgresql.dlSuffix} | wc -l)" = "${ - toString (numberOfVersions + 1) + toString (numberOfVersionsBuilt + 1) }" ) @@ -109,13 +116,18 @@ buildEnv { }; passthru = { - inherit versions numberOfVersions switch-ext-version; + versions = versionsBuilt; + numberOfVersions = numberOfVersionsBuilt; + inherit switch-ext-version latestOnly; hasBackgroundWorker = true; defaultSettings = { shared_preload_libraries = [ "pg_cron" ]; "cron.database_name" = "postgres"; }; version = - "multi-" + lib.concatStringsSep "-" (map (v: lib.replaceStrings [ "." ] [ "-" ] v) versions); + if latestOnly then + latestVersion + else + "multi-" + lib.concatStringsSep "-" (map (v: lib.replaceStrings [ "." ] [ "-" ] v) versions); }; } diff --git a/nix/ext/pg_graphql/default.nix b/nix/ext/pg_graphql/default.nix index a7f6d1065..11ea156dc 100644 --- a/nix/ext/pg_graphql/default.nix +++ b/nix/ext/pg_graphql/default.nix @@ -7,6 +7,7 @@ postgresql, rust-bin, rsync, + latestOnly ? false, }: let @@ -124,9 +125,15 @@ let ) allVersions; versions = lib.naturalSort (lib.attrNames supportedVersions); latestVersion = lib.last versions; - numberOfVersions = builtins.length versions; + versionsToUse = + if latestOnly then + { "${latestVersion}" = supportedVersions.${latestVersion}; } + else + supportedVersions; + versionsBuilt = if latestOnly then [ latestVersion ] else versions; + numberOfVersionsBuilt = builtins.length versionsBuilt; packages = builtins.attrValues ( - lib.mapAttrs (name: value: build name value.hash value.rust value.pgrx) supportedVersions + lib.mapAttrs (name: value: build name value.hash value.rust value.pgrx) versionsToUse ); in (buildEnv { @@ -167,14 +174,19 @@ in # checks (set -x test "$(ls -A $out/lib/${pname}*${postgresql.dlSuffix} | wc -l)" = "${ - toString (numberOfVersions + 1) + toString (numberOfVersionsBuilt + 1) }" ) ''; passthru = { - inherit versions numberOfVersions pname; + versions = versionsBuilt; + numberOfVersions = numberOfVersionsBuilt; + inherit pname latestOnly; version = - "multi-" + lib.concatStringsSep "-" (map (v: lib.replaceStrings [ "." ] [ "-" ] v) versions); + if latestOnly then + latestVersion + else + "multi-" + lib.concatStringsSep "-" (map (v: lib.replaceStrings [ "." ] [ "-" ] v) versions); }; }).overrideAttrs (_: { diff --git a/nix/ext/pg_hashids.nix b/nix/ext/pg_hashids.nix index b11c5ce68..c8fc3fef5 100644 --- a/nix/ext/pg_hashids.nix +++ b/nix/ext/pg_hashids.nix @@ -4,6 +4,7 @@ fetchFromGitHub, postgresql, buildEnv, + latestOnly ? false, }: let pname = "pg_hashids"; @@ -71,9 +72,15 @@ let ) allVersions; versions = lib.naturalSort (lib.attrNames supportedVersions); latestVersion = lib.last versions; - numberOfVersions = builtins.length versions; + versionsToUse = + if latestOnly then + { "${latestVersion}" = supportedVersions.${latestVersion}; } + else + supportedVersions; + versionsBuilt = if latestOnly then [ latestVersion ] else versions; + numberOfVersionsBuilt = builtins.length versionsBuilt; packages = builtins.attrValues ( - lib.mapAttrs (name: value: build name value.hash (value.revision or name)) supportedVersions + lib.mapAttrs (name: value: build name value.hash (value.revision or name)) versionsToUse ); in buildEnv { @@ -87,14 +94,19 @@ buildEnv { # checks (set -x test "$(ls -A $out/lib/${pname}*${postgresql.dlSuffix} | wc -l)" = "${ - toString (numberOfVersions + 1) + toString (numberOfVersionsBuilt + 1) }" ) ''; passthru = { - inherit versions numberOfVersions pname; + versions = versionsBuilt; + numberOfVersions = numberOfVersionsBuilt; + inherit pname latestOnly; version = - "multi-" + lib.concatStringsSep "-" (map (v: lib.replaceStrings [ "." ] [ "-" ] v) versions); + if latestOnly then + latestVersion + else + "multi-" + lib.concatStringsSep "-" (map (v: lib.replaceStrings [ "." ] [ "-" ] v) versions); }; } diff --git a/nix/ext/pg_jsonschema/default.nix b/nix/ext/pg_jsonschema/default.nix index d3a72036f..4ec4f97a9 100644 --- a/nix/ext/pg_jsonschema/default.nix +++ b/nix/ext/pg_jsonschema/default.nix @@ -6,6 +6,7 @@ fetchFromGitHub, postgresql, rust-bin, + latestOnly ? false, }: let pname = "pg_jsonschema"; @@ -131,10 +132,16 @@ let ) allVersions; versions = lib.naturalSort (lib.attrNames supportedVersions); latestVersion = lib.last versions; - numberOfVersions = builtins.length versions; + versionsToUse = + if latestOnly then + { "${latestVersion}" = supportedVersions.${latestVersion}; } + else + supportedVersions; packages = builtins.attrValues ( - lib.mapAttrs (name: value: build name value.hash value.rust value.pgrx) supportedVersions + lib.mapAttrs (name: value: build name value.hash value.rust value.pgrx) versionsToUse ); + versionsBuilt = if latestOnly then [ latestVersion ] else versions; + numberOfVersionsBuilt = builtins.length versionsBuilt; in (pkgs.buildEnv { name = pname; @@ -147,7 +154,7 @@ in # checks (set -x test "$(ls -A $out/lib/${pname}*${postgresql.dlSuffix} | wc -l)" = "${ - toString (numberOfVersions + 1) + toString (numberOfVersionsBuilt + 1) }" ) @@ -171,9 +178,14 @@ in ''; passthru = { - inherit versions numberOfVersions pname; + versions = versionsBuilt; + numberOfVersions = numberOfVersionsBuilt; + inherit pname latestOnly; version = - "multi-" + lib.concatStringsSep "-" (map (v: lib.replaceStrings [ "." ] [ "-" ] v) versions); + if latestOnly then + latestVersion + else + "multi-" + lib.concatStringsSep "-" (map (v: lib.replaceStrings [ "." ] [ "-" ] v) versions); }; }).overrideAttrs (_: { diff --git a/nix/ext/pg_net.nix b/nix/ext/pg_net.nix index 60304138d..09692b6ac 100644 --- a/nix/ext/pg_net.nix +++ b/nix/ext/pg_net.nix @@ -8,6 +8,7 @@ makeWrapper, switch-ext-version, curl_8_6, + latestOnly ? false, }: let @@ -98,15 +99,23 @@ let ) platformFilteredVersions; versions = lib.naturalSort (lib.attrNames supportedVersions); latestVersion = lib.last versions; - numberOfVersions = builtins.length versions; - packages = builtins.attrValues ( - lib.mapAttrs (name: value: build name value.hash) supportedVersions - ); + versionsToUse = + if latestOnly then + { "${latestVersion}" = supportedVersions.${latestVersion}; } + else + supportedVersions; + packages = builtins.attrValues (lib.mapAttrs (name: value: build name value.hash) versionsToUse); + versionsBuilt = if latestOnly then [ latestVersion ] else versions; + numberOfVersionsBuilt = builtins.length versionsBuilt; in pkgs.buildEnv { name = pname; paths = packages; nativeBuildInputs = [ makeWrapper ]; + pathsToLink = [ + "/lib" + "/share/postgresql/extension" + ]; postBuild = '' { echo "default_version = '${latestVersion}'" @@ -118,7 +127,7 @@ pkgs.buildEnv { # checks (set -x test "$(ls -A $out/lib/${pname}*${postgresql.dlSuffix} | wc -l)" = "${ - toString (numberOfVersions + 1) + toString (numberOfVersionsBuilt + 1) }" ) @@ -127,12 +136,17 @@ pkgs.buildEnv { ''; passthru = { - inherit versions numberOfVersions pname; + versions = versionsBuilt; + numberOfVersions = numberOfVersionsBuilt; + inherit pname latestOnly; hasBackgroundWorker = true; defaultSettings = { shared_preload_libraries = [ "pg_net" ]; }; version = - "multi-" + lib.concatStringsSep "-" (map (v: lib.replaceStrings [ "." ] [ "-" ] v) versions); + if latestOnly then + latestVersion + else + "multi-" + lib.concatStringsSep "-" (map (v: lib.replaceStrings [ "." ] [ "-" ] v) versions); }; } diff --git a/nix/ext/pg_partman.nix b/nix/ext/pg_partman.nix index 809861d52..4c36e765f 100644 --- a/nix/ext/pg_partman.nix +++ b/nix/ext/pg_partman.nix @@ -6,6 +6,7 @@ postgresql, makeWrapper, switch-ext-version, + latestOnly ? false, }: let @@ -60,10 +61,14 @@ let ) allVersions; versions = lib.naturalSort (lib.attrNames supportedVersions); latestVersion = lib.last versions; - numberOfVersions = builtins.length versions; - packages = builtins.attrValues ( - lib.mapAttrs (name: value: build name value.hash) supportedVersions - ); + versionsToUse = + if latestOnly then + { "${latestVersion}" = supportedVersions.${latestVersion}; } + else + supportedVersions; + versionsBuilt = if latestOnly then [ latestVersion ] else versions; + numberOfVersionsBuilt = builtins.length versionsBuilt; + packages = builtins.attrValues (lib.mapAttrs (name: value: build name value.hash) versionsToUse); in pkgs.buildEnv { name = pname; @@ -86,7 +91,7 @@ pkgs.buildEnv { # checks (set -x test "$(ls -A $out/lib/${pname}*${postgresql.dlSuffix} | wc -l)" = "${ - toString (numberOfVersions + 1) + toString (numberOfVersionsBuilt + 1) }" ) @@ -95,12 +100,9 @@ pkgs.buildEnv { ''; passthru = { - inherit - versions - numberOfVersions - switch-ext-version - libName - ; + versions = versionsBuilt; + numberOfVersions = numberOfVersionsBuilt; + inherit switch-ext-version libName latestOnly; pname = "${pname}-all"; hasBackgroundWorker = true; defaultSchema = "partman"; @@ -108,6 +110,9 @@ pkgs.buildEnv { shared_preload_libraries = [ libName ]; }; version = - "multi-" + lib.concatStringsSep "-" (map (v: lib.replaceStrings [ "." ] [ "-" ] v) versions); + if latestOnly then + latestVersion + else + "multi-" + lib.concatStringsSep "-" (map (v: lib.replaceStrings [ "." ] [ "-" ] v) versions); }; } diff --git a/nix/ext/pg_plan_filter.nix b/nix/ext/pg_plan_filter.nix index dfb3262b7..402f6b192 100644 --- a/nix/ext/pg_plan_filter.nix +++ b/nix/ext/pg_plan_filter.nix @@ -5,6 +5,7 @@ fetchFromGitHub, postgresql, makeWrapper, + latestOnly ? false, }: let @@ -50,9 +51,15 @@ let ) allVersions; versions = lib.naturalSort (lib.attrNames supportedVersions); latestVersion = lib.last versions; - numberOfVersions = builtins.length versions; + versionsToUse = + if latestOnly then + { "${latestVersion}" = supportedVersions.${latestVersion}; } + else + supportedVersions; + versionsBuilt = if latestOnly then [ latestVersion ] else versions; + numberOfVersionsBuilt = builtins.length versionsBuilt; packages = builtins.attrValues ( - lib.mapAttrs (name: value: build name value.rev value.hash) supportedVersions + lib.mapAttrs (name: value: build name value.rev value.hash) versionsToUse ); in pkgs.buildEnv { @@ -69,18 +76,23 @@ pkgs.buildEnv { # checks (set -x test "$(ls -A $out/lib/${pname}*${postgresql.dlSuffix} | wc -l)" = "${ - toString (numberOfVersions + 1) + toString (numberOfVersionsBuilt + 1) }" ) ''; passthru = { - inherit versions numberOfVersions pname; + versions = versionsBuilt; + numberOfVersions = numberOfVersionsBuilt; + inherit pname latestOnly; defaultSettings = { shared_preload_libraries = [ "plan_filter" ]; }; pgRegressTestName = "pg_plan_filter"; version = - "multi-" + lib.concatStringsSep "-" (map (v: lib.replaceStrings [ "." ] [ "-" ] v) versions); + if latestOnly then + latestVersion + else + "multi-" + lib.concatStringsSep "-" (map (v: lib.replaceStrings [ "." ] [ "-" ] v) versions); }; } diff --git a/nix/ext/pg_repack.nix b/nix/ext/pg_repack.nix index 153cebd76..89b1d1118 100644 --- a/nix/ext/pg_repack.nix +++ b/nix/ext/pg_repack.nix @@ -6,6 +6,7 @@ postgresqlTestHook, testers, buildEnv, + latestOnly ? false, }: let pname = "pg_repack"; @@ -21,10 +22,14 @@ let # Derived version information versions = lib.naturalSort (lib.attrNames supportedVersions); latestVersion = lib.last versions; - numberOfVersions = builtins.length versions; - packages = builtins.attrValues ( - lib.mapAttrs (name: value: build name value.hash) supportedVersions - ); + versionsToUse = + if latestOnly then + { "${latestVersion}" = supportedVersions.${latestVersion}; } + else + supportedVersions; + versionsBuilt = if latestOnly then [ latestVersion ] else versions; + numberOfVersionsBuilt = builtins.length versionsBuilt; + packages = builtins.attrValues (lib.mapAttrs (name: value: build name value.hash) versionsToUse); # Build function for individual versions build = @@ -117,7 +122,7 @@ buildEnv { postBuild = '' # Verify all expected library files are present - expectedFiles=${toString (numberOfVersions + 1)} + expectedFiles=${toString (numberOfVersionsBuilt + 1)} actualFiles=$(ls -l $out/lib/${pname}*${postgresql.dlSuffix} | wc -l) if [[ "$actualFiles" != "$expectedFiles" ]]; then @@ -129,8 +134,13 @@ buildEnv { ''; passthru = { - inherit versions numberOfVersions pname; + versions = versionsBuilt; + numberOfVersions = numberOfVersionsBuilt; + inherit pname latestOnly; version = - "multi-" + lib.concatStringsSep "-" (map (v: lib.replaceStrings [ "." ] [ "-" ] v) versions); + if latestOnly then + latestVersion + else + "multi-" + lib.concatStringsSep "-" (map (v: lib.replaceStrings [ "." ] [ "-" ] v) versions); }; } diff --git a/nix/ext/pg_stat_monitor.nix b/nix/ext/pg_stat_monitor.nix index ddf46de30..c82eaf830 100644 --- a/nix/ext/pg_stat_monitor.nix +++ b/nix/ext/pg_stat_monitor.nix @@ -4,6 +4,7 @@ fetchFromGitHub, postgresql, buildEnv, + latestOnly ? false, }: let pname = "pg_stat_monitor"; @@ -19,9 +20,15 @@ let # Derived version information versions = lib.naturalSort (lib.attrNames supportedVersions); latestVersion = lib.last versions; - numberOfVersions = builtins.length versions; + versionsToUse = + if latestOnly then + { "${latestVersion}" = supportedVersions.${latestVersion}; } + else + supportedVersions; + versionsBuilt = if latestOnly then [ latestVersion ] else versions; + numberOfVersionsBuilt = builtins.length versionsBuilt; packages = builtins.attrValues ( - lib.mapAttrs (name: value: build name value.hash value.revision) supportedVersions + lib.mapAttrs (name: value: build name value.hash value.revision) versionsToUse ); # Build function for individual versions @@ -85,7 +92,7 @@ buildEnv { postBuild = '' # Verify all expected library files are present - expectedFiles=${toString (numberOfVersions + 1)} + expectedFiles=${toString (numberOfVersionsBuilt + 1)} actualFiles=$(ls -l $out/lib/${pname}*${postgresql.dlSuffix} | wc -l) if [[ "$actualFiles" != "$expectedFiles" ]]; then @@ -97,8 +104,13 @@ buildEnv { ''; passthru = { - inherit versions numberOfVersions pname; + versions = versionsBuilt; + numberOfVersions = numberOfVersionsBuilt; + inherit pname latestOnly; version = - "multi-" + lib.concatStringsSep "-" (map (v: lib.replaceStrings [ "." ] [ "-" ] v) versions); + if latestOnly then + latestVersion + else + "multi-" + lib.concatStringsSep "-" (map (v: lib.replaceStrings [ "." ] [ "-" ] v) versions); }; } diff --git a/nix/ext/pg_tle.nix b/nix/ext/pg_tle.nix index 7101952a2..d5d1e4446 100644 --- a/nix/ext/pg_tle.nix +++ b/nix/ext/pg_tle.nix @@ -7,6 +7,7 @@ flex, openssl, libkrb5, + latestOnly ? false, }: let pname = "pg_tle"; @@ -78,10 +79,14 @@ let ) allVersions; versions = lib.naturalSort (lib.attrNames supportedVersions); latestVersion = lib.last versions; - numberOfVersions = builtins.length versions; - packages = builtins.attrValues ( - lib.mapAttrs (name: value: build name value.hash) supportedVersions - ); + versionsToUse = + if latestOnly then + { "${latestVersion}" = supportedVersions.${latestVersion}; } + else + supportedVersions; + versionsBuilt = if latestOnly then [ latestVersion ] else versions; + numberOfVersionsBuilt = builtins.length versionsBuilt; + packages = builtins.attrValues (lib.mapAttrs (name: value: build name value.hash) versionsToUse); in buildEnv { name = pname; @@ -94,17 +99,22 @@ buildEnv { # checks (set -x test "$(ls -A $out/lib/${pname}*${postgresql.dlSuffix} | wc -l)" = "${ - toString (numberOfVersions + 1) + toString (numberOfVersionsBuilt + 1) }" ) ''; passthru = { - inherit versions numberOfVersions pname; + versions = versionsBuilt; + numberOfVersions = numberOfVersionsBuilt; + inherit pname latestOnly; defaultSettings = { shared_preload_libraries = [ "pg_tle" ]; }; version = - "multi-" + lib.concatStringsSep "-" (map (v: lib.replaceStrings [ "." ] [ "-" ] v) versions); + if latestOnly then + latestVersion + else + "multi-" + lib.concatStringsSep "-" (map (v: lib.replaceStrings [ "." ] [ "-" ] v) versions); }; } diff --git a/nix/ext/pgaudit.nix b/nix/ext/pgaudit.nix index 55dd237f7..06e4bca40 100644 --- a/nix/ext/pgaudit.nix +++ b/nix/ext/pgaudit.nix @@ -6,6 +6,7 @@ libkrb5, openssl, postgresql, + latestOnly ? false, }: #adapted from https://github.com/NixOS/nixpkgs/blob/master/pkgs/servers/sql/postgresql/ext/pgaudit.nix let @@ -24,12 +25,16 @@ let # Supported versions sorted (for libraries) versions = lib.naturalSort (lib.attrNames supportedVersions); latestVersion = lib.last versions; - numberOfVersions = builtins.length versions; + versionsToUse = + if latestOnly then + { "${latestVersion}" = supportedVersions.${latestVersion}; } + else + supportedVersions; + versionsBuilt = if latestOnly then [ latestVersion ] else versions; + numberOfVersionsBuilt = builtins.length versionsBuilt; # Build packages only for supported versions (with libraries) - packages = builtins.attrValues ( - lib.mapAttrs (name: value: build name value.hash) supportedVersions - ); + packages = builtins.attrValues (lib.mapAttrs (name: value: build name value.hash) versionsToUse); # Helper function to generate migration SQL file pairs # Returns a list of {from, to} pairs for sequential migrations @@ -217,7 +222,7 @@ buildEnv { '') versions} # Verify all expected library files are present (one per version + symlink) - expectedFiles=${toString (numberOfVersions + 1)} + expectedFiles=${toString (numberOfVersionsBuilt + 1)} actualFiles=$(ls -A $out/lib/${pname}*${postgresql.dlSuffix} | wc -l) if [[ "$actualFiles" != "$expectedFiles" ]]; then @@ -229,9 +234,14 @@ buildEnv { ''; passthru = { - inherit versions numberOfVersions pname; + versions = versionsBuilt; + numberOfVersions = numberOfVersionsBuilt; + inherit pname latestOnly; version = - "multi-" + lib.concatStringsSep "-" (map (v: lib.replaceStrings [ "." ] [ "-" ] v) versions); + if latestOnly then + latestVersion + else + "multi-" + lib.concatStringsSep "-" (map (v: lib.replaceStrings [ "." ] [ "-" ] v) versions); defaultSettings = { shared_preload_libraries = "pgaudit"; }; diff --git a/nix/ext/pgjwt.nix b/nix/ext/pgjwt.nix index 6bac9dcd8..348b534c3 100644 --- a/nix/ext/pgjwt.nix +++ b/nix/ext/pgjwt.nix @@ -5,6 +5,7 @@ fetchFromGitHub, postgresql, unstableGitUpdater, + latestOnly ? false, }: let pname = "pgjwt"; @@ -14,9 +15,13 @@ let ) allVersions; versions = lib.naturalSort (lib.attrNames supportedVersions); latestVersion = lib.last versions; - numberOfVersions = builtins.trace "Versions: ${toString (builtins.length versions)}" ( - builtins.length versions - ); + versionsToUse = + if latestOnly then + { "${latestVersion}" = supportedVersions.${latestVersion}; } + else + supportedVersions; + versionsBuilt = if latestOnly then [ latestVersion ] else versions; + numberOfVersionsBuilt = builtins.length versionsBuilt; build = version: hash: revision: stdenv.mkDerivation { @@ -68,7 +73,7 @@ let }; }; packages = builtins.attrValues ( - lib.mapAttrs (name: value: build name value.hash value.revision) supportedVersions + lib.mapAttrs (name: value: build name value.hash value.revision) versionsToUse ); in buildEnv { @@ -77,8 +82,13 @@ buildEnv { pathsToLink = [ "/share/postgresql/extension" ]; passthru = { - inherit versions numberOfVersions pname; + versions = versionsBuilt; + numberOfVersions = numberOfVersionsBuilt; + inherit pname latestOnly; version = - "multi-" + lib.concatStringsSep "-" (map (v: lib.replaceStrings [ "." ] [ "-" ] v) versions); + if latestOnly then + latestVersion + else + "multi-" + lib.concatStringsSep "-" (map (v: lib.replaceStrings [ "." ] [ "-" ] v) versions); }; } diff --git a/nix/ext/pgmq/default.nix b/nix/ext/pgmq/default.nix index 518308211..42613b6ac 100644 --- a/nix/ext/pgmq/default.nix +++ b/nix/ext/pgmq/default.nix @@ -4,6 +4,7 @@ fetchFromGitHub, postgresql, buildEnv, + latestOnly ? false, }: let pname = "pgmq"; @@ -19,10 +20,14 @@ let # Derived version information versions = lib.naturalSort (lib.attrNames supportedVersions); latestVersion = lib.last versions; - numberOfVersions = builtins.length versions; - packages = builtins.attrValues ( - lib.mapAttrs (name: value: build name value.hash) supportedVersions - ); + versionsToUse = + if latestOnly then + { "${latestVersion}" = supportedVersions.${latestVersion}; } + else + supportedVersions; + versionsBuilt = if latestOnly then [ latestVersion ] else versions; + numberOfVersionsBuilt = builtins.length versionsBuilt; + packages = builtins.attrValues (lib.mapAttrs (name: value: build name value.hash) versionsToUse); # Build function for individual versions build = @@ -99,11 +104,16 @@ buildEnv { pathsToLink = [ "/share/postgresql/extension" ]; passthru = { - inherit versions numberOfVersions pname; + versions = versionsBuilt; + numberOfVersions = numberOfVersionsBuilt; + inherit pname latestOnly; defaultSettings = { search_path = "\"$user\", public, auth, extensions"; }; version = - "multi-" + lib.concatStringsSep "-" (map (v: lib.replaceStrings [ "." ] [ "-" ] v) versions); + if latestOnly then + latestVersion + else + "multi-" + lib.concatStringsSep "-" (map (v: lib.replaceStrings [ "." ] [ "-" ] v) versions); }; } diff --git a/nix/ext/pgroonga/default.nix b/nix/ext/pgroonga/default.nix index 89aca72a2..4a824ac25 100644 --- a/nix/ext/pgroonga/default.nix +++ b/nix/ext/pgroonga/default.nix @@ -11,6 +11,7 @@ buildEnv, supabase-groonga, mecab-naist-jdic, + latestOnly ? false, }: let pname = "pgroonga"; @@ -26,10 +27,14 @@ let # Derived version information versions = lib.naturalSort (lib.attrNames supportedVersions); latestVersion = lib.last versions; - numberOfVersions = builtins.length versions; - packages = builtins.attrValues ( - lib.mapAttrs (name: value: build name value.hash) supportedVersions - ); + versionsToUse = + if latestOnly then + { "${latestVersion}" = supportedVersions.${latestVersion}; } + else + supportedVersions; + versionsBuilt = if latestOnly then [ latestVersion ] else versions; + numberOfVersionsBuilt = builtins.length versionsBuilt; + packages = builtins.attrValues (lib.mapAttrs (name: value: build name value.hash) versionsToUse); # List of C extensions to be included in the build cExtensions = [ @@ -159,7 +164,7 @@ buildEnv { ]; postBuild = '' # Verify all expected library files are present - expectedFiles=${toString ((numberOfVersions + 1) * (builtins.length cExtensions))} + expectedFiles=${toString ((numberOfVersionsBuilt + 1) * (builtins.length cExtensions))} actualFiles=$(ls -l $out/lib/${pname}*${postgresql.dlSuffix} | wc -l) if [[ "$actualFiles" != "$expectedFiles" ]]; then @@ -171,8 +176,13 @@ buildEnv { ''; passthru = { - inherit versions numberOfVersions pname; + versions = versionsBuilt; + numberOfVersions = numberOfVersionsBuilt; + inherit pname latestOnly; version = - "multi-" + lib.concatStringsSep "-" (map (v: lib.replaceStrings [ "." ] [ "-" ] v) versions); + if latestOnly then + latestVersion + else + "multi-" + lib.concatStringsSep "-" (map (v: lib.replaceStrings [ "." ] [ "-" ] v) versions); }; } diff --git a/nix/ext/pgrouting/default.nix b/nix/ext/pgrouting/default.nix index a05101dd8..cff4e7d86 100644 --- a/nix/ext/pgrouting/default.nix +++ b/nix/ext/pgrouting/default.nix @@ -7,6 +7,7 @@ cmake, boost, buildEnv, + latestOnly ? false, }: let pname = "pgrouting"; @@ -22,10 +23,14 @@ let # Derived version information versions = lib.naturalSort (lib.attrNames supportedVersions); latestVersion = lib.last versions; - numberOfVersions = builtins.length versions; - packages = builtins.attrValues ( - lib.mapAttrs (name: value: build name value.hash) supportedVersions - ); + versionsToUse = + if latestOnly then + { "${latestVersion}" = supportedVersions.${latestVersion}; } + else + supportedVersions; + versionsBuilt = if latestOnly then [ latestVersion ] else versions; + numberOfVersionsBuilt = builtins.length versionsBuilt; + packages = builtins.attrValues (lib.mapAttrs (name: value: build name value.hash) versionsToUse); # Build function for individual versions build = @@ -130,7 +135,7 @@ buildEnv { postBuild = '' #Verify all expected library files are present - expectedFiles=${toString (numberOfVersions + 1)} + expectedFiles=${toString (numberOfVersionsBuilt + 1)} actualFiles=$(ls -l $out/lib/lib${pname}*${postgresql.dlSuffix} | wc -l) if [[ "$actualFiles" != "$expectedFiles" ]]; then @@ -142,8 +147,13 @@ buildEnv { ''; passthru = { - inherit versions numberOfVersions pname; + versions = versionsBuilt; + numberOfVersions = numberOfVersionsBuilt; + inherit pname latestOnly; version = - "multi-" + lib.concatStringsSep "-" (map (v: lib.replaceStrings [ "." ] [ "-" ] v) versions); + if latestOnly then + latestVersion + else + "multi-" + lib.concatStringsSep "-" (map (v: lib.replaceStrings [ "." ] [ "-" ] v) versions); }; } diff --git a/nix/ext/pgsodium.nix b/nix/ext/pgsodium.nix index fa111d8a5..ad5cd008b 100644 --- a/nix/ext/pgsodium.nix +++ b/nix/ext/pgsodium.nix @@ -5,6 +5,7 @@ fetchFromGitHub, postgresql, libsodium, + latestOnly ? false, }: let pname = "pgsodium"; @@ -20,10 +21,14 @@ let # Derived version information versions = lib.naturalSort (lib.attrNames supportedVersions); latestVersion = lib.last versions; - numberOfVersions = builtins.length versions; - packages = builtins.attrValues ( - lib.mapAttrs (name: value: build name value.hash) supportedVersions - ); + versionsToUse = + if latestOnly then + { "${latestVersion}" = supportedVersions.${latestVersion}; } + else + supportedVersions; + packages = builtins.attrValues (lib.mapAttrs (name: value: build name value.hash) versionsToUse); + versionsBuilt = if latestOnly then [ latestVersion ] else versions; + numberOfVersionsBuilt = builtins.length versionsBuilt; # Build function for individual pgsodium versions build = @@ -89,7 +94,7 @@ pkgs.buildEnv { postBuild = '' # Verify all expected library files are present - expectedFiles=${toString (numberOfVersions + 1)} + expectedFiles=${toString (numberOfVersionsBuilt + 1)} actualFiles=$(ls -A $out/lib/${pname}*${postgresql.dlSuffix} | wc -l) if [[ "$actualFiles" != "$expectedFiles" ]]; then @@ -101,8 +106,13 @@ pkgs.buildEnv { ''; passthru = { - inherit versions numberOfVersions pname; + versions = versionsBuilt; + numberOfVersions = numberOfVersionsBuilt; + inherit pname latestOnly; version = - "multi-" + lib.concatStringsSep "-" (map (v: lib.replaceStrings [ "." ] [ "-" ] v) versions); + if latestOnly then + latestVersion + else + "multi-" + lib.concatStringsSep "-" (map (v: lib.replaceStrings [ "." ] [ "-" ] v) versions); }; } diff --git a/nix/ext/pgsql-http.nix b/nix/ext/pgsql-http.nix index 3ad03b80c..e36f4a218 100644 --- a/nix/ext/pgsql-http.nix +++ b/nix/ext/pgsql-http.nix @@ -5,6 +5,7 @@ fetchFromGitHub, postgresql, curl, + latestOnly ? false, }: let pname = "http"; @@ -20,10 +21,14 @@ let # Derived version information versions = lib.naturalSort (lib.attrNames supportedVersions); latestVersion = lib.last versions; - numberOfVersions = builtins.length versions; - packages = builtins.attrValues ( - lib.mapAttrs (name: value: build name value.hash) supportedVersions - ); + versionsToUse = + if latestOnly then + { "${latestVersion}" = supportedVersions.${latestVersion}; } + else + supportedVersions; + versionsBuilt = if latestOnly then [ latestVersion ] else versions; + numberOfVersionsBuilt = builtins.length versionsBuilt; + packages = builtins.attrValues (lib.mapAttrs (name: value: build name value.hash) versionsToUse); # Build function for individual versions build = @@ -91,7 +96,7 @@ pkgs.buildEnv { ]; postBuild = '' # Verify all expected library files are present - expectedFiles=${toString (numberOfVersions + 1)} + expectedFiles=${toString (numberOfVersionsBuilt + 1)} actualFiles=$(ls -A $out/lib/${pname}*${postgresql.dlSuffix} | wc -l) if [[ "$actualFiles" != "$expectedFiles" ]]; then @@ -103,8 +108,13 @@ pkgs.buildEnv { ''; passthru = { - inherit versions numberOfVersions pname; + versions = versionsBuilt; + numberOfVersions = numberOfVersionsBuilt; + inherit pname latestOnly; version = - "multi-" + lib.concatStringsSep "-" (map (v: lib.replaceStrings [ "." ] [ "-" ] v) versions); + if latestOnly then + latestVersion + else + "multi-" + lib.concatStringsSep "-" (map (v: lib.replaceStrings [ "." ] [ "-" ] v) versions); }; } diff --git a/nix/ext/pgvector.nix b/nix/ext/pgvector.nix index bcf86ebfb..12b8816d6 100644 --- a/nix/ext/pgvector.nix +++ b/nix/ext/pgvector.nix @@ -4,6 +4,7 @@ stdenv, fetchFromGitHub, postgresql, + latestOnly ? false, }: let pname = "vector"; @@ -19,10 +20,14 @@ let # Derived version information versions = lib.naturalSort (lib.attrNames supportedVersions); latestVersion = lib.last versions; - numberOfVersions = builtins.length versions; - packages = builtins.attrValues ( - lib.mapAttrs (name: value: build name value.hash) supportedVersions - ); + versionsToUse = + if latestOnly then + { "${latestVersion}" = supportedVersions.${latestVersion}; } + else + supportedVersions; + packages = builtins.attrValues (lib.mapAttrs (name: value: build name value.hash) versionsToUse); + versionsBuilt = if latestOnly then [ latestVersion ] else versions; + numberOfVersionsBuilt = builtins.length versionsBuilt; # Build function for individual versions build = @@ -83,9 +88,14 @@ pkgs.buildEnv { ]; passthru = { - inherit versions numberOfVersions pname; + versions = versionsBuilt; + numberOfVersions = numberOfVersionsBuilt; + inherit pname latestOnly; version = - "multi-" + lib.concatStringsSep "-" (map (v: lib.replaceStrings [ "." ] [ "-" ] v) versions); + if latestOnly then + latestVersion + else + "multi-" + lib.concatStringsSep "-" (map (v: lib.replaceStrings [ "." ] [ "-" ] v) versions); pgRegressTestName = "pgvector"; }; } diff --git a/nix/ext/plpgsql-check.nix b/nix/ext/plpgsql-check.nix index faf918c67..05542b949 100644 --- a/nix/ext/plpgsql-check.nix +++ b/nix/ext/plpgsql-check.nix @@ -7,6 +7,7 @@ buildEnv, makeWrapper, switch-ext-version, + latestOnly ? false, }: let pname = "plpgsql_check"; @@ -22,9 +23,15 @@ let # Derived version information versions = lib.naturalSort (lib.attrNames supportedVersions); latestVersion = lib.last versions; - numberOfVersions = builtins.length versions; + versionsToUse = + if latestOnly then + { "${latestVersion}" = supportedVersions.${latestVersion}; } + else + supportedVersions; + versionsBuilt = if latestOnly then [ latestVersion ] else versions; + numberOfVersionsBuilt = builtins.length versionsBuilt; packages = builtins.attrValues ( - lib.mapAttrs (name: value: build name value.hash value.revision) supportedVersions + lib.mapAttrs (name: value: build name value.hash value.revision) versionsToUse ); # Build function for individual versions @@ -108,7 +115,7 @@ buildEnv { ln -sfn ${pname}-${latestVersion}${postgresql.dlSuffix} $out/lib/${pname}${postgresql.dlSuffix} # Verify all expected library files are present - expectedFiles=${toString (numberOfVersions + 1)} + expectedFiles=${toString (numberOfVersionsBuilt + 1)} actualFiles=$(ls -l $out/lib/${pname}*${postgresql.dlSuffix} | wc -l) if [[ "$actualFiles" != "$expectedFiles" ]]; then @@ -133,7 +140,9 @@ buildEnv { ''; passthru = { - inherit versions numberOfVersions switch-ext-version; + versions = versionsBuilt; + numberOfVersions = numberOfVersionsBuilt; + inherit switch-ext-version latestOnly; hasBackgroundWorker = true; defaultSettings = { shared_preload_libraries = [ @@ -142,6 +151,9 @@ buildEnv { ]; }; version = - "multi-" + lib.concatStringsSep "-" (map (v: lib.replaceStrings [ "." ] [ "-" ] v) versions); + if latestOnly then + latestVersion + else + "multi-" + lib.concatStringsSep "-" (map (v: lib.replaceStrings [ "." ] [ "-" ] v) versions); }; } diff --git a/nix/ext/plv8/default.nix b/nix/ext/plv8/default.nix index 50927521b..93a17434a 100644 --- a/nix/ext/plv8/default.nix +++ b/nix/ext/plv8/default.nix @@ -14,6 +14,7 @@ nodejs_20, libcxx, v8_oldstable, + latestOnly ? false, }: let @@ -30,10 +31,14 @@ let # Derived version information versions = lib.naturalSort (lib.attrNames supportedVersions); latestVersion = lib.last versions; - numberOfVersions = builtins.length versions; - packages = builtins.attrValues ( - lib.mapAttrs (name: value: build name value.hash) supportedVersions - ); + versionsToUse = + if latestOnly then + { "${latestVersion}" = supportedVersions.${latestVersion}; } + else + supportedVersions; + versionsBuilt = if latestOnly then [ latestVersion ] else versions; + numberOfVersionsBuilt = builtins.length versionsBuilt; + packages = builtins.attrValues (lib.mapAttrs (name: value: build name value.hash) versionsToUse); # plv8 3.1 requires an older version of v8 (we cannot use nodejs.libv8) v8 = v8_oldstable; @@ -221,7 +226,7 @@ buildEnv { ]; postBuild = '' # Verify all expected library files are present - expectedFiles=${toString (numberOfVersions + 1)} + expectedFiles=${toString (numberOfVersionsBuilt + 1)} actualFiles=$(ls -A $out/lib/${pname}*${postgresql.dlSuffix} | wc -l) if [[ "$actualFiles" != "$expectedFiles" ]]; then @@ -233,8 +238,13 @@ buildEnv { ''; passthru = { - inherit versions numberOfVersions pname; + versions = versionsBuilt; + numberOfVersions = numberOfVersionsBuilt; + inherit pname latestOnly; version = - "multi-" + lib.concatStringsSep "-" (map (v: lib.replaceStrings [ "." ] [ "-" ] v) versions); + if latestOnly then + latestVersion + else + "multi-" + lib.concatStringsSep "-" (map (v: lib.replaceStrings [ "." ] [ "-" ] v) versions); }; } diff --git a/nix/ext/postgis.nix b/nix/ext/postgis.nix index 3989e8aae..74539e5de 100644 --- a/nix/ext/postgis.nix +++ b/nix/ext/postgis.nix @@ -17,6 +17,7 @@ callPackage, buildEnv, sfcgal, + latestOnly ? false, }: let @@ -34,10 +35,14 @@ let # Derived version information versions = lib.naturalSort (lib.attrNames supportedVersions); latestVersion = lib.last versions; - numberOfVersions = builtins.length versions; - packages = builtins.attrValues ( - lib.mapAttrs (name: value: build name value.hash) supportedVersions - ); + versionsToUse = + if latestOnly then + { "${latestVersion}" = supportedVersions.${latestVersion}; } + else + supportedVersions; + versionsBuilt = if latestOnly then [ latestVersion ] else versions; + numberOfVersionsBuilt = builtins.length versionsBuilt; + packages = builtins.attrValues (lib.mapAttrs (name: value: build name value.hash) versionsToUse); # List of C extensions to be included in the build cExtensions = [ @@ -190,9 +195,9 @@ in ]; postBuild = '' # Verify all expected library files are present - # We expect: (numberOfVersions * cExtensions) versioned libraries + cExtensions symlinks + # We expect: (numberOfVersionsBuilt * cExtensions) versioned libraries + cExtensions symlinks expectedFiles=${ - toString ((numberOfVersions * builtins.length cExtensions) + builtins.length cExtensions) + toString ((numberOfVersionsBuilt * builtins.length cExtensions) + builtins.length cExtensions) } actualFiles=$(ls -A $out/lib/*${postgresql.dlSuffix} | wc -l) @@ -205,9 +210,14 @@ in ''; passthru = { - inherit versions numberOfVersions pname; + versions = versionsBuilt; + numberOfVersions = numberOfVersionsBuilt; + inherit pname latestOnly; version = - "multi-" + lib.concatStringsSep "-" (map (v: lib.replaceStrings [ "." ] [ "-" ] v) versions); + if latestOnly then + latestVersion + else + "multi-" + lib.concatStringsSep "-" (map (v: lib.replaceStrings [ "." ] [ "-" ] v) versions); }; }).overrideAttrs (_: { diff --git a/nix/ext/rum.nix b/nix/ext/rum.nix index 6a9492e38..a16be47c9 100644 --- a/nix/ext/rum.nix +++ b/nix/ext/rum.nix @@ -4,6 +4,7 @@ fetchFromGitHub, postgresql, buildEnv, + latestOnly ? false, }: let pname = "rum"; @@ -19,9 +20,15 @@ let # Derived version information versions = lib.naturalSort (lib.attrNames supportedVersions); latestVersion = lib.last versions; - numberOfVersions = builtins.length versions; + versionsToUse = + if latestOnly then + { "${latestVersion}" = supportedVersions.${latestVersion}; } + else + supportedVersions; + versionsBuilt = if latestOnly then [ latestVersion ] else versions; + numberOfVersionsBuilt = builtins.length versionsBuilt; packages = builtins.attrValues ( - lib.mapAttrs (name: value: build name value.hash value.revision) supportedVersions + lib.mapAttrs (name: value: build name value.hash value.revision) versionsToUse ); # Build function for individual versions @@ -82,7 +89,7 @@ buildEnv { postBuild = '' # Verify all expected library files are present - expectedFiles=${toString (numberOfVersions + 1)} + expectedFiles=${toString (numberOfVersionsBuilt + 1)} actualFiles=$(ls -l $out/lib/${pname}*${postgresql.dlSuffix} | wc -l) if [[ "$actualFiles" != "$expectedFiles" ]]; then @@ -94,8 +101,13 @@ buildEnv { ''; passthru = { - inherit versions numberOfVersions pname; + versions = versionsBuilt; + numberOfVersions = numberOfVersionsBuilt; + inherit pname latestOnly; version = - "multi-" + lib.concatStringsSep "-" (map (v: lib.replaceStrings [ "." ] [ "-" ] v) versions); + if latestOnly then + latestVersion + else + "multi-" + lib.concatStringsSep "-" (map (v: lib.replaceStrings [ "." ] [ "-" ] v) versions); }; } diff --git a/nix/ext/timescaledb.nix b/nix/ext/timescaledb.nix index 765ca5267..dbfb2a836 100644 --- a/nix/ext/timescaledb.nix +++ b/nix/ext/timescaledb.nix @@ -11,6 +11,7 @@ switch-ext-version, coreutils, writeShellApplication, + latestOnly ? false, }: let @@ -97,9 +98,15 @@ let ) allVersions; versions = lib.naturalSort (lib.attrNames supportedVersions); latestVersion = lib.last versions; - numberOfVersions = builtins.length versions; + versionsToUse = + if latestOnly then + { "${latestVersion}" = supportedVersions.${latestVersion}; } + else + supportedVersions; + versionsBuilt = if latestOnly then [ latestVersion ] else versions; + numberOfVersionsBuilt = builtins.length versionsBuilt; packages = builtins.attrValues ( - lib.mapAttrs (name: value: build name value.hash (value.revision or name)) supportedVersions + lib.mapAttrs (name: value: build name value.hash (value.revision or name)) versionsToUse ); switch-timescaledb-loader = writeShellApplication { name = "switch_timescaledb_loader"; @@ -145,13 +152,18 @@ buildEnv { ]; passthru = { - inherit versions numberOfVersions switch-ext-version; + versions = versionsBuilt; + numberOfVersions = numberOfVersionsBuilt; + inherit switch-ext-version latestOnly; hasBackgroundWorker = true; libName = "timescaledb-loader"; defaultSettings = { shared_preload_libraries = [ "timescaledb" ]; }; version = - "multi-" + lib.concatStringsSep "-" (map (v: lib.replaceStrings [ "." ] [ "-" ] v) versions); + if latestOnly then + latestVersion + else + "multi-" + lib.concatStringsSep "-" (map (v: lib.replaceStrings [ "." ] [ "-" ] v) versions); }; } diff --git a/nix/ext/vault.nix b/nix/ext/vault.nix index 537febc0b..c48546ecb 100644 --- a/nix/ext/vault.nix +++ b/nix/ext/vault.nix @@ -5,6 +5,7 @@ fetchFromGitHub, libsodium, postgresql, + latestOnly ? false, }: let pname = "supabase_vault"; @@ -20,10 +21,14 @@ let # Derived version information versions = lib.naturalSort (lib.attrNames supportedVersions); latestVersion = lib.last versions; - numberOfVersions = builtins.length versions; - packages = builtins.attrValues ( - lib.mapAttrs (name: value: build name value.hash) supportedVersions - ); + versionsToUse = + if latestOnly then + { "${latestVersion}" = supportedVersions.${latestVersion}; } + else + supportedVersions; + versionsBuilt = if latestOnly then [ latestVersion ] else versions; + numberOfVersionsBuilt = builtins.length versionsBuilt; + packages = builtins.attrValues (lib.mapAttrs (name: value: build name value.hash) versionsToUse); # Build function for individual pgsodium versions build = @@ -86,9 +91,14 @@ pkgs.buildEnv { ]; passthru = { - inherit versions numberOfVersions pname; + versions = versionsBuilt; + numberOfVersions = numberOfVersionsBuilt; + inherit pname latestOnly; version = - "multi-" + lib.concatStringsSep "-" (map (v: lib.replaceStrings [ "." ] [ "-" ] v) versions); + if latestOnly then + latestVersion + else + "multi-" + lib.concatStringsSep "-" (map (v: lib.replaceStrings [ "." ] [ "-" ] v) versions); pgRegressTestName = "vault"; }; } diff --git a/nix/ext/wal2json.nix b/nix/ext/wal2json.nix index 43ddab8df..f1ccd273b 100644 --- a/nix/ext/wal2json.nix +++ b/nix/ext/wal2json.nix @@ -5,6 +5,7 @@ fetchFromGitHub, postgresql, makeWrapper, + latestOnly ? false, }: let @@ -56,9 +57,15 @@ let ) allVersions; versions = lib.naturalSort (lib.attrNames supportedVersions); latestVersion = lib.last versions; - numberOfVersions = builtins.length versions; + versionsToUse = + if latestOnly then + { "${latestVersion}" = supportedVersions.${latestVersion}; } + else + supportedVersions; + versionsBuilt = if latestOnly then [ latestVersion ] else versions; + numberOfVersionsBuilt = builtins.length versionsBuilt; packages = builtins.attrValues ( - lib.mapAttrs (name: value: build name value.rev value.hash) supportedVersions + lib.mapAttrs (name: value: build name value.rev value.hash) versionsToUse ); in pkgs.buildEnv { @@ -89,15 +96,20 @@ pkgs.buildEnv { # checks (set -x test "$(ls -A $out/lib/${pname}*${postgresql.dlSuffix} | wc -l)" = "${ - toString (numberOfVersions + 1) + toString (numberOfVersionsBuilt + 1) }" ) ''; passthru = { - inherit versions numberOfVersions pname; + versions = versionsBuilt; + numberOfVersions = numberOfVersionsBuilt; + inherit pname latestOnly; version = - "multi-" + lib.concatStringsSep "-" (map (v: lib.replaceStrings [ "." ] [ "-" ] v) versions); + if latestOnly then + latestVersion + else + "multi-" + lib.concatStringsSep "-" (map (v: lib.replaceStrings [ "." ] [ "-" ] v) versions); defaultSettings = { wal_level = "logical"; }; diff --git a/nix/ext/wrappers/default.nix b/nix/ext/wrappers/default.nix index 696358ea4..5383e30ec 100644 --- a/nix/ext/wrappers/default.nix +++ b/nix/ext/wrappers/default.nix @@ -9,6 +9,7 @@ buildEnv, rust-bin, git, + latestOnly ? false, }: let pname = "wrappers"; @@ -207,6 +208,13 @@ let versions = lib.naturalSort (lib.attrNames supportedVersions); latestVersion = lib.last versions; numberOfVersions = builtins.length versions; + versionsToUse = + if latestOnly then + lib.filterAttrs (n: _: n == latestVersion) supportedVersions + else + supportedVersions; + versionsBuilt = if latestOnly then [ latestVersion ] else versions; + numberOfVersionsBuilt = builtins.length versionsBuilt; # Filter out previously packaged versions that are actually built for this PG version # This prevents double-counting when a version appears in both lists previouslyPackagedVersions = builtins.filter ( @@ -216,7 +224,7 @@ let packagesAttrSet = lib.mapAttrs' (name: value: { name = lib.replaceStrings [ "." ] [ "_" ] name; value = build name value.hash value.rust value.pgrx; - }) supportedVersions; + }) versionsToUse; packages = builtins.attrValues packagesAttrSet; in (buildEnv { @@ -240,69 +248,101 @@ in # Create main library symlink to latest version ln -sfn ${pname}-${latestVersion}${postgresql.dlSuffix} $out/lib/${pname}${postgresql.dlSuffix} - # Create symlinks for all previously packaged versions to main library - for v in ${lib.concatStringsSep " " previouslyPackagedVersions}; do - ln -sfn $out/lib/${pname}${postgresql.dlSuffix} $out/lib/${pname}-$v${postgresql.dlSuffix} - done + ${ + if latestOnly then + '' + # latestOnly mode: skip previouslyPackagedVersions symlinks + '' + else + '' + # Create symlinks for all previously packaged versions to main library + for v in ${lib.concatStringsSep " " previouslyPackagedVersions}; do + ln -sfn $out/lib/${pname}${postgresql.dlSuffix} $out/lib/${pname}-$v${postgresql.dlSuffix} + done + '' + } } - create_migration_sql_files() { + ${ + if latestOnly then + '' + # latestOnly mode: skip migration SQL files entirely + '' + else + '' + create_migration_sql_files() { - PREVIOUS_VERSION="" - while IFS= read -r i; do - FILENAME=$(basename "$i") - VERSION="$(grep -oE '[0-9]+\.[0-9]+\.[0-9]+' <<< $FILENAME)" - if [[ "$PREVIOUS_VERSION" != "" ]]; then - # Always write to $out/share/postgresql/extension, not $DIRNAME - # because $DIRNAME might be a symlinked read-only path from the Nix store - # We use -L with cp to dereference symlinks (copy the actual file content, not the symlink) - MIGRATION_FILENAME="$out/share/postgresql/extension/''${FILENAME/$VERSION/$PREVIOUS_VERSION--$VERSION}" - cp -L "$i" "$MIGRATION_FILENAME" - fi - PREVIOUS_VERSION="$VERSION" - done < <(find $out -name '*.sql' | sort -V) + PREVIOUS_VERSION="" + while IFS= read -r i; do + FILENAME=$(basename "$i") + VERSION="$(grep -oE '[0-9]+\.[0-9]+\.[0-9]+' <<< $FILENAME)" + if [[ "$PREVIOUS_VERSION" != "" ]]; then + # Always write to $out/share/postgresql/extension, not $DIRNAME + # because $DIRNAME might be a symlinked read-only path from the Nix store + # We use -L with cp to dereference symlinks (copy the actual file content, not the symlink) + MIGRATION_FILENAME="$out/share/postgresql/extension/''${FILENAME/$VERSION/$PREVIOUS_VERSION--$VERSION}" + cp -L "$i" "$MIGRATION_FILENAME" + fi + PREVIOUS_VERSION="$VERSION" + done < <(find $out -name '*.sql' | sort -V) - # Create empty SQL files for previously packaged versions that don't exist - # This compensates for versions that failed to produce SQL files in the past - for prev_version in ${lib.concatStringsSep " " previouslyPackagedVersions}; do - sql_file="$out/share/postgresql/extension/wrappers--$prev_version.sql" - if [ ! -f "$sql_file" ]; then - echo "-- Empty migration file for previously packaged version $prev_version" > "$sql_file" - fi - done + # Create empty SQL files for previously packaged versions that don't exist + # This compensates for versions that failed to produce SQL files in the past + for prev_version in ${lib.concatStringsSep " " previouslyPackagedVersions}; do + sql_file="$out/share/postgresql/extension/wrappers--$prev_version.sql" + if [ ! -f "$sql_file" ]; then + echo "-- Empty migration file for previously packaged version $prev_version" > "$sql_file" + fi + done - # Create migration SQL files from previous versions to newer versions - # Skip if the migration file already exists (to avoid conflicts with the first loop) - for prev_version in ${lib.concatStringsSep " " previouslyPackagedVersions}; do - for curr_version in ${lib.concatStringsSep " " versions}; do - if [[ "$(printf '%s\n%s' "$prev_version" "$curr_version" | sort -V | head -n1)" == "$prev_version" ]] && [[ "$prev_version" != "$curr_version" ]]; then - main_sql_file="$out/share/postgresql/extension/wrappers--$curr_version.sql" - new_file="$out/share/postgresql/extension/wrappers--$prev_version--$curr_version.sql" - # Only create if it doesn't already exist (first loop may have created it) - if [ -f "$main_sql_file" ] && [ ! -f "$new_file" ]; then - cp "$main_sql_file" "$new_file" - sed -i 's|$libdir/wrappers-[0-9.]*|$libdir/wrappers|g' "$new_file" - fi - fi - done - done + # Create migration SQL files from previous versions to newer versions + # Skip if the migration file already exists (to avoid conflicts with the first loop) + for prev_version in ${lib.concatStringsSep " " previouslyPackagedVersions}; do + for curr_version in ${lib.concatStringsSep " " versions}; do + if [[ "$(printf '%s\n%s' "$prev_version" "$curr_version" | sort -V | head -n1)" == "$prev_version" ]] && [[ "$prev_version" != "$curr_version" ]]; then + main_sql_file="$out/share/postgresql/extension/wrappers--$curr_version.sql" + new_file="$out/share/postgresql/extension/wrappers--$prev_version--$curr_version.sql" + # Only create if it doesn't already exist (first loop may have created it) + if [ -f "$main_sql_file" ] && [ ! -f "$new_file" ]; then + cp "$main_sql_file" "$new_file" + sed -i 's|$libdir/wrappers-[0-9.]*|$libdir/wrappers|g' "$new_file" + fi + fi + done + done + } + '' } create_control_files create_lib_files - create_migration_sql_files + ${if latestOnly then "" else "create_migration_sql_files"} # Verify library count matches expected - (test "$(ls -A $out/lib/${pname}*${postgresql.dlSuffix} | wc -l)" = "${ - toString (numberOfVersions + numberOfPreviouslyPackagedVersions + 1) - }") + ${ + if latestOnly then + '' + (test "$(ls -A $out/lib/${pname}*${postgresql.dlSuffix} | wc -l)" = "2") + '' + else + '' + (test "$(ls -A $out/lib/${pname}*${postgresql.dlSuffix} | wc -l)" = "${ + toString (numberOfVersions + numberOfPreviouslyPackagedVersions + 1) + }") + '' + } ''; passthru = { - inherit versions numberOfVersions; + versions = versionsBuilt; + numberOfVersions = numberOfVersionsBuilt; pname = "${pname}"; + inherit latestOnly; version = - "multi-" + lib.concatStringsSep "-" (map (v: lib.replaceStrings [ "." ] [ "-" ] v) versions); + if latestOnly then + latestVersion + else + "multi-" + lib.concatStringsSep "-" (map (v: lib.replaceStrings [ "." ] [ "-" ] v) versions); # Expose individual packages for CI to build separately packages = packagesAttrSet // { recurseForDerivations = true; diff --git a/nix/packages/default.nix b/nix/packages/default.nix index c146e0096..60694333d 100644 --- a/nix/packages/default.nix +++ b/nix/packages/default.nix @@ -45,6 +45,7 @@ gatekeeper = pkgs.callPackage ./gatekeeper.nix { inherit inputs pkgs; }; supabase-groonga = pkgs.callPackage ../ext/pgroonga/groonga.nix { }; http-mock-server = pkgs.callPackage ./http-mock-server.nix { }; + image-size-analyzer = pkgs.callPackage ./image-size-analyzer.nix { }; local-infra-bootstrap = pkgs.callPackage ./local-infra-bootstrap.nix { }; mecab-naist-jdic = pkgs.callPackage ./mecab-naist-jdic.nix { }; migrate-tool = pkgs.callPackage ./migrate-tool.nix { psql_15 = self'.packages."psql_15/bin"; }; diff --git a/nix/packages/image-size-analyzer.nix b/nix/packages/image-size-analyzer.nix new file mode 100644 index 000000000..a91cacc50 --- /dev/null +++ b/nix/packages/image-size-analyzer.nix @@ -0,0 +1,394 @@ +{ + runCommand, + makeWrapper, + dive, + jq, + docker, + coreutils, + gawk, + gnused, + bc, +}: +runCommand "image-size-analyzer" + { + nativeBuildInputs = [ makeWrapper ]; + buildInputs = [ + dive + jq + docker + coreutils + gawk + gnused + bc + ]; + } + '' + mkdir -p $out/bin + cat > $out/bin/image-size-analyzer << 'SCRIPT' + #!/usr/bin/env bash + set -euo pipefail + + # Default values + OUTPUT_JSON=false + NO_BUILD=false + declare -a IMAGES=() + ALL_DOCKERFILES=("Dockerfile-15" "Dockerfile-17" "Dockerfile-orioledb-17") + TIMESTAMP=$(date +%s) + TEMP_DIR="/tmp/image-size-analyzer-$TIMESTAMP" + + show_help() { + cat << EOF + Usage: image-size-analyzer [OPTIONS] + + Analyze Docker image sizes for Supabase Postgres images. + + Options: + --json Output results as JSON instead of TUI + --image DOCKERFILE Analyze specific Dockerfile (can be used multiple times) + Valid values: Dockerfile-15, Dockerfile-17, Dockerfile-orioledb-17 + --no-build Skip building images, analyze existing ones + --help Show this help message + + Examples: + image-size-analyzer # Analyze all images + image-size-analyzer --json # Output as JSON + image-size-analyzer --image Dockerfile-17 # Analyze only Dockerfile-17 + image-size-analyzer --image Dockerfile-15 --image Dockerfile-17 + image-size-analyzer --no-build # Skip build step + EOF + } + + cleanup() { + rm -rf "$TEMP_DIR" 2>/dev/null || true + } + trap cleanup EXIT + + # Parse arguments + while [[ $# -gt 0 ]]; do + case $1 in + --json) + OUTPUT_JSON=true + shift + ;; + --no-build) + NO_BUILD=true + shift + ;; + --image) + if [[ -z "$2" ]]; then + echo "Error: --image requires a value" + exit 1 + fi + IMAGES+=("$2") + shift 2 + ;; + --help) + show_help + exit 0 + ;; + *) + echo "Error: Unknown option: $1" + show_help + exit 1 + ;; + esac + done + + # If no images specified, use all + num_images=''${#IMAGES[@]} + if [[ $num_images -eq 0 ]]; then + IMAGES=("''${ALL_DOCKERFILES[@]}") + fi + + # Validate image names + for img in "''${IMAGES[@]}"; do + valid=false + for valid_img in "''${ALL_DOCKERFILES[@]}"; do + if [[ "$img" == "$valid_img" ]]; then + valid=true + break + fi + done + if [[ "$valid" == "false" ]]; then + echo "Error: Invalid Dockerfile: $img" + echo "Valid options: ''${ALL_DOCKERFILES[*]}" + exit 1 + fi + done + + # Check Docker is running + if ! docker info &>/dev/null; then + echo "Error: Docker daemon is not running" + exit 3 + fi + + mkdir -p "$TEMP_DIR" + + # Helper to format bytes + format_bytes() { + local bytes=$1 + if [[ $bytes -ge 1073741824 ]]; then + printf "%.2f GB" "$(echo "scale=2; $bytes / 1073741824" | bc)" + elif [[ $bytes -ge 1048576 ]]; then + printf "%.2f MB" "$(echo "scale=2; $bytes / 1048576" | bc)" + elif [[ $bytes -ge 1024 ]]; then + printf "%.2f KB" "$(echo "scale=2; $bytes / 1024" | bc)" + else + printf "%d B" "$bytes" + fi + } + + # Get tag name from Dockerfile name + get_tag() { + local dockerfile=$1 + local suffix=''${dockerfile#Dockerfile-} + echo "supabase-postgres:$suffix-analyze" + } + + # Build a single image + build_image() { + local dockerfile=$1 + local tag + tag=$(get_tag "$dockerfile") + + echo "Building $dockerfile as $tag..." + if ! docker build -f "$dockerfile" -t "$tag" . ; then + echo "Error: Failed to build $dockerfile" + return 1 + fi + } + + # Get total image size + get_total_size() { + local tag=$1 + docker inspect --format='{{.Size}}' "$tag" 2>/dev/null || echo "0" + } + + # Get layer info using dive + get_layers() { + local tag=$1 + local safe_tag=''${tag//[:\/]/-} + local output_file="$TEMP_DIR/dive-$safe_tag.json" + + if ! dive "$tag" --json "$output_file" >/dev/null; then + echo "Warning: dive failed for $tag" >&2 + echo "[]" + return + fi + + # Extract layer info from dive output (note: dive uses sizeBytes not size) + jq -c '[.layer[] | {index: .index, size_bytes: .sizeBytes, command: .command}] | sort_by(-.size_bytes) | .[0:10]' "$output_file" 2>/dev/null || echo "[]" + } + + # Get directory sizes from dive output + get_directories() { + local tag=$1 + local safe_tag=''${tag//[:\/]/-} + local output_file="$TEMP_DIR/dive-$safe_tag.json" + + if [[ ! -f "$output_file" ]]; then + echo "[]" + return + fi + + # Aggregate file sizes by top-level directory from all layers + jq -c ' + [.layer[].fileList[] | select(.isDir == false and .size > 0)] + | group_by(.path | split("/")[0]) + | map({path: ("/" + (.[0].path | split("/")[0])), size_bytes: (map(.size) | add)}) + | sort_by(-.size_bytes) + | .[0:10] + ' "$output_file" 2>/dev/null || echo "[]" + } + + # Get Nix package sizes + get_nix_packages() { + local tag=$1 + + docker run --rm "$tag" sh -c 'du -sb /nix/store/*/ 2>/dev/null | sort -rn | head -15' 2>/dev/null | \ + awk '{ + size=$1 + path=$2 + # Extract package name from path like /nix/store/abc123-packagename-1.0/ + n=split(path, parts, "/") + store_path=parts[n-1] # Get the nix store hash-name part + # Remove the hash prefix (32 chars + dash) + if (length(store_path) > 33) { + name=substr(store_path, 34) + } else { + name=store_path + } + # Remove trailing slash from name + gsub(/\/$/, "", name) + printf "{\"name\":\"%s\",\"size_bytes\":%d}\n", name, size + }' | jq -s '.' 2>/dev/null || echo "[]" + } + + # Get APT/APK package sizes (handles both Debian and Alpine) + get_apt_packages() { + local tag=$1 + local result + + # Try dpkg first (Debian/Ubuntu), then apk (Alpine) + result=$(docker run --rm "$tag" sh -c ' + if command -v dpkg-query >/dev/null 2>&1; then + dpkg-query -W -f="''${Package}\t''${Installed-Size}\n" 2>/dev/null | sort -t" " -k2 -rn | head -15 | awk -F"\t" "{printf \"{\\\"name\\\":\\\"%s\\\",\\\"size_bytes\\\":%d}\\n\", \$1, \$2 * 1024}" + elif command -v apk >/dev/null 2>&1; then + apk info -s 2>/dev/null | paste - - | sort -t" " -k2 -rn | head -15 | awk -F"\t" "{gsub(/ /, \"\", \$2); printf \"{\\\"name\\\":\\\"%s\\\",\\\"size_bytes\\\":%s}\\n\", \$1, \$2}" + else + echo "" + fi + ' 2>/dev/null) + + if [[ -n "$result" ]]; then + echo "$result" | jq -s '.' 2>/dev/null || echo "[]" + else + echo "[]" + fi + } + + # Analyze a single image + analyze_image() { + local dockerfile=$1 + local tag + tag=$(get_tag "$dockerfile") + + local total_size + total_size=$(get_total_size "$tag") + [[ -z "$total_size" || "$total_size" == "" ]] && total_size="0" + + local layers + layers=$(get_layers "$tag") + [[ -z "$layers" || "$layers" == "" ]] && layers="[]" + + local directories + directories=$(get_directories "$tag") + [[ -z "$directories" || "$directories" == "" ]] && directories="[]" + + local nix_packages + nix_packages=$(get_nix_packages "$tag") + [[ -z "$nix_packages" || "$nix_packages" == "" ]] && nix_packages="[]" + + local apt_packages + apt_packages=$(get_apt_packages "$tag") + [[ -z "$apt_packages" || "$apt_packages" == "" ]] && apt_packages="[]" + + # Build JSON result for this image + jq -n \ + --arg dockerfile "$dockerfile" \ + --argjson total_size "$total_size" \ + --argjson layers "$layers" \ + --argjson directories "$directories" \ + --argjson nix_packages "$nix_packages" \ + --argjson apt_packages "$apt_packages" \ + '{ + dockerfile: $dockerfile, + total_size_bytes: $total_size, + layers: $layers, + directories: $directories, + nix_packages: $nix_packages, + apt_packages: $apt_packages + }' + } + + # Print TUI output for a single image + print_tui() { + local json=$1 + + local dockerfile + dockerfile=$(echo "$json" | jq -r '.dockerfile') + + local total_size + total_size=$(echo "$json" | jq -r '.total_size_bytes') + + echo "" + echo "================================================================================" + echo "IMAGE: $dockerfile" + echo "================================================================================" + echo "Total Size: $(format_bytes "$total_size")" + echo "" + + echo "LAYERS (top 10 by size)" + echo "--------------------------------------------------------------------------------" + printf " %-4s %-12s %s\n" "#" "SIZE" "COMMAND" + echo "$json" | jq -r '.layers[] | "\(.index)\t\(.size_bytes)\t\(.command)"' 2>/dev/null | \ + while IFS=$'\t' read -r idx size cmd; do + cmd_short=$(echo "$cmd" | cut -c1-60) + printf " %-4s %-12s %s\n" "$idx" "$(format_bytes "$size")" "$cmd_short" + done + echo "" + + echo "DIRECTORIES (top 10 by size)" + echo "--------------------------------------------------------------------------------" + echo "$json" | jq -r '.directories[] | "\(.path)\t\(.size_bytes)"' 2>/dev/null | \ + while IFS=$'\t' read -r path size; do + printf " %-45s %s\n" "$path" "$(format_bytes "$size")" + done + echo "" + + echo "NIX PACKAGES (top 15 by size)" + echo "--------------------------------------------------------------------------------" + echo "$json" | jq -r '.nix_packages[] | "\(.name)\t\(.size_bytes)"' 2>/dev/null | \ + while IFS=$'\t' read -r name size; do + printf " %-45s %s\n" "$name" "$(format_bytes "$size")" + done + echo "" + + echo "APT PACKAGES (top 15 by size)" + echo "--------------------------------------------------------------------------------" + echo "$json" | jq -r '.apt_packages[] | "\(.name)\t\(.size_bytes)"' 2>/dev/null | \ + while IFS=$'\t' read -r name size; do + printf " %-45s %s\n" "$name" "$(format_bytes "$size")" + done + } + + # Main execution + main() { + # Build images if needed + if [[ "$NO_BUILD" == "false" ]]; then + for dockerfile in "''${IMAGES[@]}"; do + build_image "$dockerfile" || exit 1 + done + fi + + # Analyze each image + declare -a results=() + for dockerfile in "''${IMAGES[@]}"; do + local tag + tag=$(get_tag "$dockerfile") + + # Check image exists + if ! docker image inspect "$tag" &>/dev/null; then + echo "Error: Image $tag not found. Run without --no-build to build it first." + exit 1 + fi + + echo "Analyzing $dockerfile..." >&2 + local result + result=$(analyze_image "$dockerfile") + results+=("$result") + done + + # Output results + if [[ "$OUTPUT_JSON" == "true" ]]; then + # Combine all results into JSON array + printf '%s\n' "''${results[@]}" | jq -s '{images: .}' + else + for result in "''${results[@]}"; do + print_tui "$result" + done + fi + } + + main + SCRIPT + chmod +x $out/bin/image-size-analyzer + wrapProgram $out/bin/image-size-analyzer \ + --prefix PATH : ${dive}/bin \ + --prefix PATH : ${jq}/bin \ + --prefix PATH : ${docker}/bin \ + --prefix PATH : ${coreutils}/bin \ + --prefix PATH : ${gawk}/bin \ + --prefix PATH : ${gnused}/bin \ + --prefix PATH : ${bc}/bin + '' diff --git a/nix/packages/postgres.nix b/nix/packages/postgres.nix index ad1779f68..b58429fec 100644 --- a/nix/packages/postgres.nix +++ b/nix/packages/postgres.nix @@ -55,7 +55,12 @@ orioledbExtensions = orioleFilteredExtensions ++ [ ../ext/orioledb.nix ]; dbExtensions17 = orioleFilteredExtensions; - getPostgresqlPackage = version: pkgs."postgresql_${version}"; + getPostgresqlPackage = + version: latestOnly: + let + base = pkgs."postgresql_${version}"; + in + if latestOnly then base.override { systemdSupport = false; } else base; # Create a 'receipt' file for a given postgresql package. This is a way # of adding a bit of metadata to the package, which can be used by other # tools to inspect what the contents of the install are: the PSQL @@ -93,8 +98,11 @@ makeOurPostgresPkgs = version: + { + latestOnly ? false, + }: let - postgresql = getPostgresqlPackage version; + postgresql = getPostgresqlPackage version latestOnly; extensionsToUse = if (builtins.elem version [ "orioledb-17" ]) then orioledbExtensions @@ -105,7 +113,7 @@ extCallPackage = pkgs.lib.callPackageWith ( pkgs // { - inherit postgresql; + inherit postgresql latestOnly; switch-ext-version = extCallPackage ./switch-ext-version.nix { }; overlayfs-on-package = extCallPackage ./overlayfs-on-package.nix { }; } @@ -116,8 +124,11 @@ # Create an attrset that contains all the extensions included in a server. makeOurPostgresPkgsSet = version: + { + latestOnly ? false, + }: let - pkgsList = makeOurPostgresPkgs version; + pkgsList = makeOurPostgresPkgs version { inherit latestOnly; }; baseAttrs = builtins.listToAttrs ( map (drv: { name = drv.name; @@ -142,9 +153,12 @@ # basis for building extensions, etc. makePostgresBin = version: + { + latestOnly ? false, + }: let - postgresql = getPostgresqlPackage version; - postgres-pkgs = makeOurPostgresPkgs version; + postgresql = getPostgresqlPackage version latestOnly; + postgres-pkgs = makeOurPostgresPkgs version { inherit latestOnly; }; ourExts = map (ext: { name = ext.name; version = ext.version; @@ -171,22 +185,30 @@ # package names. makePostgres = version: + { + latestOnly ? false, + }: lib.recurseIntoAttrs { - bin = makePostgresBin version; - exts = makeOurPostgresPkgsSet version; + bin = makePostgresBin version { inherit latestOnly; }; + exts = makeOurPostgresPkgsSet version { inherit latestOnly; }; }; basePackages = { - psql_15 = makePostgres "15"; - psql_17 = makePostgres "17"; - psql_orioledb-17 = makePostgres "orioledb-17"; + psql_15 = makePostgres "15" { }; + psql_17 = makePostgres "17" { }; + psql_orioledb-17 = makePostgres "orioledb-17" { }; + }; + slimPackages = { + psql_15_slim = makePostgres "15" { latestOnly = true; }; + psql_17_slim = makePostgres "17" { latestOnly = true; }; + psql_orioledb-17_slim = makePostgres "orioledb-17" { latestOnly = true; }; }; binPackages = lib.mapAttrs' (name: value: { name = "${name}/bin"; value = value.bin; - }) basePackages; + }) (basePackages // slimPackages); in { packages = binPackages; - legacyPackages = basePackages; + legacyPackages = basePackages // slimPackages; }; } diff --git a/nix/postgresql/generic.nix b/nix/postgresql/generic.nix index a99ecad6d..c9dcae841 100644 --- a/nix/postgresql/generic.nix +++ b/nix/postgresql/generic.nix @@ -132,7 +132,13 @@ let ++ lib.optionals pythonSupport [ python3 ] ++ lib.optionals gssSupport [ libkrb5 ] ++ lib.optionals stdenv'.isLinux [ linux-pam ] - ++ lib.optionals (!stdenv'.isDarwin) [ libossp_uuid ] + ++ lib.optionals (!stdenv'.isDarwin) [ libossp_uuid ]; + + nativeBuildInputs = [ + makeWrapper + pkg-config + ] + # Build tools for PG17+ and OrioleDB - these are NOT runtime dependencies ++ lib.optionals (isOrioleDB || (lib.versionAtLeast version "17")) [ perl bison @@ -141,11 +147,6 @@ let docbook_xml_dtd_45 docbook_xsl_ns libxslt - ]; - - nativeBuildInputs = [ - makeWrapper - pkg-config ] ++ lib.optionals jitSupport [ llvmPackages.llvm.dev