Add automatic daemon startup feature to client
- Client now checks if daemon is running and starts it if needed - Finds daemon binary based on client executable location - Waits for daemon to start up before continuing - Also implements proper handling of --shutdown flag - Improves user experience by removing need to manually start daemonmain
parent
39d7302a4e
commit
16720f5ad2
|
|
@ -3,7 +3,7 @@
|
||||||
//! This is the client component of the Cypraea shell. It connects to the daemon,
|
//! This is the client component of the Cypraea shell. It connects to the daemon,
|
||||||
//! sends commands, and displays output to the user.
|
//! sends commands, and displays output to the user.
|
||||||
|
|
||||||
use anyhow::{Context, Result};
|
use anyhow::{anyhow, Context, Result};
|
||||||
use clap::Parser;
|
use clap::Parser;
|
||||||
use cypraea_common::paths;
|
use cypraea_common::paths;
|
||||||
use cypraea_common::protocol::{ClientMessage, DaemonMessage};
|
use cypraea_common::protocol::{ClientMessage, DaemonMessage};
|
||||||
|
|
@ -66,12 +66,72 @@ async fn main() -> Result<()> {
|
||||||
.to_string(),
|
.to_string(),
|
||||||
};
|
};
|
||||||
|
|
||||||
// Connect to the daemon
|
// Handle shutdown request if specified
|
||||||
let stream = UnixStream::connect(&socket_path)
|
if args.shutdown {
|
||||||
.await
|
// First try to connect to the daemon
|
||||||
.context("Failed to connect to daemon")?;
|
match UnixStream::connect(&socket_path).await {
|
||||||
|
Ok(stream) => {
|
||||||
|
info!("Connected to daemon at {}", socket_path);
|
||||||
|
|
||||||
|
// Send the shutdown message
|
||||||
|
let mut writer = tokio::io::BufWriter::new(stream);
|
||||||
|
let shutdown_msg = ClientMessage::Shutdown;
|
||||||
|
send_message(&mut writer, &shutdown_msg).await
|
||||||
|
.context("Failed to send shutdown message")?;
|
||||||
|
|
||||||
|
println!("Daemon shutdown requested");
|
||||||
|
return Ok(());
|
||||||
|
},
|
||||||
|
Err(_) => {
|
||||||
|
println!("No daemon running at {}", socket_path);
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
info!("Connected to daemon at {}", socket_path);
|
// Try to connect to the daemon
|
||||||
|
let stream = match UnixStream::connect(&socket_path).await {
|
||||||
|
Ok(stream) => {
|
||||||
|
info!("Connected to daemon at {}", socket_path);
|
||||||
|
stream
|
||||||
|
},
|
||||||
|
Err(_e) => {
|
||||||
|
// Daemon not running, try to start it
|
||||||
|
info!("Daemon not running, attempting to start it");
|
||||||
|
|
||||||
|
// Find the daemon binary (should be in the same directory as the client)
|
||||||
|
let current_exe = std::env::current_exe()
|
||||||
|
.context("Failed to get current executable path")?;
|
||||||
|
let daemon_dir = current_exe.parent()
|
||||||
|
.context("Failed to get parent directory of current executable")?;
|
||||||
|
let daemon_path = daemon_dir.join("cypraeadd");
|
||||||
|
|
||||||
|
if !daemon_path.exists() {
|
||||||
|
return Err(anyhow!("Daemon binary not found at {}", daemon_path.display()));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Start the daemon process
|
||||||
|
let _daemon_process = tokio::process::Command::new(&daemon_path)
|
||||||
|
.stdout(std::process::Stdio::null())
|
||||||
|
.stderr(std::process::Stdio::null())
|
||||||
|
.spawn()
|
||||||
|
.context("Failed to start daemon process")?;
|
||||||
|
|
||||||
|
// Give the daemon a moment to start up
|
||||||
|
tokio::time::sleep(tokio::time::Duration::from_millis(500)).await;
|
||||||
|
|
||||||
|
// Try to connect again
|
||||||
|
match UnixStream::connect(&socket_path).await {
|
||||||
|
Ok(stream) => {
|
||||||
|
info!("Successfully connected to newly started daemon");
|
||||||
|
stream
|
||||||
|
},
|
||||||
|
Err(e) => {
|
||||||
|
return Err(anyhow!("Failed to connect to daemon after starting it: {}", e));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
// Split the stream into reader and writer
|
// Split the stream into reader and writer
|
||||||
let (reader, writer) = tokio::io::split(stream);
|
let (reader, writer) = tokio::io::split(stream);
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue