omaha_client/installer.rs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106
// Copyright 2019 The Fuchsia Authors
//
// Licensed under a BSD-style license <LICENSE-BSD>, Apache License, Version 2.0
// <LICENSE-APACHE or https://www.apache.org/licenses/LICENSE-2.0>, or the MIT
// license <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your option.
// This file may not be copied, modified, or distributed except according to
// those terms.
use crate::{
cup_ecdsa::RequestMetadata, protocol::response::Response, request_builder::RequestParams,
};
use futures::future::{BoxFuture, LocalBoxFuture};
pub mod stub;
/// The trait for the Install Plan that can be acted on by an Installer implementation.
///
pub trait Plan: std::marker::Sized + std::marker::Sync {
/// A string that can identify individual install plans, used to check if the current plan is
/// the same as the previous one.
fn id(&self) -> String;
}
/// The trait for the platform-specific Installer to implement.
///
/// The Installer trait has two associated types:
///
/// InstallPlan - This is the type that implements the Plan trait, and represents the platform-
/// specific installation plan (the data used to define what an update is).
///
/// InstallResult - InstallResult is data passed from the Installer trait implementation to the PolicyEngine
/// trait implementation to help the PolicyEngine schedule the reboot.
///
/// Error - This the type that implements the thiserror::Error trait and is used to collect all of
/// the errors that can occur during the installation of an update.
pub trait Installer {
type InstallPlan: Plan;
type InstallResult;
type Error: std::error::Error + std::marker::Send + std::marker::Sync + 'static;
/// Perform the installation as given by the install plan (as parsed form the Omaha server
/// response). If given, provide progress via the observer, and a final finished or Error
/// indication via the Future.
/// The returned Vec of AppInstallResult must only include apps that have an update available
/// and must be kept in the same order as it appears in the omaha response.
#[allow(clippy::type_complexity)]
fn perform_install<'a>(
&'a mut self,
install_plan: &'a Self::InstallPlan,
observer: Option<&'a dyn ProgressObserver>,
) -> LocalBoxFuture<'a, (Self::InstallResult, Vec<AppInstallResult<Self::Error>>)>;
/// Perform a reboot of the system (in whichever manner that the installer needs to perform
/// a reboot. This fn should not return unless reboot failed.
fn perform_reboot(&mut self) -> LocalBoxFuture<'_, Result<(), anyhow::Error>>;
/// Try to create a new Plan from the given response, returning a Error if unable to do so.
/// For update with multiple apps, the install plan must keep the order of the apps from the
/// response.
fn try_create_install_plan<'a>(
&'a self,
request_params: &'a RequestParams,
request_metadata: Option<&'a RequestMetadata>,
response: &'a Response,
response_bytes: Vec<u8>,
ecdsa_signature: Option<Vec<u8>>,
) -> LocalBoxFuture<'a, Result<Self::InstallPlan, Self::Error>>;
}
#[derive(Debug)]
pub enum AppInstallResult<E> {
Installed,
Deferred,
Failed(E),
}
impl<E> From<Result<(), E>> for AppInstallResult<E> {
fn from(result: Result<(), E>) -> Self {
match result {
Ok(()) => Self::Installed,
Err(e) => Self::Failed(e),
}
}
}
/// The trait for observing progress on the initiated installation.
///
/// The StateMachine may pass an implementation of this trait to the Installer, so that it can
/// receive reports of the progress of the installation of the update.
///
pub trait ProgressObserver: Sync {
/// Receive progress on the installation.
///
/// operation - The current operation of the install (if applicable)
/// progress - 0 to 1 fraction completed.
/// total_size - Maximal size of the download of the install
/// size_so_far - Downloaded data so far (may move forward erratically based on cached or
/// previously downloaded data)
fn receive_progress(
&self,
operation: Option<&str>,
progress: f32,
total_size: Option<u64>,
size_so_far: Option<u64>,
) -> BoxFuture<'_, ()>;
}