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