From 7dd15fb89b405dc7a88c3439acaf10c5e9c4180d Mon Sep 17 00:00:00 2001 From: Shaun Taheri Date: Mon, 5 Sep 2016 11:28:22 +0200 Subject: Send packages and system info after successful authentication --- Makefile | 8 +------- run/sota.toml.env | 2 +- src/datatype/command.rs | 46 ++++++++++++++++++++++++++++------------------ src/datatype/config.rs | 4 ++-- src/datatype/event.rs | 13 +++++++++---- src/http/auth_client.rs | 2 +- src/interpreter.rs | 43 +++++++++++++++++++++++++++---------------- src/main.rs | 15 +-------------- src/rvi/parameters.rs | 1 - tests/sota.toml | 2 +- 10 files changed, 71 insertions(+), 65 deletions(-) diff --git a/Makefile b/Makefile index cd07a78..9750616 100644 --- a/Makefile +++ b/Makefile @@ -30,7 +30,7 @@ define make-pkg endef -.PHONY: help run clean test doc client image deb rpm version for-meta-rust +.PHONY: help run clean test doc client image deb rpm version .DEFAULT_GOAL := help help: @@ -83,12 +83,6 @@ rpm: client ## Create a new RPM package of the client. version: ## Print the version that will be used for building packages. @echo $(PACKAGE_VERSION) -for-meta-rust: - $(RUST_IN_DOCKER) /bin/bash -c "\ - /root/.cargo/bin/rustup override set 1.7.0 && \ - cargo clean && \ - cargo test" - rust-openssl: @git clone https://github.com/sfackler/rust-openssl $@ @cd $@ && git checkout df30e9e700225fb981d8a3cdfaf0b359722a4c9a diff --git a/run/sota.toml.env b/run/sota.toml.env index 595f905..1ef5619 100644 --- a/run/sota.toml.env +++ b/run/sota.toml.env @@ -27,7 +27,7 @@ NETWORK_HTTP_SERVER=http://127.0.0.1:8888 NETWORK_RVI_EDGE_SERVER=http://127.0.0.1:9080 NETWORK_SOCKET_COMMANDS_PATH=/tmp/sota-commands.socket NETWORK_SOCKET_EVENTS_PATH=/tmp/sota-events.socket -NETWORK_WEBSOCKET_SERVER=ws://127.0.0.1:3012 +NETWORK_WEBSOCKET_SERVER=127.0.0.1:3012 RVI_CLIENT=http://127.0.0.1:8901 RVI_STORAGE_DIR=/var/sota diff --git a/src/datatype/command.rs b/src/datatype/command.rs index d449bb6..0f59b1a 100644 --- a/src/datatype/command.rs +++ b/src/datatype/command.rs @@ -20,8 +20,8 @@ pub enum Command { GetNewUpdates, /// List the installed packages on the system. ListInstalledPackages, - /// Get the latest system information, and optionally publish it to Core. - RefreshSystemInfo(bool), + /// List the system information. + ListSystemInfo, /// Start downloading one or more updates. StartDownload(Vec), @@ -32,6 +32,8 @@ pub enum Command { SendInstalledPackages(Vec), /// Send a list of all packages and firmware to the Core server. SendInstalledSoftware(InstalledSoftware), + /// Send the system information to the Core server. + SendSystemInfo, /// Send a package update report to the Core server. SendUpdateReport(UpdateReport), } @@ -63,14 +65,16 @@ named!(command <(Command, Vec<&str>)>, chain!( => { |_| Command::GetNewUpdates } | alt_complete!(tag!("ListInstalledPackages") | tag!("ls")) => { |_| Command::ListInstalledPackages } - | alt_complete!(tag!("RefreshSystemInfo") | tag!("info")) - => { |_| Command::RefreshSystemInfo(false) } + | alt_complete!(tag!("ListSystemInfo") | tag!("info")) + => { |_| Command::ListSystemInfo } | alt_complete!(tag!("Shutdown") | tag!("shutdown")) => { |_| Command::Shutdown } | alt_complete!(tag!("SendInstalledPackages") | tag!("sendpack")) => { |_| Command::SendInstalledPackages(Vec::new()) } | alt_complete!(tag!("SendInstalledSoftware") | tag!("sendinst")) => { |_| Command::SendInstalledSoftware(InstalledSoftware::default()) } + | alt_complete!(tag!("SendSystemInfo") | tag!("sendinfo")) + => { |_| Command::SendSystemInfo } | alt_complete!(tag!("SendUpdateReport") | tag!("sendup")) => { |_| Command::SendUpdateReport(UpdateReport::default()) } | alt_complete!(tag!("StartDownload") | tag!("dl")) @@ -118,16 +122,9 @@ fn parse_arguments(cmd: Command, args: Vec<&str>) -> Result { _ => Err(Error::Command(format!("unexpected ListInstalledPackages args: {:?}", args))), }, - Command::RefreshSystemInfo(_) => match args.len() { - 0 => Ok(Command::RefreshSystemInfo(false)), - 1 => { - if let Ok(b) = args[0].parse::() { - Ok(Command::RefreshSystemInfo(b)) - } else { - Err(Error::Command("couldn't parse 1st argument as boolean".to_string())) - } - } - _ => Err(Error::Command(format!("unexpected RefreshSystemInfo args: {:?}", args))), + Command::ListSystemInfo => match args.len() { + 0 => Ok(Command::ListSystemInfo), + _ => Err(Error::Command(format!("unexpected ListSystemInfo args: {:?}", args))), }, Command::SendInstalledPackages(_) => match args.len() { @@ -150,6 +147,11 @@ fn parse_arguments(cmd: Command, args: Vec<&str>) -> Result { _ => Err(Error::Command(format!("unexpected SendInstalledSoftware args: {:?}", args))), }, + Command::SendSystemInfo => match args.len() { + 0 => Ok(Command::SendSystemInfo), + _ => Err(Error::Command(format!("unexpected SendSystemInfo args: {:?}", args))), + }, + Command::SendUpdateReport(_) => match args.len() { 0 | 1 => Err(Error::Command("usage: sendup ".to_string())), 2 => { @@ -238,10 +240,10 @@ mod tests { } #[test] - fn refresh_system_info_test() { - assert_eq!("RefreshSystemInfo true".parse::().unwrap(), Command::RefreshSystemInfo(true)); - assert_eq!("info".parse::().unwrap(), Command::RefreshSystemInfo(false)); - assert!("RefreshSystemInfo 1 2".parse::().is_err()); + fn list_system_info_test() { + assert_eq!("ListSystemInfo".parse::().unwrap(), Command::ListSystemInfo); + assert_eq!("info".parse::().unwrap(), Command::ListSystemInfo); + assert!("ListSystemInfo 1 2".parse::().is_err()); assert!("info please".parse::().is_err()); } @@ -270,6 +272,14 @@ mod tests { assert!("sendsoft some".parse::().is_err()); } + #[test] + fn send_system_info_test() { + assert_eq!("SendSystemInfo".parse::().unwrap(), Command::SendSystemInfo); + assert_eq!("sendinfo".parse::().unwrap(), Command::SendSystemInfo); + assert!("SendSystemInfo 1 2".parse::().is_err()); + assert!("sendinfo please".parse::().is_err()); + } + #[test] fn send_update_report_test() { assert_eq!("SendUpdateReport myid OK".parse::().unwrap(), Command::SendUpdateReport( diff --git a/src/datatype/config.rs b/src/datatype/config.rs index 5db0f12..650008b 100644 --- a/src/datatype/config.rs +++ b/src/datatype/config.rs @@ -266,7 +266,7 @@ impl Default for NetworkConfig { rvi_edge_server: "http://127.0.0.1:9080".to_string(), socket_commands_path: "/tmp/sota-commands.socket".to_string(), socket_events_path: "/tmp/sota-events.socket".to_string(), - websocket_server: "ws://127.0.0.1:3012".to_string() + websocket_server: "127.0.0.1:3012".to_string() } } } @@ -352,7 +352,7 @@ mod tests { rvi_edge_server = "http://127.0.0.1:9080" socket_commands_path = "/tmp/sota-commands.socket" socket_events_path = "/tmp/sota-events.socket" - websocket_server = "ws://127.0.0.1:3012" + websocket_server = "127.0.0.1:3012" "#; const RVI_CONFIG: &'static str = diff --git a/src/datatype/event.rs b/src/datatype/event.rs index e3f84ca..63ae850 100644 --- a/src/datatype/event.rs +++ b/src/datatype/event.rs @@ -26,10 +26,6 @@ pub enum Event { FoundInstalledPackages(Vec), /// An update on the system information was received. FoundSystemInfo(String), - /// A list of installed packages was sent to the Core server. - InstalledPackagesSent, - /// An update report was sent to the Core server. - UpdateReportSent, /// Downloading an update. DownloadingUpdate(UpdateRequestId), @@ -45,6 +41,15 @@ pub enum Event { /// The installation of an update failed. InstallFailed(UpdateReport), + /// An update report was sent to the Core server. + UpdateReportSent, + /// A list of installed packages was sent to the Core server. + InstalledPackagesSent, + /// A list of installed software was sent to the Core server. + InstalledSoftwareSent, + /// The system information was sent to the Core server. + SystemInfoSent, + /// A broadcast event requesting an update on externally installed software. InstalledSoftwareNeeded, } diff --git a/src/http/auth_client.rs b/src/http/auth_client.rs index f4ad38b..f97f4d7 100644 --- a/src/http/auth_client.rs +++ b/src/http/auth_client.rs @@ -88,7 +88,7 @@ impl AuthHandler { match resp.headers().get::() { Some(&Location(ref loc)) => self.req.url.join(loc).map(|url| { debug!("redirecting to {}", url); - // drop Authentication Header on redirect + // drop Authorization Header on redirect let client = AuthClient::default(); let resp_rx = client.send_request(Request { url: url, diff --git a/src/interpreter.rs b/src/interpreter.rs index b286ba5..7d95007 100644 --- a/src/interpreter.rs +++ b/src/interpreter.rs @@ -36,6 +36,16 @@ impl Interpreter for EventInterpreter { fn interpret(&mut self, event: Event, ctx: &Sender) { info!("Event received: {}", event); match event { + Event::Authenticated => { + ctx.send(Command::SendSystemInfo); + + if self.package_manager != PackageManager::Off { + self.package_manager.installed_packages().map(|packages| { + ctx.send(Command::SendInstalledPackages(packages)); + }).unwrap_or_else(|err| error!("couldn't send a list of packages: {}", err)); + } + } + Event::NotAuthenticated => { info!("Trying to authenticate again..."); ctx.send(Command::Authenticate(None)); @@ -88,8 +98,7 @@ pub struct GlobalInterpreter<'t> { pub config: Config, pub token: Option>, pub http_client: Box, - pub rvi: Option, - pub loopback_tx: Sender, + pub rvi: Option } impl<'t> Interpreter for GlobalInterpreter<'t> { @@ -159,13 +168,9 @@ impl<'t> GlobalInterpreter<'t> { etx.send(Event::FoundInstalledPackages(packages)); } - Command::RefreshSystemInfo(post) => { + Command::ListSystemInfo => { let info = try!(self.config.device.system_info.report()); - etx.send(Event::FoundSystemInfo(info.clone())); - if post { - let _ = sota.send_system_info(&info) - .map_err(|err| etx.send(Event::Error(format!("{}", err)))); - } + etx.send(Event::FoundSystemInfo(info)); } Command::SendInstalledPackages(packages) => { @@ -178,6 +183,14 @@ impl<'t> GlobalInterpreter<'t> { if let Some(ref rvi) = self.rvi { let _ = rvi.remote.lock().unwrap().send_installed_software(sw); } + etx.send(Event::InstalledSoftwareSent); + } + + Command::SendSystemInfo => { + let info = try!(self.config.device.system_info.report()); + let _ = sota.send_system_info(&info) + .map_err(|err| error!("couldn't send system info: {}", err)); + etx.send(Event::SystemInfoSent); } Command::SendUpdateReport(report) => { @@ -193,7 +206,6 @@ impl<'t> GlobalInterpreter<'t> { Command::StartDownload(ref ids) => { for id in ids { etx.send(Event::DownloadingUpdate(id.clone())); - if let Some(ref rvi) = self.rvi { let _ = rvi.remote.lock().unwrap().send_download_started(id.clone()); } else { @@ -231,10 +243,11 @@ impl<'t> GlobalInterpreter<'t> { Command::GetNewUpdates | Command::ListInstalledPackages | - Command::RefreshSystemInfo(_) | + Command::ListSystemInfo | Command::SendInstalledPackages(_) | Command::SendInstalledSoftware(_) | Command::SendUpdateReport(_) | + Command::SendSystemInfo | Command::StartDownload(_) | Command::StartInstall(_) => etx.send(Event::NotAuthenticated), @@ -270,15 +283,13 @@ mod tests { fn new_interpreter(replies: Vec, pkg_mgr: PackageManager) -> (Sender, Receiver) { let (etx, erx) = chan::sync::(0); let (ctx, crx) = chan::sync::(0); - let (itx, _) = chan::sync::(0); thread::spawn(move || { let mut gi = GlobalInterpreter { config: Config::default(), token: Some(AccessToken::default().into()), http_client: Box::new(TestClient::from(replies)), - rvi: None, - loopback_tx: itx, + rvi: None }; gi.config.device.package_manager = pkg_mgr; @@ -327,7 +338,7 @@ mod tests { } #[test] - fn install_update() { + fn install_update_success() { let replies = vec!["[]".to_string(); 10]; let pkg_mgr = PackageManager::new_tpm(true); let (ctx, erx) = new_interpreter(replies, pkg_mgr); @@ -345,7 +356,7 @@ mod tests { } #[test] - fn failed_installation() { + fn install_update_failed() { let replies = vec!["[]".to_string(); 10]; let pkg_mgr = PackageManager::new_tpm(false); let (ctx, erx) = new_interpreter(replies, pkg_mgr); @@ -358,7 +369,7 @@ mod tests { assert_rx(erx, &[ Event::InstallFailed( UpdateReport::single("1".to_string(), UpdateResultCode::INSTALL_FAILED, "failed".to_string()) - ) + ), ]); } } diff --git a/src/main.rs b/src/main.rs index 61fa02a..3fd5667 100644 --- a/src/main.rs +++ b/src/main.rs @@ -25,7 +25,6 @@ use sota::gateway::{Console, DBus, Gateway, Interpret, Http, Socket, Websocket}; use sota::broadcast::Broadcast; use sota::http::{AuthClient, set_ca_certificates}; use sota::interpreter::{EventInterpreter, CommandInterpreter, Interpreter, GlobalInterpreter}; -use sota::package_manager::PackageManager; use sota::rvi::{Edge, Services}; @@ -59,17 +58,6 @@ fn start_update_poller(interval: u64, itx: Sender) { } } -fn send_startup_commands(config: &Config, ctx: &Sender) { - ctx.send(Command::Authenticate(None)); - ctx.send(Command::RefreshSystemInfo(true)); - - if config.device.package_manager != PackageManager::Off { - config.device.package_manager.installed_packages().map(|packages| { - ctx.send(Command::SendInstalledPackages(packages)); - }).unwrap_or_else(|err| exit!("Couldn't get list of packages: {}", err)); - } -} - fn main() { setup_logging(); @@ -81,7 +69,7 @@ fn main() { let (itx, irx) = chan::async::(); let mut broadcast = Broadcast::new(erx); - send_startup_commands(&config, &ctx); + ctx.send(Command::Authenticate(None)); crossbeam::scope(|scope| { // Must subscribe to the signal before spawning ANY other threads @@ -157,7 +145,6 @@ fn main() { token: None, http_client: Box::new(AuthClient::default()), rvi: rvi, - loopback_tx: itx, }.run(irx, etx)); scope.spawn(move || broadcast.start()); diff --git a/src/rvi/parameters.rs b/src/rvi/parameters.rs index 1fa1a87..f48ea44 100644 --- a/src/rvi/parameters.rs +++ b/src/rvi/parameters.rs @@ -1,4 +1,3 @@ -use std::str; use std::sync::Mutex; use datatype::{ChunkReceived, Event, DownloadComplete, UpdateRequestId, UpdateAvailable}; diff --git a/tests/sota.toml b/tests/sota.toml index 0801509..87cf144 100644 --- a/tests/sota.toml +++ b/tests/sota.toml @@ -37,7 +37,7 @@ http_server = "http://127.0.0.1:8888" rvi_edge_server = "http://127.0.0.1:9080" socket_commands_path = "/tmp/sota-commands.socket" socket_events_path = "/tmp/sota-events.socket" -websocket_server = "ws://127.0.0.1:3012" +websocket_server = "127.0.0.1:3012" [rvi] client = "http://127.0.0.1:8901" -- cgit v1.2.1