add stopping and starting function for toolboxes

This commit is contained in:
2024-05-30 18:45:50 +02:00
parent d98f27229d
commit 8b3ca5cad3
2 changed files with 102 additions and 63 deletions

View File

@@ -1,3 +1,5 @@
use crate::util::toolbox::start_toolbox_container;
use crate::util::toolbox::stop_toolbox_container;
use gtk::prelude::ButtonExt; use gtk::prelude::ButtonExt;
use relm4::adw; use relm4::adw;
use relm4::adw::prelude::ActionRowExt; use relm4::adw::prelude::ActionRowExt;
@@ -6,11 +8,11 @@ use relm4::factory::{FactoryComponent, FactorySender};
use relm4::gtk; use relm4::gtk;
use relm4::gtk::prelude::WidgetExt; use relm4::gtk::prelude::WidgetExt;
use relm4_icons::icon_names; use relm4_icons::icon_names;
#[derive(Debug, PartialEq)] #[derive(Debug, PartialEq)]
pub enum ContainerStatus { pub enum ContainerStatus {
Running, Running,
NotRunning, NotRunning,
Refreshing,
} }
#[derive(Debug)] #[derive(Debug)]
@@ -27,6 +29,12 @@ pub enum ContainerMsg {
OpenTerminal, OpenTerminal,
} }
#[derive(Debug)]
pub enum CommandMessage {
SetStarted,
SetStopped,
}
pub struct ContainerInit { pub struct ContainerInit {
pub name: String, pub name: String,
pub status: ContainerStatus, pub status: ContainerStatus,
@@ -37,7 +45,7 @@ impl FactoryComponent for Container {
type Init = ContainerInit; type Init = ContainerInit;
type Input = ContainerMsg; type Input = ContainerMsg;
type Output = (); type Output = ();
type CommandOutput = (); type CommandOutput = CommandMessage;
type Widgets = ContainerWidgets; type Widgets = ContainerWidgets;
type ParentWidget = gtk::ListBox; type ParentWidget = gtk::ListBox;
type Index = String; type Index = String;
@@ -53,6 +61,18 @@ impl FactoryComponent for Container {
gtk::AspectFrame{ gtk::AspectFrame{
set_ratio: 1.0, set_ratio: 1.0,
gtk::Box{ gtk::Box{
gtk::Button {
#[watch]
set_visible: self.status == ContainerStatus::Refreshing,
#[wrap(Some)]
set_child = &gtk::Spinner {
#[watch]
set_spinning: self.status == ContainerStatus::Refreshing,
},
set_margin_top: 10,
set_margin_bottom: 10,
set_css_classes: &["circular"],
},
gtk::Button { gtk::Button {
#[watch] #[watch]
set_visible: self.status == ContainerStatus::NotRunning, set_visible: self.status == ContainerStatus::NotRunning,
@@ -105,11 +125,32 @@ impl FactoryComponent for Container {
} }
} }
fn update(&mut self, msg: Self::Input, _sender: FactorySender<Self>) { fn update(&mut self, msg: Self::Input, sender: FactorySender<Self>) {
match msg { match msg {
ContainerMsg::Start => {} ContainerMsg::Start => {
ContainerMsg::Stop => {} 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 => {} ContainerMsg::OpenTerminal => {}
} }
} }
fn update_cmd(&mut self, message: Self::CommandOutput, sender: FactorySender<Self>) {
match message {
CommandMessage::SetStarted => self.status = ContainerStatus::Running,
CommandMessage::SetStopped => self.status = ContainerStatus::NotRunning,
};
}
} }

View File

@@ -147,71 +147,69 @@ impl ToolbxContainer {
self.status = ToolbxStatus::from_str(inspect_result.state.status.as_str())?; self.status = ToolbxStatus::from_str(inspect_result.state.status.as_str())?;
Ok(()) Ok(())
} }
}
pub fn stop(&mut self) -> Result<(), ToolbxError> { pub fn stop_toolbox_container(hash: &str) -> Result<(), ToolbxError> {
let output = Command::new("flatpak-spawn") let output = Command::new("flatpak-spawn")
.arg("--host") //Command::new("podman") .arg("--host") //Command::new("podman")
.arg("podman") .arg("podman")
.arg("stop") .arg("stop")
.arg(self.name.clone()) .arg(hash)
.output(); .output();
if output.is_err() { if output.is_err() {
return Err(ToolbxError::CommandExecutionError( return Err(ToolbxError::CommandExecutionError(
output.unwrap_err().to_string(), 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(),
))
}
} }
let output = output.unwrap();
pub fn start(&mut self) -> Result<(), ToolbxError> { // Success: Output { status: ExitStatus(unix_wait_status(0)), stdout: "tbx_name\n", stderr: "" }
let output = Command::new("flatpak-spawn") //Fail:
.arg("--host") //Command::new("podman") // Output {
.arg("podman") // status: ExitStatus(unix_wait_status(32000)),
.arg("start") // stdout: "",
.arg(self.name.clone()) // stderr: "Error: no container with name or ID \"tbx_name\" found: no such container\n"
.output(); // }
if output.is_err() { if output.status.code() == Some(0) {
return Err(ToolbxError::CommandExecutionError( Ok(())
output.unwrap_err().to_string(), } else {
)); Err(ToolbxError::CommandUnsuccessfulError(
} String::from_utf8_lossy(&output.stderr).into_owned(),
let output = output.unwrap(); ))
}
}
// Success: status: Output { ExitStatus(unix_wait_status(0)), stdout: "tbx_name\n", stderr: "" } pub fn start_toolbox_container(hash: &str) -> Result<(), ToolbxError> {
// Fail: status: let output = Command::new("flatpak-spawn")
// Output { .arg("--host") //Command::new("podman")
// status: ExitStatus(unix_wait_status(32000)), .arg("podman")
// stdout: "", .arg("start")
// stderr: "Error: no container with name or ID \"tbx_name\" found: no such container\n" .arg(hash)
// } .output();
if output.status.code() == Some(0) { if output.is_err() {
self.status = ToolbxStatus::Running; return Err(ToolbxError::CommandExecutionError(
Ok(()) output.unwrap_err().to_string(),
} else { ));
Err(ToolbxError::CommandUnsuccessfulError( }
String::from_utf8_lossy(&output.stderr).into_owned(), 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(),
))
} }
} }