use crate::config::{GuestOs, Result, VmProfile};
use crate::ssh::VmSession;
#[derive(Debug, Clone, Copy)]
pub enum LogKind {
Build,
Run,
}
impl std::str::FromStr for LogKind {
type Err = String;
fn from_str(s: &str) -> std::result::Result<Self, Self::Err> {
match s {
"build" => Ok(LogKind::Build),
"run" => Ok(LogKind::Run),
_ => Err(format!("unknown log kind: {s}")),
}
}
}
#[derive(Debug, Clone, Copy)]
pub enum LogMode {
Dump,
Follow,
Errors,
Tail(u32),
}
#[derive(Debug)]
pub struct LogOpts {
pub kind: LogKind,
pub mode: LogMode,
}
pub fn log_path(profile: &VmProfile, kind: LogKind) -> String {
match (profile.os, kind) {
(GuestOs::Linux, LogKind::Build) => "/home/vagrant/.testbed-build/build.log".to_string(),
(GuestOs::Linux, LogKind::Run) => "/home/vagrant/.testbed-run/run.log".to_string(),
(GuestOs::MacOS, LogKind::Build) => "/Users/vagrant/.testbed-build/build.log".to_string(),
(GuestOs::MacOS, LogKind::Run) => "/Users/vagrant/.testbed-run/run.log".to_string(),
(GuestOs::Windows, LogKind::Build) => "C:\\Users\\vagrant\\.testbed-build\\build.log".to_string(),
(GuestOs::Windows, LogKind::Run) => "C:\\Users\\vagrant\\.testbed-run\\run.log".to_string(),
}
}
pub fn get_logs(profile: &VmProfile, session: &mut VmSession, opts: &LogOpts) -> Result<String> {
let path = log_path(profile, opts.kind);
match opts.mode {
LogMode::Dump => dump_log(session, &path),
LogMode::Follow => follow_log(profile, session, &path),
LogMode::Errors => extract_errors(session, &path),
LogMode::Tail(n) => tail_log(session, &path, n),
}
}
fn dump_log(session: &mut VmSession, path: &str) -> Result<String> {
crate::ssh::exec(session, &format!("cat {path}"))
}
fn follow_log(profile: &VmProfile, session: &mut VmSession, path: &str) -> Result<String> {
let cmd = match profile.os {
GuestOs::Linux | GuestOs::MacOS => format!("tail -F {path}"),
GuestOs::Windows => format!("Get-Content -Path '{path}' -Wait"),
};
crate::ssh::exec(session, &cmd)
}
fn extract_errors(session: &mut VmSession, path: &str) -> Result<String> {
let content = crate::ssh::exec(session, &format!("cat {path}"))?;
crate::build::logs::extract_errors(&content)
}
fn tail_log(session: &mut VmSession, path: &str, n: u32) -> Result<String> {
crate::ssh::exec(session, &format!("tail -n {n} {path}"))
}