builtin_scripts.rs 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113
  1. //! Built-in host scripts baked into the binary at compile time.
  2. //!
  3. //! Each script lives as a real `.sh` file under `host-scripts/` (so it stays
  4. //! diffable, shellcheck-able, and editor-friendly) and is embedded here via
  5. //! `include_str!`. Recipes reference a script by **alias** in a
  6. //! `before_serve` / `after_stop` list (e.g. `{ script = "stop_dgx_services" }`);
  7. //! the launcher resolves the alias to the script body and runs it over SSH on
  8. //! each node. No file copy from the operator's machine is needed.
  9. //!
  10. //! Only **generic** helpers belong here (cluster-wide service toggles, display
  11. //! memory unlocks). Anything that knows about a specific recipe — NAS paths,
  12. //! model revisions, per-rank staging — lives NEXT TO THAT RECIPE in the shared
  13. //! recipe repo and is referenced as a relative path:
  14. //!
  15. //! ```toml
  16. //! before_serve = [{ script = "scripts/prepare.sh" }] # <recipe dir>/scripts/prepare.sh
  17. //! ```
  18. //!
  19. //! The launcher reads it from the recipe directory, uploads it, and runs it
  20. //! with `NODE_RANK` exported — same contract as a built-in alias. That keeps
  21. //! recipe-specific staging versioned with the recipe (and updatable by the
  22. //! add-on's recipe-repo sync) instead of requiring a launcher release.
  23. //!
  24. //! To add a new built-in:
  25. //! 1. Drop the `.sh` file into `host-scripts/`.
  26. //! 2. Add an `include_str!` line + a `(alias, body)` entry below.
  27. //! 3. Document the alias in AGENTS.md.
  28. /// A built-in script: its alias and the embedded body.
  29. pub struct BuiltinScript {
  30. pub alias: &'static str,
  31. pub body: &'static str,
  32. }
  33. /// The registry of all baked-in scripts. Order is the display order for
  34. /// error hints.
  35. pub static BUILTIN_SCRIPTS: &[BuiltinScript] = &[
  36. BuiltinScript {
  37. alias: "stop_dgx_services",
  38. body: include_str!("../host-scripts/stop-dgx-services.sh"),
  39. },
  40. BuiltinScript {
  41. alias: "restore_dgx_services",
  42. body: include_str!("../host-scripts/restore-dgx-services.sh"),
  43. },
  44. // Temporary (per-boot) 2 GiB display-reserve unlock for the EXL3 2x
  45. // runtime (nvidia_drm modeset=1 fbdev=0 remod; no UEFI/boot changes).
  46. BuiltinScript {
  47. alias: "unlock_display_ram",
  48. body: include_str!("../host-scripts/unlock-display-ram.sh"),
  49. },
  50. BuiltinScript {
  51. alias: "restore_display_ram",
  52. body: include_str!("../host-scripts/restore-display-ram.sh"),
  53. },
  54. ];
  55. /// Resolve an alias to its script body. Returns `None` (and the caller
  56. /// formats the list of known aliases) when the alias is unknown.
  57. pub fn resolve(alias: &str) -> Option<&'static str> {
  58. BUILTIN_SCRIPTS
  59. .iter()
  60. .find(|s| s.alias == alias)
  61. .map(|s| s.body)
  62. }
  63. /// Comma-separated list of known aliases, for error messages.
  64. pub fn known_aliases() -> String {
  65. BUILTIN_SCRIPTS
  66. .iter()
  67. .map(|s| s.alias)
  68. .collect::<Vec<_>>()
  69. .join(", ")
  70. }
  71. #[cfg(test)]
  72. mod tests {
  73. use super::*;
  74. #[test]
  75. fn resolves_known_aliases() {
  76. assert!(resolve("stop_dgx_services").is_some());
  77. assert!(resolve("restore_dgx_services").is_some());
  78. let body = resolve("stop_dgx_services").unwrap();
  79. // Sanity: the embedded script is non-empty and starts with a shebang.
  80. assert!(body.starts_with("#!/usr/bin/env bash"));
  81. assert!(body.contains("systemctl"));
  82. }
  83. #[test]
  84. fn unknown_alias_returns_none() {
  85. assert!(resolve("nope").is_none());
  86. }
  87. #[test]
  88. fn known_aliases_lists_all() {
  89. let list = known_aliases();
  90. assert!(list.contains("stop_dgx_services"));
  91. assert!(list.contains("restore_dgx_services"));
  92. }
  93. #[test]
  94. fn scripts_reference_each_other_correctly() {
  95. // The restore script's docstring mentions the stop script by its
  96. // filename (`stop-dgx-services.sh`, not the old `glmnf3` name) —
  97. // regression guard for the rename.
  98. let restore = resolve("restore_dgx_services").unwrap();
  99. assert!(restore.contains("stop-dgx-services.sh"));
  100. assert!(!restore.contains("glmnf3"));
  101. let stop = resolve("stop_dgx_services").unwrap();
  102. assert!(!stop.contains("glmnf3"));
  103. }
  104. }