MCPcopy Create free account
hub / github.com/NVIDIA/OpenShell / ssh_tar_upload

Function ssh_tar_upload

crates/openshell-cli/src/ssh.rs:751–799  ·  view source on GitHub ↗

Core tar-over-SSH upload: streams a tar archive into `dest_dir` on the sandbox. Callers are responsible for splitting the destination path so that `dest_dir` is always a directory. When `dest_dir` is `None`, the sandbox user's home directory (`$HOME`) is used as the extraction target. This avoids hard-coding any particular path and works for custom container images with non-default `WORKDIR`.

(
    server: &str,
    name: &str,
    dest_dir: Option<&str>,
    source: UploadSource,
    tls: &TlsOptions,
)

Source from the content-addressed store, hash-verified

749/// used as the extraction target. This avoids hard-coding any particular
750/// path and works for custom container images with non-default `WORKDIR`.
751async fn ssh_tar_upload(
752 server: &str,
753 name: &str,
754 dest_dir: Option<&str>,
755 source: UploadSource,
756 tls: &TlsOptions,
757) -> Result<()> {
758 let session = ssh_session_config(server, name, tls).await?;
759
760 // When no explicit destination is given, use the unescaped `$HOME` shell
761 // variable so the remote shell resolves it at runtime.
762 let escaped_dest = dest_dir.map_or_else(|| "$HOME".to_string(), shell_escape);
763
764 let mut ssh = ssh_base_command(&session.proxy_command);
765 ssh.arg("-T")
766 .arg("-o")
767 .arg("RequestTTY=no")
768 .arg("sandbox")
769 .arg(format!(
770 "mkdir -p {escaped_dest} && cat | tar xf - -C {escaped_dest}",
771 ))
772 .stdin(Stdio::piped())
773 .stdout(Stdio::inherit())
774 .stderr(Stdio::inherit());
775
776 let mut child = ssh.spawn().into_diagnostic()?;
777 let stdin = child
778 .stdin
779 .take()
780 .ok_or_else(|| miette::miette!("failed to open stdin for ssh process"))?;
781
782 // Build the tar archive in a blocking task since the tar crate is synchronous.
783 tokio::task::spawn_blocking(move || -> Result<()> { write_upload_archive(stdin, source) })
784 .await
785 .into_diagnostic()??;
786
787 let status = tokio::task::spawn_blocking(move || child.wait())
788 .await
789 .into_diagnostic()?
790 .into_diagnostic()?;
791
792 if !status.success() {
793 return Err(miette::miette!(
794 "ssh tar extract exited with status {status}"
795 ));
796 }
797
798 Ok(())
799}
800
801/// Split a sandbox path into (`parent_directory`, basename).
802///

Callers 2

sandbox_sync_up_filesFunction · 0.85
sandbox_sync_upFunction · 0.85

Calls 6

ssh_session_configFunction · 0.85
ssh_base_commandFunction · 0.85
write_upload_archiveFunction · 0.85
waitMethod · 0.80
spawnMethod · 0.45
successMethod · 0.45

Tested by

no test coverage detected