use std::os::fd::{FromRawFd, OwnedFd};
use std::sync::Arc;
use arcbox_constants::ports::{KUBERNETES_API_HOST_PORT, KUBERNETES_API_VSOCK_PORT};
use arcbox_core::Runtime;
use arcbox_docker::proxy::RawFdStream;
use tokio::net::TcpListener;
use tracing::{info, warn};
pub async fn start(runtime: Arc<Runtime>) -> Option<tokio::task::JoinHandle<()>> {
let listener = match TcpListener::bind(("127.0.0.1", KUBERNETES_API_HOST_PORT)).await {
Ok(listener) => listener,
Err(e) => {
warn!(
"Failed to bind Kubernetes API proxy on 127.0.0.1:{}: {}",
KUBERNETES_API_HOST_PORT, e
);
return None;
}
};
info!(
"Kubernetes API proxy listening on 127.0.0.1:{}",
KUBERNETES_API_HOST_PORT
);
let handle = tokio::spawn(async move {
loop {
let Ok((mut host_stream, _)) = listener.accept().await else {
continue;
};
let runtime = Arc::clone(&runtime);
tokio::spawn(async move {
let fd = match runtime
.connect_vsock_port(runtime.default_machine_name(), KUBERNETES_API_VSOCK_PORT)
{
Ok(fd) => fd,
Err(e) => {
tracing::debug!("failed to connect Kubernetes API vsock: {}", e);
return;
}
};
let owned = unsafe { OwnedFd::from_raw_fd(fd) };
let mut guest_stream = match RawFdStream::new(owned) {
Ok(stream) => stream,
Err(e) => {
tracing::debug!("failed to wrap Kubernetes API fd: {}", e);
return;
}
};
if let Err(e) =
tokio::io::copy_bidirectional(&mut host_stream, &mut guest_stream).await
{
tracing::debug!("Kubernetes API proxy connection ended: {}", e);
}
});
}
});
Some(handle)
}