diff --git a/packages/marmel/package.nix b/packages/marmel/package.nix index 45b6958..9c440a1 100644 --- a/packages/marmel/package.nix +++ b/packages/marmel/package.nix @@ -7,26 +7,31 @@ rustPlatform.buildRustPackage rec { pname = "marmel"; - # Upstream publishes no git tags, so this is pinned to the 1.0.0 release - # commit ("1.0.0 (#6)"). + # Upstream publishes no git tags and no GitHub releases, and Cargo.toml still + # says 1.0.0, so the version is meaningless and the source is tracked by + # branch head. Bump with nix-update (see passthru.updateScript). version = "1.0.0"; src = fetchFromGitHub { owner = "Na1w"; repo = "marmel"; - rev = "d6627d7cf3bf509d1e6db0d9d78736116e92e82a"; - hash = "sha256-UlrSp/n3og0GAQXzISsB24OfK3qOUPE7jYOkEbZ2neI="; + rev = "3f238ff217ee2e1033c937c840bd2d33ec57abc4"; + hash = "sha256-ijSsUAJom/uIiE09PM1kfXqNVCRqnipAQo72KXlr8sQ="; }; cargoHash = "sha256-etqW3xcxkiNfkiPxl/Emt5pQCkNnoIhHFkX0Zqfs4rc="; nativeCheckInputs = [ cacert ]; + patches = [ ./session-boot-trust-store.patch ]; + # The test suite builds `reqwest::Client`s, and rustls rejects construction # outright when no system trust store is found ("No CA certificates were - # loaded from the system"). The sandbox has no /etc/ssl, so point the tests - # at nixpkgs' bundle. Build-time only; the installed binary still uses the - # host's trust store at runtime. + # loaded from the system"). rustls-native-certs probes only SSL_CERT_FILE, + # SSL_CERT_DIR and a fixed list of /etc dirs (/etc/ssl, /etc/pki/tls, ...), + # none of which exist in the build sandbox, so point the tests at nixpkgs' + # bundle. Build-time only; the installed binary still uses the host's trust + # store at runtime. preCheck = '' export SSL_CERT_FILE=${cacert}/etc/ssl/certs/ca-bundle.crt ''; diff --git a/packages/marmel/session-boot-trust-store.patch b/packages/marmel/session-boot-trust-store.patch new file mode 100644 index 0000000..2ba4965 --- /dev/null +++ b/packages/marmel/session-boot-trust-store.patch @@ -0,0 +1,43 @@ +Give the env-cleared child process a trust store. + +run_marmel() wipes the child environment so the binary under test cannot +inherit the runner's MARMEL_* variables or its terminal. reqwest's TLS stack +is rustls-native-certs, which reads SSL_CERT_FILE / SSL_CERT_DIR and then the +well-known /etc paths, so where no system trust store exists at all the child +dies inside reqwest::Client::new() ("No CA certificates were loaded from the +system") before it ever reads the bundle. Four cases in this file assert the +CLI's exit codes and stderr, and they then observe the panic's 101 instead. + +Forward the test runner's SSL_CERT_FILE when it has one. On a normal Linux +host the child picks the trust store up from /etc as before, so the assertions +themselves are unchanged. + +This is a workaround, not the real fix. The panic should not happen at all: +src/llm/client.rs builds the client with unwrap_or_default() on a +Result, and reqwest's Client::default() is +Client::new(), which repeats the same build and .expect()s it, so the fallback +can never recover. Upstream was told; drop this patch once the error is +propagated instead of discarded. + +--- a/tests/test_session_boot.rs ++++ b/tests/test_session_boot.rs +@@ -221,8 +221,17 @@ + let err_file = std::fs::File::create(&err_path).expect("stderr file"); + + let mut cmd = Command::new(env!("CARGO_BIN_EXE_marmel")); +- cmd.current_dir(dir) +- .env_clear() ++ cmd.current_dir(dir).env_clear(); ++ // rustls-native-certs reads SSL_CERT_FILE / SSL_CERT_DIR, both of which the ++ // env_clear() above drops, so when no system trust store can be probed ++ // either the child dies inside reqwest::Client::new() ("No CA certificates ++ // were loaded from the system") before it ever reaches the bundle, and the ++ // exit-code assertions below then see the panic's 101. Forward the runner's ++ // value when it has one; the assertions themselves are untouched. ++ if let Some(trust_store) = std::env::var("SSL_CERT_FILE").ok().filter(|p| !p.is_empty()) { ++ cmd.env("SSL_CERT_FILE", trust_store); ++ } ++ cmd + // A minimal, deterministic environment: the binary must not inherit the + // test runner's `MARMEL_*` variables or its terminal. + .env("PATH", "/usr/bin:/bin")