exp: cross #2
This commit is contained in:
@@ -2,7 +2,9 @@
|
||||
/// Context driver: Copies over SFTP with ssh2, executes commands over ssh2 channels
|
||||
use super::api::ContextDriver;
|
||||
use log::debug;
|
||||
use ssh2;
|
||||
use std::fs;
|
||||
use std::io::Write;
|
||||
use std::io::{self, Read};
|
||||
use std::net::TcpStream;
|
||||
#[cfg(unix)]
|
||||
@@ -90,7 +92,13 @@ impl ContextDriver for SshDriver {
|
||||
Ok(files)
|
||||
}
|
||||
|
||||
fn run(&self, program: &str, args: &[String], env: &[(String, String)]) -> io::Result<std::process::ExitStatus> {
|
||||
fn run(
|
||||
&self,
|
||||
program: &str,
|
||||
args: &[String],
|
||||
env: &[(String, String)],
|
||||
cwd: Option<&str>,
|
||||
) -> io::Result<std::process::ExitStatus> {
|
||||
let sess = connect_ssh(&self.host, self.user.as_deref(), self.port)?;
|
||||
let mut channel = sess.channel_session().map_err(io::Error::other)?;
|
||||
|
||||
@@ -98,7 +106,14 @@ impl ContextDriver for SshDriver {
|
||||
// TODO: No, use ssh2 channel.set_env
|
||||
let mut cmd_line = String::new();
|
||||
for (key, value) in env {
|
||||
cmd_line.push_str(&format!("export {}='{}'; ", key, value.replace("'", "'\\''")));
|
||||
cmd_line.push_str(&format!(
|
||||
"export {}='{}'; ",
|
||||
key,
|
||||
value.replace("'", "'\\''")
|
||||
));
|
||||
}
|
||||
if let Some(dir) = cwd {
|
||||
cmd_line.push_str(&format!("cd {} && ", dir));
|
||||
}
|
||||
cmd_line.push_str(program);
|
||||
for arg in args {
|
||||
@@ -124,14 +139,27 @@ impl ContextDriver for SshDriver {
|
||||
Ok(ExitStatus::from_raw(code))
|
||||
}
|
||||
|
||||
fn run_output(&self, program: &str, args: &[String], env: &[(String, String)]) -> io::Result<std::process::Output> {
|
||||
fn run_output(
|
||||
&self,
|
||||
program: &str,
|
||||
args: &[String],
|
||||
env: &[(String, String)],
|
||||
cwd: Option<&str>,
|
||||
) -> io::Result<std::process::Output> {
|
||||
let sess = connect_ssh(&self.host, self.user.as_deref(), self.port)?;
|
||||
let mut channel = sess.channel_session().map_err(io::Error::other)?;
|
||||
|
||||
// Construct command line with env vars
|
||||
let mut cmd_line = String::new();
|
||||
for (key, value) in env {
|
||||
cmd_line.push_str(&format!("export {}='{}'; ", key, value.replace("'", "'\\''")));
|
||||
cmd_line.push_str(&format!(
|
||||
"export {}='{}'; ",
|
||||
key,
|
||||
value.replace("'", "'\\''")
|
||||
));
|
||||
}
|
||||
if let Some(dir) = cwd {
|
||||
cmd_line.push_str(&format!("cd {} && ", dir));
|
||||
}
|
||||
cmd_line.push_str(program);
|
||||
for arg in args {
|
||||
@@ -164,7 +192,7 @@ impl ContextDriver for SshDriver {
|
||||
})
|
||||
}
|
||||
|
||||
fn prepare_work_dir(&self) -> io::Result<String> {
|
||||
fn create_temp_dir(&self) -> io::Result<String> {
|
||||
let sess = connect_ssh(&self.host, self.user.as_deref(), self.port)?;
|
||||
let mut channel = sess.channel_session().map_err(io::Error::other)?;
|
||||
|
||||
@@ -182,6 +210,40 @@ impl ContextDriver for SshDriver {
|
||||
|
||||
Ok(stdout.trim().to_string())
|
||||
}
|
||||
|
||||
fn copy_path(&self, src: &Path, dest: &Path) -> io::Result<()> {
|
||||
let sess = connect_ssh(&self.host, self.user.as_deref(), self.port)?;
|
||||
let mut channel = sess.channel_session().map_err(io::Error::other)?;
|
||||
// TODO: use sftp
|
||||
let cmd = format!("cp -a {:?} {:?}", src, dest);
|
||||
debug!("Executing remote copy: {}", cmd);
|
||||
channel.exec(&cmd).map_err(io::Error::other)?;
|
||||
channel.wait_close().map_err(io::Error::other)?;
|
||||
if channel.exit_status().unwrap_or(-1) != 0 {
|
||||
return Err(io::Error::other(format!("Remote copy failed: {}", cmd)));
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn read_file(&self, path: &Path) -> io::Result<String> {
|
||||
let sess = connect_ssh(&self.host, self.user.as_deref(), self.port)?;
|
||||
let sftp = sess.sftp().map_err(io::Error::other)?;
|
||||
let mut remote_file = sftp.open(path).map_err(io::Error::other)?;
|
||||
let mut content = String::new();
|
||||
remote_file.read_to_string(&mut content)?;
|
||||
Ok(content)
|
||||
}
|
||||
|
||||
fn write_file(&self, path: &Path, content: &str) -> io::Result<()> {
|
||||
let sess = connect_ssh(&self.host, self.user.as_deref(), self.port)?;
|
||||
let sftp = sess.sftp().map_err(io::Error::other)?;
|
||||
if let Some(parent) = path.parent() {
|
||||
let _ = sftp.mkdir(parent, 0o755);
|
||||
}
|
||||
let mut remote_file = sftp.create(path).map_err(io::Error::other)?;
|
||||
remote_file.write_all(content.as_bytes())?;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl SshDriver {
|
||||
|
||||
Reference in New Issue
Block a user