Merge commit '80221289935e227820aec902988a4f987273e05e' into work/T-549-provider-published-ref
# Conflicts: # crates/worker-runtime/src/runtime.rs
This commit is contained in:
@@ -3842,7 +3842,6 @@ fn embedded_worker_status_label(status: EmbeddedWorkerStatus) -> &'static str {
|
||||
EmbeddedWorkerStatus::Running => "running",
|
||||
EmbeddedWorkerStatus::Paused => "paused",
|
||||
EmbeddedWorkerStatus::Stopped => "stopped",
|
||||
EmbeddedWorkerStatus::Cancelled => "cancelled",
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5827,7 +5826,7 @@ mod tests {
|
||||
json!({
|
||||
"workers": [
|
||||
worker_json_with_status("remote:primary", &worker_ids[0], "stopped"),
|
||||
worker_json_with_status("remote:primary", &worker_ids[1], "cancelled"),
|
||||
worker_json_with_status("remote:primary", &worker_ids[1], "running"),
|
||||
worker_json_with_status("remote:primary", &worker_ids[2], "paused"),
|
||||
worker_json_with_status("remote:primary", &worker_ids[3], "idle")
|
||||
]
|
||||
@@ -5866,11 +5865,11 @@ mod tests {
|
||||
let workers = registry.list_workers(10);
|
||||
assert_eq!(workers.items.len(), 4);
|
||||
assert!(!workers.items[0].capabilities.can_stop);
|
||||
assert!(!workers.items[1].capabilities.can_stop);
|
||||
assert!(workers.items[1].capabilities.can_stop);
|
||||
assert!(workers.items[2].capabilities.can_stop);
|
||||
assert!(workers.items[3].capabilities.can_stop);
|
||||
assert_eq!(workers.items[0].state, "stopped");
|
||||
assert_eq!(workers.items[1].state, "cancelled");
|
||||
assert_eq!(workers.items[1].state, "running");
|
||||
assert_eq!(workers.items[2].state, "paused");
|
||||
assert_eq!(workers.items[3].state, "idle");
|
||||
|
||||
|
||||
@@ -58,25 +58,28 @@ use worker::feature::builtin::{WorkerObservationSubject, WorkerObservationSubjec
|
||||
use worker_runtime::resource::{BackendResourceError, BackendResourceFetchRequest};
|
||||
use worker_runtime::worker_backend::{ProfileRuntimeWorkerFactory, WorkerRuntimeExecutionBackend};
|
||||
use workspace_api::{
|
||||
CreateRemoteRuntimeRequest, CreateRepositorySshCredentialRequest,
|
||||
CreateWorkspaceRepositoryRequest, CreateWorkspaceRepositoryResponse,
|
||||
DeleteRepositorySshCredentialRequest, DeleteRepositorySshHostTrustRequest,
|
||||
ObjectiveCreateRequest, ObjectiveEditRequest, ObjectiveLinkTicketRequest,
|
||||
ObjectiveStateRequest, ProfileSettingsResponse, PutRepositorySshHostTrustRequest,
|
||||
RepositoryAccessProjection, RepositoryDetailResponse, RepositoryListResponse,
|
||||
RepositoryLogResponse, RepositorySshCredential, RepositorySshHostTrust,
|
||||
BrowserCreateWorkerResponse, BrowserWorkspaceOrchestratorResponse, CreateRemoteRuntimeRequest,
|
||||
CreateRepositorySshCredentialRequest, CreateWorkspaceRepositoryRequest,
|
||||
CreateWorkspaceRepositoryResponse, CreateWorkspaceWorkerRequest,
|
||||
CreateWorkspaceWorkerTicketAssignmentRequest, DeleteRepositorySshCredentialRequest,
|
||||
DeleteRepositorySshHostTrustRequest, ObjectiveCreateRequest, ObjectiveEditRequest,
|
||||
ObjectiveLinkTicketRequest, ObjectiveStateRequest, ProfileSettingsResponse,
|
||||
PutRepositorySshHostTrustRequest, RepositoryAccessProjection, RepositoryDetailResponse,
|
||||
RepositoryListResponse, RepositoryLogResponse, RepositorySshCredential, RepositorySshHostTrust,
|
||||
RotateRepositorySshCredentialRequest, RuntimeConnectionTestResponse, RuntimeManagementSummary,
|
||||
TICKET_ORCHESTRATION_PLANS_QUERY_PATH, TICKET_RELATIONS_QUERY_PATH,
|
||||
UpdateWorkspaceMetadataRequest,
|
||||
UpdateWorkspaceMetadataRequest, WorkerLaunchOptionsResponse, WorkerLaunchProfileCandidate,
|
||||
WorkerLaunchRuntimeOption, WorkerLaunchWorkerSummary,
|
||||
WorkingDirectoryCreateRequest as BrowserWorkingDirectoryCreateRequest,
|
||||
WorkingDirectoryCreateResponse as BrowserWorkingDirectoryCreateResponse,
|
||||
WorkingDirectoryDetailResponse as BrowserWorkingDirectoryDetailResponse,
|
||||
WorkingDirectoryListResponse as BrowserWorkingDirectoryListResponse,
|
||||
WorkingDirectoryRemovalDisposition, WorkingDirectoryRemovalRequest,
|
||||
WorkingDirectoryRemovalResponse, WorkspaceCatalogListResponse, WorkspaceCreateResponse,
|
||||
WorkspaceExtensionPointState, WorkspaceExtensionPoints, WorkspaceMetadataMutationResponse,
|
||||
WorkspaceMetadataSettingsResponse, WorkspacePermissionSummary, WorkspaceRepositoryRecord,
|
||||
WorkspaceResponse, WorkspaceRuntimeResource, WorkspaceSummary, WorkspaceWorkerDiscoveryItem,
|
||||
WorkingDirectoryRemovalResponse, WorkingDirectoryRepositoryOption,
|
||||
WorkspaceCatalogListResponse, WorkspaceCreateResponse, WorkspaceExtensionPointState,
|
||||
WorkspaceExtensionPoints, WorkspaceMetadataMutationResponse, WorkspaceMetadataSettingsResponse,
|
||||
WorkspacePermissionSummary, WorkspaceRepositoryRecord, WorkspaceResponse,
|
||||
WorkspaceRuntimeResource, WorkspaceSummary, WorkspaceWorkerDiscoveryItem,
|
||||
WorkspaceWorkerDiscoveryPage, WorkspaceWorkerSubject,
|
||||
};
|
||||
|
||||
@@ -3097,98 +3100,6 @@ pub struct WorkerRetentionResponse {
|
||||
pub retention_state: String,
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
pub struct WorkerLaunchOptionsResponse {
|
||||
pub workspace_id: String,
|
||||
pub runtimes: Vec<WorkerLaunchRuntimeOption>,
|
||||
pub default_profile: Option<String>,
|
||||
pub profiles: Vec<WorkerLaunchProfileCandidate>,
|
||||
pub repositories: Vec<WorkingDirectoryRepositoryOption>,
|
||||
pub working_directories: Vec<WorkingDirectorySummary>,
|
||||
pub diagnostics: Vec<RuntimeDiagnostic>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
pub struct WorkerLaunchRuntimeOption {
|
||||
pub runtime_id: String,
|
||||
pub display_name: String,
|
||||
pub built_in: bool,
|
||||
pub worker_creation_available: bool,
|
||||
pub working_directory_required: bool,
|
||||
pub status: String,
|
||||
pub diagnostics: Vec<RuntimeDiagnostic>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct WorkerLaunchProfileCandidate {
|
||||
pub id: String,
|
||||
pub label: String,
|
||||
pub description: String,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct WorkingDirectoryRepositoryOption {
|
||||
pub repository_key: String,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub default_selector: Option<String>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
#[serde(deny_unknown_fields)]
|
||||
pub struct BrowserWorkerWorkingDirectorySelection {
|
||||
pub working_directory_id: String,
|
||||
#[serde(default)]
|
||||
pub relative_cwd: Option<String>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
pub struct BrowserWorkspaceOrchestratorResponse {
|
||||
pub workspace_id: String,
|
||||
pub online: bool,
|
||||
pub disposition: String,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub worker: Option<WorkerSummary>,
|
||||
pub diagnostics: Vec<RuntimeDiagnostic>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
#[serde(deny_unknown_fields)]
|
||||
pub struct CreateWorkspaceWorkerTicketAssignmentRequest {
|
||||
pub ticket_id: String,
|
||||
pub operation_id: String,
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
#[serde(deny_unknown_fields)]
|
||||
pub struct CreateWorkspaceWorkerRequest {
|
||||
pub runtime_id: String,
|
||||
pub display_name: String,
|
||||
#[serde(default)]
|
||||
pub profile: Option<String>,
|
||||
#[serde(default)]
|
||||
pub ticket_assignment: Option<CreateWorkspaceWorkerTicketAssignmentRequest>,
|
||||
#[serde(default)]
|
||||
pub initial_submit: Vec<Segment>,
|
||||
#[serde(default)]
|
||||
pub working_directory: Option<BrowserWorkerWorkingDirectorySelection>,
|
||||
/// Backend idempotency key used only for authenticated Worker-owned spawn/control.
|
||||
#[serde(default)]
|
||||
pub control_operation_id: Option<String>,
|
||||
/// Trusted resolution populated only by the authenticated worker-control handler.
|
||||
#[serde(skip, default)]
|
||||
pub resolved_control_operation: Option<WorkerControlOperation>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
pub struct BrowserCreateWorkerResponse {
|
||||
pub workspace_id: String,
|
||||
#[serde(flatten)]
|
||||
pub worker_ref: RuntimeWorkerRef,
|
||||
pub console_href: String,
|
||||
pub worker: WorkerSummary,
|
||||
pub diagnostics: Vec<RuntimeDiagnostic>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Deserialize)]
|
||||
struct LogQuery {
|
||||
limit: Option<usize>,
|
||||
@@ -8135,9 +8046,9 @@ fn start_memory_staging_consolidation(
|
||||
resolved_config_bundle,
|
||||
resolved_worker_observation_enabled: false,
|
||||
resolved_worker_observation_grants: Vec::new(),
|
||||
resolved_control_operation: None,
|
||||
resolved_workspace_api: None,
|
||||
resolved_memory_settings: None,
|
||||
resolved_control_operation: None,
|
||||
},
|
||||
)?;
|
||||
if result.state != WorkerOperationState::Accepted {
|
||||
@@ -9088,18 +8999,20 @@ async fn spawn_known_worker(
|
||||
.map(|byte| format!("{byte:02x}"))
|
||||
.collect::<String>()
|
||||
);
|
||||
request.resolved_control_operation = Some(WorkerControlOperation {
|
||||
let resolved_control_operation = Some(WorkerControlOperation {
|
||||
operation_id: scoped_worker_control_operation_id(&controller, &operation_id),
|
||||
input_fingerprint,
|
||||
});
|
||||
let response = create_workspace_worker(State(api.clone()), headers, Json(request)).await?;
|
||||
let response =
|
||||
create_workspace_worker_inner(api.clone(), headers, request, resolved_control_operation)
|
||||
.await?;
|
||||
if let Err(error) = api
|
||||
.store
|
||||
.create_worker_control_grant(&WorkerControlGrantRecord {
|
||||
workspace_id: path.workspace_id.clone(),
|
||||
grant_id: new_id("wcg"),
|
||||
controller,
|
||||
subject: response.0.worker_ref.clone(),
|
||||
subject: RuntimeWorkerRef::new(&response.0.runtime_id, &response.0.worker_id),
|
||||
relation: relation.to_string(),
|
||||
origin: "worker_spawn".to_string(),
|
||||
permissions: vec![
|
||||
@@ -9432,9 +9345,9 @@ async fn scoped_start_workspace_orchestrator(
|
||||
resolved_config_bundle: None,
|
||||
resolved_worker_observation_enabled: true,
|
||||
resolved_worker_observation_grants: Vec::new(),
|
||||
resolved_control_operation: None,
|
||||
resolved_workspace_api: None,
|
||||
resolved_memory_settings: None,
|
||||
resolved_control_operation: None,
|
||||
},
|
||||
)?;
|
||||
if result.state != WorkerOperationState::Accepted || result.worker.is_none() {
|
||||
@@ -9462,6 +9375,42 @@ async fn scoped_start_workspace_orchestrator(
|
||||
Ok(Json(workspace_orchestrator_response(&api, "created")))
|
||||
}
|
||||
|
||||
fn worker_launch_worker_summary(worker: WorkerSummary) -> WorkerLaunchWorkerSummary {
|
||||
WorkerLaunchWorkerSummary {
|
||||
runtime_id: worker.worker.runtime_id,
|
||||
worker_id: worker.worker.worker_id,
|
||||
host_id: worker.host_id,
|
||||
display_name: worker.display_name,
|
||||
label: worker.label,
|
||||
profile: worker.profile,
|
||||
singleton_key: worker.singleton_key,
|
||||
tags: worker.tags,
|
||||
workspace: workspace_api::WorkerWorkspaceSummary {
|
||||
visibility: worker.workspace.visibility,
|
||||
identity: worker.workspace.identity,
|
||||
workspace_id: worker.workspace.workspace_id,
|
||||
},
|
||||
state: worker.state,
|
||||
last_seen_at: worker.last_seen_at,
|
||||
pinned: worker.pinned,
|
||||
retention_state: worker.retention_state,
|
||||
implementation: workspace_api::WorkerImplementationSummary {
|
||||
kind: worker.implementation.kind,
|
||||
display_hint: worker.implementation.display_hint,
|
||||
},
|
||||
capabilities: workspace_api::WorkerCapabilitySummary {
|
||||
can_stop: worker.capabilities.can_stop,
|
||||
can_spawn_followup: worker.capabilities.can_spawn_followup,
|
||||
},
|
||||
working_directory: worker.working_directory,
|
||||
diagnostics: worker
|
||||
.diagnostics
|
||||
.into_iter()
|
||||
.map(workspace_api::Diagnostic::from)
|
||||
.collect(),
|
||||
}
|
||||
}
|
||||
|
||||
fn workspace_orchestrator_response(
|
||||
api: &WorkspaceApi,
|
||||
disposition: &str,
|
||||
@@ -9472,13 +9421,20 @@ fn workspace_orchestrator_response(
|
||||
.is_some_and(workspace_orchestrator_is_online);
|
||||
let diagnostics = worker
|
||||
.as_ref()
|
||||
.map(|worker| worker.diagnostics.clone())
|
||||
.map(|worker| {
|
||||
worker
|
||||
.diagnostics
|
||||
.iter()
|
||||
.cloned()
|
||||
.map(workspace_api::Diagnostic::from)
|
||||
.collect()
|
||||
})
|
||||
.unwrap_or_default();
|
||||
BrowserWorkspaceOrchestratorResponse {
|
||||
workspace_id: api.config.workspace_id.clone(),
|
||||
online,
|
||||
disposition: disposition.to_string(),
|
||||
worker,
|
||||
worker: worker.map(worker_launch_worker_summary),
|
||||
diagnostics,
|
||||
}
|
||||
}
|
||||
@@ -12835,6 +12791,15 @@ async fn create_workspace_worker(
|
||||
State(api): State<WorkspaceApi>,
|
||||
headers: HeaderMap,
|
||||
Json(request): Json<CreateWorkspaceWorkerRequest>,
|
||||
) -> ApiResult<Json<BrowserCreateWorkerResponse>> {
|
||||
create_workspace_worker_inner(api, headers, request, None).await
|
||||
}
|
||||
|
||||
async fn create_workspace_worker_inner(
|
||||
api: WorkspaceApi,
|
||||
headers: HeaderMap,
|
||||
request: CreateWorkspaceWorkerRequest,
|
||||
resolved_control_operation: Option<WorkerControlOperation>,
|
||||
) -> ApiResult<Json<BrowserCreateWorkerResponse>> {
|
||||
let CreateWorkspaceWorkerRequest {
|
||||
runtime_id,
|
||||
@@ -12844,7 +12809,6 @@ async fn create_workspace_worker(
|
||||
initial_submit,
|
||||
working_directory,
|
||||
control_operation_id: _,
|
||||
resolved_control_operation,
|
||||
} = request;
|
||||
let config_state = api
|
||||
.config_store
|
||||
@@ -13142,10 +13106,14 @@ fn browser_worker_response_from_summary(
|
||||
);
|
||||
Ok(BrowserCreateWorkerResponse {
|
||||
workspace_id,
|
||||
worker_ref: RuntimeWorkerRef::new(&runtime_id, &worker_id),
|
||||
runtime_id,
|
||||
worker_id,
|
||||
console_href,
|
||||
worker,
|
||||
diagnostics,
|
||||
worker: worker_launch_worker_summary(worker),
|
||||
diagnostics: diagnostics
|
||||
.into_iter()
|
||||
.map(workspace_api::Diagnostic::from)
|
||||
.collect(),
|
||||
})
|
||||
}
|
||||
|
||||
@@ -13576,22 +13544,13 @@ fn compensate_failed_worker_spawn(
|
||||
let cancellation = api
|
||||
.runtime
|
||||
.cancel_worker(&worker.worker, lifecycle_request.clone());
|
||||
let cancellation_accepted = cancellation
|
||||
let stop = api.runtime.stop_worker(&worker.worker, lifecycle_request);
|
||||
let stop_accepted = stop
|
||||
.as_ref()
|
||||
.is_ok_and(|result| result.state == WorkerOperationState::Accepted);
|
||||
let stop = (!cancellation_accepted)
|
||||
.then(|| api.runtime.stop_worker(&worker.worker, lifecycle_request));
|
||||
let stop_accepted = stop.as_ref().is_some_and(|result| {
|
||||
result
|
||||
.as_ref()
|
||||
.is_ok_and(|result| result.state == WorkerOperationState::Accepted)
|
||||
});
|
||||
let termination_detail = (!cancellation_accepted && !stop_accepted).then(|| {
|
||||
let termination_detail = (!stop_accepted).then(|| {
|
||||
let cancellation = lifecycle_failure_detail("cancel", &cancellation);
|
||||
let stop = stop
|
||||
.as_ref()
|
||||
.map(|result| lifecycle_failure_detail("stop", result))
|
||||
.unwrap_or_else(|| "stop was not attempted".to_string());
|
||||
let stop = lifecycle_failure_detail("stop", &stop);
|
||||
format!("{cancellation}; {stop}")
|
||||
});
|
||||
|
||||
@@ -15187,7 +15146,11 @@ fn worker_launch_options_response(api: &WorkspaceApi) -> ApiResult<WorkerLaunchO
|
||||
worker_creation_available: runtime.worker_creation_available,
|
||||
working_directory_required: !built_in,
|
||||
status: runtime.status,
|
||||
diagnostics: runtime.diagnostics,
|
||||
diagnostics: runtime
|
||||
.diagnostics
|
||||
.into_iter()
|
||||
.map(workspace_api::Diagnostic::from)
|
||||
.collect(),
|
||||
}
|
||||
})
|
||||
.collect();
|
||||
@@ -17707,9 +17670,9 @@ mod tests {
|
||||
resolved_config_bundle: None,
|
||||
resolved_worker_observation_enabled: false,
|
||||
resolved_worker_observation_grants: Vec::new(),
|
||||
resolved_control_operation: None,
|
||||
resolved_workspace_api: None,
|
||||
resolved_memory_settings: None,
|
||||
resolved_control_operation: None,
|
||||
};
|
||||
assert!(
|
||||
api.validate_worker_spawn_repository_scope(&workdir_flow_launch)
|
||||
@@ -17953,9 +17916,9 @@ mod tests {
|
||||
resolved_config_bundle: None,
|
||||
resolved_worker_observation_enabled: false,
|
||||
resolved_worker_observation_grants: Vec::new(),
|
||||
resolved_control_operation: None,
|
||||
resolved_workspace_api: None,
|
||||
resolved_memory_settings: None,
|
||||
resolved_control_operation: None,
|
||||
};
|
||||
|
||||
assert!(
|
||||
@@ -18002,7 +17965,6 @@ mod tests {
|
||||
}],
|
||||
working_directory: None,
|
||||
control_operation_id: None,
|
||||
resolved_control_operation: None,
|
||||
}),
|
||||
)
|
||||
.await
|
||||
@@ -18018,7 +17980,8 @@ mod tests {
|
||||
.get_current_ticket_coder_assignment(&api.config.workspace_id, &ticket.id)
|
||||
.unwrap()
|
||||
.unwrap();
|
||||
assert_eq!(current.worker, response.worker_ref);
|
||||
let response_ref = RuntimeWorkerRef::new(&response.runtime_id, &response.worker_id);
|
||||
assert_eq!(current.worker, response_ref);
|
||||
let operation = api
|
||||
.store
|
||||
.get_ticket_assignment_operation(
|
||||
@@ -18028,7 +17991,7 @@ mod tests {
|
||||
.unwrap()
|
||||
.unwrap();
|
||||
assert_eq!(operation.assignment_id, Some(current.assignment_id));
|
||||
assert_eq!(operation.worker, Some(response.worker_ref));
|
||||
assert_eq!(operation.worker, Some(response_ref));
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
@@ -18058,7 +18021,6 @@ mod tests {
|
||||
}],
|
||||
working_directory: None,
|
||||
control_operation_id: None,
|
||||
resolved_control_operation: None,
|
||||
}),
|
||||
)
|
||||
.await;
|
||||
@@ -18092,7 +18054,6 @@ mod tests {
|
||||
initial_submit: Vec::new(),
|
||||
working_directory: None,
|
||||
control_operation_id: None,
|
||||
resolved_control_operation: None,
|
||||
}),
|
||||
)
|
||||
.await
|
||||
@@ -18100,11 +18061,11 @@ mod tests {
|
||||
let mut headers = HeaderMap::new();
|
||||
headers.insert(
|
||||
"x-yoi-runtime-id",
|
||||
axum::http::HeaderValue::from_str(&created.worker_ref.runtime_id).unwrap(),
|
||||
axum::http::HeaderValue::from_str(&created.runtime_id).unwrap(),
|
||||
);
|
||||
headers.insert(
|
||||
"x-yoi-worker-id",
|
||||
axum::http::HeaderValue::from_str(&created.worker_ref.worker_id).unwrap(),
|
||||
axum::http::HeaderValue::from_str(&created.worker_id).unwrap(),
|
||||
);
|
||||
let error =
|
||||
authenticate_worker_mutation_source(&api, "other-workspace", &headers).unwrap_err();
|
||||
@@ -18128,14 +18089,14 @@ mod tests {
|
||||
initial_submit: Vec::new(),
|
||||
working_directory: None,
|
||||
control_operation_id: None,
|
||||
resolved_control_operation: None,
|
||||
}),
|
||||
)
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
let generic_ref = RuntimeWorkerRef::new(&generic.runtime_id, &generic.worker_id);
|
||||
assert!(matches!(
|
||||
require_online_workspace_orchestrator_source(&api, &generic.worker_ref),
|
||||
require_online_workspace_orchestrator_source(&api, &generic_ref),
|
||||
Err(Error::TicketAssignmentConflict(_))
|
||||
));
|
||||
|
||||
@@ -18147,10 +18108,11 @@ mod tests {
|
||||
)
|
||||
.await
|
||||
.unwrap();
|
||||
let orchestrator = started.worker.unwrap().worker;
|
||||
let orchestrator = started.worker.unwrap();
|
||||
let orchestrator = RuntimeWorkerRef::new(&orchestrator.runtime_id, &orchestrator.worker_id);
|
||||
require_online_workspace_orchestrator_source(&api, &orchestrator).unwrap();
|
||||
assert!(matches!(
|
||||
require_online_workspace_orchestrator_source(&api, &generic.worker_ref),
|
||||
require_online_workspace_orchestrator_source(&api, &generic_ref),
|
||||
Err(Error::TicketAssignmentConflict(_))
|
||||
));
|
||||
|
||||
@@ -18219,8 +18181,8 @@ mod tests {
|
||||
assert!(started.online);
|
||||
let worker = started
|
||||
.worker
|
||||
.expect("production Workspace Orchestrator Worker")
|
||||
.worker;
|
||||
.expect("production Workspace Orchestrator Worker");
|
||||
let worker = RuntimeWorkerRef::new(&worker.runtime_id, &worker.worker_id);
|
||||
|
||||
let stopped = api
|
||||
.runtime
|
||||
@@ -18320,12 +18282,12 @@ mod tests {
|
||||
initial_submit: Vec::new(),
|
||||
working_directory: None,
|
||||
control_operation_id: None,
|
||||
resolved_control_operation: None,
|
||||
}),
|
||||
)
|
||||
.await
|
||||
.unwrap();
|
||||
let controller = controller_worker.worker_ref;
|
||||
let controller =
|
||||
RuntimeWorkerRef::new(&controller_worker.runtime_id, &controller_worker.worker_id);
|
||||
assert_ne!(
|
||||
scoped_worker_control_operation_id(&controller, "same-operation"),
|
||||
scoped_worker_control_operation_id(
|
||||
@@ -18351,7 +18313,6 @@ mod tests {
|
||||
initial_submit: Vec::new(),
|
||||
working_directory: None,
|
||||
control_operation_id: Some("control-spawn-retry".to_string()),
|
||||
resolved_control_operation: None,
|
||||
};
|
||||
|
||||
let Json(first) = spawn_known_worker(
|
||||
@@ -18375,7 +18336,8 @@ mod tests {
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
assert_eq!(retried.worker_ref, first.worker_ref);
|
||||
assert_eq!(retried.runtime_id, first.runtime_id);
|
||||
assert_eq!(retried.worker_id, first.worker_id);
|
||||
let mut conflicting_request = request();
|
||||
conflicting_request.display_name = "Different controlled child".to_string();
|
||||
let conflict = spawn_known_worker(
|
||||
@@ -18405,7 +18367,10 @@ mod tests {
|
||||
.list_active_worker_control_grants(&workspace_id, &controller, 10)
|
||||
.unwrap();
|
||||
assert_eq!(grants.len(), 1);
|
||||
assert_eq!(grants[0].subject, first.worker_ref);
|
||||
assert_eq!(
|
||||
grants[0].subject,
|
||||
RuntimeWorkerRef::new(&first.runtime_id, &first.worker_id)
|
||||
);
|
||||
assert_eq!(grants[0].operation_id, "control-spawn-retry");
|
||||
}
|
||||
|
||||
@@ -18427,7 +18392,6 @@ mod tests {
|
||||
initial_submit: Vec::new(),
|
||||
working_directory: None,
|
||||
control_operation_id: None,
|
||||
resolved_control_operation: None,
|
||||
}),
|
||||
)
|
||||
.await
|
||||
@@ -18445,7 +18409,6 @@ mod tests {
|
||||
initial_submit: Vec::new(),
|
||||
working_directory: None,
|
||||
control_operation_id: None,
|
||||
resolved_control_operation: None,
|
||||
}),
|
||||
)
|
||||
.await
|
||||
@@ -18466,14 +18429,16 @@ mod tests {
|
||||
dedicated.singleton_key.as_deref(),
|
||||
Some(crate::hosts::WORKSPACE_ORCHESTRATOR_SINGLETON_KEY)
|
||||
);
|
||||
assert_ne!(dedicated.worker.worker_id, generic.worker_ref.worker_id);
|
||||
let dedicated_ref = RuntimeWorkerRef::new(&dedicated.runtime_id, &dedicated.worker_id);
|
||||
let generic_ref = RuntimeWorkerRef::new(&generic.runtime_id, &generic.worker_id);
|
||||
assert_ne!(dedicated.worker_id, generic.worker_id);
|
||||
|
||||
api.store
|
||||
.create_worker_control_grant(&WorkerControlGrantRecord {
|
||||
workspace_id: workspace_id.clone(),
|
||||
grant_id: "orchestrator-controls-generic".to_string(),
|
||||
controller: dedicated.worker.clone(),
|
||||
subject: generic.worker_ref.clone(),
|
||||
controller: dedicated_ref.clone(),
|
||||
subject: generic_ref.clone(),
|
||||
relation: "spawned".to_string(),
|
||||
origin: "test".to_string(),
|
||||
permissions: vec!["observe".to_string()],
|
||||
@@ -18486,11 +18451,11 @@ mod tests {
|
||||
let mut observation_headers = HeaderMap::new();
|
||||
observation_headers.insert(
|
||||
"x-yoi-runtime-id",
|
||||
axum::http::HeaderValue::from_str(&dedicated.worker.runtime_id).unwrap(),
|
||||
axum::http::HeaderValue::from_str(&dedicated.runtime_id).unwrap(),
|
||||
);
|
||||
observation_headers.insert(
|
||||
"x-yoi-worker-id",
|
||||
axum::http::HeaderValue::from_str(&dedicated.worker.worker_id).unwrap(),
|
||||
axum::http::HeaderValue::from_str(&dedicated.worker_id).unwrap(),
|
||||
);
|
||||
let Json(known) = list_known_workers(
|
||||
State(api.clone()),
|
||||
@@ -18502,7 +18467,7 @@ mod tests {
|
||||
.await
|
||||
.unwrap();
|
||||
assert_eq!(known.items.len(), 1);
|
||||
assert_eq!(known.items[0].subject, generic.worker_ref);
|
||||
assert_eq!(known.items[0].subject, generic_ref);
|
||||
assert_eq!(known.items[0].permissions, ["observe"]);
|
||||
|
||||
let Json(sessions) = scoped_list_worker_observation_sessions(
|
||||
@@ -18521,8 +18486,8 @@ mod tests {
|
||||
.iter()
|
||||
.any(|session| {
|
||||
session["subject"]["kind"] == "runtime_worker"
|
||||
&& session["subject"]["runtime_id"] == generic.worker_ref.runtime_id
|
||||
&& session["subject"]["worker_id"] == generic.worker_ref.worker_id
|
||||
&& session["subject"]["runtime_id"] == generic.runtime_id
|
||||
&& session["subject"]["worker_id"] == generic.worker_id
|
||||
})
|
||||
);
|
||||
let Json(capture) = scoped_capture_worker_observation_session(
|
||||
@@ -18532,8 +18497,8 @@ mod tests {
|
||||
}),
|
||||
observation_headers.clone(),
|
||||
Json(WorkerObservationSubjectRef::RuntimeWorker {
|
||||
runtime_id: generic.worker_ref.runtime_id.clone(),
|
||||
worker_id: generic.worker_ref.worker_id.clone(),
|
||||
runtime_id: generic.runtime_id.clone(),
|
||||
worker_id: generic.worker_id.clone(),
|
||||
}),
|
||||
)
|
||||
.await
|
||||
@@ -18556,8 +18521,8 @@ mod tests {
|
||||
}),
|
||||
observation_headers.clone(),
|
||||
Json(WorkerObservationSubjectRef::RuntimeWorker {
|
||||
runtime_id: generic.worker_ref.runtime_id.clone(),
|
||||
worker_id: generic.worker_ref.worker_id.clone(),
|
||||
runtime_id: generic.runtime_id.clone(),
|
||||
worker_id: generic.worker_id.clone(),
|
||||
}),
|
||||
)
|
||||
.await
|
||||
@@ -18570,11 +18535,11 @@ mod tests {
|
||||
let mut unauthorized_headers = HeaderMap::new();
|
||||
unauthorized_headers.insert(
|
||||
"x-yoi-runtime-id",
|
||||
axum::http::HeaderValue::from_str(&generic.worker_ref.runtime_id).unwrap(),
|
||||
axum::http::HeaderValue::from_str(&generic.runtime_id).unwrap(),
|
||||
);
|
||||
unauthorized_headers.insert(
|
||||
"x-yoi-worker-id",
|
||||
axum::http::HeaderValue::from_str(&generic.worker_ref.worker_id).unwrap(),
|
||||
axum::http::HeaderValue::from_str(&generic.worker_id).unwrap(),
|
||||
);
|
||||
let Json(unauthorized) = scoped_list_worker_observation_sessions(
|
||||
State(api.clone()),
|
||||
@@ -18596,10 +18561,7 @@ mod tests {
|
||||
.await
|
||||
.unwrap();
|
||||
assert_eq!(existing.disposition, "existing");
|
||||
assert_eq!(
|
||||
existing.worker.unwrap().worker.worker_id,
|
||||
dedicated.worker.worker_id
|
||||
);
|
||||
assert_eq!(existing.worker.unwrap().worker_id, dedicated.worker_id);
|
||||
|
||||
let Json(status) = scoped_workspace_orchestrator_status(
|
||||
State(api),
|
||||
@@ -18607,10 +18569,7 @@ mod tests {
|
||||
)
|
||||
.await
|
||||
.unwrap();
|
||||
assert_eq!(
|
||||
status.worker.unwrap().worker.worker_id,
|
||||
dedicated.worker.worker_id
|
||||
);
|
||||
assert_eq!(status.worker.unwrap().worker_id, dedicated.worker_id);
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
@@ -20414,7 +20373,8 @@ mod tests {
|
||||
)
|
||||
.await
|
||||
.unwrap();
|
||||
let orchestrator = started.worker.unwrap().worker;
|
||||
let orchestrator = started.worker.unwrap();
|
||||
let orchestrator = RuntimeWorkerRef::new(&orchestrator.runtime_id, &orchestrator.worker_id);
|
||||
execution.take_inputs();
|
||||
|
||||
let mut input = ticket::NewTicket::new("Bounded notification");
|
||||
@@ -20784,7 +20744,7 @@ mod tests {
|
||||
.iter()
|
||||
.any(|assignment| assignment.role == "coder")
|
||||
);
|
||||
assert_eq!(api.runtime.worker(&worker).unwrap().state, "cancelled");
|
||||
assert_eq!(api.runtime.worker(&worker).unwrap().state, "idle");
|
||||
|
||||
let Json(replayed) = scoped_cancel_ticket_implementation(State(api), path(), request())
|
||||
.await
|
||||
@@ -21525,8 +21485,8 @@ mod tests {
|
||||
.unwrap()
|
||||
.0
|
||||
.worker
|
||||
.expect("Workspace Orchestrator should be available")
|
||||
.worker;
|
||||
.expect("Workspace Orchestrator should be available");
|
||||
let orchestrator = RuntimeWorkerRef::new(&orchestrator.runtime_id, &orchestrator.worker_id);
|
||||
let _ = execution.take_inputs();
|
||||
let backend = browser_ticket_backend(&api).unwrap();
|
||||
let mut input = ticket::NewTicket::new("Queued notification");
|
||||
@@ -21722,7 +21682,7 @@ mod tests {
|
||||
Some(ticket_ref.id.as_str())
|
||||
);
|
||||
*api.orchestrator_attention_fingerprint.lock().unwrap() = None;
|
||||
let worker_id = started.worker.as_ref().unwrap().worker.worker_id.clone();
|
||||
let worker_id = started.worker.as_ref().unwrap().worker_id.clone();
|
||||
maybe_dispatch_orchestrator_turn_end(
|
||||
&api,
|
||||
&worker_id,
|
||||
@@ -21853,9 +21813,9 @@ mod tests {
|
||||
resolved_config_bundle: None,
|
||||
resolved_worker_observation_enabled: false,
|
||||
resolved_worker_observation_grants: Vec::new(),
|
||||
resolved_control_operation: None,
|
||||
resolved_workspace_api: None,
|
||||
resolved_memory_settings: None,
|
||||
resolved_control_operation: None,
|
||||
};
|
||||
let Json(first) = scoped_create_runtime_worker(
|
||||
State(api.clone()),
|
||||
@@ -22018,7 +21978,6 @@ mod tests {
|
||||
ticket_id: second_ticket.id.clone(),
|
||||
operation_id: "pending-spawn-operation".to_string(),
|
||||
}),
|
||||
resolved_control_operation: None,
|
||||
..request
|
||||
};
|
||||
pending_request.resolved_workspace_api =
|
||||
@@ -22136,9 +22095,9 @@ mod tests {
|
||||
resolved_config_bundle: None,
|
||||
resolved_worker_observation_enabled: false,
|
||||
resolved_worker_observation_grants: Vec::new(),
|
||||
resolved_control_operation: None,
|
||||
resolved_workspace_api: None,
|
||||
resolved_memory_settings: None,
|
||||
resolved_control_operation: None,
|
||||
};
|
||||
let Json(created) = scoped_create_runtime_worker(
|
||||
State(api.clone()),
|
||||
@@ -22846,7 +22805,8 @@ mod tests {
|
||||
)
|
||||
.await
|
||||
.unwrap();
|
||||
let source = orchestrator.worker.unwrap().worker;
|
||||
let source = orchestrator.worker.unwrap();
|
||||
let source = RuntimeWorkerRef::new(&source.runtime_id, &source.worker_id);
|
||||
let verified_source = || crate::worker_source::VerifiedWorkerMutationSource {
|
||||
runtime_id: source.runtime_id.clone(),
|
||||
worker_id: source.worker_id.clone(),
|
||||
@@ -22922,7 +22882,8 @@ mod tests {
|
||||
)
|
||||
.await
|
||||
.unwrap();
|
||||
let source = orchestrator.worker.unwrap().worker;
|
||||
let source = orchestrator.worker.unwrap();
|
||||
let source = RuntimeWorkerRef::new(&source.runtime_id, &source.worker_id);
|
||||
|
||||
let spawned = api
|
||||
.spawn_workspace_worker(
|
||||
@@ -27445,9 +27406,9 @@ mod tests {
|
||||
resolved_config_bundle: Some(runtime_test_bundle()),
|
||||
resolved_worker_observation_enabled: false,
|
||||
resolved_worker_observation_grants: Vec::new(),
|
||||
resolved_control_operation: None,
|
||||
resolved_workspace_api: None,
|
||||
resolved_memory_settings: None,
|
||||
resolved_control_operation: None,
|
||||
};
|
||||
let spawned = api
|
||||
.spawn_workspace_worker(EMBEDDED_WORKER_RUNTIME_ID, spawn_request)
|
||||
|
||||
Reference in New Issue
Block a user