use {
anyhow::Error,
app_set::{AppMetadata, MinimalAppSet},
argh::FromArgs,
futures::{FutureExt as _, StreamExt, lock::Mutex, stream::FuturesUnordered},
http_request::MinimalHttpRequest,
log::{error, info},
metrics::MinimalMetricsReporter,
omaha_client::{
common::App,
configuration::{Config, Updater},
cup_ecdsa::StandardCupv2Handler,
protocol::{Cohort, request::OS},
state_machine::StateMachineBuilder,
time::StandardTimeSource,
},
std::rc::Rc,
};
mod app_set;
mod http_request;
mod installer;
mod metrics;
mod policy;
mod storage;
mod timer;
const APP_ID: &str = "appid_01";
#[derive(FromArgs)]
struct Args {
#[argh(
option,
short = 'u',
description = "URL of the omaha service to connect to, e.g. 'http://[::]:1234'. This service must accept connections."
)]
url: String,
}
#[tokio::main]
async fn main() {
info!("Starting omaha client...");
if let Err(e) = main_inner().await {
error!("Error running omaha-client: {:#}", e);
std::process::exit(1);
}
info!("Shutting down omaha client...");
}
async fn main_inner() -> Result<(), Error> {
let args: Args = argh::from_env();
let http = MinimalHttpRequest::new();
let platform_config = Config {
updater: Updater {
name: "FuchsiaUpdater".to_string(),
version: [0, 0, 1, 0].into(),
},
os: OS {
platform: "Fuchsia".to_string(),
version: "14.20230831.4.72".to_string(),
service_pack: "".to_string(),
arch: "aarch64".to_string(),
},
service_url: args.url,
omaha_public_keys: None,
};
let cup_handler: Option<StandardCupv2Handler> = platform_config
.omaha_public_keys
.as_ref()
.map(StandardCupv2Handler::new);
let app = App::builder()
.id(APP_ID)
.version([14, 20230831, 4, 72])
.cohort(Cohort::from_hint("stable-channel"))
.build();
let app_set = Rc::new(Mutex::new(MinimalAppSet::new(
app,
AppMetadata {
appid_source: app_set::AppIdSource::DefaultEmpty,
},
)));
let installer = installer::MinimalInstaller { should_fail: false };
let metrics_reporter = MinimalMetricsReporter;
let stash = storage::MinimalStorage;
let stash_ref = Rc::new(Mutex::new(stash));
let policy_engine =
policy::MinimalPolicyEngine::new(StandardTimeSource, metrics_reporter.clone());
let futures = FuturesUnordered::new();
let (_state_machine_control, state_machine) = StateMachineBuilder::new(
policy_engine,
http,
installer,
timer::MinimalTimer,
metrics_reporter,
Rc::clone(&stash_ref),
platform_config.clone(),
Rc::clone(&app_set),
cup_handler,
)
.start()
.await;
futures.push(
async move {
futures::pin_mut!(state_machine);
while let Some(event) = state_machine.next().await {
println!("Event: {:#?}", event);
}
}
.boxed_local(),
);
futures.collect::<()>().await;
Ok(())
}