aboutsummaryrefslogtreecommitdiff
path: root/src/remote/host.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/remote/host.rs')
-rw-r--r--src/remote/host.rs46
1 files changed, 46 insertions, 0 deletions
diff --git a/src/remote/host.rs b/src/remote/host.rs
new file mode 100644
index 00000000..1ff6d1e5
--- /dev/null
+++ b/src/remote/host.rs
@@ -0,0 +1,46 @@
+//! Remote-host side of the SSH stdio bridge.
+
+use std::io;
+use std::time::Duration;
+
+pub(crate) fn run_remote_client_bridge() -> io::Result<()> {
+ ensure_remote_server_running()?;
+
+ let socket_path = crate::server::socket_paths::client_socket_path();
+ let stream = crate::ipc::connect_local_stream(&socket_path).map_err(|err| {
+ io::Error::new(
+ err.kind(),
+ format!(
+ "failed to connect to remote Herdr client socket {}: {err}",
+ socket_path.display()
+ ),
+ )
+ })?;
+
+ crate::platform::forward_remote_bridge_stdio(stream)
+}
+
+fn ensure_remote_server_running() -> io::Result<()> {
+ let socket_path = crate::server::socket_paths::client_socket_path();
+ if crate::server::autodetect::is_server_listening() {
+ let status = crate::api::read_runtime_status_at(
+ &crate::api::socket_path(),
+ Duration::from_millis(500),
+ )?
+ .ok_or_else(|| io::Error::other("remote server status API is unavailable"))?;
+ if status
+ .capabilities
+ .as_ref()
+ .and_then(|capabilities| capabilities.endpoint_protocol_generation)
+ == Some(crate::protocol::endpoint::ENDPOINT_PROTOCOL_GENERATION)
+ {
+ return Ok(());
+ }
+ return Err(io::Error::other(
+ "remote herdr server needs one final update before this bridge can attach; rerun `herdr --remote` from an interactive terminal to approve it",
+ ));
+ }
+
+ crate::server::autodetect::spawn_server_daemon()?;
+ crate::server::autodetect::wait_for_server_socket(&socket_path, Duration::from_secs(5))
+}