From 8b3ca5cad3e15adf590cc62a93800539c1f85e1a Mon Sep 17 00:00:00 2001 From: Hannes Kuchelmeister Date: Thu, 30 May 2024 18:45:50 +0200 Subject: [PATCH] add stopping and starting function for toolboxes --- src/factories/container_list.rs | 51 ++++++++++++-- src/util/toolbox.rs | 114 ++++++++++++++++---------------- 2 files changed, 102 insertions(+), 63 deletions(-) diff --git a/src/factories/container_list.rs b/src/factories/container_list.rs index b752987..7605822 100644 --- a/src/factories/container_list.rs +++ b/src/factories/container_list.rs @@ -1,3 +1,5 @@ +use crate::util::toolbox::start_toolbox_container; +use crate::util::toolbox::stop_toolbox_container; use gtk::prelude::ButtonExt; use relm4::adw; use relm4::adw::prelude::ActionRowExt; @@ -6,11 +8,11 @@ use relm4::factory::{FactoryComponent, FactorySender}; use relm4::gtk; use relm4::gtk::prelude::WidgetExt; use relm4_icons::icon_names; - #[derive(Debug, PartialEq)] pub enum ContainerStatus { Running, NotRunning, + Refreshing, } #[derive(Debug)] @@ -27,6 +29,12 @@ pub enum ContainerMsg { OpenTerminal, } +#[derive(Debug)] +pub enum CommandMessage { + SetStarted, + SetStopped, +} + pub struct ContainerInit { pub name: String, pub status: ContainerStatus, @@ -37,7 +45,7 @@ impl FactoryComponent for Container { type Init = ContainerInit; type Input = ContainerMsg; type Output = (); - type CommandOutput = (); + type CommandOutput = CommandMessage; type Widgets = ContainerWidgets; type ParentWidget = gtk::ListBox; type Index = String; @@ -53,6 +61,18 @@ impl FactoryComponent for Container { gtk::AspectFrame{ set_ratio: 1.0, gtk::Box{ + gtk::Button { + #[watch] + set_visible: self.status == ContainerStatus::Refreshing, + #[wrap(Some)] + set_child = >k::Spinner { + #[watch] + set_spinning: self.status == ContainerStatus::Refreshing, + }, + set_margin_top: 10, + set_margin_bottom: 10, + set_css_classes: &["circular"], + }, gtk::Button { #[watch] set_visible: self.status == ContainerStatus::NotRunning, @@ -105,11 +125,32 @@ impl FactoryComponent for Container { } } - fn update(&mut self, msg: Self::Input, _sender: FactorySender) { + fn update(&mut self, msg: Self::Input, sender: FactorySender) { match msg { - ContainerMsg::Start => {} - ContainerMsg::Stop => {} + ContainerMsg::Start => { + self.status = ContainerStatus::Refreshing; + let hash = (&self.hash).clone(); + sender.spawn_oneshot_command(move || match start_toolbox_container(&hash) { + Ok(_) => CommandMessage::SetStarted, + Err(_) => CommandMessage::SetStopped, + }); + } + ContainerMsg::Stop => { + self.status = ContainerStatus::Refreshing; + let hash = (&self.hash).clone(); + sender.spawn_oneshot_command(move || match stop_toolbox_container(&hash) { + Ok(_) => CommandMessage::SetStopped, + Err(_) => CommandMessage::SetStarted, + }); + } ContainerMsg::OpenTerminal => {} } } + + fn update_cmd(&mut self, message: Self::CommandOutput, sender: FactorySender) { + match message { + CommandMessage::SetStarted => self.status = ContainerStatus::Running, + CommandMessage::SetStopped => self.status = ContainerStatus::NotRunning, + }; + } } diff --git a/src/util/toolbox.rs b/src/util/toolbox.rs index 7d939ba..78e42c4 100644 --- a/src/util/toolbox.rs +++ b/src/util/toolbox.rs @@ -147,71 +147,69 @@ impl ToolbxContainer { self.status = ToolbxStatus::from_str(inspect_result.state.status.as_str())?; Ok(()) } +} - pub fn stop(&mut self) -> Result<(), ToolbxError> { - let output = Command::new("flatpak-spawn") - .arg("--host") //Command::new("podman") - .arg("podman") - .arg("stop") - .arg(self.name.clone()) - .output(); +pub fn stop_toolbox_container(hash: &str) -> Result<(), ToolbxError> { + let output = Command::new("flatpak-spawn") + .arg("--host") //Command::new("podman") + .arg("podman") + .arg("stop") + .arg(hash) + .output(); - if output.is_err() { - return Err(ToolbxError::CommandExecutionError( - output.unwrap_err().to_string(), - )); - } - let output = output.unwrap(); - - // Success: Output { status: ExitStatus(unix_wait_status(0)), stdout: "tbx_name\n", stderr: "" } - //Fail: - // Output { - // status: ExitStatus(unix_wait_status(32000)), - // stdout: "", - // stderr: "Error: no container with name or ID \"tbx_name\" found: no such container\n" - // } - - if output.status.code() == Some(0) { - self.status = ToolbxStatus::Exited; - Ok(()) - } else { - Err(ToolbxError::CommandUnsuccessfulError( - String::from_utf8_lossy(&output.stderr).into_owned(), - )) - } + if output.is_err() { + return Err(ToolbxError::CommandExecutionError( + output.unwrap_err().to_string(), + )); } + let output = output.unwrap(); - pub fn start(&mut self) -> Result<(), ToolbxError> { - let output = Command::new("flatpak-spawn") - .arg("--host") //Command::new("podman") - .arg("podman") - .arg("start") - .arg(self.name.clone()) - .output(); + // Success: Output { status: ExitStatus(unix_wait_status(0)), stdout: "tbx_name\n", stderr: "" } + //Fail: + // Output { + // status: ExitStatus(unix_wait_status(32000)), + // stdout: "", + // stderr: "Error: no container with name or ID \"tbx_name\" found: no such container\n" + // } - if output.is_err() { - return Err(ToolbxError::CommandExecutionError( - output.unwrap_err().to_string(), - )); - } - let output = output.unwrap(); + if output.status.code() == Some(0) { + Ok(()) + } else { + Err(ToolbxError::CommandUnsuccessfulError( + String::from_utf8_lossy(&output.stderr).into_owned(), + )) + } +} - // Success: status: Output { ExitStatus(unix_wait_status(0)), stdout: "tbx_name\n", stderr: "" } - // Fail: status: - // Output { - // status: ExitStatus(unix_wait_status(32000)), - // stdout: "", - // stderr: "Error: no container with name or ID \"tbx_name\" found: no such container\n" - // } +pub fn start_toolbox_container(hash: &str) -> Result<(), ToolbxError> { + let output = Command::new("flatpak-spawn") + .arg("--host") //Command::new("podman") + .arg("podman") + .arg("start") + .arg(hash) + .output(); - if output.status.code() == Some(0) { - self.status = ToolbxStatus::Running; - Ok(()) - } else { - Err(ToolbxError::CommandUnsuccessfulError( - String::from_utf8_lossy(&output.stderr).into_owned(), - )) - } + if output.is_err() { + return Err(ToolbxError::CommandExecutionError( + output.unwrap_err().to_string(), + )); + } + let output = output.unwrap(); + + // Success: status: Output { ExitStatus(unix_wait_status(0)), stdout: "tbx_name\n", stderr: "" } + // Fail: status: + // Output { + // status: ExitStatus(unix_wait_status(32000)), + // stdout: "", + // stderr: "Error: no container with name or ID \"tbx_name\" found: no such container\n" + // } + + if output.status.code() == Some(0) { + Ok(()) + } else { + Err(ToolbxError::CommandUnsuccessfulError( + String::from_utf8_lossy(&output.stderr).into_owned(), + )) } }