Skip to content
This repository was archived by the owner on Nov 1, 2023. It is now read-only.

Tevoinea/add version checking in local tasks #3517

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
78 changes: 78 additions & 0 deletions src/agent/onefuzz-task/src/check_for_update.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
use std::process::Stdio;

use anyhow::Result;
use serde_json::Value;

pub fn run(onefuzz_built_version: &str) -> Result<()> {
// Find onefuzz cli
let common_names = ["onefuzz", "onefuzz.exe", "onefuzz.cmd"];
let mut valid_commands: Vec<_> = common_names
.into_iter()
.map(|name| {
(
name,
std::process::Command::new(name)
.stderr(Stdio::null())
.stdout(Stdio::null())
.arg("-h")
.spawn(),
)
})
.filter_map(|(name, child)| child.ok().map(|c| (name, c)))
.collect();

if valid_commands.is_empty() {
bail!(
"Could not find any of the following common names for the onefuzz-cli: {:?}",
common_names
);
}

let (name, child) = valid_commands
.first_mut()
.expect("Expected valid_commands to not be empty");

info!("Found the onefuzz cli at: {}", name);

// We just used this to check if it exists, we'll invoke it again later
let _ = child.kill();

// Run onefuzz info get
let output = std::process::Command::new(&name)
.args(["info", "get"])
.output()?;

if !output.status.success() {
bail!(
"Failed to run command `{} info get`. stderr: {:?}, stdout: {:?}",
name,
String::from_utf8(output.stderr),
String::from_utf8(output.stdout)
)
}

let stdout = String::from_utf8(output.stdout)?;
let info: Value = serde_json::from_str(&stdout)?;

if let Some(onefuzz_service_version) = info["versions"]["onefuzz"]["version"].as_str() {
if onefuzz_service_version == onefuzz_built_version {
println!("You are up to date!");
} else {
println!(
"Version mismatch. onefuzz-task version: {} | onefuzz service version: {}",
onefuzz_built_version, onefuzz_service_version
);
println!(
"To update, please run the following command: {} tools get .",
name
);
println!("Then extract the onefuzz-task binary from the appropriate OS folder");
}
return Ok(());
}

bail!(
"Failed to get onefuzz service version from cli response: {}",
stdout
)
}
14 changes: 12 additions & 2 deletions src/agent/onefuzz-task/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,29 +11,38 @@ extern crate onefuzz;

use anyhow::Result;
use clap::{ArgMatches, Command};

use std::io::{stdout, Write};

mod check_for_update;
mod local;
mod managed;
mod tasks;

const LICENSE_CMD: &str = "licenses";
const LOCAL_CMD: &str = "local";
const MANAGED_CMD: &str = "managed";
const CHECK_FOR_UPDATE: &str = "check_for_update";

const ONEFUZZ_BUILT_VERSION: &str = env!("ONEFUZZ_VERSION");

fn main() -> Result<()> {
let built_version = format!(
"{} onefuzz:{} git:{}",
crate_version!(),
env!("ONEFUZZ_VERSION"),
ONEFUZZ_BUILT_VERSION,
env!("GIT_VERSION")
);

let app = Command::new("onefuzz-task")
.version(built_version)
.subcommand(managed::cmd::args(MANAGED_CMD))
.subcommand(local::cmd::args(LOCAL_CMD))
.subcommand(Command::new(LICENSE_CMD).about("display third-party licenses"));
.subcommand(Command::new(LICENSE_CMD).about("display third-party licenses"))
.subcommand(
Command::new(CHECK_FOR_UPDATE)
.about("compares the version of onefuzz-task with the onefuzz service"),
);

let matches = app.get_matches();

Expand All @@ -55,6 +64,7 @@ async fn run(args: ArgMatches) -> Result<()> {
Some((LICENSE_CMD, _)) => licenses(),
Some((LOCAL_CMD, sub)) => local::cmd::run(sub.to_owned()).await,
Some((MANAGED_CMD, sub)) => managed::cmd::run(sub).await,
Some((CHECK_FOR_UPDATE, _)) => check_for_update::run(ONEFUZZ_BUILT_VERSION),
_ => anyhow::bail!("No command provided. Run with 'help' to see available commands."),
}
}
Expand Down