Add local pipe registry commands

This commit is contained in:
Eric Wendland 2026-05-17 20:17:26 +02:00
commit c991825127
13 changed files with 235 additions and 14 deletions

View file

@ -13,6 +13,7 @@ use geth_document::{DocumentResource, DocumentState};
use geth_iroh::{EndpointStatus, GethIrohConfig, GethIrohEndpoint, GethRelayMode};
use geth_keychain::{KeychainOp, KeychainOpKind};
use geth_kv::{KvEntry, KvResource};
use geth_pipe::{PipeConnection, PipeListener};
use geth_pubsub::PubsubMessage;
use geth_resource::ResourceDescriptor;
use geth_secrets::{BearerAccess, ResourceMasterSecret};
@ -30,7 +31,7 @@ use geth_types::{
AuthOpId, Capability, KeyId, NodeId, PrincipalId, ResourceId, ResourceKind, ResourceName,
SshCertId, SshCertRequestId, UnixMillis,
};
use std::collections::VecDeque;
use std::collections::{BTreeMap, VecDeque};
use std::path::Path;
use std::sync::{Arc, Mutex};
use tokio::io::{AsyncBufReadExt, AsyncWriteExt, BufReader};
@ -80,6 +81,8 @@ pub enum NodeError {
Secrets(#[from] geth_secrets::SecretsError),
#[error("pubsub error: {0}")]
Pubsub(#[from] geth_pubsub::PubsubError),
#[error("pipe error: {0}")]
Pipe(#[from] geth_pipe::PipeError),
#[error("runtime state lock poisoned")]
RuntimeLockPoisoned,
#[error("invalid ssh certificate kind: {0}")]
@ -110,6 +113,7 @@ pub struct LocalNode {
#[derive(Debug)]
struct NodeRuntime {
pubsub: Mutex<PubsubRuntime>,
pipes: Mutex<PipeRuntime>,
}
#[derive(Debug, Default)]
@ -117,7 +121,14 @@ struct PubsubRuntime {
messages: VecDeque<PubsubMessage>,
}
#[derive(Debug, Default)]
struct PipeRuntime {
listeners: BTreeMap<String, PipeListener>,
connections: VecDeque<PipeConnection>,
}
const PUBSUB_RING_LIMIT: usize = 256;
const PIPE_CONNECTION_RING_LIMIT: usize = 256;
pub fn init_node(paths: &GethPaths) -> Result<LocalNode, NodeError> {
paths.ensure_base_dirs()?;
@ -143,6 +154,7 @@ pub fn init_node(paths: &GethPaths) -> Result<LocalNode, NodeError> {
iroh_status: EndpointStatus::scaffolded(),
runtime: Arc::new(NodeRuntime {
pubsub: Mutex::new(PubsubRuntime::default()),
pipes: Mutex::new(PipeRuntime::default()),
}),
})
}
@ -890,6 +902,42 @@ pub fn handle_request(
note: geth_pubsub::pubsub_storage_warning().to_owned(),
})
}
ControlRequest::PipeListen { name } => {
geth_pipe::validate_pipe_name(&name)?;
let listener = PipeListener {
id: format!("pipe:{name}").into(),
name: name.clone(),
listened_at: UnixMillis(geth_store::now_ms()),
note: geth_pipe::local_pipe_runtime_note().to_owned(),
};
let mut runtime = node
.runtime
.pipes
.lock()
.map_err(|_| NodeError::RuntimeLockPoisoned)?;
runtime.listeners.insert(name, listener.clone());
Ok(ControlResponse::PipeListening { listener })
}
ControlRequest::PipeConnect { target } => {
geth_pipe::validate_pipe_name(&target)?;
let mut runtime = node
.runtime
.pipes
.lock()
.map_err(|_| NodeError::RuntimeLockPoisoned)?;
let local_listener_found = runtime.listeners.contains_key(&target);
let connection = PipeConnection {
target,
connected_at: UnixMillis(geth_store::now_ms()),
local_listener_found,
note: geth_pipe::local_pipe_runtime_note().to_owned(),
};
runtime.connections.push_back(connection.clone());
while runtime.connections.len() > PIPE_CONNECTION_RING_LIMIT {
runtime.connections.pop_front();
}
Ok(ControlResponse::PipeConnected { connection })
}
ControlRequest::ModuleStub { module, command } => {
Ok(ControlResponse::NotImplemented { module, command })
}