Skip to content

Commit

Permalink
WIP Squash into sftp commit / make uploaded files executable
Browse files Browse the repository at this point in the history
  • Loading branch information
MarkusPettersson98 committed Dec 11, 2024
1 parent 78ebdb2 commit ea43a8d
Showing 1 changed file with 21 additions and 6 deletions.
27 changes: 21 additions & 6 deletions test/test-manager/src/vm/provision.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use crate::{
tests::config::BOOTSTRAP_SCRIPT,
};
use anyhow::{bail, Context, Result};
use ssh2::Session;
use ssh2::{File, Session};
use std::{
io::{self, Read},
net::{IpAddr, SocketAddr, TcpStream},
Expand Down Expand Up @@ -115,6 +115,7 @@ fn blocking_ssh(
let temp_dir = Path::new(remote_temp_dir);
// Transfer a test runner
let source = local_runner_dir.join("test-runner");
// TODO: Create good API for making these files executable if necessary
ssh_send_file(&session, &source, temp_dir)
.with_context(|| format!("Failed to send '{source:?}' to remote"))?;

Expand Down Expand Up @@ -145,8 +146,10 @@ fn blocking_ssh(
// TODO: Move this name to a constant somewhere?
if matches!(os_type, OsType::Linux | OsType::Macos) {
let bootstrap_script_dest = temp_dir.join("ssh-setup.sh");
ssh_write(&session, &bootstrap_script_dest, BOOTSTRAP_SCRIPT)
let bootstrap_script = ssh_write(&session, &bootstrap_script_dest, BOOTSTRAP_SCRIPT)
.context("failed to send bootstrap script to remote")?;
// Make sure that the script is executable!
make_executable(bootstrap_script)?;

// Run setup script
let app_package_path = local_app_manifest
Expand Down Expand Up @@ -201,19 +204,31 @@ fn ssh_send_file<P: AsRef<Path> + Copy>(
let source = std::fs::read(source)
.with_context(|| format!("Failed to open file at {}", source.as_ref().display()))?;

ssh_write(session, &dest, &source[..])?;
let remote_file = ssh_write(session, &dest, &source[..])?;
make_executable(remote_file)?;

Ok(dest)
}

/// Analogues to [`std::fs::write`], but over ssh!
fn ssh_write<P: AsRef<Path>>(session: &Session, dest: P, mut source: impl Read) -> Result<()> {
/// Create a new file at location `dest` and write the content of `source` into it.
/// Returns a handle to the newly created file.
fn ssh_write<P: AsRef<Path>>(session: &Session, dest: P, mut source: impl Read) -> Result<File> {
let sftp = session.sftp()?;
let mut remote_file = sftp.create(dest.as_ref())?;

io::copy(&mut source, &mut remote_file).context("failed to write file")?;

Ok(())
Ok(remote_file)
}

fn make_executable(mut file: File) -> Result<File> {
// Make sure that the script is executable!
let mut file_stat = file.stat()?;
// 0x111 is the executable bit for Owner/Group/Public
let perm = file_stat.perm.map(|perm| perm | 0x111).unwrap_or(0x111);
file_stat.perm = Some(perm);
file.setstat(file_stat)?;
Ok(file)
}

/// Execute an arbitrary string of commands via ssh.
Expand Down

0 comments on commit ea43a8d

Please sign in to comment.