1use std::{2 ffi::OsStr,3 process::{Command, Stdio},4};56use anyhow::{Context, Result};7use serde::Deserialize;89pub struct CommandOutput(pub Vec<u8>);10impl CommandOutput {11 pub fn into_json<'d, T: Deserialize<'d>>(&'d self) -> Result<T> {12 let str = self.as_str().ok();13 Ok(serde_json::from_slice(&self.0).with_context(|| format!("{:?}", str))?)14 }15 pub fn as_str(&self) -> Result<&str> {16 Ok(std::str::from_utf8(&self.0)?)17 }18}1920pub fn ssh_command<I, S>(host: impl AsRef<OsStr>, command: I) -> Result<CommandOutput>21where22 I: IntoIterator<Item = S>,23 S: AsRef<OsStr>,24{25 let out = Command::new("ssh")26 .stderr(Stdio::inherit())27 .arg(host)28 .args(command)29 .output()?;30 if !out.status.success() {31 anyhow::bail!("command failed");32 }33 Ok(CommandOutput(out.stdout))34}