cli: add service integration for macos, observability

Adds support for running the tunnel as a service on macOS via launchservices.

It also hooks up observability (`code tunnel service log`) on macOS and Linux.
On macOS--and later Windows, hence the manual implementation of `tail`--it
saves output to a log file and watches it. On Linux, it simply delegates to
journalctl.

The "tailing" is implemented via simple polling of the file size. I didn't want
to pull in a giant set of dependencies for inotify/kqueue/etc just for this use
case; performance when polling a single log file is not a huge concern.
This commit is contained in:
Connor Peet
2022-11-15 15:17:48 -08:00
parent 2ab5e3f458
commit 1bf3323015
12 changed files with 606 additions and 52 deletions

View File

@@ -2,10 +2,34 @@
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
use super::errors::{wrap, WrappedError};
use std::{ffi::OsStr, process::Stdio};
use super::errors::{wrap, AnyError, CommandFailed, WrappedError};
use std::{ffi::OsStr, process::Stdio, borrow::Cow};
use tokio::process::Command;
pub async fn capture_command_and_check_status(
command_str: impl AsRef<OsStr>,
args: &[impl AsRef<OsStr>],
) -> Result<std::process::Output, AnyError> {
let output = capture_command(&command_str, args).await?;
if !output.status.success() {
return Err(CommandFailed {
command: format!(
"{} {}",
command_str.as_ref().to_string_lossy(),
args.iter()
.map(|a| a.as_ref().to_string_lossy())
.collect::<Vec<Cow<'_, str>>>()
.join(" ")
),
output,
}
.into());
}
Ok(output)
}
pub async fn capture_command<A, I, S>(
command_str: A,
args: I,