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

start work towards enabling launching fuzzing within docker #133

Closed
wants to merge 42 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
42 commits
Select commit Hold shift + click to select a range
68b685f
start work towards enabling launching fuzzing within docker
demoray Oct 12, 2020
bfb21cc
Merge branch 'main' into docker-agent
bmc-msft Oct 12, 2020
5bba662
Merge branch 'main' into docker-agent
bmc-msft Oct 12, 2020
a5352aa
update supervisor to support config from env
demoray Oct 12, 2020
5bc5243
enable simple builds of the agent/supervisor when built locally
demoray Oct 12, 2020
7e71369
for local testing, just build the agent, don't run the full CI script
demoray Oct 12, 2020
0d5a622
continued dev
demoray Oct 13, 2020
c4c93d8
Merge branch 'main' into docker-agent
bmc-msft Oct 13, 2020
7b3c14b
cargo fmt
demoray Oct 13, 2020
d14c7d4
fix appid
demoray Oct 13, 2020
fa00dfb
continued dev
demoray Oct 13, 2020
a26e570
cargo fmt
demoray Oct 13, 2020
3d90b77
isort
demoray Oct 13, 2020
df5feb2
ignore env-config
demoray Oct 13, 2020
758f407
don't init app insights if it's optional
demoray Oct 13, 2020
485f6de
add version command
demoray Oct 13, 2020
53d2b38
make /onefuzz/etc & start supervisor
demoray Oct 13, 2020
91cf6d1
continued dev
demoray Oct 13, 2020
83eeb9c
put auth code in onefuzz (to be reused for agent-startup)
demoray Oct 13, 2020
2f6c738
cargo fmt
demoray Oct 13, 2020
a1700a5
move to using a downloader to ensure the container is always in-sync
demoray Oct 13, 2020
fc83bbc
fix lint
demoray Oct 13, 2020
80db79c
add downloader to ci
demoray Oct 13, 2020
d2d7a6a
fix windows path
demoray Oct 13, 2020
591705d
use parse_uri instead of parse_request
demoray Oct 13, 2020
d9e138c
custom install path
demoray Oct 13, 2020
8783a0f
Merge branch 'main' into docker-agent
bmc-msft Oct 13, 2020
ce3c9f8
add basic setup-download.sh script
demoray Oct 13, 2020
1963674
don't fail if we can't alter the environment
demoray Oct 13, 2020
a6716aa
move more install tasks into setup.sh
demoray Oct 13, 2020
875ca9e
use configurable onefuzz_path
demoray Oct 13, 2020
7f8d864
Merge branch 'main' into docker-agent
bmc-msft Oct 13, 2020
506460f
don't consume stdout/stderr from supervisor
demoray Oct 13, 2020
ae402a5
fix log message
demoray Oct 13, 2020
33cee2c
install github3 prereq
demoray Oct 13, 2020
5be47a5
fix requirements
demoray Oct 13, 2020
c581e58
split name to prevent double inclusion
demoray Oct 13, 2020
7cb6629
Merge remote-tracking branch 'upstream/main' into docker-agent
demoray Oct 13, 2020
8884a6c
dos2unix
demoray Oct 13, 2020
a29fcd9
use ~ 1.3.0
demoray Oct 13, 2020
15a8ead
Merge remote-tracking branch 'upstream/main' into docker-agent
demoray Oct 19, 2020
d085d14
address merge issues
demoray Oct 19, 2020
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
2 changes: 2 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -253,8 +253,10 @@ jobs:
cp artifacts/azcopy/azcopy.exe artifacts/azcopy/ThirdPartyNotice.txt src/deployment/tools/win64
cp artifacts/agent/onefuzz-supervisor.exe src/deployment/tools/win64/
cp artifacts/agent/onefuzz-agent.exe src/deployment/tools/win64/
cp artifacts/agent/onefuzz-downloader.exe src/deployment/tools/win64/
cp artifacts/agent/onefuzz-supervisor src/deployment/tools/linux/
cp artifacts/agent/onefuzz-agent src/deployment/tools/linux/
cp artifacts/agent/onefuzz-downloader src/deployment/tools/linux/
cp artifacts/proxy/onefuzz-proxy-manager src/deployment/tools/linux/
cp artifacts/service/api-service.zip src/deployment
cp -r artifacts/third-party src/deployment
Expand Down
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,6 @@
.idea
**/.direnv
**/.envrc

artifacts
# vim
*.swp
23 changes: 23 additions & 0 deletions src/agent/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions src/agent/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ members = [
"input-tester",
"onefuzz",
"onefuzz-agent",
"onefuzz-downloader",
"onefuzz-supervisor",
"storage-queue",
"win-util",
Expand Down
3 changes: 3 additions & 0 deletions src/agent/onefuzz-downloader/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
/target
Cargo.lock
data/licenses.json
26 changes: 26 additions & 0 deletions src/agent/onefuzz-downloader/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
[package]
name = "onefuzz-downloader"
version = "0.1.0"
authors = ["fuzzing@microsoft.com"]
edition = "2018"
publish = false


[dependencies]
anyhow = "1.0.31"
appinsights = "0.1"
async-trait = "0.1.36"
downcast-rs = "1.2.0"
env_logger = "0.7"
futures = "0.3.5"
log = "0.4"
onefuzz = { path = "../onefuzz" }
reqwest = { version = "0.10", features = ["json", "stream"] }
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"
storage-queue = { path = "../storage-queue" }
structopt = "0.3"
tokio = { version = "0.2.13", features = ["full"] }
url = { version = "2.1.1", features = ["serde"] }
uuid = { version = "0.8.1", features = ["serde", "v4"] }
clap = "2.33"
56 changes: 56 additions & 0 deletions src/agent/onefuzz-downloader/build.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
use std::env;
use std::error::Error;
use std::fs::File;
use std::io::prelude::*;
use std::process::Command;

fn run_cmd(args: &[&str]) -> Result<String, Box<dyn Error>> {
let cmd = Command::new(args[0]).args(&args[1..]).output()?;
if cmd.status.success() {
Ok(String::from_utf8_lossy(&cmd.stdout).trim().to_string())
} else {
Err(From::from("failed"))
}
}

fn read_file(filename: &str) -> Result<String, Box<dyn Error>> {
let mut file = File::open(filename)?;
let mut contents = String::new();
file.read_to_string(&mut contents)?;
contents = contents.trim().to_string();

Ok(contents)
}

fn print_version(include_sha: bool, include_local: bool) -> Result<(), Box<dyn Error>> {
let mut version = read_file("../../../CURRENT_VERSION")?;
let sha = run_cmd(&["git", "rev-parse", "HEAD"])?;

if include_sha {
version.push('-');
version.push_str(&sha);

// if we're a non-release build, check to see if git has
// unstaged changes
if include_local && run_cmd(&["git", "diff", "--quiet"]).is_err() {
version.push('.');
version.push_str("localchanges");
}
}

println!("cargo:rustc-env=GIT_VERSION={}", sha);
println!("cargo:rustc-env=ONEFUZZ_VERSION={}", version);

Ok(())
}

fn main() -> Result<(), Box<dyn Error>> {
// If we're built off of a tag, we accept CURRENT_VERSION as is. Otherwise
// modify it to indicate local build
let (include_sha, include_local_changes) = if let Ok(val) = env::var("GITHUB_REF") {
(!val.starts_with("refs/tags/"), false)
} else {
(true, true)
};
print_version(include_sha, include_local_changes)
}
104 changes: 104 additions & 0 deletions src/agent/onefuzz-downloader/src/config.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.

use anyhow::Result;
use onefuzz::auth::{ClientCredentials, Credentials, ManagedIdentityCredentials};
use std::path::Path;
use url::Url;
use uuid::Uuid;

#[derive(Clone, Debug, Deserialize, Eq, PartialEq)]
pub struct StaticConfig {
pub credentials: Credentials,
pub pool_name: String,
pub onefuzz_url: Url,
pub instrumentation_key: Option<Uuid>,
pub telemetry_key: Option<Uuid>,
}

// Temporary shim type to bridge the current service-provided config.
#[derive(Clone, Debug, Deserialize, Eq, PartialEq)]
struct RawStaticConfig {
pub credentials: Option<ClientCredentials>,
pub pool_name: String,
pub onefuzz_url: Url,
pub instrumentation_key: Option<Uuid>,
pub telemetry_key: Option<Uuid>,
}

impl StaticConfig {
pub fn new(data: &[u8]) -> Result<Self> {
let config: RawStaticConfig = serde_json::from_slice(data)?;

let credentials = match config.credentials {
Some(client) => client.into(),
None => {
// Remove trailing `/`, which is treated as a distinct resource.
let resource = config
.onefuzz_url
.to_string()
.trim_end_matches('/')
.to_owned();
let managed = ManagedIdentityCredentials::new(resource);
managed.into()
}
};
let config = StaticConfig {
credentials,
pool_name: config.pool_name,
onefuzz_url: config.onefuzz_url,
instrumentation_key: config.instrumentation_key,
telemetry_key: config.telemetry_key,
};

Ok(config)
}

pub fn from_env() -> Result<Self> {
let client_id = Uuid::parse_str(&std::env::var("ONEFUZZ_CLIENT_ID")?)?;
let client_secret = std::env::var("ONEFUZZ_CLIENT_SECRET")?.into();
let tenant = std::env::var("ONEFUZZ_TENANT")?;
let onefuzz_url = Url::parse(&std::env::var("ONEFUZZ_URL")?)?;
let pool_name = std::env::var("ONEFUZZ_POOL")?;

let instrumentation_key = if let Ok(key) = std::env::var("ONEFUZZ_INSTRUMENTATION_KEY") {
Some(Uuid::parse_str(&key)?)
} else {
None
};

let telemetry_key = if let Ok(key) = std::env::var("ONEFUZZ_TELEMETRY_KEY") {
Some(Uuid::parse_str(&key)?)
} else {
None
};

let credentials = ClientCredentials::new(
client_id,
client_secret,
onefuzz_url.clone().to_string(),
tenant,
)
.into();

Ok(Self {
credentials,
pool_name,
onefuzz_url,
instrumentation_key,
telemetry_key,
})
}

pub fn from_file(config_path: impl AsRef<Path>) -> Result<Self> {
verbose!("loading config from: {}", config_path.as_ref().display());
let data = std::fs::read(config_path)?;
Self::new(&data)
}

pub fn download_url(&self) -> Url {
let mut url = self.onefuzz_url.clone();
url.set_path("/api/agents/download");
url
}
}
127 changes: 127 additions & 0 deletions src/agent/onefuzz-downloader/src/main.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.

#[macro_use]
extern crate anyhow;
#[macro_use]
extern crate onefuzz;
#[macro_use]
extern crate serde;
#[macro_use]
extern crate clap;

use std::path::PathBuf;

use anyhow::Result;
use onefuzz::{
machine_id::get_machine_id,
telemetry::{self, EventData},
};
use structopt::StructOpt;

pub mod config;
pub mod setup;

use config::StaticConfig;

#[derive(StructOpt, Debug)]
enum Opt {
Run(RunOpt),
Licenses,
Version,
}

#[derive(StructOpt, Debug)]
struct RunOpt {
#[structopt(short, long = "--config", parse(from_os_str))]
config_path: Option<PathBuf>,

#[structopt(short, long = "--onefuzz_path", parse(from_os_str))]
onefuzz_path: Option<PathBuf>,

#[structopt(short, long)]
start_supervisor: bool,
}

fn main() -> Result<()> {
env_logger::init();

let opt = Opt::from_args();

match opt {
Opt::Run(opt) => run(opt)?,
Opt::Licenses => licenses()?,
Opt::Version => versions()?,
};

Ok(())
}

fn versions() -> Result<()> {
println!(
"{} onefuzz:{} git:{}",
crate_version!(),
env!("ONEFUZZ_VERSION"),
env!("GIT_VERSION")
);
Ok(())
}

fn licenses() -> Result<()> {
use std::io::{self, Write};
io::stdout().write_all(include_bytes!("../../data/licenses.json"))?;
Ok(())
}

fn run(opt: RunOpt) -> Result<()> {
// We can't send telemetry if this fails.
let config = load_config(&opt);

if let Err(err) = &config {
error!("error loading supervisor agent config: {:?}", err);
}

let config = config?;
init_telemetry(&config);

let mut rt = tokio::runtime::Runtime::new()?;
let result = rt.block_on(run_downloader(config, &opt));

if let Err(err) = &result {
error!("error running downloader: {}", err);
}

telemetry::try_flush_and_close();

result
}

fn load_config(opt: &RunOpt) -> Result<StaticConfig> {
info!("loading downloader config");
let config = match &opt.config_path {
Some(config_path) => StaticConfig::from_file(config_path)?,
None => StaticConfig::from_env()?,
};

Ok(config)
}

async fn run_downloader(config: StaticConfig, opt: &RunOpt) -> Result<()> {
telemetry::set_property(EventData::MachineId(get_machine_id().await?));
telemetry::set_property(EventData::Version(env!("ONEFUZZ_VERSION").to_string()));

let setup_inst = setup::Setup { config };
setup_inst.run(&opt.onefuzz_path).await?;

if opt.start_supervisor {
setup_inst.launch_supervisor(&opt.config_path).await?;
}

Ok(())
}

fn init_telemetry(config: &StaticConfig) {
let inst_key = config.instrumentation_key;
let tele_key = config.telemetry_key;
telemetry::set_appinsights_clients(inst_key, tele_key);
}
Loading