From a111ea94bcbf4f0df31887b08e839deb06e3c5ba Mon Sep 17 00:00:00 2001 From: philip Date: Thu, 30 Mar 2023 14:26:04 +0200 Subject: [PATCH] feat(rust): handle ctrlc signal on foreground nodes --- Cargo.lock | 84 +++++++++++-------- .../rust/ockam/ockam_command/Cargo.toml | 1 + .../ockam/ockam_command/src/node/create.rs | 65 ++++++++------ 3 files changed, 88 insertions(+), 62 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 85d212ba922..fc7fe9d27c2 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -176,7 +176,7 @@ checksum = "0e97ce7de6cf12de5d7226c73f5ba9811622f4db3a5b91b55c53e987e5f91cba" dependencies = [ "proc-macro2", "quote", - "syn 2.0.11", + "syn 2.0.13", ] [[package]] @@ -187,7 +187,7 @@ checksum = "b9ccdd8f2a161be9bd5c023df56f1b2a0bd1d83872ae53b71a84a12c9bf6e842" dependencies = [ "proc-macro2", "quote", - "syn 2.0.11", + "syn 2.0.13", ] [[package]] @@ -961,7 +961,7 @@ dependencies = [ "heck 0.4.1", "proc-macro2", "quote", - "syn 2.0.11", + "syn 2.0.13", ] [[package]] @@ -1389,6 +1389,16 @@ dependencies = [ "cipher", ] +[[package]] +name = "ctrlc" +version = "3.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbcf33c2a618cbe41ee43ae6e9f2e48368cd9f9db2896f10167d8d762679f639" +dependencies = [ + "nix", + "windows-sys 0.45.0", +] + [[package]] name = "curve25519-dalek" version = "3.2.0" @@ -1834,22 +1844,22 @@ checksum = "c34f04666d835ff5d62e058c3995147c06f42fe86ff053337632bca83e42702d" [[package]] name = "enumflags2" -version = "0.7.5" +version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e75d4cd21b95383444831539909fbb14b9dc3fdceb2a6f5d36577329a1f55ccb" +checksum = "0044ebdf7fbb2a772e0c0233a9d3173c5cd8af8ae7078d4c5188af44ffffaa4b" dependencies = [ "enumflags2_derive", ] [[package]] name = "enumflags2_derive" -version = "0.7.4" +version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f58dc3c5e468259f19f2d46304a6b28f1c3d034442e14b322d2b850e36f6d5ae" +checksum = "9d2c772ccdbdfd1967b4f5d79d17c98ebf92009fdcc838db7aa434462f600c26" dependencies = [ "proc-macro2", "quote", - "syn 1.0.109", + "syn 2.0.13", ] [[package]] @@ -1957,12 +1967,12 @@ dependencies = [ [[package]] name = "fd-lock" -version = "3.0.10" +version = "3.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ef1a30ae415c3a691a4f41afddc2dbcd6d70baf338368d85ebc1e8ed92cedb9" +checksum = "9799aefb4a2e4a01cc47610b1dd47c18ab13d991f27bbcaed9296f5a53d5cbad" dependencies = [ "cfg-if", - "rustix 0.36.11", + "rustix 0.37.6", "windows-sys 0.45.0", ] @@ -2148,7 +2158,7 @@ checksum = "89ca545a94061b6365f2c7355b4b32bd20df3ff95f02da9329b34ccc3bd6ee72" dependencies = [ "proc-macro2", "quote", - "syn 2.0.11", + "syn 2.0.13", ] [[package]] @@ -2604,7 +2614,7 @@ checksum = "256017f749ab3117e93acb91063009e1f1bb56d03965b14c2c8df4eb02c524d8" dependencies = [ "hermit-abi 0.3.1", "io-lifetimes", - "rustix 0.37.4", + "rustix 0.37.6", "windows-sys 0.45.0", ] @@ -2736,9 +2746,9 @@ checksum = "f051f77a7c8e6957c0696eac88f26b0117e54f52d3fc682ab19397a8812846a4" [[package]] name = "linux-raw-sys" -version = "0.3.0" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd550e73688e6d578f0ac2119e32b797a327631a42f9433e59d02e139c8df60d" +checksum = "d59d8c75012853d2e872fb56bc8a2e53718e2cafe1a4c823143141c6d90c322f" [[package]] name = "lmdb-rkv" @@ -3305,6 +3315,7 @@ dependencies = [ "console", "const-str", "crossbeam-channel", + "ctrlc", "dialoguer", "directories", "dirs", @@ -3674,9 +3685,9 @@ dependencies = [ [[package]] name = "openssl" -version = "0.10.48" +version = "0.10.49" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "518915b97df115dd36109bfa429a48b8f737bd05508cf9588977b599648926d2" +checksum = "4d2f106ab837a24e03672c59b1239669a0596406ff657c3c0835b6b7f0f35a33" dependencies = [ "bitflags 1.3.2", "cfg-if", @@ -3689,13 +3700,13 @@ dependencies = [ [[package]] name = "openssl-macros" -version = "0.1.0" +version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b501e44f11665960c7e7fcf062c7d96a14ade4aa98116c004b2e37b5be7d736c" +checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" dependencies = [ "proc-macro2", "quote", - "syn 1.0.109", + "syn 2.0.13", ] [[package]] @@ -3706,11 +3717,10 @@ checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" [[package]] name = "openssl-sys" -version = "0.9.83" +version = "0.9.84" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "666416d899cf077260dac8698d60a60b435a46d57e82acb1be3d0dad87284e5b" +checksum = "3a20eace9dc2d82904039cb76dcf50fb1a0bba071cfd1629720b5d6f1ddba0fa" dependencies = [ - "autocfg", "cc", "libc", "pkg-config", @@ -3999,9 +4009,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.54" +version = "1.0.55" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e472a104799c74b514a57226160104aa483546de37e839ec50e3c2e41dd87534" +checksum = "1d0dd4be24fcdcfeaa12a432d588dc59bbad6cad3510c67e74a2b6b2fc950564" dependencies = [ "unicode-ident", ] @@ -4351,15 +4361,15 @@ dependencies = [ [[package]] name = "rustix" -version = "0.37.4" +version = "0.37.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c348b5dc624ecee40108aa2922fed8bad89d7fcc2b9f8cb18f632898ac4a37f9" +checksum = "d097081ed288dfe45699b72f5b5d648e5f15d64d900c7080273baa20c16a6849" dependencies = [ "bitflags 1.3.2", "errno 0.3.0", "io-lifetimes", "libc", - "linux-raw-sys 0.3.0", + "linux-raw-sys 0.3.1", "windows-sys 0.45.0", ] @@ -4625,7 +4635,7 @@ checksum = "4c614d17805b093df4b147b51339e7e44bf05ef59fba1e45d83500bcfb4d8585" dependencies = [ "proc-macro2", "quote", - "syn 2.0.11", + "syn 2.0.13", ] [[package]] @@ -5019,9 +5029,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.11" +version = "2.0.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "21e3787bb71465627110e7d87ed4faaa36c1f61042ee67badb9e2ef173accc40" +checksum = "4c9da457c5285ac1f936ebd076af6dac17a61cfe7826f2076b4d015cf47bc8ec" dependencies = [ "proc-macro2", "quote", @@ -5095,7 +5105,7 @@ dependencies = [ "cfg-if", "fastrand", "redox_syscall 0.3.5", - "rustix 0.37.4", + "rustix 0.37.6", "windows-sys 0.45.0", ] @@ -5164,7 +5174,7 @@ checksum = "f9456a42c5b0d803c8cd86e73dd7cc9edd429499f37a3550d286d5e86720569f" dependencies = [ "proc-macro2", "quote", - "syn 2.0.11", + "syn 2.0.13", ] [[package]] @@ -5257,7 +5267,7 @@ checksum = "61a573bdc87985e9d6ddeed1b3d864e8a302c847e40d647746df2f1de209d1ce" dependencies = [ "proc-macro2", "quote", - "syn 2.0.11", + "syn 2.0.13", ] [[package]] @@ -5997,11 +6007,11 @@ dependencies = [ [[package]] name = "zeroize_derive" -version = "1.4.1" +version = "1.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25588073e5216b50bca71d61cb8595cdb9745e87032a58c199730def2862c934" +checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69" dependencies = [ "proc-macro2", "quote", - "syn 2.0.11", + "syn 2.0.13", ] diff --git a/implementations/rust/ockam/ockam_command/Cargo.toml b/implementations/rust/ockam/ockam_command/Cargo.toml index 31aa0170fd1..9e2b983d2ac 100644 --- a/implementations/rust/ockam/ockam_command/Cargo.toml +++ b/implementations/rust/ockam/ockam_command/Cargo.toml @@ -104,6 +104,7 @@ ockam_multiaddr = { path = "../ockam_multiaddr", version = "0.17.0", features = ockam_vault = { path = "../ockam_vault", version = "^0.73.0", features = ["storage", "aws", "rustcrypto"] } ockam_core = { path = "../ockam_core", version = "^0.77.0" } ockam_identity = { path = "../ockam_identity", version = "^0.71.0" } +ctrlc = { version = "3.2.5" , features = ["termination"] } [dev-dependencies] assert_cmd = "2" diff --git a/implementations/rust/ockam/ockam_command/src/node/create.rs b/implementations/rust/ockam/ockam_command/src/node/create.rs index 0302317dd03..45934976423 100644 --- a/implementations/rust/ockam/ockam_command/src/node/create.rs +++ b/implementations/rust/ockam/ockam_command/src/node/create.rs @@ -1,12 +1,13 @@ use clap::Args; +use colorful::Colorful; use ockam_identity::PublicIdentity; use ockam_multiaddr::MultiAddr; use ockam_vault::Vault; use rand::prelude::random; -use tokio::io::AsyncBufReadExt; use tokio::time::{sleep, Duration}; use anyhow::{anyhow, Context as _}; +use std::io::{self, Read}; use std::{ net::{IpAddr, SocketAddr}, path::PathBuf, @@ -214,7 +215,7 @@ fn create_foreground_node(opts: &CommandGlobalOpts, cmd: &CreateCommand) -> crat async fn run_foreground_node( mut ctx: Context, - (opts, cmd, addr): (CommandGlobalOpts, CreateCommand, SocketAddr), + (mut opts, cmd, addr): (CommandGlobalOpts, CreateCommand, SocketAddr), ) -> crate::Result<()> { let cfg = &opts.config; let node_name = parse_node_name(&cmd.node_name)?; @@ -351,8 +352,44 @@ async fn run_foreground_node( } } + // Create a channel for communicating back to the main thread + let (tx, mut rx) = tokio::sync::mpsc::channel(2); + + // Register a handler for SIGINT, SIGTERM, SIGHUP + let tx_clone = tx.clone(); + let mut opts_clone = opts.clone(); + ctrlc::set_handler(move || { + let _ = tx_clone.blocking_send(()); + let _ = opts_clone + .shell + .write_line(format!("{} Ctrl+C signal received", "!".light_yellow()).as_str()); + }) + .expect("Error setting Ctrl+C handler"); + + // Spawn a thread to monitor STDIN for EOF if cmd.exit_on_eof { - stop_node_on_eof(&mut ctx, &opts, &node_name).await?; + let tx_clone = tx.clone(); + let mut opts_clone = opts.clone(); + std::thread::spawn(move || { + let mut buffer = Vec::new(); + let mut handle = io::stdin().lock(); + handle + .read_to_end(&mut buffer) + .expect("Error reading from stdin"); + let _ = tx_clone.blocking_send(()); + let _ = opts_clone + .shell + .write_line(format!("{} EOF received", "!".light_yellow()).as_str()); + }); + } + + // Shutdown on SIGINT, SIGTERM, SIGHUP or EOF + if rx.recv().await.is_some() { + opts.state.nodes.get(&node_name)?.kill_process(false)?; + ctx.stop().await?; + opts.shell + .write_line(format!("{}Node stopped successfully", "✔︎".light_green()).as_str()) + .unwrap(); } Ok(()) @@ -373,28 +410,6 @@ pub fn load_pre_trusted_identities(cmd: &CreateCommand) -> Result crate::Result<()> { - let reader = tokio::io::BufReader::new(tokio::io::stdin()); - let mut lines = reader.lines(); - - loop { - match lines.next_line().await { - Ok(Some(_)) => (), - Ok(None) => break, - Err(_) => unreachable!(), - } - } - - ctx.stop().await?; - opts.state.nodes.get(node_name)?.kill_process(false)?; - Ok(()) -} - async fn start_services( ctx: &Context, tcp: &TcpTransport,