mirror of
https://github.com/microsoft/vscode.git
synced 2026-05-02 14:31:31 +01:00
cli: initial wsl control server
Adds an stdin/out json rpc server for wsl. Exposes a singular install_local command to install+boot the vscode server on a port from a local archive. Also refines the common rpc layer some more. I'm decently happy with it now.
This commit is contained in:
@@ -146,6 +146,22 @@ impl<'a> From<&'a CliCore> for CodeServerArgs {
|
||||
pub enum StandaloneCommands {
|
||||
/// Updates the CLI.
|
||||
Update(StandaloneUpdateArgs),
|
||||
|
||||
/// Internal commands for WSL serving.
|
||||
#[clap(hide = true)]
|
||||
Wsl(WslArgs),
|
||||
}
|
||||
|
||||
#[derive(Args, Debug, Clone)]
|
||||
pub struct WslArgs {
|
||||
#[clap(subcommand)]
|
||||
pub command: WslCommands,
|
||||
}
|
||||
|
||||
#[derive(Subcommand, Debug, Clone)]
|
||||
pub enum WslCommands {
|
||||
/// Runs the WSL server on stdin/out
|
||||
Serve,
|
||||
}
|
||||
|
||||
#[derive(Args, Debug, Clone)]
|
||||
|
||||
32
cli/src/commands/internal_wsl.rs
Normal file
32
cli/src/commands/internal_wsl.rs
Normal file
@@ -0,0 +1,32 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
use crate::{
|
||||
tunnels::{serve_wsl, shutdown_signal::ShutdownSignal},
|
||||
util::{errors::AnyError, prereqs::PreReqChecker},
|
||||
};
|
||||
|
||||
use super::CommandContext;
|
||||
|
||||
pub async fn serve(ctx: CommandContext) -> Result<i32, AnyError> {
|
||||
let signal = ShutdownSignal::create_rx(&[ShutdownSignal::CtrlC]);
|
||||
let platform = spanf!(
|
||||
ctx.log,
|
||||
ctx.log.span("prereq"),
|
||||
PreReqChecker::new().verify()
|
||||
)?;
|
||||
|
||||
serve_wsl(
|
||||
ctx.log,
|
||||
ctx.paths,
|
||||
(&ctx.args).into(),
|
||||
platform,
|
||||
ctx.http,
|
||||
signal,
|
||||
)
|
||||
.await?;
|
||||
|
||||
Ok(0)
|
||||
}
|
||||
@@ -5,11 +5,9 @@
|
||||
|
||||
use async_trait::async_trait;
|
||||
use sha2::{Digest, Sha256};
|
||||
use std::fmt;
|
||||
use std::str::FromStr;
|
||||
use sysinfo::{Pid, SystemExt};
|
||||
use sysinfo::Pid;
|
||||
use tokio::sync::mpsc;
|
||||
use tokio::time::{sleep, Duration};
|
||||
|
||||
use super::{
|
||||
args::{
|
||||
@@ -20,6 +18,7 @@ use super::{
|
||||
};
|
||||
|
||||
use crate::tunnels::dev_tunnels::ActiveTunnel;
|
||||
use crate::tunnels::shutdown_signal::ShutdownSignal;
|
||||
use crate::{
|
||||
auth::Auth,
|
||||
log::{self, Logger},
|
||||
@@ -93,22 +92,6 @@ impl ServiceContainer for TunnelServiceContainer {
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
/// Describes the signal to manully stop the server
|
||||
pub enum ShutdownSignal {
|
||||
CtrlC,
|
||||
ParentProcessKilled,
|
||||
ServiceStopped,
|
||||
}
|
||||
|
||||
impl fmt::Display for ShutdownSignal {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
match self {
|
||||
ShutdownSignal::CtrlC => write!(f, "Ctrl-C received"),
|
||||
ShutdownSignal::ParentProcessKilled => write!(f, "Parent process no longer exists"),
|
||||
ShutdownSignal::ServiceStopped => write!(f, "Service stopped"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn service(
|
||||
ctx: CommandContext,
|
||||
@@ -269,32 +252,17 @@ async fn serve_with_csa(
|
||||
|
||||
let shutdown_tx = if let Some(tx) = shutdown_rx {
|
||||
tx
|
||||
} else {
|
||||
let (tx, rx) = mpsc::unbounded_channel::<ShutdownSignal>();
|
||||
if let Some(process_id) = gateway_args.parent_process_id {
|
||||
match Pid::from_str(&process_id) {
|
||||
Ok(pid) => {
|
||||
let tx = tx.clone();
|
||||
info!(log, "checking for parent process {}", process_id);
|
||||
tokio::spawn(async move {
|
||||
let mut s = sysinfo::System::new();
|
||||
while s.refresh_process(pid) {
|
||||
sleep(Duration::from_millis(2000)).await;
|
||||
}
|
||||
tx.send(ShutdownSignal::ParentProcessKilled).ok();
|
||||
});
|
||||
}
|
||||
Err(_) => {
|
||||
info!(log, "invalid parent process id: {}", process_id);
|
||||
}
|
||||
}
|
||||
}
|
||||
tokio::spawn(async move {
|
||||
tokio::signal::ctrl_c().await.ok();
|
||||
tx.send(ShutdownSignal::CtrlC).ok();
|
||||
});
|
||||
rx
|
||||
};
|
||||
} else if let Some(pid) = gateway_args
|
||||
.parent_process_id
|
||||
.and_then(|p| Pid::from_str(&p).ok())
|
||||
{
|
||||
ShutdownSignal::create_rx(&[
|
||||
ShutdownSignal::CtrlC,
|
||||
ShutdownSignal::ParentProcessKilled(pid),
|
||||
])
|
||||
} else {
|
||||
ShutdownSignal::create_rx(&[ShutdownSignal::CtrlC])
|
||||
};
|
||||
|
||||
let mut r = crate::tunnels::serve(&log, tunnel, &paths, &csa, platform, shutdown_tx).await?;
|
||||
r.tunnel.close().await.ok();
|
||||
|
||||
Reference in New Issue
Block a user