fix: refresh repository access for worker workdirs
This commit is contained in:
@@ -6504,15 +6504,6 @@ async fn open_current_worker_workdir_session_locked(
|
|||||||
worker: &RuntimeWorkerRef,
|
worker: &RuntimeWorkerRef,
|
||||||
link: &WorkerWorkdirLinkRecord,
|
link: &WorkerWorkdirLinkRecord,
|
||||||
) -> Result<WorkdirSessionHandle> {
|
) -> Result<WorkdirSessionHandle> {
|
||||||
if let Some(session) = api
|
|
||||||
.workdir_sessions
|
|
||||||
.lock()
|
|
||||||
.expect("Workdir session registry lock poisoned")
|
|
||||||
.get(worker)
|
|
||||||
.cloned()
|
|
||||||
{
|
|
||||||
return Ok(session);
|
|
||||||
}
|
|
||||||
let workdir = api
|
let workdir = api
|
||||||
.store
|
.store
|
||||||
.list_workdir_registry(&api.config.workspace_id, 10_000)?
|
.list_workdir_registry(&api.config.workspace_id, 10_000)?
|
||||||
@@ -6526,6 +6517,40 @@ async fn open_current_worker_workdir_session_locked(
|
|||||||
link.workdir_id
|
link.workdir_id
|
||||||
),
|
),
|
||||||
})?;
|
})?;
|
||||||
|
let repository = api
|
||||||
|
.require_configured_workspace_repository(&workdir.repository_id)
|
||||||
|
.map_err(|error| error.error)?;
|
||||||
|
let repository_requires_access =
|
||||||
|
repository.source.kind == workspace_api::RepositorySourceKind::Ssh;
|
||||||
|
if repository_requires_access {
|
||||||
|
close_current_worker_session_locked(api, worker).await?;
|
||||||
|
let access = repository_access_request_for_workdir(
|
||||||
|
api,
|
||||||
|
&workdir.runtime_id,
|
||||||
|
&workdir.workdir_id,
|
||||||
|
&format!(
|
||||||
|
"workdir-session:{}:{}:{}",
|
||||||
|
worker.runtime_id, worker.worker_id, workdir.workdir_id
|
||||||
|
),
|
||||||
|
)
|
||||||
|
.map_err(|error| error.error)?
|
||||||
|
.ok_or_else(|| Error::RuntimeOperationFailed {
|
||||||
|
runtime_id: workdir.runtime_id.clone(),
|
||||||
|
code: "working_directory_remote_repository_access_required".to_string(),
|
||||||
|
message: "current Repository SSH access authority is unavailable".to_string(),
|
||||||
|
})?;
|
||||||
|
api.runtime
|
||||||
|
.authorize_working_directory_repository_access(&workdir.runtime_id, access)
|
||||||
|
.map_err(RuntimeRegistryError::into_error)?;
|
||||||
|
} else if let Some(session) = api
|
||||||
|
.workdir_sessions
|
||||||
|
.lock()
|
||||||
|
.expect("Workdir session registry lock poisoned")
|
||||||
|
.get(worker)
|
||||||
|
.cloned()
|
||||||
|
{
|
||||||
|
return Ok(session);
|
||||||
|
}
|
||||||
let owner_worker_id = runtime_local_owner_worker_id(worker, &workdir.runtime_id);
|
let owner_worker_id = runtime_local_owner_worker_id(worker, &workdir.runtime_id);
|
||||||
let session = api
|
let session = api
|
||||||
.runtime
|
.runtime
|
||||||
@@ -12071,14 +12096,31 @@ async fn create_runtime_worker(
|
|||||||
.as_ref()
|
.as_ref()
|
||||||
.map(|working_directory| configured_working_directory_request(&api, working_directory))
|
.map(|working_directory| configured_working_directory_request(&api, working_directory))
|
||||||
.transpose()?;
|
.transpose()?;
|
||||||
|
let repository_operation_id = request
|
||||||
|
.resolved_control_operation
|
||||||
|
.as_ref()
|
||||||
|
.map(|operation| operation.operation_id.clone())
|
||||||
|
.or_else(|| {
|
||||||
|
request
|
||||||
|
.ticket_assignment
|
||||||
|
.as_ref()
|
||||||
|
.map(|assignment| assignment.operation_id.clone())
|
||||||
|
});
|
||||||
let prepared_workdir_id = if let Some(working_directory_request) =
|
let prepared_workdir_id = if let Some(working_directory_request) =
|
||||||
request.resolved_working_directory_request.as_mut()
|
request.resolved_working_directory_request.as_mut()
|
||||||
{
|
{
|
||||||
Some(upsert_pending_backend_workdir(
|
let workdir_id =
|
||||||
|
upsert_pending_backend_workdir(&api, &runtime_id, working_directory_request)?;
|
||||||
|
let operation_id = repository_operation_id
|
||||||
|
.clone()
|
||||||
|
.unwrap_or_else(|| format!("worker-spawn-workdir:{workdir_id}"));
|
||||||
|
authorize_worker_spawn_workdir_materialization(
|
||||||
&api,
|
&api,
|
||||||
&runtime_id,
|
&runtime_id,
|
||||||
|
&operation_id,
|
||||||
working_directory_request,
|
working_directory_request,
|
||||||
)?)
|
)?;
|
||||||
|
Some(workdir_id)
|
||||||
} else {
|
} else {
|
||||||
request
|
request
|
||||||
.resolved_working_directory
|
.resolved_working_directory
|
||||||
@@ -14236,6 +14278,16 @@ fn repository_access_expiry() -> u64 {
|
|||||||
.saturating_add(300)
|
.saturating_add(300)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn authorize_worker_spawn_workdir_materialization(
|
||||||
|
api: &WorkspaceApi,
|
||||||
|
runtime_id: &str,
|
||||||
|
operation_id: &str,
|
||||||
|
request: &mut WorkingDirectoryRequest,
|
||||||
|
) -> ApiResult<()> {
|
||||||
|
let projection = active_repository_access_projection(api, &api.config.workspace_id)?;
|
||||||
|
authorize_repository_materialization(api, runtime_id, operation_id, &projection, request)
|
||||||
|
}
|
||||||
|
|
||||||
fn authorize_repository_materialization(
|
fn authorize_repository_materialization(
|
||||||
api: &WorkspaceApi,
|
api: &WorkspaceApi,
|
||||||
runtime_id: &str,
|
runtime_id: &str,
|
||||||
@@ -15445,6 +15497,21 @@ mod tests {
|
|||||||
.is_err()
|
.is_err()
|
||||||
);
|
);
|
||||||
|
|
||||||
|
let mut local_workdir_request =
|
||||||
|
working_directory_request_from_repository(&api.config.repositories[0], Some("HEAD"));
|
||||||
|
authorize_worker_spawn_workdir_materialization(
|
||||||
|
&api,
|
||||||
|
"runtime-1",
|
||||||
|
"worker-spawn-operation",
|
||||||
|
&mut local_workdir_request,
|
||||||
|
)
|
||||||
|
.unwrap();
|
||||||
|
let materialization = local_workdir_request.materialization.unwrap();
|
||||||
|
assert_eq!(materialization.workspace_id, api.config.workspace_id);
|
||||||
|
assert_eq!(materialization.runtime_id, "runtime-1");
|
||||||
|
assert_eq!(materialization.operation_id, "worker-spawn-operation");
|
||||||
|
assert!(materialization.ssh.is_none());
|
||||||
|
|
||||||
let mut foreign_repository = api.config.repositories[0].clone();
|
let mut foreign_repository = api.config.repositories[0].clone();
|
||||||
foreign_repository.id = "foreign".to_string();
|
foreign_repository.id = "foreign".to_string();
|
||||||
let workdir_flow_launch = WorkerSpawnRequest {
|
let workdir_flow_launch = WorkerSpawnRequest {
|
||||||
|
|||||||
Reference in New Issue
Block a user