mirror of
https://github.com/microsoft/vscode.git
synced 2026-04-23 10:08:49 +01:00
cli: use hostname-based generation instead of bird names (#173220)
Fixes #167708 by using a more predictable naming scheme. ``` me> Write a haiku about the extinction of birds chatgpt> Silent skies above, Once lively songs now gone, Fading memories. ```
This commit is contained in:
@@ -4,7 +4,8 @@
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
use crate::auth;
|
||||
use crate::constants::{
|
||||
CONTROL_PORT, PROTOCOL_VERSION_TAG, PROTOCOL_VERSION_TAG_PREFIX, TUNNEL_SERVICE_USER_AGENT, IS_INTERACTIVE_CLI,
|
||||
CONTROL_PORT, IS_INTERACTIVE_CLI, PROTOCOL_VERSION_TAG, PROTOCOL_VERSION_TAG_PREFIX,
|
||||
TUNNEL_SERVICE_USER_AGENT,
|
||||
};
|
||||
use crate::state::{LauncherPaths, PersistedState};
|
||||
use crate::util::errors::{
|
||||
@@ -31,8 +32,6 @@ use tunnels::management::{
|
||||
NO_REQUEST_OPTIONS,
|
||||
};
|
||||
|
||||
use super::name_generator;
|
||||
|
||||
#[derive(Clone, Serialize, Deserialize)]
|
||||
pub struct PersistedTunnel {
|
||||
pub name: String,
|
||||
@@ -636,10 +635,14 @@ impl DevTunnels {
|
||||
mut use_random_name: bool,
|
||||
) -> Result<String, AnyError> {
|
||||
let existing_tunnels = self.list_all_server_tunnels().await?;
|
||||
println!("{:?}", existing_tunnels);
|
||||
let is_name_free = |n: &str| {
|
||||
!existing_tunnels
|
||||
.iter()
|
||||
.any(|v| v.tags.iter().any(|t| t == n))
|
||||
!existing_tunnels.iter().any(|v| {
|
||||
v.status
|
||||
.as_ref()
|
||||
.and_then(|s| s.host_connection_count.as_ref().map(|c| c.get_count()))
|
||||
.unwrap_or(0) > 0 && v.tags.iter().any(|t| t == n)
|
||||
})
|
||||
};
|
||||
|
||||
if let Some(machine_name) = preferred_name {
|
||||
@@ -658,11 +661,19 @@ impl DevTunnels {
|
||||
use_random_name = true;
|
||||
}
|
||||
|
||||
let mut placeholder_name = name_generator::generate_name(MAX_TUNNEL_NAME_LENGTH);
|
||||
if use_random_name || !*IS_INTERACTIVE_CLI {
|
||||
while !is_name_free(&placeholder_name) {
|
||||
placeholder_name = name_generator::generate_name(MAX_TUNNEL_NAME_LENGTH);
|
||||
let mut placeholder_name =
|
||||
clean_hostname_for_tunnel(&gethostname::gethostname().to_string_lossy());
|
||||
if !is_name_free(&placeholder_name) {
|
||||
for i in 2.. {
|
||||
let fixed_name = format!("{}{}", placeholder_name, i);
|
||||
if is_name_free(&fixed_name) {
|
||||
placeholder_name = fixed_name;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if use_random_name || !*IS_INTERACTIVE_CLI {
|
||||
return Ok(placeholder_name);
|
||||
}
|
||||
|
||||
@@ -959,3 +970,49 @@ impl Backoff {
|
||||
self.failures = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/// Cleans up the hostname so it can be used as a tunnel name.
|
||||
/// See TUNNEL_NAME_PATTERN in the tunnels SDK for the rules we try to use.
|
||||
fn clean_hostname_for_tunnel(hostname: &str) -> String {
|
||||
let mut out = String::new();
|
||||
for char in hostname.chars().take(60) {
|
||||
match char {
|
||||
'-' | '_' | ' ' => {
|
||||
out.push('-');
|
||||
}
|
||||
'0'..='9' | 'a'..='z' | 'A'..='Z' => {
|
||||
out.push(char);
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
||||
let trimmed = out.trim_matches('-');
|
||||
if trimmed.len() < 2 {
|
||||
"remote-machine".to_string() // placeholder if the result was empty
|
||||
} else {
|
||||
trimmed.to_owned()
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_clean_hostname_for_tunnel() {
|
||||
assert_eq!(
|
||||
clean_hostname_for_tunnel("hello123"),
|
||||
"hello123".to_string()
|
||||
);
|
||||
assert_eq!(
|
||||
clean_hostname_for_tunnel("-cool-name-"),
|
||||
"cool-name".to_string()
|
||||
);
|
||||
assert_eq!(
|
||||
clean_hostname_for_tunnel("cool!name with_chars"),
|
||||
"coolname-with-chars".to_string()
|
||||
);
|
||||
assert_eq!(clean_hostname_for_tunnel("z"), "remote-machine".to_string());
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user