blob: 0083c94faef77f2c3cf588f651ac8b791b5d0d84 [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.
library fuchsia.update.installer;
/// Monitors a single update installation attempt.
///
/// Clients interested in receiving progress information for an update attempt
/// should implement this protocol and provide the client end to
/// [`Installer.StartUpdate`] or [`Installer.MonitorUpdate`].
closed protocol Monitor {
/// Receives a status update for this installation attempt.
///
/// This request will be called for all state changes, skipping none.
/// However, message delivery is throttled by the rate at which the
/// implementation acknowledges the messages.
///
/// The throttled delivery doesn't impact the underlying state of the
/// [`Installer`]. It does not wait for any acknowledgements before it
/// moves on to the next state in its state machine. The [`Installer`] will
/// simply queue up the states for the [`Monitor`] implementor to receive.
///
/// During states with data that changes as the updage progress, the
/// [`Installer`] may, at its discretion, collapse redundant information
/// like the fraction completed, in the event that the [`Monitor`]
/// implementation is not responding to the `OnState()` requests in a timely
/// manner.
///
/// + request `state` The new state of the update installation attempt.
/// - response The implementation is ready to receive the next
/// [`State`] from the [`Installer`].
strict OnState(struct {
state State;
}) -> ();
};
/// The set of states that a [`Monitor`] can receive during an update
/// installation attempt.
///
/// An installation attempt ends when it enters a terminal state, denoted below
/// as the states on the right-hand side of the diagram with no arrows leading
/// out of them.
///
/// # State Machine Diagram
///
/// ```
/// +----------------+ +----------------+
/// +----------| prepare |---->| fail_prepare |
/// | +----------------+ +----------------+
/// | |
/// | v
/// | +----------------+ +----------------+
/// +----------| stage |---->| fail_stage |
/// | +----------------+ +----------------+
/// | |
/// | v
/// | +----------------+ +----------------+
/// +----------| fetch |---->| fail_fetch |
/// | +----------------+ +----------------+
/// | |
/// | v
/// | +----------------+ +----------------+
/// +----------| commit |---->| fail_commit |
/// | +----------------+ +----------------+
/// v |
/// +----------------+ | +----------------+
/// | canceled | +------------> | complete |
/// +----------------+ | +----------------+
/// v
/// +----------------+ +----------------+
/// | wait_to_reboot |---->| defer_reboot |
/// +----------------+ +----------------+
/// |
/// | +----------------+
/// +------------->| reboot |
/// +----------------+
/// ```
type State = strict union {
/// Fetching required metadata to begin the update and verifying system
/// state.
///
/// Next States:
/// * `stage` system is ready to install the update.
/// * `fail_prepare` on error.
/// * `canceled` on cancel.
1: prepare PrepareData;
/// Fetching and writing kernel and firmware images.
///
/// Next States:
/// * `fetch` required kernel and firmware images are written.
/// * `fail_stage` on error.
/// * `canceled` on cancel.
2: stage StageData;
/// Fetching packages.
///
/// Next States:
/// * `commit` packages were fetched successfully.
/// * `fail_fetch` on error.
/// * `canceled` on cancel.
3: fetch FetchData;
/// Prepare to switch over to the new system by writing the packages
/// and switching the active partition.
///
/// Next States:
/// * `wait_to_reboot` if a reboot is necessary to complete the update.
/// * `complete` if no reboot is necessary to complete the update.
/// * `fail_commit` on error.
/// * `canceled` on cancel.
4: commit CommitData;
/// The system is configured to boot the updated OS on next boot, and the
/// installer is waiting for the trigger to reboot the system.
///
/// Next States:
/// * `reboot` when the installer decides it is time to initiate the reboot.
/// * `defer_reboot` if the initiator specifically requests to not reboot.
///
5: wait_to_reboot WaitToRebootData;
/// The installer has initiated a system reboot into the updated OS.
///
/// **This is a terminal state**
///
6: reboot RebootData;
/// The initiator specifically requested to skip the reboot, but a reboot is
/// still required to complete the update.
///
/// **This is a terminal state**
///
7: defer_reboot DeferRebootData;
/// The update is complete and no reboot was required.
///
/// **This is a terminal state**
///
8: complete CompleteData;
/// An error occurred while preparing the install.
///
/// **This is a terminal state**
///
9: fail_prepare FailPrepareData;
/// An error occurred while staging the images for the OS.
///
/// **This is a terminal state**
///
10: fail_stage FailStageData;
/// An error occurred while fetching the required artifacts.
///
/// **This is a terminal state**
///
11: fail_fetch FailFetchData;
/// An error occured while switching partitions.
///
/// **This is a terminal state**
///
12: fail_commit FailCommitData;
/// The update is canceled.
///
/// **This is a terminal state**
///
13: canceled CanceledData;
};
/// Data associated with [`State.prepare`].
type PrepareData = table {};
/// Data associated with [`State.stage`].
type StageData = table {
1: info UpdateInfo;
2: progress InstallationProgress;
};
/// Data associated with [`State.fetch`].
type FetchData = table {
1: info UpdateInfo;
2: progress InstallationProgress;
};
/// Data associated with [`State.commit`].
type CommitData = table {
1: info UpdateInfo;
2: progress InstallationProgress;
};
/// Data associated with [`State.wait_to_reboot`].
type WaitToRebootData = table {
1: info UpdateInfo;
2: progress InstallationProgress;
};
/// Data associated with [`State.reboot`].
type RebootData = table {
1: info UpdateInfo;
2: progress InstallationProgress;
};
/// Data associated with [`State.defer_reboot`].
type DeferRebootData = table {
1: info UpdateInfo;
2: progress InstallationProgress;
};
/// Data associated with [`State.complete`].
type CompleteData = table {
1: info UpdateInfo;
2: progress InstallationProgress;
};
/// Data associated with [`State.fail_prepare`].
type FailPrepareData = table {
1: reason PrepareFailureReason;
};
/// Data associated with [`State.fail_stage`].
type FailStageData = table {
1: info UpdateInfo;
2: progress InstallationProgress;
3: reason StageFailureReason;
};
/// Data associated with [`State.fail_fetch`].
type FailFetchData = table {
1: info UpdateInfo;
2: progress InstallationProgress;
3: reason FetchFailureReason;
};
/// Data associated with [`State.fail_commit`].
type FailCommitData = table {
1: info UpdateInfo;
2: progress InstallationProgress;
};
/// Data associated with [`State.canceled`].
type CanceledData = table {};
/// Metadata for an update. Once a field is populated during an installation
/// attempt, the value will not change.
type UpdateInfo = table {
/// The total number of bytes that may be downloaded to apply this update.
/// Optional, the installer may not be able to provide this value.
1: download_size uint64;
};
/// Current progress for an installation attempt.
type InstallationProgress = table {
/// The fraction [0-1.0f] of the installation that has been completed.
1: fraction_completed float32;
/// The number of bytes downloaded during this installation attempt. Less
/// than or equal to [`UpdateInfo.download_size`] and only present if that
/// field is also present.
2: bytes_downloaded uint64;
};
/// The set of values provided when an installation attempt fails on [`State.prepare`].
type PrepareFailureReason = strict enum {
/// The prepare failed because of some other reason.
INTERNAL = 0;
/// The prepare failed because the system does not have enough space to fetch
/// the update package.
OUT_OF_SPACE = 1;
/// The prepare failed because the system cannot downgrade across a version boundary. Not all
/// unsupported downgrades will fail with this error -- just the ones the system can detect. For
/// more context, see [RFC-0071](/docs/contribute/governance/rfcs/0071_ota_backstop.md).
UNSUPPORTED_DOWNGRADE = 2;
};
/// The set of values provided when an installation attempt fails on [`State.stage`].
type StageFailureReason = strict enum {
/// The stage failed because of some other reason.
INTERNAL = 0;
/// The stage failed because the system does not have enough space to fetch a package.
OUT_OF_SPACE = 1;
};
/// The set of values provided when an installation attempt fails on [`State.fetch`].
type FetchFailureReason = strict enum {
/// The fetch failed because of some other reason.
INTERNAL = 0;
/// The fetch failed because the system does not have enough space to fetch a package.
OUT_OF_SPACE = 1;
};