Compare commits
5 Commits
7758724eb5
...
v0.1.1
| Author | SHA1 | Date | |
|---|---|---|---|
| 9cc109910c | |||
| 6da385425e | |||
| 5d4c68eaf5 | |||
| c3771d22f2 | |||
| 6c49217e9c |
@@ -3,10 +3,27 @@
|
|||||||
//! ## Scoped by what cannot be fetched again
|
//! ## Scoped by what cannot be fetched again
|
||||||
//!
|
//!
|
||||||
//! Most of what this installer writes is replaceable: the sidecar binary and every overlay file are
|
//! Most of what this installer writes is replaceable: the sidecar binary and every overlay file are
|
||||||
//! re-downloadable and hash-named in the bundle, and the sidecar's database is a cache with a schema
|
//! re-downloadable and hash-named in the bundle, and the sidecar's database is overwhelmingly a
|
||||||
//! — `link`'s `store.rs` creates every table `IF NOT EXISTS` and every one of them holds shard state
|
//! projection of shard state that the sweeps repopulate. Backing it up would be bulk with little
|
||||||
//! the sweeps repopulate. Backing those up would be bulk with no recovery value, and the bulk is not
|
//! recovery value, and the bulk is not free: it would bury the two things that matter.
|
||||||
//! free: it would bury the two things that matter.
|
//!
|
||||||
|
//! That reasoning used to be stated two ways that are no longer true, and the correction is worth
|
||||||
|
//! keeping rather than quietly deleting:
|
||||||
|
//!
|
||||||
|
//! - It said the database is safe because `store.rs` creates every table `IF NOT EXISTS`. That held
|
||||||
|
//! only while every schema change added a whole *table*. Protocol 4 adds a *column* to a table
|
||||||
|
//! that already exists, which `IF NOT EXISTS` cannot do, so `link` now carries a real migration
|
||||||
|
//! (`PRAGMA user_version` steps). A run can therefore change the database's structure, not just
|
||||||
|
//! its contents.
|
||||||
|
//! - It said every table holds state the sweeps repopulate. `events` does not: it is never pruned,
|
||||||
|
//! and the website backfills the events it missed from `GET /history` on every reconnect. So a
|
||||||
|
//! lost database costs the gap-recovery window for anything that happened while the site was down.
|
||||||
|
//!
|
||||||
|
//! The decision is unchanged — this still does not copy the database — because the argument against
|
||||||
|
//! backing up unbounded bulk survives both corrections: `events` grows without limit, the migration
|
||||||
|
//! is transactional and additive, and the website holds its own durable copy of everything it has
|
||||||
|
//! already ingested. Only the *reason* was wrong. Whether that table should be pruned or protected
|
||||||
|
//! is a question for `link`, on its own merits, not something to settle inside a backup policy.
|
||||||
//!
|
//!
|
||||||
//! What a run can destroy irrecoverably is short:
|
//! What a run can destroy irrecoverably is short:
|
||||||
//!
|
//!
|
||||||
|
|||||||
@@ -77,7 +77,7 @@ pub struct Cli {
|
|||||||
pub patches_unsupported_servuo: bool,
|
pub patches_unsupported_servuo: bool,
|
||||||
/// `--host <name>`: the hostname to print in the website URLs.
|
/// `--host <name>`: the hostname to print in the website URLs.
|
||||||
pub host: Option<String>,
|
pub host: Option<String>,
|
||||||
/// `--site-url <url>`: the site's base URL, for the Admin → Shard link.
|
/// `--site-url <url>`: the site's base URL, for the Admin → Shard (uo-link) link.
|
||||||
pub site_url: Option<String>,
|
pub site_url: Option<String>,
|
||||||
/// `--yes`: assume the default answer to every prompt.
|
/// `--yes`: assume the default answer to every prompt.
|
||||||
pub assume_yes: bool,
|
pub assume_yes: bool,
|
||||||
@@ -137,7 +137,7 @@ Options:
|
|||||||
--host <NAME> install. The hostname to print in the
|
--host <NAME> install. The hostname to print in the
|
||||||
website URLs.
|
website URLs.
|
||||||
--site-url <URL> install. Your site's base URL, for the
|
--site-url <URL> install. Your site's base URL, for the
|
||||||
Admin → Shard link.
|
Admin → Shard (uo-link) link.
|
||||||
--yes Assume the default answer to every prompt.
|
--yes Assume the default answer to every prompt.
|
||||||
On uninstall it means yes: that prompt
|
On uninstall it means yes: that prompt
|
||||||
defaults to no, and typing `uninstall
|
defaults to no, and typing `uninstall
|
||||||
|
|||||||
@@ -294,6 +294,18 @@ fn port_of(bind: &str) -> &str {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Where the shard settings live in the website's admin panel.
|
||||||
|
///
|
||||||
|
/// NOT `/admin/shard`, which is what this printed until 2026-08-24 and what an operator who ran
|
||||||
|
/// an older build still has in their scrollback. Those screens belong to the `uo` MODULE now, and
|
||||||
|
/// a module owns one path segment wherever it appears (website `MODULE_SYSTEM.md` §2.8), so the
|
||||||
|
/// page moved. The old path does not 404 — the SPA sends it to the dashboard, which is the worst
|
||||||
|
/// way for a link in a handoff to be wrong, because it looks like it worked.
|
||||||
|
///
|
||||||
|
/// API routes are NOT affected by that rule and keep `/api/v1/admin/shard/*`. This is the SPA URL
|
||||||
|
/// a person types.
|
||||||
|
const ADMIN_SHARD_PATH: &str = "/admin/uo/link";
|
||||||
|
|
||||||
/// The end-of-run block from PLAN.md §6 — the one manual step the installer cannot do.
|
/// The end-of-run block from PLAN.md §6 — the one manual step the installer cannot do.
|
||||||
///
|
///
|
||||||
/// Returned as a string rather than printed so it can be tested, and so the caller decides where it
|
/// Returned as a string rather than printed so it can be tested, and so the caller decides where it
|
||||||
@@ -312,12 +324,13 @@ pub fn handoff(doc: &ConfigDoc, host: &str, site_url: Option<&str>) -> String {
|
|||||||
Protocol version {protocol}\n \
|
Protocol version {protocol}\n \
|
||||||
Auth token {token}\n \
|
Auth token {token}\n \
|
||||||
(also in {config})\n\n\
|
(also in {config})\n\n\
|
||||||
Paste these into Admin → Shard on your Runic Gateway site:\n \
|
Paste these into Admin → Shard (uo-link) on your Runic Gateway site:\n \
|
||||||
{site}/admin/shard\n\n\
|
{site}{admin_path}\n\n\
|
||||||
The token is write-only once saved — the site will never show it back to you.\n",
|
The token is write-only once saved — the site will never show it back to you.\n",
|
||||||
protocol = doc.protocol,
|
protocol = doc.protocol,
|
||||||
token = doc.web.auth_token,
|
token = doc.web.auth_token,
|
||||||
config = doc.config_path,
|
config = doc.config_path,
|
||||||
|
admin_path = ADMIN_SHARD_PATH,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -401,7 +414,7 @@ mod tests {
|
|||||||
assert!(block.contains(&doc.web.auth_token), "{block}");
|
assert!(block.contains(&doc.web.auth_token), "{block}");
|
||||||
// The trailing slash on the site URL must not produce a double slash in the link.
|
// The trailing slash on the site URL must not produce a double slash in the link.
|
||||||
assert!(
|
assert!(
|
||||||
block.contains("https://my-site.example/admin/shard"),
|
block.contains("https://my-site.example/admin/uo/link"),
|
||||||
"{block}"
|
"{block}"
|
||||||
);
|
);
|
||||||
assert!(block.contains("/etc/runicgateway/sidecar.toml"), "{block}");
|
assert!(block.contains("/etc/runicgateway/sidecar.toml"), "{block}");
|
||||||
@@ -412,7 +425,10 @@ mod tests {
|
|||||||
// An unattended run has nobody to ask, and the token is far too useful to withhold over a
|
// An unattended run has nobody to ask, and the token is far too useful to withhold over a
|
||||||
// link the operator does not need.
|
// link the operator does not need.
|
||||||
let block = handoff(&doc(), "shard", None);
|
let block = handoff(&doc(), "shard", None);
|
||||||
assert!(block.contains("https://<your-site>/admin/shard"), "{block}");
|
assert!(
|
||||||
|
block.contains("https://<your-site>/admin/uo/link"),
|
||||||
|
"{block}"
|
||||||
|
);
|
||||||
assert!(block.contains("4f9c"), "{block}");
|
assert!(block.contains("4f9c"), "{block}");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -81,7 +81,7 @@ pub fn closing(prior: Option<&InstallRecord>, bundle: &Bundle, now: &InstallReco
|
|||||||
println!();
|
println!();
|
||||||
ui::warn(&format!(
|
ui::warn(&format!(
|
||||||
"The protocol version changed: {} → {}.\n \
|
"The protocol version changed: {} → {}.\n \
|
||||||
Update the Protocol version field in Admin → Shard on your website. Nothing else \
|
Update the Protocol version field in Admin → Shard (uo-link) on your website. Nothing else \
|
||||||
changed —\n the URLs and the auth token are the same, and the sidecar answers a \
|
changed —\n the URLs and the auth token are the same, and the sidecar answers a \
|
||||||
website still set to\n {} with 409 rather than mis-parsing it.",
|
website still set to\n {} with 409 rather than mis-parsing it.",
|
||||||
previous_protocol.unwrap_or(bundle.protocol),
|
previous_protocol.unwrap_or(bundle.protocol),
|
||||||
|
|||||||
Reference in New Issue
Block a user