use anyhow::Context; pub struct Plan {} impl Plan { pub fn new() -> Self { Self {} } pub async fn tasks(&self) -> anyhow::Result> { Ok(vec![Task::new()]) } } pub struct Task {} impl Task { pub fn new() -> Self { Self {} } pub fn id(&self) -> String { "apt".into() } pub async fn should_run(&self) -> anyhow::Result { Ok(true) } pub async fn execute(&self) -> anyhow::Result<()> { let mut cmd = tokio::process::Command::new("apt-get"); cmd.args(["update", "-q"]); let output = cmd.output().await.context("failed to run apt update")?; match output.status.success() { true => tracing::info!("successfully ran apt update"), false => { anyhow::bail!( "failed to run apt update: {}", std::str::from_utf8(&output.stderr)? ); } } let mut cmd = tokio::process::Command::new("apt-get"); cmd.env("DEBIAN_FRONTEND", "noninteractive") .args(["upgrade", "-y"]); let output = cmd.output().await.context("failed to run apt upgrade")?; match output.status.success() { true => tracing::info!("successfully ran apt upgrade"), false => { anyhow::bail!( "failed to run apt upgrade: {}", std::str::from_utf8(&output.stderr)? ); } } Ok(()) } }