Add Transport.file_exists to clean up the run method for builtin tasks

This commit is contained in:
R Tyler Croy 2021-01-01 15:03:14 -08:00
parent 4888aa9ecf
commit c6d62687b4
4 changed files with 50 additions and 24 deletions

4
Cargo.lock generated
View File

@ -515,9 +515,9 @@ dependencies = [
[[package]]
name = "syn"
version = "1.0.56"
version = "1.0.57"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a9802ddde94170d186eeee5005b798d9c159fa970403f1be19976d0cfb939b72"
checksum = "4211ce9909eb971f111059df92c45640aad50a619cf55cd76476be803c4c68e6"
dependencies = [
"proc-macro2",
"quote",

View File

@ -4,6 +4,7 @@ extern crate pest;
extern crate pest_derive;
use std::collections::HashMap;
use std::path::PathBuf;
pub mod inventory;
pub mod plan;
@ -13,7 +14,7 @@ pub mod transport;
pub use crate::plan::Plan;
pub use crate::task::Task;
pub use crate::transport::Transport;
pub use crate::transport::{Transport, TransportError};
/**
* An ExecutableTask is a light container over a Task execpt with user-provided information and is
@ -29,4 +30,16 @@ impl ExecutableTask {
pub fn new(task: Task, parameters: HashMap<String, String>) -> Self {
Self { task, parameters }
}
/**
* Provides will return the files that the ExecutableTask provides
*
* If these files exist, the task should not be executed
*/
pub fn provides() -> Vec<PathBuf> {
vec![]
}
}
#[cfg(test)]
mod tests {}

View File

@ -5,6 +5,10 @@ use std::path::Path;
pub mod ssh;
pub enum TransportError {
GeneralError(String),
}
/**
* The Transport trait allows for multiple transports to be implemented for
* connecting to targets
@ -12,6 +16,8 @@ pub mod ssh;
pub trait Transport {
fn connect(&mut self, target: &Target) -> bool;
fn disconnect(&mut self);
fn file_exists(&self, path: &Path) -> Result<bool, TransportError>;
fn run(&mut self, command: &ExecutableTask, target: &Target, dry_run: bool) -> i32;
fn run_group(
&mut self,
cmd: &ExecutableTask,
@ -19,6 +25,5 @@ pub trait Transport {
inv: &Inventory,
dry_run: bool,
) -> i32;
fn run(&mut self, command: &ExecutableTask, target: &Target, dry_run: bool) -> i32;
fn send_bytes(&self, remote_path: &Path, bytes: &Vec<u8>, mode: i32) -> bool;
}

View File

@ -1,6 +1,6 @@
use crate::inventory::{Group, Inventory, Target};
use crate::transport::Transport;
use crate::ExecutableTask;
use crate::{ExecutableTask, TransportError};
use colored::*;
@ -90,6 +90,28 @@ impl Transport for Ssh {
true
}
fn file_exists(&self, path: &Path) -> Result<bool, TransportError> {
if let Err(error) = self.session.scp_recv(path) {
if error.code() == ssh2::ErrorCode::Session(-28) {
debug!("The file ({}) does not exist", path.display());
} else {
error!(
"A failure occurred while trying to check a file exists: {:?}",
error
);
return Err(TransportError::GeneralError(
"Failed to check that file exists".into(),
));
}
} else {
// If we successfully fetched the provided file, then we should
// return 0 and skip the function
trace!("The file exists: {}", path.display());
return Ok(true);
}
return Ok(false);
}
fn run(&mut self, command: &ExecutableTask, target: &Target, dry_run: bool) -> i32 {
if !self.connect(target) {
error!("Failed to connect to {:?}", target);
@ -102,27 +124,13 @@ impl Transport for Ssh {
provides
);
if let Err(error) = self.session.scp_recv(&Path::new(&provides)) {
if error.code() == ssh2::ErrorCode::Session(-28) {
debug!(
"The provided file ({}) does not exist, the command should be run",
provides
);
} else {
error!(
"A failure occurred while trying to check the provided file: {:?}",
error
);
return -1;
if let Ok(found) = self.file_exists(Path::new(provides)) {
if found {
debug!("File {} exists, skipping task", provides);
return 0;
}
} else {
// If we successfully fetched the provided file, then we should
// return 0 and skip the function
debug!(
"The provided file ({}) was found, avoiding re-running",
provides
);
return 0;
return -1;
}
}