feat(cli): add kill-session command (#745)
* feat: add kill-session command * style: apply formatting rules * feat: add new instruction for kill-session * feat: update feedback of kill-session * separation of command `kill-session` and `kill-all-sessions` function. * Add information to various situations * Add a question (yes or no) when executing the `kill-all-sessions` command. * chore: adjust clippy warning * fix warning wording * make rustfmt happy Co-authored-by: Aram Drevekenin <aram@poor.dev>
This commit is contained in:
parent
8415004834
commit
0ca5c18729
7 changed files with 102 additions and 2 deletions
61
src/main.rs
61
src/main.rs
|
|
@ -5,8 +5,8 @@ mod tests;
|
||||||
|
|
||||||
use crate::install::populate_data_dir;
|
use crate::install::populate_data_dir;
|
||||||
use sessions::{
|
use sessions::{
|
||||||
assert_session, assert_session_ne, get_active_session, get_sessions, list_sessions,
|
assert_session, assert_session_ne, get_active_session, get_sessions, kill_session,
|
||||||
print_sessions, session_exists, ActiveSession,
|
list_sessions, print_sessions, session_exists, ActiveSession,
|
||||||
};
|
};
|
||||||
use std::process;
|
use std::process;
|
||||||
use zellij_client::{os_input_output::get_client_os_input, start_client, ClientInfo};
|
use zellij_client::{os_input_output::get_client_os_input, start_client, ClientInfo};
|
||||||
|
|
@ -27,6 +27,63 @@ pub fn main() {
|
||||||
list_sessions();
|
list_sessions();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if let Some(Command::Sessions(Sessions::KillAllSessions { yes })) = opts.command {
|
||||||
|
match get_sessions() {
|
||||||
|
Ok(sessions) => {
|
||||||
|
if sessions.is_empty() {
|
||||||
|
println!("No active zellij sessions found.");
|
||||||
|
process::exit(1);
|
||||||
|
} else {
|
||||||
|
let kill_all_sessions = |sessions: Vec<std::string::String>| {
|
||||||
|
for session in sessions.iter() {
|
||||||
|
kill_session(session);
|
||||||
|
}
|
||||||
|
process::exit(0)
|
||||||
|
};
|
||||||
|
|
||||||
|
if yes {
|
||||||
|
kill_all_sessions(sessions);
|
||||||
|
} else {
|
||||||
|
use std::io::{stdin, stdout, Write};
|
||||||
|
|
||||||
|
let mut answer = String::new();
|
||||||
|
println!("WARNING: this action will kill all sessions.");
|
||||||
|
print!("Do you want to continue? [y/N] ");
|
||||||
|
let _ = stdout().flush();
|
||||||
|
stdin().read_line(&mut answer).unwrap();
|
||||||
|
|
||||||
|
match answer.as_str().trim() {
|
||||||
|
"y" | "Y" | "yes" | "Yes" => kill_all_sessions(sessions),
|
||||||
|
_ => {
|
||||||
|
println!("Abort.");
|
||||||
|
process::exit(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Err(e) => {
|
||||||
|
eprintln!("Error occured: {:?}", e);
|
||||||
|
process::exit(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Some(Command::Sessions(Sessions::KillSession { target_session })) = opts.command.clone()
|
||||||
|
{
|
||||||
|
match target_session.as_ref() {
|
||||||
|
Some(target_session) => {
|
||||||
|
assert_session(target_session);
|
||||||
|
kill_session(target_session);
|
||||||
|
process::exit(0);
|
||||||
|
}
|
||||||
|
None => {
|
||||||
|
println!("Please specify the session name to kill.");
|
||||||
|
process::exit(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
atomic_create_dir(&*ZELLIJ_TMP_DIR).unwrap();
|
atomic_create_dir(&*ZELLIJ_TMP_DIR).unwrap();
|
||||||
atomic_create_dir(&*ZELLIJ_TMP_LOG_DIR).unwrap();
|
atomic_create_dir(&*ZELLIJ_TMP_LOG_DIR).unwrap();
|
||||||
if let Some(path) = opts.server {
|
if let Some(path) = opts.server {
|
||||||
|
|
|
||||||
|
|
@ -84,6 +84,19 @@ pub(crate) fn get_active_session() -> ActiveSession {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub(crate) fn kill_session(name: &str) {
|
||||||
|
let path = &*ZELLIJ_SOCK_DIR.join(name);
|
||||||
|
match LocalSocketStream::connect(path) {
|
||||||
|
Ok(stream) => {
|
||||||
|
IpcSenderWithContext::new(stream).send(ClientToServerMsg::KillSession);
|
||||||
|
}
|
||||||
|
Err(e) => {
|
||||||
|
eprintln!("Error occured: {:?}", e);
|
||||||
|
process::exit(1);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
pub(crate) fn list_sessions() {
|
pub(crate) fn list_sessions() {
|
||||||
let exit_code = match get_sessions() {
|
let exit_code = match get_sessions() {
|
||||||
Ok(sessions) => {
|
Ok(sessions) => {
|
||||||
|
|
|
||||||
|
|
@ -65,6 +65,7 @@ pub(crate) enum ServerInstruction {
|
||||||
ClientExit(ClientId),
|
ClientExit(ClientId),
|
||||||
RemoveClient(ClientId),
|
RemoveClient(ClientId),
|
||||||
Error(String),
|
Error(String),
|
||||||
|
KillSession,
|
||||||
DetachSession(ClientId),
|
DetachSession(ClientId),
|
||||||
AttachClient(ClientAttributes, Options, ClientId),
|
AttachClient(ClientAttributes, Options, ClientId),
|
||||||
}
|
}
|
||||||
|
|
@ -78,6 +79,7 @@ impl From<&ServerInstruction> for ServerContext {
|
||||||
ServerInstruction::ClientExit(..) => ServerContext::ClientExit,
|
ServerInstruction::ClientExit(..) => ServerContext::ClientExit,
|
||||||
ServerInstruction::RemoveClient(..) => ServerContext::RemoveClient,
|
ServerInstruction::RemoveClient(..) => ServerContext::RemoveClient,
|
||||||
ServerInstruction::Error(_) => ServerContext::Error,
|
ServerInstruction::Error(_) => ServerContext::Error,
|
||||||
|
ServerInstruction::KillSession => ServerContext::KillSession,
|
||||||
ServerInstruction::DetachSession(..) => ServerContext::DetachSession,
|
ServerInstruction::DetachSession(..) => ServerContext::DetachSession,
|
||||||
ServerInstruction::AttachClient(..) => ServerContext::AttachClient,
|
ServerInstruction::AttachClient(..) => ServerContext::AttachClient,
|
||||||
}
|
}
|
||||||
|
|
@ -400,6 +402,14 @@ pub fn start_server(mut os_input: Box<dyn ServerOsApi>, socket_path: PathBuf) {
|
||||||
.unwrap();
|
.unwrap();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
ServerInstruction::KillSession => {
|
||||||
|
let client_ids = session_state.read().unwrap().client_ids();
|
||||||
|
for client_id in client_ids {
|
||||||
|
os_input.send_to_client(client_id, ServerToClientMsg::Exit(ExitReason::Normal));
|
||||||
|
remove_client!(client_id, os_input, session_state);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
ServerInstruction::DetachSession(client_id) => {
|
ServerInstruction::DetachSession(client_id) => {
|
||||||
os_input.send_to_client(client_id, ServerToClientMsg::Exit(ExitReason::Normal));
|
os_input.send_to_client(client_id, ServerToClientMsg::Exit(ExitReason::Normal));
|
||||||
remove_client!(client_id, os_input, session_state);
|
remove_client!(client_id, os_input, session_state);
|
||||||
|
|
|
||||||
|
|
@ -358,6 +358,9 @@ pub(crate) fn route_thread_main(
|
||||||
let _ = to_server.send(ServerInstruction::RemoveClient(client_id));
|
let _ = to_server.send(ServerInstruction::RemoveClient(client_id));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
ClientToServerMsg::KillSession => {
|
||||||
|
to_server.send(ServerInstruction::KillSession).unwrap();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -89,4 +89,19 @@ pub enum Sessions {
|
||||||
#[structopt(subcommand, name = "options")]
|
#[structopt(subcommand, name = "options")]
|
||||||
options: Option<SessionCommand>,
|
options: Option<SessionCommand>,
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/// Kill the specific session
|
||||||
|
#[structopt(alias = "k")]
|
||||||
|
KillSession {
|
||||||
|
/// Name of target session
|
||||||
|
target_session: Option<String>,
|
||||||
|
},
|
||||||
|
|
||||||
|
/// Kill all sessions
|
||||||
|
#[structopt(alias = "ka")]
|
||||||
|
KillAllSessions {
|
||||||
|
/// Automatic yes to prompts
|
||||||
|
#[structopt(short, long)]
|
||||||
|
yes: bool,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -304,6 +304,7 @@ pub enum ServerContext {
|
||||||
ClientExit,
|
ClientExit,
|
||||||
RemoveClient,
|
RemoveClient,
|
||||||
Error,
|
Error,
|
||||||
|
KillSession,
|
||||||
DetachSession,
|
DetachSession,
|
||||||
AttachClient,
|
AttachClient,
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -68,6 +68,7 @@ pub enum ClientToServerMsg {
|
||||||
AttachClient(ClientAttributes, Options),
|
AttachClient(ClientAttributes, Options),
|
||||||
Action(Action),
|
Action(Action),
|
||||||
ClientExited,
|
ClientExited,
|
||||||
|
KillSession,
|
||||||
}
|
}
|
||||||
|
|
||||||
// Types of messages sent from the server to the client
|
// Types of messages sent from the server to the client
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue