mirror of
https://github.com/kevinveenbirkenbach/computer-playbook.git
synced 2026-11-06 10:59:59 +00:00
fix(env): point python at the OS trust store
The package-cache frontend terminates TLS for package traffic and signs with its own CA: probed from inside the test container, pypi.org arrives as subject CN=pypi.org issued by CN=Infinito Package-Cache Frontend CA. package-frontend-ca.sh installs that CA into the OS store, which is why apt, pip, curl and urllib work — but requests reads certifi, which has never heard of it, so test-external failed its reachability precondition with CERTIFICATE_VERIFY_FAILED. Upgrading certifi does not help; the issuer is not a public root. load.sh is where the runner puts the venv on PATH, so it is also where the interpreter carrying the pip certifi is chosen; pointing REQUESTS_CA_BUNDLE and SSL_CERT_FILE at the store the stack deliberately fills keeps one trust decision instead of two. A caller-set value still wins. The bundle location was about to become a fourth copy: dev-nix and the network diagnose CLI each carried their own candidate list, and the two had already drifted apart in their fourth entry. All of them now read group_vars CA_BUNDLE_CANDIDATES — Ansible directly, the shell through a generated env key, python through read_group_paths. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
1 parent
3e56117548
commit
fc0881ff33
8 files changed
+76
-12
No files matched your search
@@ -2,6 +2,8 @@
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from utils.paths import read_group_paths
|
||||
|
||||
DEFAULT_HOSTS: tuple[str, ...] = (
|
||||
"github.com",
|
||||
"objects.githubusercontent.com",
|
||||
@@ -58,12 +60,7 @@ PROXY_ENV_KEYS: tuple[str, ...] = (
|
||||
"CA_TRUST_NAME",
|
||||
)
|
||||
|
||||
CA_BUNDLE_CANDIDATES: tuple[str, ...] = (
|
||||
"/etc/ssl/certs/ca-certificates.crt",
|
||||
"/etc/pki/tls/certs/ca-bundle.crt",
|
||||
"/etc/ssl/ca-bundle.pem",
|
||||
"/etc/pki/ca-trust/extracted/pem/tls-ca-bundle.pem",
|
||||
)
|
||||
CA_BUNDLE_CANDIDATES: tuple[str, ...] = tuple(read_group_paths("CA_BUNDLE_CANDIDATES"))
|
||||
|
||||
PMTU_PROBE_SIZES: tuple[int, ...] = (1472, 1452, 1400, 1300, 1200, 1024, 576, 256)
|
||||
|
||||
|
||||
@@ -30,3 +30,10 @@ DIR_RESCUE_DIAGNOSTICS: "/tmp/infinito-rescue-diagnostics"
|
||||
FILE_DNS53_SAMPLER_LOG: "/var/log/infinito/dns53-sampler.log"
|
||||
|
||||
FILE_ENVIRONMENT: "/etc/environment" # File to safe environment variables in
|
||||
|
||||
CA_BUNDLE_CANDIDATES: # Where the distributions keep the extracted CA bundle, most likely first
|
||||
- "/etc/ssl/certs/ca-certificates.crt"
|
||||
- "/etc/pki/tls/certs/ca-bundle.crt"
|
||||
- "/etc/ssl/ca-bundle.pem"
|
||||
- "/etc/pki/tls/cacert.pem"
|
||||
- "/etc/pki/ca-trust/extracted/pem/tls-ca-bundle.pem"
|
||||
@@ -38,8 +38,4 @@ dev_nix_experimental_features:
|
||||
- nix-command
|
||||
- flakes
|
||||
|
||||
DEV_NIX_SSL_CERT_FILE_CANDIDATES:
|
||||
- /etc/ssl/certs/ca-certificates.crt
|
||||
- /etc/pki/tls/certs/ca-bundle.crt
|
||||
- /etc/ssl/ca-bundle.pem
|
||||
- /etc/pki/tls/cacert.pem
|
||||
DEV_NIX_SSL_CERT_FILE_CANDIDATES: "{{ CA_BUNDLE_CANDIDATES }}"
|
||||
@@ -26,7 +26,7 @@
|
||||
| map(attribute="item")
|
||||
| list
|
||||
| first
|
||||
) | default("/etc/ssl/certs/ca-certificates.crt", true)
|
||||
) | default(CA_BUNDLE_CANDIDATES | first, true)
|
||||
}}
|
||||
|
||||
- name: 📦 Install Nix via package manager on Arch-based systems
|
||||
|
||||
Vendored
+11
@@ -86,6 +86,17 @@ for _infinito_env_key in "${!_infinito_env_preserved[@]}"; do
|
||||
done
|
||||
unset _infinito_env_key _infinito_env_preserved
|
||||
|
||||
if [[ -z "${REQUESTS_CA_BUNDLE:-}" ]]; then
|
||||
for _infinito_env_ca in ${INFINITO_CA_BUNDLE_CANDIDATES}; do
|
||||
if [[ -r "${_infinito_env_ca}" ]]; then
|
||||
export REQUESTS_CA_BUNDLE="${_infinito_env_ca}"
|
||||
export SSL_CERT_FILE="${SSL_CERT_FILE:-${_infinito_env_ca}}"
|
||||
break
|
||||
fi
|
||||
done
|
||||
unset _infinito_env_ca
|
||||
fi
|
||||
|
||||
export INFINITO_ENV_LOADED="1"
|
||||
_infinito_env_mtime="$(stat -c %Y "${_infinito_env_dotenv}" 2>/dev/null || echo 0)"
|
||||
export INFINITO_ENV_LOADED_MTIME="${_infinito_env_mtime}"
|
||||
|
||||
Vendored
+2
@@ -15,6 +15,7 @@ from . import (
|
||||
passthrough,
|
||||
)
|
||||
from .infinito import (
|
||||
ca_bundle_candidates,
|
||||
ca_cert_host,
|
||||
container,
|
||||
distros,
|
||||
@@ -70,6 +71,7 @@ ORDERED_HANDLERS = [
|
||||
running_on_github,
|
||||
tor_socks_port,
|
||||
is_wsl2,
|
||||
ca_bundle_candidates,
|
||||
ca_cert_host,
|
||||
outer_network_mtu,
|
||||
inventory,
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
"""INFINITO_CA_BUNDLE_CANDIDATES: where the distributions keep the extracted CA
|
||||
bundle, read from the group_vars paths SPOT (group_vars/all/05_paths.yml
|
||||
CA_BUNDLE_CANDIDATES)."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
from utils.paths import read_group_paths
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from utils.env.builder import BuildContext, EnvBuilder
|
||||
|
||||
KEY = "INFINITO_CA_BUNDLE_CANDIDATES"
|
||||
COMMENT = "Extracted CA bundle per distribution layout, most likely first; consumers take the first readable one (SPOT: group_vars/all/05_paths.yml CA_BUNDLE_CANDIDATES)."
|
||||
|
||||
|
||||
def apply(eb: EnvBuilder, ctx: BuildContext) -> None:
|
||||
eb.setdefault(
|
||||
KEY, " ".join(read_group_paths("CA_BUNDLE_CANDIDATES")), comment=COMMENT
|
||||
)
|
||||
@@ -27,6 +27,7 @@ _GROUP_PATHS_FILE = str(PROJECT_ROOT / "group_vars" / "all" / "05_paths.yml")
|
||||
_ENTRY_RE = re.compile(
|
||||
r'^(?P<key>[A-Za-z_][A-Za-z0-9_]*):\s*"?(?P<value>[^"#]*)"?\s*(?:#.*)?$'
|
||||
)
|
||||
_ITEM_RE = re.compile(r'^\s+-\s*"?(?P<value>[^"#]*)"?\s*(?:#.*)?$')
|
||||
|
||||
|
||||
def read_group_path(key: str) -> str:
|
||||
@@ -56,6 +57,35 @@ def read_group_path(key: str) -> str:
|
||||
raise KeyError(f"{key} not defined in {_GROUP_PATHS_FILE}")
|
||||
|
||||
|
||||
def read_group_paths(key: str) -> list[str]:
|
||||
"""Plain-string list value from the group_vars paths SPOT.
|
||||
|
||||
Args:
|
||||
key: top-level variable name whose value is a YAML block sequence.
|
||||
|
||||
Returns:
|
||||
The literal string entries, in file order.
|
||||
|
||||
Raises:
|
||||
KeyError: the key is not defined in the SPOT or carries no entry.
|
||||
"""
|
||||
entries: list[str] = []
|
||||
collecting = False
|
||||
for line in read_text(_GROUP_PATHS_FILE).splitlines():
|
||||
if line.startswith(f"{key}:"):
|
||||
collecting = True
|
||||
continue
|
||||
if not collecting:
|
||||
continue
|
||||
item = _ITEM_RE.match(line)
|
||||
if item is None:
|
||||
break
|
||||
entries.append(item.group("value").strip())
|
||||
if not entries:
|
||||
raise KeyError(f"{key} not defined as a list in {_GROUP_PATHS_FILE}")
|
||||
return entries
|
||||
|
||||
|
||||
def _dir_var_lib() -> str:
|
||||
env = os.environ.get("INFINITO_DIR_VAR_LIB")
|
||||
if env:
|
||||
|
||||
Reference in new issue
Block a user