Let the console add and remove printers; keep them in a local SQLite store
The only way to give a gateway a printer was to edit printers.toml and restart it. A printer added from the console now arrives as a provision_printer message, is checked by actually connecting to it (so a mistyped access code is reported to the operator, not discovered later), and only then is saved to the gateway's own SQLite file and joined to the running fleet - no restart. remove_printer undoes it. Both are answered with a command_result carrying the request id. The access code exists only on the gateway: the cloud relays it once and keeps nothing, which is the platform's rule for printer credentials. The store file is created owner-only; the message type's Debug and the fleet entry's Debug redact the credential; and an unparseable message from the cloud is no longer logged with its payload, because the message that fails to parse is exactly the one carrying an access code. The cloud may not choose a certificate path or serial port on the gateway's disk, so provision_printer cannot carry them. Startup now reads printers.toml (strict, as before; a missing file is fine) and the store (a bad stored entry is skipped, not fatal), so the gateway comes up with its fleet with the API unreachable. Discovery treats stored printers as already configured. rusqlite (MIT, bundled SQLite) passes cargo deny.
This commit is contained in:
+26
-2
@@ -68,7 +68,30 @@ async fn main() -> anyhow::Result<()> {
|
||||
// Loaded and connected here, once, at startup - nothing yet re-reads
|
||||
// printers.toml on a running daemon, so adding or removing a printer
|
||||
// still means a restart.
|
||||
let mut fleet = fleet::load(std::path::Path::new(&config.printers_path))?;
|
||||
// Two sources, one fleet: `printers.toml` (a hand-written file - strict,
|
||||
// a typo stops startup) and the local store (printers added from the
|
||||
// console, which were checked before they were saved). The store is
|
||||
// opened first and is what lets the gateway come up with no file at all.
|
||||
let store = std::sync::Arc::new(continuum_proxy::store::Store::open(std::path::Path::new(&config.store_path))?);
|
||||
let mut fleet = Vec::new();
|
||||
for entry in fleet::entries(std::path::Path::new(&config.printers_path))? {
|
||||
fleet.push(fleet::build(entry)?);
|
||||
}
|
||||
for entry in store.printers()? {
|
||||
if fleet.iter().any(|printer| printer.base().id == entry.id) {
|
||||
tracing::warn!(printer = %entry.id, "in both printers.toml and the local store; using printers.toml");
|
||||
continue;
|
||||
}
|
||||
// Skipped, not fatal: one entry the build no longer accepts should
|
||||
// not keep the rest of a farm offline.
|
||||
match fleet::build(entry) {
|
||||
Ok(printer) => fleet.push(printer),
|
||||
Err(err) => tracing::error!(%err, "a printer in the local store could not be built; skipping it"),
|
||||
}
|
||||
}
|
||||
if fleet.is_empty() {
|
||||
tracing::warn!("no printers yet - add one from the console, or list some in printers.toml");
|
||||
}
|
||||
connect_fleet(&mut fleet).await;
|
||||
|
||||
// The fleet is now shared with the uplink rather than just parked here
|
||||
@@ -134,10 +157,11 @@ async fn main() -> anyhow::Result<()> {
|
||||
_ = shutdown_requested() => {
|
||||
info!("stop requested; exiting so go2rtc is stopped with us");
|
||||
}
|
||||
_ = uplink::run(config.clone(), fleet.clone(), outbound.clone(), inbox) => {}
|
||||
_ = uplink::run(config.clone(), fleet.clone(), Some(store.clone()), outbound.clone(), inbox) => {}
|
||||
_ = continuum_proxy::discovery::report::run(
|
||||
config.discovery.clone(),
|
||||
config.printers_path.clone(),
|
||||
Some(store.clone()),
|
||||
outbound.clone(),
|
||||
) => {}
|
||||
_ = go2rtc::watchdog(
|
||||
|
||||
Reference in New Issue
Block a user