diff --git a/Cargo.lock b/Cargo.lock index ec75a85..06e0dba 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -404,6 +404,12 @@ dependencies = [ "libc", ] +[[package]] +name = "itoa" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "112c678d4050afce233f4f2852bb2eb519230b3cf12f33585275537d7e41578d" + [[package]] name = "libadwaita" version = "0.1.1" @@ -684,6 +690,12 @@ dependencies = [ "semver", ] +[[package]] +name = "ryu" +version = "1.0.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f3f6f92acf49d1b98f7a81226834412ada05458b7364277387724a237f062695" + [[package]] name = "scopeguard" version = "1.1.0" @@ -713,6 +725,31 @@ name = "serde" version = "1.0.136" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ce31e24b01e1e524df96f1c2fdd054405f8d7376249a5110886fb4b658484789" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.136" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08597e7152fcd306f41838ed3e37be9eaeed2b61c42e2117266a554fab4662f9" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "serde_json" +version = "1.0.81" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b7ce2b32a1aed03c558dc61a5cd328f15aff2dbc17daad8fb8af04d2100e15c" +dependencies = [ + "itoa", + "ryu", + "serde", +] [[package]] name = "signal-hook-registry" @@ -834,6 +871,8 @@ name = "toolbox-tuner" version = "0.0.0" dependencies = [ "relm4", + "serde", + "serde_json", "tokio", ] diff --git a/Cargo.toml b/Cargo.toml index cda2fb4..19b754f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -8,6 +8,8 @@ edition = "2021" [dependencies] relm4 = {version="0.4", features = ["libadwaita", "macros"]} tokio = { version = "1", features = ["full"] } +serde = { version = "1.0", features = ["derive"] } +serde_json = "1.0" [package.metadata.appimage] auto_link = true diff --git a/src/toolbx/mod.rs b/src/toolbx/mod.rs index 5944049..6cffd45 100644 --- a/src/toolbx/mod.rs +++ b/src/toolbx/mod.rs @@ -1,8 +1,10 @@ use std::{fmt::Display, iter::zip, process::Command, str::FromStr, string::ParseError, sync::Arc}; +use serde::{Serialize, Deserialize}; #[derive(Debug, PartialEq)] pub enum ToolbxError { ParseStatusError(String), + JSONSerializationError(String), CommandExecutionError(String), CommandUnsuccessfulError(String), } @@ -16,6 +18,9 @@ impl Display for ToolbxError { ToolbxError::CommandExecutionError(command_exec_error) => { write!(f, "{}", command_exec_error) } + ToolbxError::JSONSerializationError(msg) => { + write!(f, "{}", msg) + } ToolbxError::CommandUnsuccessfulError(command_unsuc_error) => { write!(f, "{}", command_unsuc_error) } @@ -61,6 +66,32 @@ pub struct ToolbxContainer { pub image: String, } +pub type PodmanInspectArray = Vec; + +#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct PodmanInspectInfo { + #[serde(rename = "Id")] + pub id: String, + #[serde(rename = "Created")] + pub created: String, + #[serde(rename = "State")] + pub state: PodManInspectState, + #[serde(rename = "Image")] + pub image: String, + #[serde(rename = "ImageName")] + pub image_name: String, + #[serde(rename = "Name")] + pub name: String, +} + +#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct PodManInspectState { + #[serde(rename = "Status")] + pub status: String, +} + impl ToolbxContainer { pub fn get_toolboxes() -> Vec { let output = run_cmd_toolbx_list_containers(); @@ -68,6 +99,40 @@ impl ToolbxContainer { parse_cmd_list_containers(output.as_str()) } + fn parse_status(output : &str) -> Result { + let result : Result = serde_json::from_str(output); + match result { + Ok(inspect_vec) => { + match inspect_vec.first() { + Some(info) => { + Ok(info.clone()) + } + None => { + Err(ToolbxError::JSONSerializationError("Inspect command returned empty vecotr.".to_string())) + } + } + } + Err(e) => { + Err(ToolbxError::JSONSerializationError(e.to_string())) + } + } + + } + + pub fn update_status(&mut self) -> Result<(), ToolbxError>{ + let output = Command::new("podman") + .arg("container") + .arg("inspect") + .arg(self.name.clone()) + .output() + .expect("Failed to execute command"); + + let output = String::from_utf8_lossy(&output.stdout).to_string(); + let inspect_result = ToolbxContainer::parse_status(output.as_str())?; + self.status = ToolbxStatus::from_str(inspect_result.state.status.as_str())?; + Ok(()) + } + pub fn stop(&mut self) -> Result<(), ToolbxError> { let output = Command::new("podman") .arg("stop") @@ -141,6 +206,24 @@ fn test_start_1non_existing_containter() { //tbx.stop(); } +#[test] +fn test_inspect_parsing() { + let podman_inspect = concat!( + "[{", + "\"Id\": \"ae05203091ab4cdf047a9aeba6af8a7bed8105f7f59d09a35d2b64c837ecac0d\",", + "\"Created\": \"2021-12-10T20:51:43.140418098+01:00\",", + "\"State\": {", + "\"Status\": \"running\"", + "},", + "\"Image\": \"ab8bc106d4a710a7a27c538762864610467b3559f80b413d30e0a1bfcfe272a5\",", + "\"ImageName\": \"registry.fedoraproject.org/fedora-toolbox:35\",", + "\"Name\": \"rust\"", + "}]" + ); + let inspect_info = ToolbxContainer::parse_status(podman_inspect).unwrap(); + assert_eq!("running", inspect_info.state.status); +} + #[test] fn test_start_non_existing_containter() { let mut tbx = ToolbxContainer { diff --git a/src/ui/app/update.rs b/src/ui/app/update.rs index 7502293..7fd8200 100644 --- a/src/ui/app/update.rs +++ b/src/ui/app/update.rs @@ -78,7 +78,8 @@ impl AppUpdate for AppModel { println!("{:?}", output); - // TODO: update status + // TODO: update status on worker and add refresh spinner in the meantime + toolbx_container.toolbx_container.update_status(); } } }