Skip to content

Commit 0c85b95

Browse files
authored
stop tunnel when executable gets deleted (microsoft#181505)
stop when executable gets deleted
1 parent 3d3e22e commit 0c85b95

File tree

3 files changed

+31
-13
lines changed

3 files changed

+31
-13
lines changed

cli/src/commands/tunnels.rs

Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -303,21 +303,23 @@ async fn serve_with_csa(
303303
log = log.tee(log_broadcast.clone());
304304
log::install_global_logger(log.clone()); // re-install so that library logs are captured
305305

306-
let shutdown = match gateway_args
307-
.parent_process_id
308-
.and_then(|p| Pid::from_str(&p).ok())
309-
{
310-
Some(pid) => ShutdownRequest::create_rx([
311-
ShutdownRequest::CtrlC,
312-
ShutdownRequest::ParentProcessKilled(pid),
313-
]),
314-
None => ShutdownRequest::create_rx([ShutdownRequest::CtrlC]),
315-
};
316-
317306
// Intentionally read before starting the server. If the server updated and
318307
// respawn is requested, the old binary will get renamed, and then
319308
// current_exe will point to the wrong path.
320309
let current_exe = std::env::current_exe().unwrap();
310+
311+
let mut vec = vec![
312+
ShutdownRequest::CtrlC,
313+
ShutdownRequest::ExeUninstalled(current_exe.to_owned()),
314+
];
315+
if let Some(p) = gateway_args
316+
.parent_process_id
317+
.and_then(|p| Pid::from_str(&p).ok())
318+
{
319+
vec.push(ShutdownRequest::ParentProcessKilled(p));
320+
}
321+
let shutdown = ShutdownRequest::create_rx(vec);
322+
321323
let server = loop {
322324
if shutdown.is_open() {
323325
return Ok(0);

cli/src/tunnels/shutdown_signal.rs

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,11 @@
44
*--------------------------------------------------------------------------------------------*/
55

66
use futures::{stream::FuturesUnordered, StreamExt};
7-
use std::fmt;
7+
use std::{fmt, path::PathBuf};
88
use sysinfo::Pid;
99

1010
use crate::util::{
11-
machine::wait_until_process_exits,
11+
machine::{wait_until_exe_deleted, wait_until_process_exits},
1212
sync::{new_barrier, Barrier, Receivable},
1313
};
1414

@@ -17,6 +17,7 @@ use crate::util::{
1717
pub enum ShutdownSignal {
1818
CtrlC,
1919
ParentProcessKilled(Pid),
20+
ExeUninstalled,
2021
ServiceStopped,
2122
RpcShutdownRequested,
2223
RpcRestartRequested,
@@ -29,6 +30,9 @@ impl fmt::Display for ShutdownSignal {
2930
ShutdownSignal::ParentProcessKilled(p) => {
3031
write!(f, "Parent process {} no longer exists", p)
3132
}
33+
ShutdownSignal::ExeUninstalled => {
34+
write!(f, "Executable no longer exists")
35+
}
3236
ShutdownSignal::ServiceStopped => write!(f, "Service stopped"),
3337
ShutdownSignal::RpcShutdownRequested => write!(f, "RPC client requested shutdown"),
3438
ShutdownSignal::RpcRestartRequested => {
@@ -41,6 +45,7 @@ impl fmt::Display for ShutdownSignal {
4145
pub enum ShutdownRequest {
4246
CtrlC,
4347
ParentProcessKilled(Pid),
48+
ExeUninstalled(PathBuf),
4449
Derived(Box<dyn Receivable<ShutdownSignal> + Send>),
4550
}
4651

@@ -56,6 +61,10 @@ impl ShutdownRequest {
5661
wait_until_process_exits(pid, 2000).await;
5762
Some(ShutdownSignal::ParentProcessKilled(pid))
5863
}
64+
ShutdownRequest::ExeUninstalled(exe_path) => {
65+
wait_until_exe_deleted(&exe_path, 2000).await;
66+
Some(ShutdownSignal::ExeUninstalled)
67+
}
5968
ShutdownRequest::Derived(mut rx) => rx.recv_msg().await,
6069
}
6170
}

cli/src/util/machine.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,3 +52,10 @@ pub fn find_running_process(name: &Path) -> Option<u32> {
5252
}
5353
None
5454
}
55+
56+
pub async fn wait_until_exe_deleted(current_exe: &Path, poll_ms: u64) {
57+
let duration = Duration::from_millis(poll_ms);
58+
while current_exe.exists() {
59+
tokio::time::sleep(duration).await;
60+
}
61+
}

0 commit comments

Comments
 (0)