|
4 | 4 | *--------------------------------------------------------------------------------------------*/ |
5 | 5 |
|
6 | 6 | use async_trait::async_trait; |
7 | | -use base64::{Engine as _, engine::general_purpose as b64}; |
| 7 | +use base64::{engine::general_purpose as b64, Engine as _}; |
| 8 | +use serde::Serialize; |
8 | 9 | use sha2::{Digest, Sha256}; |
9 | 10 | use std::{str::FromStr, time::Duration}; |
10 | 11 | use sysinfo::Pid; |
@@ -247,26 +248,39 @@ pub async fn kill(ctx: CommandContext) -> Result<i32, AnyError> { |
247 | 248 | .map_err(|e| e.into()) |
248 | 249 | } |
249 | 250 |
|
| 251 | +#[derive(Serialize)] |
| 252 | +pub struct StatusOutput { |
| 253 | + pub tunnel: Option<protocol::singleton::TunnelState>, |
| 254 | + pub service_installed: bool, |
| 255 | +} |
| 256 | + |
250 | 257 | pub async fn status(ctx: CommandContext) -> Result<i32, AnyError> { |
251 | | - let status = do_single_rpc_call::<_, protocol::singleton::Status>( |
| 258 | + let tunnel_status = do_single_rpc_call::<_, protocol::singleton::Status>( |
252 | 259 | &ctx.paths.tunnel_lockfile(), |
253 | 260 | ctx.log.clone(), |
254 | 261 | protocol::singleton::METHOD_STATUS, |
255 | 262 | protocol::EmptyObject {}, |
256 | 263 | ) |
257 | 264 | .await; |
258 | 265 |
|
259 | | - match status { |
260 | | - Err(CodeError::NoRunningTunnel) => { |
261 | | - ctx.log.result(CodeError::NoRunningTunnel.to_string()); |
262 | | - Ok(1) |
263 | | - } |
264 | | - Err(e) => Err(e.into()), |
265 | | - Ok(s) => { |
266 | | - ctx.log.result(serde_json::to_string(&s).unwrap()); |
267 | | - Ok(0) |
268 | | - } |
269 | | - } |
| 266 | + let service_installed = create_service_manager(ctx.log.clone(), &ctx.paths) |
| 267 | + .is_installed() |
| 268 | + .await |
| 269 | + .unwrap_or(false); |
| 270 | + |
| 271 | + ctx.log.result( |
| 272 | + serde_json::to_string(&StatusOutput { |
| 273 | + service_installed, |
| 274 | + tunnel: match tunnel_status { |
| 275 | + Ok(s) => Some(s.tunnel), |
| 276 | + Err(CodeError::NoRunningTunnel) => None, |
| 277 | + Err(e) => return Err(e.into()), |
| 278 | + }, |
| 279 | + }) |
| 280 | + .unwrap(), |
| 281 | + ); |
| 282 | + |
| 283 | + Ok(0) |
270 | 284 | } |
271 | 285 |
|
272 | 286 | /// Removes unused servers. |
@@ -331,6 +345,13 @@ async fn serve_with_csa( |
331 | 345 | log = log.tee(log_broadcast.clone()); |
332 | 346 | log::install_global_logger(log.clone()); // re-install so that library logs are captured |
333 | 347 |
|
| 348 | + debug!( |
| 349 | + log, |
| 350 | + "Starting tunnel with `{} {}`", |
| 351 | + APPLICATION_NAME, |
| 352 | + std::env::args().collect::<Vec<_>>().join(" ") |
| 353 | + ); |
| 354 | + |
334 | 355 | // Intentionally read before starting the server. If the server updated and |
335 | 356 | // respawn is requested, the old binary will get renamed, and then |
336 | 357 | // current_exe will point to the wrong path. |
@@ -421,7 +442,10 @@ async fn serve_with_csa( |
421 | 442 |
|
422 | 443 | return Ok(exit.code().unwrap_or(1)); |
423 | 444 | } |
424 | | - Next::Exit => return Ok(0), |
| 445 | + Next::Exit => { |
| 446 | + debug!(log, "Tunnel shut down"); |
| 447 | + return Ok(0); |
| 448 | + } |
425 | 449 | Next::Restart => continue, |
426 | 450 | } |
427 | 451 | } |
|
0 commit comments