diff --git a/src/adc.rs b/src/adc.rs index f0bdc9be..bb0f3734 100644 --- a/src/adc.rs +++ b/src/adc.rs @@ -227,7 +227,7 @@ impl Adc { time.set(Timestamp::now()); } - }); + })?; Ok(adc) } diff --git a/src/backlight.rs b/src/backlight.rs index 57c0ff29..9bec66f7 100644 --- a/src/backlight.rs +++ b/src/backlight.rs @@ -62,7 +62,7 @@ impl Backlight { } Ok(()) - }); + })?; Ok(Self { brightness }) } diff --git a/src/broker.rs b/src/broker.rs index b68ca90a..b023b541 100644 --- a/src/broker.rs +++ b/src/broker.rs @@ -15,6 +15,7 @@ // with this program; if not, write to the Free Software Foundation, Inc., // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +use anyhow::Result; use async_std::sync::Arc; use serde::{de::DeserializeOwned, Serialize}; @@ -115,11 +116,13 @@ impl BrokerBuilder { /// Finish building the broker /// /// This consumes the builder so that no new topics can be registered - pub fn build(self, wtb: &mut WatchedTasksBuilder, server: &mut tide::Server<()>) { + pub fn build(self, wtb: &mut WatchedTasksBuilder, server: &mut tide::Server<()>) -> Result<()> { let topics = Arc::new(self.topics); - persistence::register(wtb, topics.clone()); + persistence::register(wtb, topics.clone())?; rest::register(server, topics.clone()); mqtt_conn::register(server, topics); + + Ok(()) } } diff --git a/src/broker/persistence.rs b/src/broker/persistence.rs index 3f1543b1..8367ba82 100644 --- a/src/broker/persistence.rs +++ b/src/broker/persistence.rs @@ -148,7 +148,7 @@ async fn save_on_change( Ok(()) } -pub fn register(wtb: &mut WatchedTasksBuilder, topics: Arc>>) { +pub fn register(wtb: &mut WatchedTasksBuilder, topics: Arc>>) -> Result<()> { load(&topics).unwrap(); let (tx, rx) = unbounded(); @@ -157,5 +157,5 @@ pub fn register(wtb: &mut WatchedTasksBuilder, topics: Arc topic.subscribe_as_bytes(tx.clone(), false); } - wtb.spawn_task("persistence-save", save_on_change(topics, rx)); + wtb.spawn_task("persistence-save", save_on_change(topics, rx)) } diff --git a/src/dbus.rs b/src/dbus.rs index 5c2dfd9b..967a0b91 100644 --- a/src/dbus.rs +++ b/src/dbus.rs @@ -23,7 +23,7 @@ use crate::watched_tasks::WatchedTasksBuilder; #[cfg(feature = "demo_mode")] mod zb { - pub type Result = std::result::Result; + pub use anyhow::Result; pub struct Connection; pub struct ConnectionBuilder; @@ -78,20 +78,17 @@ impl DbusSession { wtb: &mut WatchedTasksBuilder, led_dut: Arc>, led_uplink: Arc>, - ) -> Self { + ) -> anyhow::Result { let tacd = Tacd::new(); - let conn_builder = ConnectionBuilder::system() - .unwrap() - .name("de.pengutronix.tacd") - .unwrap(); + let conn_builder = ConnectionBuilder::system()?.name("de.pengutronix.tacd")?; - let conn = Arc::new(tacd.serve(conn_builder).build().await.unwrap()); + let conn = Arc::new(tacd.serve(conn_builder).build().await?); - Self { - network: Network::new(bb, wtb, &conn, led_dut, led_uplink), - rauc: Rauc::new(bb, wtb, &conn), - systemd: Systemd::new(bb, wtb, &conn).await, - } + Ok(Self { + network: Network::new(bb, wtb, &conn, led_dut, led_uplink)?, + rauc: Rauc::new(bb, wtb, &conn)?, + systemd: Systemd::new(bb, wtb, &conn).await?, + }) } } diff --git a/src/dbus/networkmanager/mod.rs b/src/dbus/networkmanager/mod.rs index e6bdbc92..fc829597 100644 --- a/src/dbus/networkmanager/mod.rs +++ b/src/dbus/networkmanager/mod.rs @@ -15,6 +15,7 @@ // with this program; if not, write to the Free Software Foundation, Inc., // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +use anyhow::Result; use async_std; use async_std::sync::Arc; @@ -31,7 +32,7 @@ mod hostname; // Put them inside a mod so we do not have to decorate each one with // a #[cfg(not(feature = "demo_mode"))]. mod optional_includes { - pub use anyhow::{anyhow, Result}; + pub use anyhow::anyhow; pub use async_std::stream::StreamExt; pub use async_std::task::sleep; pub use futures::{future::FutureExt, pin_mut, select}; @@ -261,7 +262,7 @@ impl Network { _conn: C, _led_dut: Arc>, _led_uplink: Arc>, - ) -> Self { + ) -> Result { let this = Self::setup_topics(bb); this.hostname.set("lxatac".to_string()); @@ -275,7 +276,7 @@ impl Network { carrier: true, }); - this + Ok(this) } #[cfg(not(feature = "demo_mode"))] @@ -285,7 +286,7 @@ impl Network { conn: &Arc, led_dut: Arc>, led_uplink: Arc>, - ) -> Self { + ) -> Result { let this = Self::setup_topics(bb); { @@ -307,7 +308,7 @@ impl Network { } Ok(()) - }); + })?; } { @@ -337,7 +338,7 @@ impl Network { } Ok(()) - }); + })?; } { @@ -364,7 +365,7 @@ impl Network { } Ok(()) - }); + })?; } { @@ -386,9 +387,9 @@ impl Network { } Ok(()) - }); + })?; } - this + Ok(this) } } diff --git a/src/dbus/rauc/mod.rs b/src/dbus/rauc/mod.rs index d42395db..a7e3d86d 100644 --- a/src/dbus/rauc/mod.rs +++ b/src/dbus/rauc/mod.rs @@ -283,7 +283,7 @@ impl Rauc { bb: &mut BrokerBuilder, wtb: &mut WatchedTasksBuilder, _conn: &Arc, - ) -> Self { + ) -> Result { let inst = Self::setup_topics(bb); inst.operation.set("idle".to_string()); @@ -300,9 +300,9 @@ impl Rauc { inst.channels.clone(), inst.slot_status.clone(), ), - ); + )?; - inst + Ok(inst) } #[cfg(not(feature = "demo_mode"))] @@ -310,7 +310,7 @@ impl Rauc { bb: &mut BrokerBuilder, wtb: &mut WatchedTasksBuilder, conn: &Arc, - ) -> Self { + ) -> Result { let inst = Self::setup_topics(bb); let conn_task = conn.clone(); @@ -409,7 +409,7 @@ impl Rauc { break Ok(()); } } - }); + })?; let conn_task = conn.clone(); let progress = inst.progress.clone(); @@ -431,7 +431,7 @@ impl Rauc { } Ok(()) - }); + })?; let conn_task = conn.clone(); let last_error = inst.last_error.clone(); @@ -453,7 +453,7 @@ impl Rauc { } Ok(()) - }); + })?; let conn_task = conn.clone(); let (mut install_stream, _) = inst.install.clone().subscribe_unbounded(); @@ -473,7 +473,7 @@ impl Rauc { } Ok(()) - }); + })?; // Reload the channel list on request let (reload_stream, _) = inst.reload.clone().subscribe_unbounded(); @@ -485,8 +485,8 @@ impl Rauc { inst.channels.clone(), inst.slot_status.clone(), ), - ); + )?; - inst + Ok(inst) } } diff --git a/src/dbus/systemd/mod.rs b/src/dbus/systemd/mod.rs index 056094e7..85490a88 100644 --- a/src/dbus/systemd/mod.rs +++ b/src/dbus/systemd/mod.rs @@ -100,8 +100,10 @@ impl Service { _wtb: &mut WatchedTasksBuilder, _conn: Arc, _unit_name: &str, - ) { + ) -> anyhow::Result<()> { self.status.set(ServiceStatus::get().await.unwrap()); + + Ok(()) } #[cfg(not(feature = "demo_mode"))] @@ -110,7 +112,7 @@ impl Service { wtb: &mut WatchedTasksBuilder, conn: Arc, unit_name: &'static str, - ) { + ) -> anyhow::Result<()> { let unit_path = { let manager = manager::ManagerProxy::new(&conn).await.unwrap(); manager.get_unit(unit_name).await.unwrap() @@ -150,7 +152,7 @@ impl Service { .await .unwrap(); } - }); + })?; let (mut action_reqs, _) = self.action.clone().subscribe_unbounded(); @@ -171,7 +173,9 @@ impl Service { } Ok(()) - }); + })?; + + Ok(()) } } @@ -181,7 +185,7 @@ impl Systemd { wtb: &mut WatchedTasksBuilder, reboot: Arc>, _conn: Arc, - ) { + ) -> anyhow::Result<()> { let (mut reboot_reqs, _) = reboot.subscribe_unbounded(); wtb.spawn_task("systemd-reboot", async move { @@ -192,7 +196,7 @@ impl Systemd { } Ok(()) - }); + }) } #[cfg(not(feature = "demo_mode"))] @@ -200,7 +204,7 @@ impl Systemd { wtb: &mut WatchedTasksBuilder, reboot: Arc>, conn: Arc, - ) { + ) -> anyhow::Result<()> { let (mut reboot_reqs, _) = reboot.subscribe_unbounded(); wtb.spawn_task("systemd-reboot", async move { @@ -215,17 +219,17 @@ impl Systemd { } Ok(()) - }); + }) } pub async fn new( bb: &mut BrokerBuilder, wtb: &mut WatchedTasksBuilder, conn: &Arc, - ) -> Self { + ) -> anyhow::Result { let reboot = bb.topic_rw("/v1/tac/reboot", Some(false)); - Self::handle_reboot(wtb, reboot.clone(), conn.clone()); + Self::handle_reboot(wtb, reboot.clone(), conn.clone())?; let networkmanager = Service::new(bb, "network-manager"); let labgrid = Service::new(bb, "labgrid-exporter"); @@ -233,17 +237,19 @@ impl Systemd { networkmanager .connect(wtb, conn.clone(), "NetworkManager.service") - .await; + .await?; labgrid .connect(wtb, conn.clone(), "labgrid-exporter.service") - .await; - iobus.connect(wtb, conn.clone(), "lxa-iobus.service").await; + .await?; + iobus + .connect(wtb, conn.clone(), "lxa-iobus.service") + .await?; - Self { + Ok(Self { reboot, networkmanager, labgrid, iobus, - } + }) } } diff --git a/src/digital_io.rs b/src/digital_io.rs index 2a2f7aad..ead7af1e 100644 --- a/src/digital_io.rs +++ b/src/digital_io.rs @@ -15,6 +15,7 @@ // with this program; if not, write to the Free Software Foundation, Inc., // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +use anyhow::Result; use async_std::prelude::*; use async_std::sync::Arc; @@ -59,7 +60,7 @@ fn handle_line_wo( initial: bool, inverted: bool, led_topic: Option>>, -) -> Arc> { +) -> Result>> { let topic = bb.topic_rw(path, Some(initial)); let line = find_line(line_name).unwrap(); let dst = line @@ -79,9 +80,9 @@ fn handle_line_wo( } Ok(()) - }); + })?; - topic + Ok(topic) } impl DigitalIo { @@ -90,7 +91,7 @@ impl DigitalIo { wtb: &mut WatchedTasksBuilder, led_0: Arc>, led_1: Arc>, - ) -> Self { + ) -> Result { let out_0 = handle_line_wo( bb, wtb, @@ -99,7 +100,7 @@ impl DigitalIo { false, false, Some(led_0), - ); + )?; let out_1 = handle_line_wo( bb, @@ -109,7 +110,7 @@ impl DigitalIo { false, false, Some(led_1), - ); + )?; let uart_rx_en = handle_line_wo( bb, @@ -119,7 +120,8 @@ impl DigitalIo { true, true, None, - ); + )?; + let uart_tx_en = handle_line_wo( bb, wtb, @@ -128,13 +130,13 @@ impl DigitalIo { true, true, None, - ); + )?; - Self { + Ok(Self { out_0, out_1, uart_rx_en, uart_tx_en, - } + }) } } diff --git a/src/dut_power.rs b/src/dut_power.rs index b5fd6444..3231436c 100644 --- a/src/dut_power.rs +++ b/src/dut_power.rs @@ -253,7 +253,7 @@ fn setup_labgrid_compat( wtb: &mut WatchedTasksBuilder, request: Arc>, state: Arc>, -) { +) -> Result<()> { let compat_request = bb.topic_wo::("/v1/dut/powered/compat", None); let compat_response = bb.topic_ro::("/v1/dut/powered/compat", None); @@ -270,7 +270,7 @@ fn setup_labgrid_compat( } Ok(()) - }); + })?; wtb.spawn_task("power-compat-to-labgrid", async move { while let Some(state) = state_stream.next().await { @@ -282,7 +282,9 @@ fn setup_labgrid_compat( } Ok(()) - }); + })?; + + Ok(()) } impl DutPwrThread { @@ -494,7 +496,7 @@ impl DutPwrThread { let request_topic = bb.topic_wo::("/v1/dut/powered", None); let state_topic = bb.topic_ro::("/v1/dut/powered", None); - setup_labgrid_compat(bb, wtb, request_topic.clone(), state_topic.clone()); + setup_labgrid_compat(bb, wtb, request_topic.clone(), state_topic.clone())?; // Requests come from the broker framework and are placed into an atomic // request variable read by the thread. @@ -507,7 +509,7 @@ impl DutPwrThread { } Ok(()) - }); + })?; // State information comes from the thread in the form of an atomic // variable and is forwarded to the broker framework. @@ -519,7 +521,7 @@ impl DutPwrThread { let curr_state = state.load(Ordering::Relaxed).into(); state_topic_task.set_if_changed(curr_state); } - }); + })?; // Forward the state information to the DUT Power LED let (mut state_stream, _) = state_topic.clone().subscribe_unbounded(); @@ -552,7 +554,7 @@ impl DutPwrThread { } Ok(()) - }); + })?; Ok(Self { request: request_topic, diff --git a/src/http_server.rs b/src/http_server.rs index f6d2abce..63536e23 100644 --- a/src/http_server.rs +++ b/src/http_server.rs @@ -18,6 +18,7 @@ use std::fs::write; use std::net::TcpListener; +use anyhow::Result; use tide::{Body, Response, Server}; use crate::watched_tasks::WatchedTasksBuilder; @@ -128,10 +129,10 @@ impl HttpServer { }); } - pub fn serve(self, wtb: &mut WatchedTasksBuilder) { + pub fn serve(self, wtb: &mut WatchedTasksBuilder) -> Result<()> { wtb.spawn_task("http-server", async move { self.server.listen(self.listeners).await?; Ok(()) - }); + }) } } diff --git a/src/iobus.rs b/src/iobus.rs index 7c7c6d71..a93f95fd 100644 --- a/src/iobus.rs +++ b/src/iobus.rs @@ -17,6 +17,7 @@ use std::time::Duration; +use anyhow::Result; use async_std::sync::Arc; use async_std::task::sleep; @@ -114,7 +115,7 @@ impl IoBus { iobus_pwr_en: Arc>, iobus_curr: CalibratedChannel, iobus_volt: CalibratedChannel, - ) -> Self { + ) -> Result { let supply_fault = bb.topic_ro("/v1/iobus/feedback/fault", None); let server_info = bb.topic_ro("/v1/iobus/server/info", None); let nodes = bb.topic_ro("/v1/iobus/server/nodes", None); @@ -153,12 +154,12 @@ impl IoBus { sleep(Duration::from_secs(1)).await; } - }); + })?; - Self { + Ok(Self { supply_fault, server_info, nodes, - } + }) } } diff --git a/src/led.rs b/src/led.rs index d33c5031..f4a2373a 100644 --- a/src/led.rs +++ b/src/led.rs @@ -17,6 +17,7 @@ use std::io::ErrorKind; +use anyhow::Result; use async_std::prelude::*; use async_std::sync::Arc; use log::{error, info, warn}; @@ -70,7 +71,7 @@ fn handle_pattern( wtb: &mut WatchedTasksBuilder, hardware_name: &'static str, topic_name: &'static str, -) -> Arc> { +) -> Result>> { let topic = bb.topic_ro(&format!("/v1/tac/led/{topic_name}/pattern"), None); if let Some(led) = get_led_checked(hardware_name) { @@ -84,10 +85,10 @@ fn handle_pattern( } Ok(()) - }); + })?; } - topic + Ok(topic) } fn handle_color( @@ -95,7 +96,7 @@ fn handle_color( wtb: &mut WatchedTasksBuilder, hardware_name: &'static str, topic_name: &'static str, -) -> Arc> { +) -> Result>> { let topic = bb.topic_ro(&format!("/v1/tac/led/{topic_name}/color"), None); if let Some(led) = get_led_checked(hardware_name) { @@ -115,22 +116,22 @@ fn handle_color( } Ok(()) - }); + })?; } - topic + Ok(topic) } impl Led { - pub fn new(bb: &mut BrokerBuilder, wtb: &mut WatchedTasksBuilder) -> Self { - Self { - out_0: handle_pattern(bb, wtb, "tac:green:out0", "out_0"), - out_1: handle_pattern(bb, wtb, "tac:green:out1", "out_1"), - dut_pwr: handle_pattern(bb, wtb, "tac:green:dutpwr", "dut_pwr"), - eth_dut: handle_pattern(bb, wtb, "tac:green:statusdut", "eth_dut"), - eth_lab: handle_pattern(bb, wtb, "tac:green:statuslab", "eth_lab"), - status: handle_pattern(bb, wtb, "rgb:status", "status"), - status_color: handle_color(bb, wtb, "rgb:status", "status"), - } + pub fn new(bb: &mut BrokerBuilder, wtb: &mut WatchedTasksBuilder) -> Result { + Ok(Self { + out_0: handle_pattern(bb, wtb, "tac:green:out0", "out_0")?, + out_1: handle_pattern(bb, wtb, "tac:green:out1", "out_1")?, + dut_pwr: handle_pattern(bb, wtb, "tac:green:dutpwr", "dut_pwr")?, + eth_dut: handle_pattern(bb, wtb, "tac:green:statusdut", "eth_dut")?, + eth_lab: handle_pattern(bb, wtb, "tac:green:statuslab", "eth_lab")?, + status: handle_pattern(bb, wtb, "rgb:status", "status")?, + status_color: handle_color(bb, wtb, "rgb:status", "status")?, + }) } } diff --git a/src/main.rs b/src/main.rs index 3f8e44d4..ab868b50 100644 --- a/src/main.rs +++ b/src/main.rs @@ -74,7 +74,7 @@ async fn main() -> Result<()> { // Expose hardware on the TAC via the broker framework. let backlight = Backlight::new(&mut bb, &mut wtb)?; - let led = Led::new(&mut bb, &mut wtb); + let led = Led::new(&mut bb, &mut wtb)?; let adc = Adc::new(&mut bb, &mut wtb).await?; let dut_pwr = DutPwrThread::new( &mut bb, @@ -84,8 +84,8 @@ async fn main() -> Result<()> { led.dut_pwr.clone(), ) .await?; - let dig_io = DigitalIo::new(&mut bb, &mut wtb, led.out_0.clone(), led.out_1.clone()); - let regulators = Regulators::new(&mut bb, &mut wtb); + let dig_io = DigitalIo::new(&mut bb, &mut wtb, led.out_0.clone(), led.out_1.clone())?; + let regulators = Regulators::new(&mut bb, &mut wtb)?; let temperatures = Temperatures::new(&mut bb, &mut wtb)?; let usb_hub = UsbHub::new( &mut bb, @@ -94,7 +94,7 @@ async fn main() -> Result<()> { adc.usb_host1_curr.fast.clone(), adc.usb_host2_curr.fast.clone(), adc.usb_host3_curr.fast.clone(), - ); + )?; // Expose other software on the TAC via the broker framework by connecting // to them via HTTP / DBus APIs. @@ -104,10 +104,10 @@ async fn main() -> Result<()> { regulators.iobus_pwr_en.clone(), adc.iobus_curr.fast.clone(), adc.iobus_volt.fast.clone(), - ); + )?; let (network, rauc, systemd) = { let dbus = - DbusSession::new(&mut bb, &mut wtb, led.eth_dut.clone(), led.eth_lab.clone()).await; + DbusSession::new(&mut bb, &mut wtb, led.eth_dut.clone(), led.eth_lab.clone()).await?; (dbus.network, dbus.rauc, dbus.systemd) }; @@ -126,7 +126,7 @@ async fn main() -> Result<()> { let mut http_server = HttpServer::new(); // Allow editing some aspects of the TAC configuration when in "setup mode". - let setup_mode = SetupMode::new(&mut bb, &mut wtb, &mut http_server.server); + let setup_mode = SetupMode::new(&mut bb, &mut wtb, &mut http_server.server)?; // Expose a live log of the TAC's systemd journal so it can be viewed // in the web interface. @@ -161,13 +161,13 @@ async fn main() -> Result<()> { // Consume the BrokerBuilder (no further topics can be added or removed) // and expose the topics via HTTP and MQTT-over-websocket. - bb.build(&mut wtb, &mut http_server.server); + bb.build(&mut wtb, &mut http_server.server)?; // Start drawing the display content - ui.run(&mut wtb, display); + ui.run(&mut wtb, display)?; // Start serving files and the API - http_server.serve(&mut wtb); + http_server.serve(&mut wtb)?; // If a watchdog was requested by systemd we can now start feeding it if let Some(watchdog) = watchdog { diff --git a/src/regulators.rs b/src/regulators.rs index 971dcb39..76ed1ee9 100644 --- a/src/regulators.rs +++ b/src/regulators.rs @@ -15,6 +15,7 @@ // with this program; if not, write to the Free Software Foundation, Inc., // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +use anyhow::Result; use async_std::prelude::*; use async_std::sync::Arc; @@ -75,7 +76,7 @@ fn handle_regulator( path: &str, regulator_name: &'static str, initial: bool, -) -> Arc> { +) -> Result>> { let topic = bb.topic_rw(path, Some(initial)); let (mut src, _) = topic.clone().subscribe_unbounded(); @@ -85,16 +86,16 @@ fn handle_regulator( } Ok(()) - }); + })?; - topic + Ok(topic) } impl Regulators { - pub fn new(bb: &mut BrokerBuilder, wtb: &mut WatchedTasksBuilder) -> Self { - Self { - iobus_pwr_en: handle_regulator(bb, wtb, "/v1/iobus/powered", "output-iobus-12v", true), - uart_pwr_en: handle_regulator(bb, wtb, "/v1/uart/powered", "output-vuart", true), - } + pub fn new(bb: &mut BrokerBuilder, wtb: &mut WatchedTasksBuilder) -> Result { + Ok(Self { + iobus_pwr_en: handle_regulator(bb, wtb, "/v1/iobus/powered", "output-iobus-12v", true)?, + uart_pwr_en: handle_regulator(bb, wtb, "/v1/uart/powered", "output-vuart", true)?, + }) } } diff --git a/src/setup_mode.rs b/src/setup_mode.rs index 3ef41261..01e3a767 100644 --- a/src/setup_mode.rs +++ b/src/setup_mode.rs @@ -19,6 +19,7 @@ use std::fs::{create_dir_all, read, write}; use std::io::ErrorKind; use std::path::Path; +use anyhow::Result; use async_std::prelude::*; use async_std::sync::Arc; use tide::{http::mime, Request, Response, Server}; @@ -106,7 +107,11 @@ impl SetupMode { }); } - fn handle_leave_requests(&self, bb: &mut BrokerBuilder, wtb: &mut WatchedTasksBuilder) { + fn handle_leave_requests( + &self, + bb: &mut BrokerBuilder, + wtb: &mut WatchedTasksBuilder, + ) -> Result<()> { // Use the "register a read-only and a write-only topic with the same name // to perform validation" trick that is also used with the DUT power endpoint. // We must make sure that a client from the web can only ever trigger _leaving_ @@ -125,14 +130,14 @@ impl SetupMode { } Ok(()) - }); + }) } pub fn new( bb: &mut BrokerBuilder, wtb: &mut WatchedTasksBuilder, server: &mut Server<()>, - ) -> Self { + ) -> Result { let this = Self { setup_mode: bb.topic("/v1/tac/setup_mode", true, false, true, Some(true), 1), show_help: bb.topic( @@ -145,9 +150,9 @@ impl SetupMode { ), }; - this.handle_leave_requests(bb, wtb); + this.handle_leave_requests(bb, wtb)?; this.expose_file_conditionally(server, AUTHORIZED_KEYS_PATH, "/v1/tac/ssh/authorized_keys"); - this + Ok(this) } } diff --git a/src/ui.rs b/src/ui.rs index 41884f96..d15db6e3 100644 --- a/src/ui.rs +++ b/src/ui.rs @@ -136,7 +136,7 @@ impl Ui { alerts.assert(AlertScreen::ScreenSaver); // Initialize all the screens now so they can be activated later - let screens = screens::init(wtb, &res, &alerts, &buttons, &reboot_message, &locator); + let screens = screens::init(wtb, &res, &alerts, &buttons, &reboot_message, &locator)?; handle_buttons( wtb, @@ -171,7 +171,7 @@ impl Ui { } Ok(()) - }); + })?; Ok(Self { screen, @@ -289,11 +289,11 @@ impl Ui { Ok(()) } - pub fn run(self, wtb: &mut WatchedTasksBuilder, display: Display) { + pub fn run(self, wtb: &mut WatchedTasksBuilder, display: Display) -> Result<()> { wtb.spawn_task("screen-render-loop", async move { self.render_loop(display).await?; Ok(()) - }); + }) } } diff --git a/src/ui/screens.rs b/src/ui/screens.rs index 6aca3601..2bd9ab9a 100644 --- a/src/ui/screens.rs +++ b/src/ui/screens.rs @@ -15,6 +15,7 @@ // with this program; if not, write to the Free Software Foundation, Inc., // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +use anyhow::Result; use async_std::sync::Arc; use async_trait::async_trait; use embedded_graphics::{ @@ -189,34 +190,38 @@ pub(super) fn init( buttons: &Arc>, reboot_message: &Arc>>, locator: &Arc>, -) -> Vec> { - vec![ +) -> Result>> { + Ok(vec![ Box::new(DigOutScreen::new()), Box::new(IoBusScreen::new()), Box::new(PowerScreen::new()), Box::new(SystemScreen::new()), Box::new(UartScreen::new()), Box::new(UsbScreen::new()), - Box::new(HelpScreen::new(wtb, alerts, &res.setup_mode.show_help)), - Box::new(IoBusHealthScreen::new(wtb, alerts, &res.iobus.supply_fault)), + Box::new(HelpScreen::new(wtb, alerts, &res.setup_mode.show_help)?), + Box::new(IoBusHealthScreen::new( + wtb, + alerts, + &res.iobus.supply_fault, + )?), Box::new(UpdateInstallationScreen::new( wtb, alerts, &res.rauc.operation, reboot_message, &res.rauc.should_reboot, - )), - Box::new(UpdateAvailableScreen::new(wtb, alerts, &res.rauc.channels)), - Box::new(RebootConfirmScreen::new(wtb, alerts, reboot_message)), - Box::new(ScreenSaverScreen::new(wtb, buttons, alerts)), - Box::new(SetupScreen::new(wtb, alerts, &res.setup_mode.setup_mode)), + )?), + Box::new(UpdateAvailableScreen::new(wtb, alerts, &res.rauc.channels)?), + Box::new(RebootConfirmScreen::new(wtb, alerts, reboot_message)?), + Box::new(ScreenSaverScreen::new(wtb, buttons, alerts)?), + Box::new(SetupScreen::new(wtb, alerts, &res.setup_mode.setup_mode)?), Box::new(OverTemperatureScreen::new( wtb, alerts, &res.temperatures.warning, - )), - Box::new(LocatorScreen::new(wtb, alerts, locator)), - Box::new(UsbOverloadScreen::new(wtb, alerts, &res.usb_hub.overload)), - Box::new(PowerFailScreen::new(wtb, alerts, &res.dut_pwr.state)), - ] + )?), + Box::new(LocatorScreen::new(wtb, alerts, locator)?), + Box::new(UsbOverloadScreen::new(wtb, alerts, &res.usb_hub.overload)?), + Box::new(PowerFailScreen::new(wtb, alerts, &res.dut_pwr.state)?), + ]) } diff --git a/src/ui/screens/help.rs b/src/ui/screens/help.rs index 4fa308f3..ed193d9a 100644 --- a/src/ui/screens/help.rs +++ b/src/ui/screens/help.rs @@ -15,6 +15,7 @@ // with this program; if not, write to the Free Software Foundation, Inc., // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +use anyhow::Result; use async_std::prelude::*; use async_std::sync::Arc; use async_trait::async_trait; @@ -69,7 +70,7 @@ impl HelpScreen { wtb: &mut WatchedTasksBuilder, alerts: &Arc>, show_help: &Arc>, - ) -> Self { + ) -> Result { let (mut show_help_events, _) = show_help.clone().subscribe_unbounded(); let alerts = alerts.clone(); @@ -83,9 +84,9 @@ impl HelpScreen { } Ok(()) - }); + })?; - Self + Ok(Self) } } diff --git a/src/ui/screens/iobus_health.rs b/src/ui/screens/iobus_health.rs index fa5b4ffc..ad59eeaa 100644 --- a/src/ui/screens/iobus_health.rs +++ b/src/ui/screens/iobus_health.rs @@ -15,6 +15,7 @@ // with this program; if not, write to the Free Software Foundation, Inc., // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +use anyhow::Result; use async_std::prelude::*; use async_std::sync::Arc; use async_trait::async_trait; @@ -45,7 +46,7 @@ impl IoBusHealthScreen { wtb: &mut WatchedTasksBuilder, alerts: &Arc>, supply_fault: &Arc>, - ) -> Self { + ) -> Result { let (mut supply_fault_events, _) = supply_fault.clone().subscribe_unbounded(); let alerts = alerts.clone(); @@ -59,9 +60,9 @@ impl IoBusHealthScreen { } Ok(()) - }); + })?; - Self + Ok(Self) } } diff --git a/src/ui/screens/locator.rs b/src/ui/screens/locator.rs index 805400ad..132744cc 100644 --- a/src/ui/screens/locator.rs +++ b/src/ui/screens/locator.rs @@ -17,6 +17,7 @@ use std::time::Instant; +use anyhow::Result; use async_std::prelude::*; use async_std::sync::Arc; use async_trait::async_trait; @@ -50,7 +51,7 @@ impl LocatorScreen { wtb: &mut WatchedTasksBuilder, alerts: &Arc>, locator: &Arc>, - ) -> Self { + ) -> Result { let (mut locator_events, _) = locator.clone().subscribe_unbounded(); let alerts = alerts.clone(); @@ -64,9 +65,9 @@ impl LocatorScreen { } Ok(()) - }); + })?; - Self + Ok(Self) } } diff --git a/src/ui/screens/overtemperature.rs b/src/ui/screens/overtemperature.rs index 182c5392..9167a5b3 100644 --- a/src/ui/screens/overtemperature.rs +++ b/src/ui/screens/overtemperature.rs @@ -15,6 +15,7 @@ // with this program; if not, write to the Free Software Foundation, Inc., // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +use anyhow::Result; use async_std::prelude::*; use async_std::sync::Arc; use async_trait::async_trait; @@ -45,7 +46,7 @@ impl OverTemperatureScreen { wtb: &mut WatchedTasksBuilder, alerts: &Arc>, warning: &Arc>, - ) -> Self { + ) -> Result { let (mut warning_events, _) = warning.clone().subscribe_unbounded(); let alerts = alerts.clone(); @@ -58,9 +59,9 @@ impl OverTemperatureScreen { } Ok(()) - }); + })?; - Self + Ok(Self) } } diff --git a/src/ui/screens/power_fail.rs b/src/ui/screens/power_fail.rs index 6ff11c52..e68f3091 100644 --- a/src/ui/screens/power_fail.rs +++ b/src/ui/screens/power_fail.rs @@ -15,6 +15,7 @@ // with this program; if not, write to the Free Software Foundation, Inc., // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +use anyhow::Result; use async_std::prelude::*; use async_std::sync::Arc; use async_trait::async_trait; @@ -62,7 +63,7 @@ impl PowerFailScreen { wtb: &mut WatchedTasksBuilder, alerts: &Arc>, out_state: &Arc>, - ) -> Self { + ) -> Result { let (mut out_state_events, _) = out_state.clone().subscribe_unbounded(); let alerts = alerts.clone(); @@ -82,9 +83,9 @@ impl PowerFailScreen { } Ok(()) - }); + })?; - Self + Ok(Self) } } diff --git a/src/ui/screens/reboot.rs b/src/ui/screens/reboot.rs index eb391511..6b1fcd56 100644 --- a/src/ui/screens/reboot.rs +++ b/src/ui/screens/reboot.rs @@ -15,6 +15,7 @@ // with this program; if not, write to the Free Software Foundation, Inc., // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +use anyhow::Result; use async_std::prelude::*; use async_std::sync::Arc; use async_trait::async_trait; @@ -44,7 +45,7 @@ impl RebootConfirmScreen { wtb: &mut WatchedTasksBuilder, alerts: &Arc>, reboot_message: &Arc>>, - ) -> Self { + ) -> Result { // Receive questions like Some("Do you want to reboot?") and activate this screen let (mut reboot_message_events, _) = reboot_message.clone().subscribe_unbounded(); let reboot_message = reboot_message.clone(); @@ -60,9 +61,9 @@ impl RebootConfirmScreen { } Ok(()) - }); + })?; - Self { reboot_message } + Ok(Self { reboot_message }) } } diff --git a/src/ui/screens/screensaver.rs b/src/ui/screens/screensaver.rs index 7fb1c607..668a0f00 100644 --- a/src/ui/screens/screensaver.rs +++ b/src/ui/screens/screensaver.rs @@ -18,6 +18,7 @@ use std::convert::TryInto; use std::time::{Duration, SystemTime}; +use anyhow::Result; use async_std::future::timeout; use async_std::prelude::*; use async_std::sync::Arc; @@ -95,7 +96,7 @@ impl ScreenSaverScreen { wtb: &mut WatchedTasksBuilder, buttons: &Arc>, alerts: &Arc>, - ) -> Self { + ) -> Result { // Activate screensaver if no button is pressed for some time let (mut buttons_events, _) = buttons.clone().subscribe_unbounded(); let alerts = alerts.clone(); @@ -115,9 +116,9 @@ impl ScreenSaverScreen { } Ok(()) - }); + })?; - Self + Ok(Self) } } diff --git a/src/ui/screens/setup.rs b/src/ui/screens/setup.rs index a59310bb..1f6dfc0f 100644 --- a/src/ui/screens/setup.rs +++ b/src/ui/screens/setup.rs @@ -15,6 +15,7 @@ // with this program; if not, write to the Free Software Foundation, Inc., // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +use anyhow::Result; use async_std::prelude::*; use async_std::sync::Arc; use async_std::task::spawn; @@ -53,7 +54,7 @@ impl SetupScreen { wtb: &mut WatchedTasksBuilder, alerts: &Arc>, setup_mode: &Arc>, - ) -> Self { + ) -> Result { let (mut setup_mode_events, _) = setup_mode.clone().subscribe_unbounded(); let alerts = alerts.clone(); @@ -67,9 +68,9 @@ impl SetupScreen { } Ok(()) - }); + })?; - Self + Ok(Self) } } diff --git a/src/ui/screens/update_available.rs b/src/ui/screens/update_available.rs index 065661c5..6fa3bd60 100644 --- a/src/ui/screens/update_available.rs +++ b/src/ui/screens/update_available.rs @@ -15,6 +15,7 @@ // with this program; if not, write to the Free Software Foundation, Inc., // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +use anyhow::Result; use async_std::prelude::*; use async_std::sync::Arc; use async_trait::async_trait; @@ -143,7 +144,7 @@ impl UpdateAvailableScreen { wtb: &mut WatchedTasksBuilder, alerts: &Arc>, channels: &Arc>>, - ) -> Self { + ) -> Result { let (mut channels_events, _) = channels.clone().subscribe_unbounded(); let alerts = alerts.clone(); let selection = Topic::anonymous(Some(Selection::new())); @@ -161,9 +162,9 @@ impl UpdateAvailableScreen { } Ok(()) - }); + })?; - Self { selection } + Ok(Self { selection }) } } diff --git a/src/ui/screens/update_installation.rs b/src/ui/screens/update_installation.rs index 15bdcfec..e3ce6867 100644 --- a/src/ui/screens/update_installation.rs +++ b/src/ui/screens/update_installation.rs @@ -15,6 +15,7 @@ // with this program; if not, write to the Free Software Foundation, Inc., // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +use anyhow::Result; use async_std::prelude::*; use async_std::sync::Arc; use async_trait::async_trait; @@ -51,7 +52,7 @@ impl UpdateInstallationScreen { operation: &Arc>, reboot_message: &Arc>>, should_reboot: &Arc>, - ) -> Self { + ) -> Result { let (mut operation_events, _) = operation.clone().subscribe_unbounded(); let alerts = alerts.clone(); @@ -64,7 +65,7 @@ impl UpdateInstallationScreen { } Ok(()) - }); + })?; let (mut should_reboot_events, _) = should_reboot.clone().subscribe_unbounded(); let reboot_message = reboot_message.clone(); @@ -77,9 +78,9 @@ impl UpdateInstallationScreen { } Ok(()) - }); + })?; - Self + Ok(Self) } } diff --git a/src/ui/screens/usb_overload.rs b/src/ui/screens/usb_overload.rs index 86a2dd05..a491c588 100644 --- a/src/ui/screens/usb_overload.rs +++ b/src/ui/screens/usb_overload.rs @@ -15,6 +15,7 @@ // with this program; if not, write to the Free Software Foundation, Inc., // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +use anyhow::Result; use async_std::prelude::*; use async_std::sync::Arc; use async_trait::async_trait; @@ -49,7 +50,7 @@ impl UsbOverloadScreen { wtb: &mut WatchedTasksBuilder, alerts: &Arc>, overload: &Arc>>, - ) -> Self { + ) -> Result { let (mut overload_events, _) = overload.clone().subscribe_unbounded(); let alerts = alerts.clone(); @@ -63,9 +64,9 @@ impl UsbOverloadScreen { } Ok(()) - }); + })?; - Self + Ok(Self) } } diff --git a/src/usb_hub.rs b/src/usb_hub.rs index 2bfcab10..7bbea692 100644 --- a/src/usb_hub.rs +++ b/src/usb_hub.rs @@ -18,6 +18,7 @@ use std::path::Path; use std::time::Duration; +use anyhow::{anyhow, Result}; use async_std::prelude::*; use async_std::sync::Arc; use async_std::task::sleep; @@ -203,7 +204,7 @@ fn handle_port( wtb: &mut WatchedTasksBuilder, name: &'static str, base: &'static str, -) -> UsbPort { +) -> Result { let port = UsbPort { request: bb.topic_wo(format!("/v1/usb/host/{name}/powered").as_str(), None), status: bb.topic_ro(format!("/v1/usb/host/{name}/powered").as_str(), None), @@ -232,7 +233,7 @@ fn handle_port( } Ok(()) - }); + })?; let status = port.status.clone(); let device = port.device.clone(); @@ -280,9 +281,9 @@ fn handle_port( sleep(POLL_INTERVAL).await; } - }); + })?; - port + Ok(port) } fn handle_overloads( @@ -292,7 +293,7 @@ fn handle_overloads( port1: CalibratedChannel, port2: CalibratedChannel, port3: CalibratedChannel, -) -> Arc>> { +) -> Result>>> { let overload = bb.topic_ro("/v1/usb/host/overload", None); let overload_task = overload.clone(); @@ -310,9 +311,9 @@ fn handle_overloads( sleep(POLL_INTERVAL).await; } - }); + })?; - overload + Ok(overload) } impl UsbHub { @@ -323,18 +324,24 @@ impl UsbHub { port1: CalibratedChannel, port2: CalibratedChannel, port3: CalibratedChannel, - ) -> Self { - let overload = handle_overloads(bb, wtb, total, port1, port2, port3); + ) -> Result { + let overload = handle_overloads(bb, wtb, total, port1, port2, port3)?; let mut ports = PORTS .iter() .map(|(name, base)| handle_port(bb, wtb, name, base)); - Self { + Ok(Self { overload, - port1: ports.next().unwrap(), - port2: ports.next().unwrap(), - port3: ports.next().unwrap(), - } + port1: ports + .next() + .ok_or_else(|| anyhow!("Failed to find USB port 1"))??, + port2: ports + .next() + .ok_or_else(|| anyhow!("Failed to find USB port 2"))??, + port3: ports + .next() + .ok_or_else(|| anyhow!("Failed to find USB port 3"))??, + }) } } diff --git a/src/watchdog.rs b/src/watchdog.rs index 7d5d3589..6c700933 100644 --- a/src/watchdog.rs +++ b/src/watchdog.rs @@ -89,7 +89,7 @@ impl Watchdog { notify(false, [(STATE_WATCHDOG, "1")].iter())?; } - }); + })?; Ok(()) } diff --git a/src/watched_tasks.rs b/src/watched_tasks.rs index 384bbd06..2a58a319 100644 --- a/src/watched_tasks.rs +++ b/src/watched_tasks.rs @@ -123,17 +123,16 @@ impl WatchedTasksBuilder { /// Future will return the Result of said task. /// The WatchedTasks Future should be .awaited at the end of main() so /// that the program ends if any of the watched tasks ends. - pub fn spawn_task(&mut self, name: S, future: F) + pub fn spawn_task(&mut self, name: S, future: F) -> Result<()> where S: Into, F: Future + Send + 'static, { - let task = task::Builder::new() - .name(name.into()) - .spawn(future) - .expect("cannot spawn task"); + let task = task::Builder::new().name(name.into()).spawn(future)?; self.tasks.push(task); + + Ok(()) } /// Spawn a thread that runs until the end of the program @@ -237,7 +236,8 @@ mod tests { let res = rx.recv().await?; println!("Bye from task {i}!"); res - }); + }) + .unwrap(); tx })