mirror of
https://github.com/microsoft/vscode.git
synced 2025-12-20 02:08:47 +00:00
cli: publish availability of wsl on tunnel tags (#186016)
I plan to use this in the explorer to add a 'connect to wsl' button on relevant tunnels
This commit is contained in:
@@ -12,6 +12,7 @@ pub mod shutdown_signal;
|
||||
pub mod singleton_client;
|
||||
pub mod singleton_server;
|
||||
|
||||
mod wsl_detect;
|
||||
mod challenge;
|
||||
mod control_server;
|
||||
mod nosleep;
|
||||
|
||||
@@ -4,8 +4,7 @@
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
use crate::auth;
|
||||
use crate::constants::{
|
||||
CONTROL_PORT, IS_INTERACTIVE_CLI, PROTOCOL_VERSION_TAG, PROTOCOL_VERSION_TAG_PREFIX,
|
||||
TUNNEL_SERVICE_USER_AGENT,
|
||||
CONTROL_PORT, IS_INTERACTIVE_CLI, PROTOCOL_VERSION_TAG, TUNNEL_SERVICE_USER_AGENT,
|
||||
};
|
||||
use crate::state::{LauncherPaths, PersistedState};
|
||||
use crate::util::errors::{
|
||||
@@ -32,6 +31,8 @@ use tunnels::management::{
|
||||
NO_REQUEST_OPTIONS,
|
||||
};
|
||||
|
||||
use super::wsl_detect::is_wsl_installed;
|
||||
|
||||
#[derive(Clone, Serialize, Deserialize)]
|
||||
pub struct PersistedTunnel {
|
||||
pub name: String,
|
||||
@@ -304,7 +305,7 @@ impl DevTunnels {
|
||||
return Ok((full_tunnel, persisted));
|
||||
}
|
||||
|
||||
full_tunnel.tags = vec![name.to_string(), VSCODE_CLI_TUNNEL_TAG.to_string()];
|
||||
full_tunnel.tags = self.get_tags(&name);
|
||||
|
||||
let new_tunnel = spanf!(
|
||||
self.log,
|
||||
@@ -383,11 +384,9 @@ impl DevTunnels {
|
||||
}
|
||||
};
|
||||
|
||||
if !tunnel.tags.iter().any(|t| t == PROTOCOL_VERSION_TAG) {
|
||||
tunnel = self
|
||||
.update_protocol_version_tag(tunnel, &HOST_TUNNEL_REQUEST_OPTIONS)
|
||||
.await?;
|
||||
}
|
||||
tunnel = self
|
||||
.sync_tunnel_tags(&persisted.name, tunnel, &HOST_TUNNEL_REQUEST_OPTIONS)
|
||||
.await?;
|
||||
|
||||
let locator = TunnelLocator::try_from(&tunnel).unwrap();
|
||||
let host_token = get_host_token_from_tunnel(&tunnel);
|
||||
@@ -504,23 +503,40 @@ impl DevTunnels {
|
||||
}
|
||||
}
|
||||
|
||||
/// Gets the expected tunnel tags
|
||||
fn get_tags(&self, name: &str) -> Vec<String> {
|
||||
let mut tags = vec![
|
||||
name.to_string(),
|
||||
PROTOCOL_VERSION_TAG.to_string(),
|
||||
VSCODE_CLI_TUNNEL_TAG.to_string(),
|
||||
];
|
||||
|
||||
if is_wsl_installed(&self.log) {
|
||||
tags.push("_wsl".to_string())
|
||||
}
|
||||
|
||||
tags
|
||||
}
|
||||
|
||||
/// Ensures the tunnel contains a tag for the current PROTCOL_VERSION, and no
|
||||
/// other version tags.
|
||||
async fn update_protocol_version_tag(
|
||||
async fn sync_tunnel_tags(
|
||||
&self,
|
||||
name: &str,
|
||||
tunnel: Tunnel,
|
||||
options: &TunnelRequestOptions,
|
||||
) -> Result<Tunnel, AnyError> {
|
||||
let new_tags = self.get_tags(name);
|
||||
if vec_eq_unsorted(&tunnel.tags, &new_tags) {
|
||||
return Ok(tunnel);
|
||||
}
|
||||
|
||||
debug!(
|
||||
self.log,
|
||||
"Updating tunnel protocol version tag to {}", PROTOCOL_VERSION_TAG
|
||||
"Updating tunnel tags {} -> {}",
|
||||
tunnel.tags.join(", "),
|
||||
new_tags.join(", ")
|
||||
);
|
||||
let mut new_tags: Vec<String> = tunnel
|
||||
.tags
|
||||
.into_iter()
|
||||
.filter(|t| !t.starts_with(PROTOCOL_VERSION_TAG_PREFIX))
|
||||
.collect();
|
||||
new_tags.push(PROTOCOL_VERSION_TAG.to_string());
|
||||
|
||||
let tunnel_update = Tunnel {
|
||||
tags: new_tags,
|
||||
@@ -982,6 +998,20 @@ fn clean_hostname_for_tunnel(hostname: &str) -> String {
|
||||
}
|
||||
}
|
||||
|
||||
fn vec_eq_unsorted(a: &[String], b: &[String]) -> bool {
|
||||
if a.len() != b.len() {
|
||||
return false;
|
||||
}
|
||||
|
||||
for item in a {
|
||||
if !b.contains(item) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
true
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use super::*;
|
||||
|
||||
51
cli/src/tunnels/wsl_detect.rs
Normal file
51
cli/src/tunnels/wsl_detect.rs
Normal file
@@ -0,0 +1,51 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
use crate::log;
|
||||
|
||||
#[cfg(not(windows))]
|
||||
pub fn is_wsl_installed(_log: &log::Logger) -> bool {
|
||||
false
|
||||
}
|
||||
|
||||
#[cfg(windows)]
|
||||
pub fn is_wsl_installed(log: &log::Logger) -> bool {
|
||||
use std::{path::PathBuf, process::Command};
|
||||
|
||||
let system32 = {
|
||||
let sys_root = match std::env::var("SystemRoot") {
|
||||
Ok(s) => s,
|
||||
Err(_) => return false,
|
||||
};
|
||||
|
||||
let is_32_on_64 = std::env::var("PROCESSOR_ARCHITEW6432").is_ok();
|
||||
let mut system32 = PathBuf::from(sys_root);
|
||||
system32.push(if is_32_on_64 { "Sysnative" } else { "System32" });
|
||||
system32
|
||||
};
|
||||
|
||||
// Windows builds < 22000
|
||||
let mut maybe_lxss = system32.join("lxss");
|
||||
maybe_lxss.push("LxssManager.dll");
|
||||
if maybe_lxss.exists() {
|
||||
trace!(log, "wsl availability detected via lxss");
|
||||
return true;
|
||||
}
|
||||
|
||||
// Windows builds >= 22000
|
||||
let maybe_wsl = system32.join("wsl.exe");
|
||||
if maybe_wsl.exists() {
|
||||
if let Ok(s) = Command::new(maybe_wsl).arg("--status").output() {
|
||||
if s.status.success() {
|
||||
trace!(log, "wsl availability detected via subprocess");
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
trace!(log, "wsl not detected");
|
||||
|
||||
false
|
||||
}
|
||||
Reference in New Issue
Block a user