-
Notifications
You must be signed in to change notification settings - Fork 0
0.3.71: the diagnostics gate had no opener — a removal wearing a switch's clothes #81
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -97,7 +97,26 @@ async fn async_main(arena_cap: diag::ArenaCap) -> anyhow::Result<()> { | |
|
|
||
| // Default: serve the node + StatusAdapter. Reconstruct the arg iterator | ||
| // (`first` was consumed by the subcommand peek). | ||
| let (home, key_id) = parse_args(first.into_iter().chain(args))?; | ||
| let (home, key_id, diagnostics_flag) = parse_args(first.into_iter().chain(args))?; | ||
|
|
||
| // THE OPENER. 0.3.69 gated `/api/v1/debug/memory` on | ||
| // `ciris_server::diag::enabled()` (CIRISStatus#73) — correct switch, and it | ||
| // could never be flipped here: `diag::enable()` is called from | ||
| // ciris-server's OWN binary entry point, which this binary does not run. We | ||
| // call `serve_with_adapter` as a library, so the atomic stayed false | ||
| // forever and the route was not "gated", it was gone, with no way for an | ||
| // operator to get it back. A gate whose only opener lives in a `main` you | ||
| // do not execute is a removal wearing a switch's clothes. | ||
| // | ||
| // Both doors, matching the sibling: `--diagnostics` (its flag) and | ||
| // `CIRIS_DIAGNOSTICS=1` (its env, read through its own parser so the truthy | ||
| // set cannot drift from theirs). Before `serve_with_adapter`, because | ||
| // `routers()` asks `enabled()` while building. | ||
| if diagnostics_flag { | ||
| ciris_server::diag::enable("ciris-status --diagnostics"); | ||
| } else if ciris_server::diag::env_requests() { | ||
| ciris_server::diag::enable("ciris-status CIRIS_DIAGNOSTICS"); | ||
| } | ||
|
|
||
| // Zero-env node config: derived entirely from `--home`/`--key-id` + config:*. | ||
| let cfg = ciris_server::ServerConfig::from_home(home, key_id)?; | ||
|
|
@@ -205,9 +224,10 @@ fn parse_config_value(raw: &str) -> ciris_server::ConfigValue { | |
| /// Parse `--home <path>` / `--key-id <name>` (both optional; `--flag=value` also | ||
| /// accepted). Unknown args are an error — fail loud, never silently ignore a | ||
| /// misspelled flag on the boot path. Mirrors ciris-server's `parse_serve_flags`. | ||
| fn parse_args(args: impl Iterator<Item = String>) -> anyhow::Result<(PathBuf, String)> { | ||
| fn parse_args(args: impl Iterator<Item = String>) -> anyhow::Result<(PathBuf, String, bool)> { | ||
| let mut home: Option<String> = None; | ||
| let mut key_id: Option<String> = None; | ||
| let mut diagnostics = false; | ||
|
|
||
| let mut it = args; | ||
| while let Some(arg) = it.next() { | ||
|
|
@@ -226,9 +246,14 @@ fn parse_args(args: impl Iterator<Item = String>) -> anyhow::Result<(PathBuf, St | |
| match name.as_str() { | ||
| "--home" => home = Some(take("--home")?), | ||
| "--key-id" => key_id = Some(take("--key-id")?), | ||
| // Mirrors ciris-server's own flag. Takes no value; `--diagnostics=1` | ||
| // is accepted too so an operator who types it either way gets what | ||
| // they meant rather than "needs a value". | ||
| "--diagnostics" => diagnostics = true, | ||
|
Comment on lines
+249
to
+252
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
When a deployment renders this boolean as Useful? React with 👍 / 👎. |
||
| other => { | ||
| return Err(anyhow::anyhow!( | ||
| "unknown arg: {other} (usage: ciris-status [--home <path>] [--key-id <name>])" | ||
| "unknown arg: {other} (usage: ciris-status [--home <path>] [--key-id <name>] \ | ||
| [--diagnostics])" | ||
| )) | ||
| } | ||
| } | ||
|
|
@@ -237,31 +262,50 @@ fn parse_args(args: impl Iterator<Item = String>) -> anyhow::Result<(PathBuf, St | |
| Ok(( | ||
| PathBuf::from(home.unwrap_or_else(|| DEFAULT_HOME.to_string())), | ||
| key_id.unwrap_or_else(|| DEFAULT_KEY_ID.to_string()), | ||
| diagnostics, | ||
| )) | ||
| } | ||
|
|
||
| #[cfg(test)] | ||
| mod tests { | ||
| use super::*; | ||
|
|
||
| fn parse(args: &[&str]) -> anyhow::Result<(PathBuf, String)> { | ||
| fn parse(args: &[&str]) -> anyhow::Result<(PathBuf, String, bool)> { | ||
| parse_args(args.iter().map(|s| s.to_string())) | ||
| } | ||
|
|
||
| #[test] | ||
| fn defaults_when_no_flags() { | ||
| let (home, key_id) = parse(&[]).unwrap(); | ||
| let (home, key_id, diagnostics) = parse(&[]).unwrap(); | ||
| assert_eq!(home, PathBuf::from(DEFAULT_HOME)); | ||
| assert_eq!(key_id, DEFAULT_KEY_ID); | ||
| assert!(!diagnostics, "diagnostics stay OFF unless asked for"); | ||
| } | ||
|
|
||
| /// CIRISStatus#73 gated the memory route on the server's switch; 0.3.69 | ||
| /// shipped that gate with no way to open it from THIS binary, because | ||
| /// `diag::enable()` is called from ciris-server's own `main`, which we do | ||
| /// not run. The flag is one of the two openers — without it the route is | ||
| /// not gated, it is gone. | ||
| #[test] | ||
| fn diagnostics_flag_is_accepted_and_off_by_default() { | ||
| let (_, _, on) = parse(&["--diagnostics"]).unwrap(); | ||
| assert!(on); | ||
| // Takes no value, and does not swallow the next argument. | ||
| let (home, key_id, on) = | ||
| parse(&["--diagnostics", "--home", "/data", "--key-id", "node-b"]).unwrap(); | ||
| assert!(on); | ||
| assert_eq!(home, PathBuf::from("/data")); | ||
| assert_eq!(key_id, "node-b"); | ||
| } | ||
|
|
||
| #[test] | ||
| fn space_and_eq_forms_parse() { | ||
| let (home, key_id) = parse(&["--home", "/data", "--key-id", "ciris-status"]).unwrap(); | ||
| let (home, key_id, _) = parse(&["--home", "/data", "--key-id", "ciris-status"]).unwrap(); | ||
| assert_eq!(home, PathBuf::from("/data")); | ||
| assert_eq!(key_id, "ciris-status"); | ||
|
|
||
| let (home, key_id) = parse(&["--home=/data", "--key-id=node-b"]).unwrap(); | ||
| let (home, key_id, _) = parse(&["--home=/data", "--key-id=node-b"]).unwrap(); | ||
| assert_eq!(home, PathBuf::from("/data")); | ||
| assert_eq!(key_id, "node-b"); | ||
| } | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Once this commit makes
CIRIS_DIAGNOSTICSand--diagnosticsfunctional, the primary setup instructions become contradictory: README.md:20-24 and 87-97 still say there are no environment variables and only two CLI inputs, while.env.example:1-7 explicitly says there is nothing to put in an environment file. Operators reading the Configuration section can therefore overlook or reject the opener advertised here; update those sections and the example alongside this endpoint documentation.Useful? React with 👍 / 👎.