use crate::core::{Result, Host};
use super::{Task as TaskTrait, TaskResult};
use tinytemplate::{TinyTemplate, format_unescaped};
use serde_json::json;
use std::io::prelude::*;
pub struct Task {
command_template: String,
}
impl Task {
pub fn new(command_template: String) -> Self {
Self { command_template }
}
}
impl TaskTrait<String> for Task {
fn prepare(&self, host: Host) -> Result<String> {
let mut tt = TinyTemplate::new();
tt.set_default_formatter(&format_unescaped);
tt.add_template("cmd", self.command_template.as_str())?;
let ctx = json!({ "host": host });
let cmd = tt.render("cmd", &ctx)?;
Ok(cmd)
}
fn apply(&self, host: Host, command: String) -> TaskResult {
let sess = host.get_session()?;
let mut channel = sess.channel_session()?;
channel.exec(&command)?;
let mut output = String::new();
channel.read_to_string(&mut output)?;
channel.wait_close()?;
let exit_code = channel.exit_status()?;
Ok(json!({
"exit_code": exit_code,
"output": output,
}))
}
}