Bump to 0.16.4 and fix #80 and fix #102

This commit is contained in:
Chip Senkbeil 2022-06-01 15:35:29 -05:00
parent e4199bb773
commit 4180ae279a
No known key found for this signature in database
GPG Key ID: 35EF1F8EC72A4131
12 changed files with 409 additions and 357 deletions

View File

@ -11,6 +11,15 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Fixed
### Removed
## [0.16.4] - 2022-06-01
### Added
- Dockerfile using Alpine linux with a basic install of distant, tagged as
`chipsenkbeil/distant:0.16.3`
### Fixed
- [Issue #90](https://github.com/chipsenkbeil/distant/issues/90)
- [Issue #103](https://github.com/chipsenkbeil/distant/issues/103)
## [0.16.3] - 2022-05-29
### Added
- New `--ssh-backend` option for CLI that accepts `libssh` or `ssh2` for

667
Cargo.lock generated

File diff suppressed because it is too large Load Diff

View File

@ -3,7 +3,7 @@ name = "distant"
description = "Operate on a remote computer through file and process manipulation"
categories = ["command-line-utilities"]
keywords = ["cli"]
version = "0.16.3"
version = "0.16.4"
authors = ["Chip Senkbeil <chip@senkbeil.org>"]
edition = "2018"
homepage = "https://github.com/chipsenkbeil/distant"
@ -26,7 +26,7 @@ ssh2 = ["distant-ssh2/ssh2"]
[dependencies]
derive_more = { version = "0.99.16", default-features = false, features = ["display", "from", "error", "is_variant"] }
distant-core = { version = "=0.16.3", path = "distant-core", features = ["structopt"] }
distant-core = { version = "=0.16.4", path = "distant-core", features = ["structopt"] }
flexi_logger = "0.18.0"
indoc = "1.0.3"
log = "0.4.14"
@ -43,7 +43,7 @@ termwiz = "0.15.0"
whoami = "1.1.2"
# Optional native SSH functionality
distant-ssh2 = { version = "=0.16.3", path = "distant-ssh2", default-features = false, features = ["serde"], optional = true }
distant-ssh2 = { version = "=0.16.4", path = "distant-ssh2", default-features = false, features = ["serde"], optional = true }
[target.'cfg(unix)'.dependencies]
fork = "0.1.18"

View File

@ -6,7 +6,7 @@ RUN apk add --no-cache curl
# 1. Specify the distant version
# 2. Download the MUSL artifact as alpine uses musl
# 3. Make the binary executable
ARG distant_version=0.16.3
ARG distant_version=0.16.4
ARG distant_url=https://github.com/chipsenkbeil/distant/releases/download/v${distant_version}/distant-linux64-musl
RUN curl -L ${distant_url} > /usr/local/bin/distant && chmod +x /usr/local/bin/distant

View File

@ -3,7 +3,7 @@ name = "distant-core"
description = "Core library for distant, enabling operation on a remote computer through file and process manipulation"
categories = ["network-programming"]
keywords = ["api", "async"]
version = "0.16.3"
version = "0.16.4"
authors = ["Chip Senkbeil <chip@senkbeil.org>"]
edition = "2018"
homepage = "https://github.com/chipsenkbeil/distant"

View File

@ -283,7 +283,7 @@ impl Session {
tokio::try_join!(self.request_task, self.response_task).map(|_| ())
}
/// Abort the session's current connection by forcing its response task to shutdown
/// Abort the session's current connection by forcing its tasks to abort
pub fn abort(&self) {
self.request_task.abort();
self.response_task.abort();

View File

@ -2,7 +2,7 @@
name = "distant-ssh2"
description = "Library to enable native ssh-2 protocol for use with distant sessions"
categories = ["network-programming"]
version = "0.16.3"
version = "0.16.4"
authors = ["Chip Senkbeil <chip@senkbeil.org>"]
edition = "2018"
homepage = "https://github.com/chipsenkbeil/distant"
@ -17,7 +17,7 @@ ssh2 = ["wezterm-ssh/ssh2", "wezterm-ssh/vendored-openssl-ssh2"]
[dependencies]
async-compat = "0.2.1"
distant-core = { version = "=0.16.3", path = "../distant-core" }
distant-core = { version = "=0.16.4", path = "../distant-core" }
futures = "0.3.16"
log = "0.4.14"
rand = { version = "0.8.4", features = ["getrandom"] }

View File

@ -513,7 +513,7 @@ impl Ssh2Session {
let host = self.host().to_string();
// Turn our ssh connection into a client session so we can use it to spawn our server
let mut session = self.into_ssh_client_session().await?;
let (mut session, cleanup_session) = self.into_ssh_client_session_impl().await?;
// Build arguments for distant to execute listen subcommand
let mut args = vec![
@ -560,6 +560,7 @@ impl Ssh2Session {
.map_err(|x| io::Error::new(io::ErrorKind::BrokenPipe, x))?;
// Close out ssh session
cleanup_session();
session.abort();
let _ = session.wait().await;
let mut output = Vec::new();
@ -609,6 +610,10 @@ impl Ssh2Session {
/// Consume [`Ssh2Session`] and produce a distant [`Session`] that is powered by an ssh client
/// underneath
pub async fn into_ssh_client_session(self) -> io::Result<Session> {
self.into_ssh_client_session_impl().await.map(|x| x.0)
}
async fn into_ssh_client_session_impl(self) -> io::Result<(Session, Box<dyn FnOnce()>)> {
// Exit early if not authenticated as this is a requirement
if !self.authenticated {
return Err(io::Error::new(
@ -630,7 +635,7 @@ impl Ssh2Session {
} = self;
let (tx, mut rx) = mpsc::channel(1);
tokio::spawn(async move {
let request_task = tokio::spawn(async move {
let state = Arc::new(Mutex::new(handler::State::default()));
while let Ok(Some(req)) = t_read.receive::<Request>().await {
if let Err(x) =
@ -642,7 +647,7 @@ impl Ssh2Session {
debug!("Ssh receiver task is now closed");
});
tokio::spawn(async move {
let send_task = tokio::spawn(async move {
while let Some(res) = rx.recv().await {
if let Err(x) = t_write.send(res).await {
error!("Ssh session sender failed: {}", x);
@ -652,6 +657,12 @@ impl Ssh2Session {
debug!("Ssh sender task is now closed");
});
Ok(session)
Ok((
session,
Box::new(move || {
send_task.abort();
request_task.abort();
}),
))
}
}

View File

@ -11,19 +11,22 @@ use tokio::task::{JoinError, JoinHandle};
/// Represents a link between a remote process' stdin/stdout/stderr and this process'
/// stdin/stdout/stderr
pub struct RemoteProcessLink {
_stdin_thread: thread::JoinHandle<()>,
stdin_task: JoinHandle<io::Result<()>>,
_stdin_thread: Option<thread::JoinHandle<()>>,
stdin_task: Option<JoinHandle<io::Result<()>>>,
stdout_task: JoinHandle<io::Result<()>>,
stderr_task: JoinHandle<io::Result<()>>,
}
macro_rules! from_pipes {
($stdin:expr, $stdout:expr, $stderr:expr) => {{
let (stdin_thread, mut stdin_rx) = stdin::spawn_channel(MAX_PIPE_CHUNK_SIZE);
let stdin_task = tokio::spawn(async move {
let mut stdin_thread = None;
let mut stdin_task = None;
if let Some(mut stdin_handle) = $stdin {
let (thread, mut rx) = stdin::spawn_channel(MAX_PIPE_CHUNK_SIZE);
let task = tokio::spawn(async move {
loop {
if let Some(input) = stdin_rx.recv().await {
if let Err(x) = $stdin.write(&*input).await {
if let Some(input) = rx.recv().await {
if let Err(x) = stdin_handle.write(&*input).await {
break Err(x);
}
} else {
@ -31,6 +34,9 @@ macro_rules! from_pipes {
}
}
});
stdin_thread = Some(thread);
stdin_task = Some(task);
}
let stdout_task = tokio::spawn(async move {
let handle = io::stdout();
loop {
@ -70,7 +76,7 @@ macro_rules! from_pipes {
impl RemoteProcessLink {
/// Creates a new process link from the pipes of a remote process
pub fn from_remote_pipes(
mut stdin: RemoteStdin,
stdin: Option<RemoteStdin>,
mut stdout: RemoteStdout,
mut stderr: RemoteStderr,
) -> Self {
@ -79,7 +85,7 @@ impl RemoteProcessLink {
/// Creates a new process link from the pipes of a remote LSP server process
pub fn from_remote_lsp_pipes(
mut stdin: RemoteLspStdin,
stdin: Option<RemoteLspStdin>,
mut stdout: RemoteLspStdout,
mut stderr: RemoteLspStderr,
) -> Self {
@ -94,12 +100,18 @@ impl RemoteProcessLink {
/// Waits for the stdin, stdout, and stderr tasks to complete
pub async fn wait(self) -> Result<(), JoinError> {
tokio::try_join!(self.stdin_task, self.stdout_task, self.stderr_task).map(|_| ())
if let Some(stdin_task) = self.stdin_task {
tokio::try_join!(stdin_task, self.stdout_task, self.stderr_task).map(|_| ())
} else {
tokio::try_join!(self.stdout_task, self.stderr_task).map(|_| ())
}
}
/// Aborts the link by aborting tasks processing stdin, stdout, and stderr
pub fn abort(&self) {
self.stdin_task.abort();
if let Some(stdin_task) = self.stdin_task.as_ref() {
stdin_task.abort();
}
self.stdout_task.abort();
self.stderr_task.abort();
}

View File

@ -147,7 +147,7 @@ async fn start(
// Now, map the remote process' stdin/stdout/stderr to our own process
let link = RemoteProcessLink::from_remote_pipes(
proc.stdin.take().unwrap(),
proc.stdin.take(),
proc.stdout.take().unwrap(),
proc.stderr.take().unwrap(),
);

View File

@ -96,7 +96,7 @@ async fn start(
// Now, map the remote LSP server's stdin/stdout/stderr to our own process
let link = RemoteProcessLink::from_remote_lsp_pipes(
proc.stdin.take().unwrap(),
proc.stdin.take(),
proc.stdout.take().unwrap(),
proc.stderr.take().unwrap(),
);

View File

@ -6,7 +6,7 @@ use crate::{
utils,
};
use derive_more::{Display, Error, From};
use distant_core::{LspData, PtySize, RemoteProcess, RemoteProcessError, RemoteStdin, Session};
use distant_core::{LspData, PtySize, RemoteProcess, RemoteProcessError, Session};
use log::*;
use terminal_size::{terminal_size, Height, Width};
use termwiz::{
@ -139,9 +139,10 @@ async fn start(
}
});
// Now, map the remote LSP server's stdin/stdout/stderr to our own process
// Now, map the remote shell's stdout/stderr to our own process,
// while stdin is handled by the task above
let link = RemoteProcessLink::from_remote_pipes(
RemoteStdin::disconnected(),
None,
proc.stdout.take().unwrap(),
proc.stderr.take().unwrap(),
);