Repository navigation
build: drop psycopg-binary from extra_proxy and use the image libpq - #42909
devin-ai-integration[bot] wants to merge 8 commits into
Conversation
…mage libpq psycopg-binary bundles its own OpenSSL 1.1.1k, which is EOL and lands in every proxy image. The only caller, ProxyExtrasDBManager.spend_logs_is_partitioned(), runs one catalog query at boot, so pure Python psycopg over the Wolfi libpq-18 package is enough. Integration tests pin the locked extra and the runtime apk list, and boot the proxy on the pure Python driver against a partitioned and an unpartitioned LiteLLM_SpendLogs Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
|
I'll fix CI failures and address comments from users with write access. I'll skip comments containing "(aside)".
|
|
Codecov Report✅ All modified and coverable lines are covered by tests. 📢 Thoughts on this report? Let us know! |
…ck is skipped psycopg imports fine without libpq and only raises when the pq wrapper is resolved, so the skipped-check warning now carries the ImportError text and points at the system libpq the images ship Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
|
bugbot run |
…hon psycopg Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
|
bugbot run |
|
bugbot run |
…sycopg Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
|
bugbot run |
There was a problem hiding this comment.
✅ Bugbot reviewed your changes and found no new issues!
Comment @cursor review or bugbot run to trigger another review on this PR
Reviewed by Cursor Bugbot for commit 36627a6. Configure here.
TLDR
Problem this solves:
psycopg-binaryships its ownlibcrypto/libsslinside every proxy imageHow it solves it:
extra_proxynow depends onpsycopgonly, no binary wheellibpq-18, psycopg picks its pure Python driver over itLiteLLM_SpendLogs, keeps working unchangeddatabaseintegration shard installslibpq5first, since the machine image has no system libpq for the pure Python driver the new tests selectUser Flow
Before: an operator scanning the proxy image for bundled crypto finds a second OpenSSL and cannot claim FIPS
ghcr.io/berriai/litellm:main-latestand runfind / -name 'libcrypto*'/usr/lib/libcrypto.so.3and/app/.venv/.../psycopg_binary.libs/libcrypto-<hash>.so.3After: the same scan finds only the distro OpenSSL, and the proxy still boots the same way
find / -name 'libcrypto*'/usr/lib/libcrypto.so.3comes back, and/usr/lib/libpq.so.5is present for psycopgGET /health/readinessreturns{"status":"healthy","db":"connected"}LiteLLM_SpendLogs,--use_prisma_db_pushstill refuses with the same partition guidance as beforeLinear ticket
Resolves LIT-8433
Pre-Submission checklist
uv run pytest tests/test_litellm/<your_test_file>.py -v. Leave the suites (make test-unit-*,make test-unit) to CI: it finishes in ~15 minutes where a laptop takes an hour or more@greptileaito re-request a review after pushing changes)Screenshots / Proof of Fix
Setup: the
extra_proxyexport of each leg, and the runtime stage ofDockerfilereproduced in acgr.dev/chainguard/wolfi-basecontainer (same digest as the Dockerfile) with the lockedpsycopg==3.3.3, pointed at a local Postgres holding a partitionedLiteLLM_SpendLogsBefore (09ebb28)
uv export --frozen --no-hashes --no-dev --no-emit-project --extra extra_proxy | grep ^psycopgpip install psycopg-binary==3.3.3 && find .venv -name 'libcrypto*' && strings <it> | grep -m1 '^OpenSSL 'apk addlist has nolibpq, so dropping the wheel alone would leave psycopg with no driverAfter (36627a6)
uv export --frozen --no-hashes --no-dev --no-emit-project --extra extra_proxy | grep ^psycopgapk add bash openssl tzdata nodejs python-3.13 libsndfile libevent libpq-18 && pip install psycopg==3.3.3 && find /v -name 'libcrypto*' -o -name 'libssl*' | wc -l && ls /usr/lib/libpq.so*PSYCOPG_IMPL=python, unpartitioned database:curl -s http://127.0.0.1:4384/health/readinesspsycopg is not installedwarningPSYCOPG_IMPL=python, partitioned database,--use_prisma_db_push: exits non-zero withLiteLLM_SpendLogs is a partitioned tableandpg_partitioned_tablestill lists the table afterwardsAudit (deterministic tests/integration, no providers, no mocks)
Rig: real Postgres and Redis, two-worker proxy per leg, scripted upstream from
tests/integration/_support/upstream.py. Base leg09ebb28473e6e9e09c80ce2f822b88d8bc24f2e4on port 4383 (dblitaudit_psycopg_base), head leg36627a61a366cbb1ad56624b98f815a50e5c131fon port 4384 (dblitaudit_psycopg_head), run ids base run_3 (merge base unchanged), head run_9 and run_10.uv run --no-sync python tests/integration/run.py database --seed 4106601 --order-seed 7tests/integration/database/test_spend_logs_partition_driver.py::test_proxy_image_extra_ships_psycopg_without_the_binary_wheel_and_uses_the_image_libpqpsycopg-binaryin export)LiteLLM_SpendLogs, db push refuses and leaves the table alonetests/integration/database/test_spend_logs_partition_driver.py::test_pure_python_psycopg_detects_partitioned_spend_logs_and_refuses_db_push/health/readinessdb connectedtests/integration/database/test_spend_logs_partition_driver.py::test_pure_python_psycopg_lets_an_unpartitioned_proxy_boot_and_servedatabasegroup (4 nodes)tests/integration/database/Head selection ran twice with identical
execution.json(7 collected, 7 passed, 0 skipped, hypothesis seed 4106601, order seed 7). Chaos not run: the change is a boot-time catalog query and packaging metadata, no request path, queue or callback to interruptMutation: with
psycopg-binaryrestored toextra_proxy(the base leg) the packaging cell fails; withlibpq-18removed from the backend, gateway and migrations runtime stages the packaging cell fails withDockerfile runtime stage installs no libpq for psycopg; withspend_logs_is_partitioned()forced toreturn Falsethe partitioned cell fails because db push proceeds against the partitioned table instead of refusing; with the skipped-check warning reverted to the old text without theImportError,tests/unit/litellm_proxy_extras/test_litellm_proxy_extras_utils.py::TestSpendLogsPartitionDetectionMissingPsycopg::test_missing_libpq_warning_names_the_libpq_errorfailsType
🚄 Infrastructure
Caveats (if any)
Medium
psycopg[c]is not used: Wolfi haspostgresql-18-dev, but the C build adds a compiler step per image for a single boot-time query, so the pure Python driver is the deliberate choicedocker/build_from_pip/Dockerfile.build_from_pipinstallslitellm[proxy,proxy-runtime]withoutextra_proxy, so it never had psycopg or the bundle; unchanged hereLow
Missing libpq outside the images still fails open (partition check skipped with a warning naming the libpq error), the same fail-open the missing psycopg case had before this PR; the images ship libpq so this only affects bare pip installs of extra_proxy on a host without libpq
The dev-only
utilsgroup still pinspsycopg-binaryfor local pytest without a system libpq; it is never installed into an imagePSYCOPG_IMPLis unset in the images; psycopg picks the C extension when present and otherwise the pure Python driver, which is what ships nowLink to Devin session: https://app.devin.ai/sessions/5cae45b6407447e0adfee8a5b8e0283a
Open in Devin Desktop: https://app.devin.ai/desktop/session/5cae45b6407447e0adfee8a5b8e0283a?variant=devin
Requested by: @yucheng-berri