2025-02-20 22:18:14 +01:00
|
|
|
/*
|
|
|
|
|
* SPDX-FileCopyrightText: 2025 April Faye John <april.john@denic.de> & Contributors
|
2025-02-20 14:04:16 +01:00
|
|
|
* SPDX-License-Identifier: AGPL-3.0-or-later
|
|
|
|
|
*/
|
|
|
|
|
|
2025-02-20 22:18:14 +01:00
|
|
|
use crate::PMAN_SENDER;
|
|
|
|
|
use anyhow::{Ok, Result};
|
|
|
|
|
use tokio::process::{Child, Command};
|
|
|
|
|
use std::sync::{Arc, Mutex};
|
|
|
|
|
use log::{debug, info};
|
|
|
|
|
use tokio::sync::mpsc;use tokio::sync::mpsc::Receiver;
|
2025-02-20 14:04:16 +01:00
|
|
|
|
2025-02-20 22:18:14 +01:00
|
|
|
pub fn init_process_manager() -> Result<()> {
|
|
|
|
|
let (tx, mut rx) = mpsc::channel::<ProcessCommand>(32);
|
|
|
|
|
let mut process_manager = ProcessManager::default();
|
|
|
|
|
let _ = PMAN_SENDER.set(tx);
|
|
|
|
|
debug!("[pman-main] Spawning pman task");
|
|
|
|
|
|
|
|
|
|
tokio::spawn(async move {
|
|
|
|
|
info!("[pman-task] Hello from Pman");
|
|
|
|
|
while process_manager.lifecycle(&mut rx).await.is_ok() {
|
|
|
|
|
let result = process_manager.alive_check().await;
|
|
|
|
|
if let Err(e) = result {
|
|
|
|
|
println!("{}", e);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
Ok(())
|
2025-02-20 14:04:16 +01:00
|
|
|
}
|
|
|
|
|
|
2025-02-20 22:18:14 +01:00
|
|
|
#[derive(Debug)]
|
2025-02-20 14:04:16 +01:00
|
|
|
pub struct ProcessManager {
|
2025-02-20 22:18:14 +01:00
|
|
|
processes: Vec<Child>,
|
2025-02-20 14:04:16 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
impl Default for ProcessManager {
|
|
|
|
|
fn default() -> ProcessManager {
|
|
|
|
|
ProcessManager {
|
|
|
|
|
processes: Vec::new(),
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2025-02-20 22:18:14 +01:00
|
|
|
#[derive(Debug)]
|
|
|
|
|
pub enum ProcessCommand {
|
|
|
|
|
SpawnShellCmd { cmd: String },
|
|
|
|
|
Shutdown,
|
|
|
|
|
}
|
|
|
|
|
|
2025-02-20 14:04:16 +01:00
|
|
|
impl ProcessManager {
|
2025-02-20 22:18:14 +01:00
|
|
|
fn spawn_shell_command(&mut self, command: String) {
|
2025-02-20 14:04:16 +01:00
|
|
|
if cfg!(target_os = "windows") {
|
|
|
|
|
return self.spawn_cmd_command(command);
|
2025-02-20 22:18:14 +01:00
|
|
|
} else if cfg!(target_os = "macos") || cfg!(target_os = "ios") {
|
|
|
|
|
// TODO: reasearch if ios also has zsh
|
2025-02-20 14:04:16 +01:00
|
|
|
return self.spawn_zsh_command(command);
|
|
|
|
|
} else {
|
|
|
|
|
return self.spawn_bash_command(command);
|
|
|
|
|
}
|
|
|
|
|
}
|
2025-02-20 22:18:14 +01:00
|
|
|
fn spawn_bash_command(&mut self, command: String) {
|
|
|
|
|
let cmd = Command::new("bash")
|
|
|
|
|
.arg("-c")
|
|
|
|
|
.arg(command)
|
|
|
|
|
.spawn().unwrap();
|
|
|
|
|
self.processes.push(cmd);
|
2025-02-20 14:04:16 +01:00
|
|
|
}
|
2025-02-20 22:18:14 +01:00
|
|
|
fn spawn_cmd_command(&mut self, command: String) {}
|
|
|
|
|
fn spawn_zsh_command(&mut self, command: String) {}
|
|
|
|
|
pub async fn lifecycle(&mut self, rx: &mut Receiver<ProcessCommand>) -> Result<()> {
|
|
|
|
|
let opt = rx.recv().await;
|
|
|
|
|
if let Some(message) = opt {
|
|
|
|
|
match message {
|
|
|
|
|
ProcessCommand::SpawnShellCmd { cmd } => {}
|
|
|
|
|
ProcessCommand::Shutdown => {
|
|
|
|
|
info!("Close command");
|
|
|
|
|
anyhow::bail!("Close command");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
anyhow::bail!("Channel closed");
|
|
|
|
|
}
|
|
|
|
|
Ok(())
|
2025-02-20 14:04:16 +01:00
|
|
|
}
|
2025-02-20 22:18:14 +01:00
|
|
|
async fn alive_check(&mut self) -> Result<()> {
|
|
|
|
|
for process in &mut self.processes {
|
|
|
|
|
process.stdout
|
|
|
|
|
}
|
|
|
|
|
Ok(())
|
2025-02-20 14:04:16 +01:00
|
|
|
}
|
|
|
|
|
}
|