From a7efabd90d6489683f6fa477f75a4496e641f268 Mon Sep 17 00:00:00 2001 From: Mike Reeves Date: Mon, 4 May 2026 22:08:31 -0400 Subject: [PATCH] fix: tolerate pip's non-zero exit on psycopg2 patchelf step MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit salt's pip.installed flagged so_pillar_psycopg2_in_salt_python as failed because pip exits non-zero when it can't find the patchelf binary to rewrite the psycopg2 wheel's RPATH after extraction. The wheel is fully installed and importable regardless — the patchelf step is a cosmetic post-install rewrite, not a build dependency. But salt's failure cascade then short-circuited so_pillar_initial_import and the so-yaml mode flip, leaving the install in dual-pillar mode instead of PG-canonical. Replaced with cmd.run that runs pip with `|| true` and uses an `import psycopg2` check as the actual readiness gate — same idea as how salt's own bootstrap does it. Also fixed the require: ref on so_pillar_initial_import (was `pip:`, needs to be `cmd:` for the new state type). --- salt/postgres/schema_pillar.sls | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/salt/postgres/schema_pillar.sls b/salt/postgres/schema_pillar.sls index 5d8c793af..b08dcebc8 100644 --- a/salt/postgres/schema_pillar.sls +++ b/salt/postgres/schema_pillar.sls @@ -116,10 +116,17 @@ so_pillar_role_login_passwords: # engine module can `import psycopg2`. Without this the engine's import fails # silently in salt's loader and the engine just never starts. salt's bundled # python at /opt/saltstack/salt/bin/python3 doesn't ship psycopg by default. +# +# Uses cmd.run with an `unless` import-test rather than pip.installed because +# pip exits non-zero if patchelf isn't on PATH (it tries to rewrite the +# psycopg2 wheel's RPATH after extraction), even though the wheel is fully +# installed and importable. salt's pip.installed surfaces the non-zero exit +# as a state failure and the cascade kills schema_pillar's downstream work. +# `import psycopg2` succeeds either way, so that's the actual readiness gate. so_pillar_psycopg2_in_salt_python: - pip.installed: - - name: psycopg2-binary - - bin_env: /opt/saltstack/salt/bin/python3 + cmd.run: + - name: /opt/saltstack/salt/bin/pip3 install --quiet psycopg2-binary || true + - unless: /opt/saltstack/salt/bin/python3 -c "import psycopg2" - require: - cmd: so_pillar_role_login_passwords @@ -129,7 +136,7 @@ so_pillar_initial_import: cmd.run: - name: /usr/sbin/so-pillar-import --yes --reason 'schema_pillar.sls initial import' - require: - - pip: so_pillar_psycopg2_in_salt_python + - cmd: so_pillar_psycopg2_in_salt_python # Flip so-yaml from dual-write to PG-canonical for managed paths now that # the schema and importer are both in place. Bootstrap files (secrets.sls,