clwrap/
lib.rs

1pub use crate::repl::ReplWrapper;
2pub use expectrl::{spawn, Session};
3use futures_lite::{AsyncRead, AsyncWrite};
4use tracing::trace;
5
6pub mod repl;
7pub mod runner;
8
9#[derive(Debug, thiserror::Error)]
10pub enum Error {
11    #[error("{0}")]
12    ExpectrlError(#[from] expectrl::Error),
13    #[error("{0}")]
14    IoError(#[from] std::io::Error),
15}
16
17/// Linux auto login then do command
18pub async fn linux_oneshot<
19    P,
20    S: AsyncRead + AsyncWrite + Unpin,
21    SS: AsRef<str> + Clone + std::fmt::Debug,
22>(
23    session: expectrl::Session<P, S>,
24    username: &str,
25    password: &str,
26    prompt: Option<String>,
27    cmd: SS,
28) -> core::result::Result<(Vec<u8>, ReplWrapper<P, S>), Error> {
29    let quit = "exit";
30    let prompt = match prompt {
31        Some(prompt) => prompt,
32        None => r".*]# |.*@.*:.*# ".to_string(),
33    };
34    let prompt = regex::Regex::new(&prompt).unwrap();
35
36    let session = runner::LinuxLoginRunner::builder()
37        .build()
38        .login(session, username, password, Some(&prompt))
39        .await?;
40    trace!("successfully logged in");
41    let mut session = ReplWrapper::new(session, prompt);
42    trace!("expect prompt...");
43    session.expect_prompt().await?;
44    trace!("run_command: {:?}", cmd);
45    let recv = session.run_command(cmd).await;
46
47    trace!("send quit command: {}", quit);
48    session.send_line(quit).await?;
49
50    Ok(recv.map(|recv| (recv, session))?)
51}