Repository navigation
fix(tmachine): provide a CA bundle for host tools on macOS - #4930
matthewgrossman wants to merge 1 commit into
Conversation
Nix's OpenSSL on Darwin only trusts the CA bundle in the default Nix profile. Installers that don't create that profile leave ansible-galaxy unable to verify galaxy.ansible.com, so environments with use_galaxy fail before the VM boots. When neither NIX_SSL_CERT_FILE nor SSL_CERT_FILE is set, the tmachine wrapper now points SSL_CERT_FILE at the pinned nixpkgs cacert bundle. User-configured bundles keep precedence. Signed-off-by: Matthew Grossman <mgrossman@nvidia.com>
|
Closing without merging: the root cause was how Nix was installed on my machine, not OpenShell. What was wrong. Nix's OpenSSL on Darwin trusts only What we changed locally.
Verified after the reinstall, using
The fallback in this PR would only help Macs whose Nix install is missing the default profile. That doesn't seem worth carrying in the wrapper or adding to #4773's runner. If someone else hits |
Summary
On macOS,
nix run .#tmachinecan fail before a VM boots:ansible-galaxycan't verifygalaxy.ansible.com(CERTIFICATE_VERIFY_FAILED: unable to get local issuer certificate). The tmachine wrapper now falls back to the pinned nixpkgs CA bundle when the user hasn't configured one.Related Issue
No separate issue. This fixes a broken build/test-tooling path on macOS. Root cause and verification are below.
Root cause
Nix's OpenSSL on Darwin is compiled to trust only
/nix/var/nix/profiles/default/etc/ssl/certs/ca-bundle.crt. Python'sssl.get_default_verify_paths()in the wrapper's Ansible (Python 3.14, OpenSSL 3.6.3) reports exactly that path, with nocapathfallback. The official Nix installer creates that profile and exportsNIX_SSL_CERT_FILE. Other installs, including flox-managed Nix, don't, so every HTTPS client linked against Nix's OpenSSL has no trust store.SSL_CERT_DIR=/etc/ssl/certsdoesn't help because macOS doesn't keep hashed certificates there.This is not specific to
ansible-galaxyor to how tmachine builds its environment. A plainurllibrequest from the same Python fails the same way, and systemcurland/usr/bin/python3succeed. On Linux, Nix's OpenSSL reads/etc/ssl/certs/ca-certificates.crt, which is why CI is unaffected.Only
ansible-galaxyuses TLS on the host. The guest runs Ansible modules with/usr/bin/python3against Ubuntu's own trust store, and base images are fetched by Nix at build time.Changes
tests/tmachine/config.nix: add a sharedhostCaBundleSetupsnippet, used by thetmachinewrapper. On Darwin, if neitherNIX_SSL_CERT_FILEnorSSL_CERT_FILEis set, it exportsSSL_CERT_FILEto${pkgs.cacert}/etc/ssl/certs/ca-bundle.crt. On other platforms it is empty, and the Linux wrapper contains no CA setting.Design notes:
runtimeEnv.runtimeEnvexports unconditionally. Nix's OpenSSL givesNIX_SSL_CERT_FILEprecedence overSSL_CERT_FILE, so setting either one unconditionally could override a corporate CA bundle a user configured on purpose. The wrapper checks both and exports onlySSL_CERT_FILE, the lower-precedence variable.pkgs.cacertrather than/etc/ssl/cert.pem. It's pinned with the rest of the toolchain and matches what the official Nix installer provides./etc/ssl/cert.pemdoesn't include CAs from the macOS Keychain either, so it adds nothing for corporate setups.openshell-test-runnerwrapper it adds also runs Ansible, and it lives next to this one inconfig.nix. It should include${hostCaBundleSetup}in itstextas well. I can follow up on whichever PR lands second.Testing
All on Apple Silicon macOS with
SSL_CERT_FILE,NIX_SSL_CERT_FILEandSSL_CERT_DIRunset:Reproduced the bug: the wrapper's Python fails
urllibtohttps://galaxy.ansible.com/api/, andansible-galaxy role installthrough the old wrapper's environment fails with the reported error.With the new wrapper's environment,
ansible-galaxy role installsucceeds.User settings still win: through the new wrapper, an empty
SSL_CERT_FILEorNIX_SSL_CERT_FILEstill makes Galaxy fail (the user value is respected), andSSL_CERT_FILE=/etc/ssl/cert.pemsucceeds.End to end:
tmachine install ubuntu-docker-rootful debwith an empty tmachine cache, so Galaxy and both layers run. The roles install, the VM boots, the nextest, Docker and OpenShell.debplaybooks pass, and the command exits 0.nix fmtshows no changes. Thex86_64-linuxtmachinederivation evaluates and contains no CA setting.Not run: Linux end to end (no behavior change there) and a test suite run. The local artifacts don't include test archives.
Checks appropriate to the affected code and behavior pass
Unit tests added/updated (if applicable)
E2E tests added/updated (if applicable)
Checklist