From 2618441de334b49837af65dbfb72999dec5a4ba6 Mon Sep 17 00:00:00 2001 From: Jean-Gabriel Gill-Couture Date: Thu, 21 Aug 2025 17:31:43 -0400 Subject: [PATCH] fix: Make sure directory exists before uploading file in opnsense http --- opnsense-config/src/config/shell/ssh.rs | 27 ++++++++++++++++++++----- 1 file changed, 22 insertions(+), 5 deletions(-) diff --git a/opnsense-config/src/config/shell/ssh.rs b/opnsense-config/src/config/shell/ssh.rs index 93586bc..0b5ddea 100644 --- a/opnsense-config/src/config/shell/ssh.rs +++ b/opnsense-config/src/config/shell/ssh.rs @@ -1,5 +1,6 @@ use std::{ net::IpAddr, + path::Path, sync::Arc, time::{SystemTime, UNIX_EPOCH}, }; @@ -48,7 +49,6 @@ impl OPNsenseShell for SshOPNSenseShell { } async fn write_content_to_file(&self, content: &str, filename: &str) -> Result { - // TODO fix this to create the directory before uploading the file let channel = self.get_ssh_channel().await?; channel .request_subsystem(true, "sftp") @@ -58,6 +58,14 @@ impl OPNsenseShell for SshOPNSenseShell { .await .expect("Should acquire sftp subsystem"); + if let Some(parent) = Path::new(filename).parent() { + if let Some(parent_str) = parent.to_str() { + if !parent_str.is_empty() { + self.ensure_remote_dir_exists(&sftp, parent_str).await?; + } + } + } + let mut file = sftp.create(filename).await.unwrap(); file.write_all(content.as_bytes()).await?; @@ -74,10 +82,7 @@ impl OPNsenseShell for SshOPNSenseShell { .await .expect("Should acquire sftp subsystem"); - if !sftp.try_exists(destination).await? { - info!("Creating remote directory {destination}"); - sftp.create_dir(destination).await?; - } + self.ensure_remote_dir_exists(&sftp, destination).await?; info!("Reading local directory {source}"); let mut entries = read_dir(source).await?; @@ -154,6 +159,18 @@ impl SshOPNSenseShell { wait_for_completion(&mut channel).await } + async fn ensure_remote_dir_exists( + &self, + sftp: &SftpSession, + path: &str, + ) -> Result<(), Error> { + if !sftp.try_exists(path).await? { + info!("Creating remote directory {path}"); + sftp.create_dir(path).await?; + } + Ok(()) + } + pub fn new(host: (IpAddr, u16), credentials: SshCredentials, ssh_config: Arc) -> Self { info!("Initializing SshOPNSenseShell on host {host:?}"); Self {