feat(rust): cut edge over to main — --game rust, named instances, schema-2 bundles (rust phase 18) #32

Merged
whitlocktech merged 9 commits from edge into main 2026-09-26 09:15:45 +00:00
3 changed files with 42 additions and 9 deletions
Showing only changes of commit 0c07b8a967 - Show all commits

View File

@@ -134,13 +134,14 @@ Gateway website.
Usage: runicgateway-installer <COMMAND> [OPTIONS]
Commands:
install Deploy the plugin overlay, install the uo-link sidecar and its
service, record what was deployed, and print the values the
website needs.
install Deploy the game-side plugin (the ServUO overlay, or the Rust
plugin), install the sidecar and its service, record what was
deployed, and print the values the website needs.
doctor Diagnose an existing deployment end to end.
update Re-resolve the bundle and move both components to it.
uninstall Remove what the installer exclusively owns. Never edits the
ServUO tree — it prints what to remove there.
ServUO tree — it prints what to remove there. For Rust it
removes only its own plugin file and keeps the plugin config.
Options:
--game <servuo|rust> Which game's shard side. Default servuo.

View File

@@ -234,7 +234,7 @@ pub fn deploy(cli: &Cli, mode: Mode) -> Result<()> {
.unwrap_or(false),
)?;
record.instances.insert(plan.id.clone(), instance);
handoffs.push((plan.id.clone(), doc, registered));
handoffs.push((plan.id.clone(), doc, registered, plan.running));
}
// Instances this run did not touch still run the binary it just replaced.
@@ -306,10 +306,17 @@ pub fn deploy(cli: &Cli, mode: Mode) -> Result<()> {
match mode {
Mode::Install => {
let host = crate::install::resolve_host(cli);
for (id, doc, registered) in &handoffs {
for (id, doc, registered, running) in &handoffs {
println!(
"{}",
sidecar::handoff(id, doc, &host, cli.site_url.as_deref(), *registered)
sidecar::handoff(
id,
doc,
&host,
cli.site_url.as_deref(),
*registered,
*running
)
);
}
}

View File

@@ -152,12 +152,17 @@ pub fn choose_port(start: u16, held: &[u16], keep: Option<u16>) -> Result<u16> {
}
/// The end-of-run block for one instance: what `/admin/rust/servers` asks for.
///
/// It says what the run did, not what it hopes: nothing here has seen the plugin connect — on a
/// stopped server it has not even loaded — so the first line never claims a link. `doctor` is the
/// command that checks one (D156).
pub fn handoff(
server_id: &str,
doc: &ConfigDoc,
host: &str,
site_url: Option<&str>,
registered: bool,
running: bool,
) -> String {
let port = port_of(&doc.web.bind)
.map(|p| p.to_string())
@@ -167,7 +172,7 @@ pub fn handoff(
.unwrap_or_else(|| "https://<your-site>".to_string());
let loopback = doc.web.bind.starts_with("127.") || doc.web.bind.starts_with("[::1]");
format!(
"\nRust server {server_id:?} is connected to its sidecar.\n\n\
"\nRust server {server_id:?} is set up. {when}\n\n\
One manual step remains — add it to the website:\n\n \
Server id {server_id}\n \
Sidecar URL http://{host}:{port}\n \
@@ -178,6 +183,13 @@ pub fn handoff(
token = doc.web.auth_token,
config = doc.config_path,
protocol = doc.protocol,
when = if running {
format!(
"The plugin loads now; `doctor --game rust --server-id {server_id}` confirms it connected."
)
} else {
"The plugin connects when the server next starts.".to_string()
},
loopback_note = if loopback {
format!(
"\nThe sidecar listens on {} only. If the website runs on another machine, put a \
@@ -229,7 +241,7 @@ mod tests {
)
.unwrap();
assert_eq!(port_of(&doc.web.bind), Some(8091));
let text = handoff("alpha", &doc, "rust.example", None, true);
let text = handoff("alpha", &doc, "rust.example", None, true, false);
for needle in [
"alpha",
"http://rust.example:8091",
@@ -240,6 +252,19 @@ mod tests {
assert!(text.contains(needle), "{needle} missing from:\n{text}");
}
assert!(text.contains("TLS proxy"), "{text}");
// D156: never a claim about a link nothing has seen.
assert!(!text.contains("is connected"), "{text}");
assert!(
text.contains("The plugin connects when the server next starts."),
"{text}"
);
let running = handoff("alpha", &doc, "rust.example", None, true, true);
assert!(!running.contains("is connected"), "{running}");
assert!(
running.contains("doctor --game rust --server-id alpha"),
"{running}"
);
}
#[test]