huskies: merge 1182 bug Sled uplinks all register as 'workspace' — containers never get HUSKIES_PROJECT_NAME
This commit is contained in:
@@ -763,6 +763,7 @@ async fn handle_adopt_project(
|
|||||||
|
|
||||||
let mut docker_args = project_docker_run_args(
|
let mut docker_args = project_docker_run_args(
|
||||||
&container_name,
|
&container_name,
|
||||||
|
name,
|
||||||
port,
|
port,
|
||||||
ssh_port,
|
ssh_port,
|
||||||
&pubkey,
|
&pubkey,
|
||||||
@@ -1150,6 +1151,7 @@ pub async fn handle_new_project(
|
|||||||
// string that is returned to the caller or written to a log.
|
// string that is returned to the caller or written to a log.
|
||||||
let mut docker_args = project_docker_run_args(
|
let mut docker_args = project_docker_run_args(
|
||||||
&container_name,
|
&container_name,
|
||||||
|
name,
|
||||||
port,
|
port,
|
||||||
ssh_port,
|
ssh_port,
|
||||||
&pubkey,
|
&pubkey,
|
||||||
@@ -1361,6 +1363,7 @@ pub async fn build_project_image(
|
|||||||
#[allow(clippy::too_many_arguments)]
|
#[allow(clippy::too_many_arguments)]
|
||||||
pub(crate) fn project_docker_run_args(
|
pub(crate) fn project_docker_run_args(
|
||||||
container_name: &str,
|
container_name: &str,
|
||||||
|
project_name: &str,
|
||||||
port: u16,
|
port: u16,
|
||||||
ssh_port: u16,
|
ssh_port: u16,
|
||||||
pubkey: &str,
|
pubkey: &str,
|
||||||
@@ -1389,6 +1392,8 @@ pub(crate) fn project_docker_run_args(
|
|||||||
"-e".into(),
|
"-e".into(),
|
||||||
"HUSKIES_PORT=3001".into(),
|
"HUSKIES_PORT=3001".into(),
|
||||||
"-e".into(),
|
"-e".into(),
|
||||||
|
format!("HUSKIES_PROJECT_NAME={project_name}"),
|
||||||
|
"-e".into(),
|
||||||
format!("HUSKIES_SSH_PUBKEY={pubkey}"),
|
format!("HUSKIES_SSH_PUBKEY={pubkey}"),
|
||||||
"-e".into(),
|
"-e".into(),
|
||||||
format!("GIT_USER_NAME={git_user_name}"),
|
format!("GIT_USER_NAME={git_user_name}"),
|
||||||
@@ -1839,6 +1844,7 @@ mod tests {
|
|||||||
fn project_docker_args_include_huskies_host_env() {
|
fn project_docker_args_include_huskies_host_env() {
|
||||||
let args = project_docker_run_args(
|
let args = project_docker_run_args(
|
||||||
"huskies-myapp",
|
"huskies-myapp",
|
||||||
|
"myapp",
|
||||||
3100,
|
3100,
|
||||||
2200,
|
2200,
|
||||||
"ssh-ed25519 AAAA...",
|
"ssh-ed25519 AAAA...",
|
||||||
@@ -1887,10 +1893,33 @@ mod tests {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn project_docker_args_include_project_name_env() {
|
||||||
|
let args = project_docker_run_args(
|
||||||
|
"huskies-myapp",
|
||||||
|
"myapp",
|
||||||
|
3100,
|
||||||
|
2200,
|
||||||
|
"ssh-ed25519 AAAA...",
|
||||||
|
"Test User",
|
||||||
|
"test@example.com",
|
||||||
|
None,
|
||||||
|
"",
|
||||||
|
);
|
||||||
|
let pairs: Vec<_> = args.windows(2).collect();
|
||||||
|
assert!(
|
||||||
|
pairs
|
||||||
|
.iter()
|
||||||
|
.any(|w| w[0] == "-e" && w[1] == "HUSKIES_PROJECT_NAME=myapp"),
|
||||||
|
"expected -e HUSKIES_PROJECT_NAME=myapp in docker args, got: {args:?}"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn project_docker_args_no_gateway_url_when_empty() {
|
fn project_docker_args_no_gateway_url_when_empty() {
|
||||||
let args = project_docker_run_args(
|
let args = project_docker_run_args(
|
||||||
"huskies-myapp",
|
"huskies-myapp",
|
||||||
|
"myapp",
|
||||||
3100,
|
3100,
|
||||||
2200,
|
2200,
|
||||||
"ssh-ed25519 AAAA...",
|
"ssh-ed25519 AAAA...",
|
||||||
@@ -1910,6 +1939,7 @@ mod tests {
|
|||||||
let creds = std::path::Path::new("/home/user/.claude/.credentials.json");
|
let creds = std::path::Path::new("/home/user/.claude/.credentials.json");
|
||||||
let args = project_docker_run_args(
|
let args = project_docker_run_args(
|
||||||
"huskies-myapp",
|
"huskies-myapp",
|
||||||
|
"myapp",
|
||||||
3100,
|
3100,
|
||||||
2200,
|
2200,
|
||||||
"ssh-ed25519 AAAA...",
|
"ssh-ed25519 AAAA...",
|
||||||
@@ -1930,6 +1960,7 @@ mod tests {
|
|||||||
fn project_docker_args_no_credentials_mount_when_none() {
|
fn project_docker_args_no_credentials_mount_when_none() {
|
||||||
let args = project_docker_run_args(
|
let args = project_docker_run_args(
|
||||||
"huskies-myapp",
|
"huskies-myapp",
|
||||||
|
"myapp",
|
||||||
3100,
|
3100,
|
||||||
2200,
|
2200,
|
||||||
"ssh-ed25519 AAAA...",
|
"ssh-ed25519 AAAA...",
|
||||||
|
|||||||
@@ -228,6 +228,7 @@ pub async fn handle_project_rebuild(
|
|||||||
|
|
||||||
let mut docker_args = super::new_project::project_docker_run_args(
|
let mut docker_args = super::new_project::project_docker_run_args(
|
||||||
&container_name,
|
&container_name,
|
||||||
|
name,
|
||||||
port,
|
port,
|
||||||
ssh_port,
|
ssh_port,
|
||||||
&pubkey,
|
&pubkey,
|
||||||
|
|||||||
@@ -395,6 +395,7 @@ mod tests {
|
|||||||
// code path that sets HUSKIES_GATEWAY_URL on the sled container.
|
// code path that sets HUSKIES_GATEWAY_URL on the sled container.
|
||||||
let docker_args = project_docker_run_args(
|
let docker_args = project_docker_run_args(
|
||||||
"huskies-sled-relay",
|
"huskies-sled-relay",
|
||||||
|
"sled-relay",
|
||||||
3200,
|
3200,
|
||||||
2300,
|
2300,
|
||||||
"ssh-ed25519 AAAA...",
|
"ssh-ed25519 AAAA...",
|
||||||
|
|||||||
@@ -343,6 +343,12 @@ async fn run_sled_uplink_session(
|
|||||||
"[gateway/sled-uplink] Sled '{}' connected and registered",
|
"[gateway/sled-uplink] Sled '{}' connected and registered",
|
||||||
identity
|
identity
|
||||||
);
|
);
|
||||||
|
if !state.projects.read().await.contains_key(&identity) {
|
||||||
|
crate::slog_warn!(
|
||||||
|
"[gateway/sled-uplink] Sled registered under name '{}', which matches no project in projects.toml",
|
||||||
|
identity
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
// Aggregator channel for perm responses produced by spawned per-request tasks.
|
// Aggregator channel for perm responses produced by spawned per-request tasks.
|
||||||
let (agg_tx, mut agg_rx) =
|
let (agg_tx, mut agg_rx) =
|
||||||
@@ -734,4 +740,49 @@ mod tests {
|
|||||||
"with no sled tokens configured anywhere, the uplink must accept unauthenticated"
|
"with no sled tokens configured anywhere, the uplink must accept unauthenticated"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[tokio::test]
|
||||||
|
async fn unconfigured_project_name_logs_warning() {
|
||||||
|
let mut projects = BTreeMap::new();
|
||||||
|
projects.insert(
|
||||||
|
"other-project".to_string(),
|
||||||
|
ProjectEntry::with_url("http://other-project:3001"),
|
||||||
|
);
|
||||||
|
let config = GatewayConfig {
|
||||||
|
projects,
|
||||||
|
sled_tokens: BTreeMap::new(),
|
||||||
|
release_channels: BTreeMap::new(),
|
||||||
|
};
|
||||||
|
let (base_url, _state) = start_test_gateway(config).await;
|
||||||
|
let url = format!("{base_url}/api/sled-uplink?project=ghost-project");
|
||||||
|
|
||||||
|
let (mut ws_stream, _) = tokio_tungstenite::connect_async(url.as_str())
|
||||||
|
.await
|
||||||
|
.expect("uplink connect should succeed when no tokens are configured");
|
||||||
|
|
||||||
|
let identity = crate::sled_uplink::UplinkEnvelope {
|
||||||
|
msg_type: "identity".to_string(),
|
||||||
|
req_id: String::new(),
|
||||||
|
payload: serde_json::json!({ "project": "ghost-project" }),
|
||||||
|
};
|
||||||
|
ws_stream
|
||||||
|
.send(tokio_tungstenite::tungstenite::Message::Text(
|
||||||
|
serde_json::to_string(&identity).unwrap().into(),
|
||||||
|
))
|
||||||
|
.await
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
// Give the server task time to process the identity frame and register.
|
||||||
|
tokio::time::sleep(std::time::Duration::from_millis(200)).await;
|
||||||
|
|
||||||
|
let warnings = crate::log_buffer::global().get_recent(
|
||||||
|
50,
|
||||||
|
Some("ghost-project"),
|
||||||
|
Some(&crate::log_buffer::LogLevel::Warn),
|
||||||
|
);
|
||||||
|
assert!(
|
||||||
|
warnings.iter().any(|w| w.contains("matches no project")),
|
||||||
|
"expected an unconfigured-project warning, got: {warnings:?}"
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user