blob: e0f2cbb9a08399e6a4d330a0d8d8f45eee8aa902 [file] [log] [blame]
// Copyright 2019 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#![feature(async_await)]
mod apply;
mod channel;
mod check;
mod config;
mod connect;
mod errors;
mod info_handler;
mod inspect;
mod poller;
mod update_manager;
mod update_monitor;
mod update_service;
use crate::config::Config;
use crate::info_handler::InfoHandler;
use crate::poller::run_periodic_update_check;
use crate::update_service::{RealUpdateManager, RealUpdateService};
use failure::{Error, ResultExt};
use fidl_fuchsia_update::{InfoRequestStream, ManagerRequestStream};
use forced_fdr::perform_fdr_if_necessary;
use fuchsia_async as fasync;
use fuchsia_component::server::ServiceFs;
use fuchsia_inspect as finspect;
use fuchsia_syslog::{fx_log_err, fx_log_warn};
use futures::prelude::*;
use std::sync::Arc;
const MAX_CONCURRENT_CONNECTIONS: usize = 100;
#[fasync::run(1)]
async fn main() -> Result<(), Error> {
fuchsia_syslog::init_with_tags(&["system-update-checker"]).context("syslog init failed")?;
let config = Config::load_from_config_data_or_default();
if let Some(url) = config.update_package_url() {
fx_log_warn!("Ignoring custom update package url: {}", url);
}
let inspector = finspect::Inspector::new();
let mut target_channel_manager =
channel::TargetChannelManager::new(connect::ServiceConnector, "/misc/ota");
if let Err(e) = target_channel_manager.update().await {
fx_log_err!("while updating the target channel: {}", e);
}
let channel_notifier =
channel::CurrentChannelNotifier::new(connect::ServiceConnector, "/misc/ota");
let channel_fut = channel_notifier.run();
let update_manager = Arc::new(RealUpdateManager::new(
target_channel_manager,
inspector.root().create_child("update-manager"),
));
let info_handler = InfoHandler::default();
let mut fs = ServiceFs::new();
let update_manager_clone = update_manager.clone();
fs.dir("svc")
.add_fidl_service(move |stream| {
IncomingServices::Manager(stream, RealUpdateService::new(update_manager_clone.clone()))
})
.add_fidl_service(move |stream| IncomingServices::Info(stream, info_handler.clone()));
inspector.export(&mut fs);
fs.take_and_serve_directory_handle().context("ServiceFs::take_and_serve_directory_handle")?;
let fidl_fut = fs.for_each_concurrent(MAX_CONCURRENT_CONNECTIONS, |incoming_service| {
handle_incoming_service(incoming_service)
.unwrap_or_else(|e| fx_log_err!("error handling client connection: {}", e))
});
let cron_fut = run_periodic_update_check(update_manager.clone(), &config);
future::join4(channel_fut, fidl_fut, cron_fut, perform_fdr_if_necessary()).await;
Ok(())
}
enum IncomingServices {
Manager(ManagerRequestStream, RealUpdateService),
Info(InfoRequestStream, InfoHandler),
}
async fn handle_incoming_service(incoming_service: IncomingServices) -> Result<(), Error> {
match incoming_service {
IncomingServices::Manager(request_stream, update_service) => {
update_service.handle_request_stream(request_stream).await
}
IncomingServices::Info(request_stream, handler) => {
handler.handle_request_stream(request_stream).await
}
}
}