Software: add initial software-version mgmt
Change-Id: I3b50488b8383c595b4b41375ea0d62d62bdc0eed
Signed-off-by: Patrick Williams <patrick@stwcx.xyz>
diff --git a/xyz/openbmc_project/FilePath.interface.yaml b/xyz/openbmc_project/FilePath.interface.yaml
new file mode 100644
index 0000000..355298a
--- /dev/null
+++ b/xyz/openbmc_project/FilePath.interface.yaml
@@ -0,0 +1,11 @@
+description: >
+ An interface which encapsulates a file-system path on the BMC.
+
+ Typically, this is added onto an existing object path to show a
+ relationship between the object, in the dbus namespace, and a file, in
+ the filesystem namespace.
+properties:
+ - name: Path
+ type: string
+ description: >
+ The filesystem path for the dbus object.
diff --git a/xyz/openbmc_project/Software/Activation.interface.yaml b/xyz/openbmc_project/Software/Activation.interface.yaml
new file mode 100644
index 0000000..37c9cb9
--- /dev/null
+++ b/xyz/openbmc_project/Software/Activation.interface.yaml
@@ -0,0 +1,49 @@
+description: >
+ Activation state for an associated xyz.openbmc_project.Software.Version.
+properties:
+ - name: Activation
+ type: enum[self.Activations]
+ description: >
+ The current Activation state of the Software.Version.
+ - name: RequestedActivation
+ type: enum[self.RequestedActivations]
+ description: >
+ The desired Activation state of the Software.Version.
+enumerations:
+ - name: Activations
+ description: >
+ The possible Activation states of the Software.Version.
+ values:
+ - name: NotReady
+ description: >
+ The system is still analyzing the Software.Version and is
+ currently unable to activate.
+ - name: Invalid
+ description: >
+ The Software.Version is invalid and unable to be activated.
+ - name: Ready
+ description: >
+ The Software.Version has been processed and is ready for
+ Activation.
+ - name: Activating
+ description: >
+ The Software.Version is in the process of being Activated.
+ - name: Active
+ description: >
+ The Software.Version is currently Active.
+ - name: Failed
+ description: >
+ The Software.Version failed during or after Activation.
+ - name: RequestedActivations
+ description: >
+ The possible RequestedActivation states of a Software.Version.
+ values:
+ - name: None
+ description: >
+ No action has been directed for this Software.Version.
+ - name: Active
+ description: >
+ The Software.Version has been requested for Activation.
+# TODO: Specify "EAGAIN" type error when requested is unable to be acted on
+# due to current system state. Currently, sdbusplus does not support
+# errors on properties.
diff --git a/xyz/openbmc_project/Software/ActivationBlocksTransition.interface.yaml b/xyz/openbmc_project/Software/ActivationBlocksTransition.interface.yaml
new file mode 100644
index 0000000..51fbc8e
--- /dev/null
+++ b/xyz/openbmc_project/Software/ActivationBlocksTransition.interface.yaml
@@ -0,0 +1,13 @@
+description: >
+ Empty interface to indicate that the associated `Software.Version` should
+ prevent a state transition of the associated managed element while the
+ `Software.Version` is in `Activating` state.
+
+ The specific state transition(s) to prevent are left to the implementation.
+ A typical use of this would be to prevent (delay) the power-on of a
+ managed host while the BIOS is being updated. The managed host, via
+ systemd transitions, might start the power-on sequence and then wait for
+ any object with this `ActivationBlocksTransition` interface to no longer be
+ in `Activating` state. Causal ordering of dbus operations can prove that
+ no update is currently being performed and the power-on sequence may safely
+ continue.
diff --git a/xyz/openbmc_project/Software/ActivationProgress.interface.yaml b/xyz/openbmc_project/Software/ActivationProgress.interface.yaml
new file mode 100644
index 0000000..9f96246
--- /dev/null
+++ b/xyz/openbmc_project/Software/ActivationProgress.interface.yaml
@@ -0,0 +1,8 @@
+description: >
+ Activation progress for an associated xyz.openbmc_project.Software.Version.
+properties:
+ - name: Progress
+ type: uint8
+ description: >
+ An integer between 0 and 100 representing the percentage complete of
+ the current activation progress.
diff --git a/xyz/openbmc_project/Software/ExtendedVersion.interface.yaml b/xyz/openbmc_project/Software/ExtendedVersion.interface.yaml
new file mode 100644
index 0000000..0bcc419
--- /dev/null
+++ b/xyz/openbmc_project/Software/ExtendedVersion.interface.yaml
@@ -0,0 +1,7 @@
+description: >
+ An extended version string for a xyz.openbmc_project.Software.Version.
+properties:
+ - name: ExtendedVersion
+ type: string
+ description: >
+ Extended version of the level.
diff --git a/xyz/openbmc_project/Software/README.md b/xyz/openbmc_project/Software/README.md
new file mode 100644
index 0000000..f732e56
--- /dev/null
+++ b/xyz/openbmc_project/Software/README.md
@@ -0,0 +1,159 @@
+# Software Version Management and Image Update
+
+## Overview
+
+There are two types of processes involved in software version management and
+code update:
+
+1. *ImageManager* - This is a process which manages a collection of, likely
+ temporary, images located somewhere in a file system.
+ These are images which are available on the BMC for update.
+2. *ItemUpdater* - This is a process which manages specific storage elements,
+ likely for an inventory item, to determine which software
+ versions are installed onto that item. A specific example of
+ this would be a process that controls and updates the BIOS
+ flash module for a managed host.
+
+A simple system design would be to include a single *ImageManager* and two
+*ItemUpdater*s: one for the BMC itself and one for the Host.
+
+### ImageManager
+
+The *ImageManager* would provide interfaces at `/xyz/openbmc_project/software`
+to allow additional images to be added to the BMC, such as Object.Add() for
+REST and DownloadViaTFTP() for TFTP. The standard Object.Delete() interface
+would also be provided to facilitate removing images which are no longer
+needed. Images maintained in the file system would be presented as a
+corresponding `/xyz/openbmc_project/software/<id>` object.
+
+It is assumed that the *ImageManager* has [at least] a bare minimum amount of
+parsing knowledge, perhaps due to a common image format, to allow it to
+populate all of the properties of `xyz.openbmc_project.Software.Version`.
+*ItemUpdater*s will likely listen for standard dbus signals to identify new
+images being created.
+
+### *ItemUpdater*
+
+The *ItemUpdater* is responsible for monitoring for new `Software.Version` elements
+being created to identify versions that are applicable to the inventory
+element(s) it is managing. The *ItemUpdater* should dynamically create
+an `xyz.openbmc_project.Software.Activation` interface under
+`/xyz/openbmc_project/software/active/`, an association of type
+`{activation,software_version}` between the `Software.Version` and
+`Software.Activation`, and an association of type `{active_image,item}` between
+the `Inventory.Item` and `Software.Activation`. Application of the software
+image is then handled through the `RequestedActivation` property of the
+`Software.Activation` interface.
+
+The *ItemUpdater* should, if possible, also create its own
+`xyz.openbmc_project.Software.Version` objects, and appropriate associations
+for software versions that are currently present on the managed inventory
+element(s). This provides a mechanism for interrogation of the
+software versions when the *ImageManager* no longer contains a copy.
+
+## Details
+
+### Image Identifier
+
+The *ImageManager* and *ItemUpdater* should use a common, though perhaps
+implementation specific, algorithm for the `<id>` portion of a dbus path for
+each `Software.Version`. This allows the same software version to be contained
+in multiple locations but represented by the same object path.
+
+A reasonable algorithm might be:
+`echo <Version.Version> <Version.Purpose> | sha512sum | cut -b 1-8`
+
+> TODO: May need an issue against the REST server to 'merge' two copies of
+> a single dbus object into a single REST object.
+
+### Activation States
+
+`xyz.openbmc_project.Software.Activation` has a property Activation that can
+be in the following states:
+
+1. *NotReady* - Indicating that the *ItemUpdater* is still processing the
+ version and it is therefore not ready for activation. This
+ might be used on an image that has a security header while
+ verification is being performed.
+2. *Invalid* - Indicating that, while the `Software.Version.Purpose` suggested
+ the image was valid for a managed element, a detailed analysis
+ by the *ItemUpdater* showed that it was not. Reasons may
+ include image corruption detected via CRC or security
+ verification failure. An event may be recorded with additional
+ details.
+3. *Ready* - Indicating that the `Software.Version` can be activated.
+4. *Activating* - Indicating that the `Software.Version` is in the process of
+ being activated.
+5. *Active* - The `Software.Version` is active on the managed element. Note
+ that on systems with redundant storage devices a version might
+ be *Active* but not the primary version.
+6. *Failed* - The `Software.Version` or the storage medium on which it is stored
+ has failed. An event may be recorded with additional details.
+
+### Blocking State Transitions
+
+It is sometimes useful to block a system state transition while activations
+are being performed. For example, we do not want to boot a managed host while
+its BIOS is being updated. In order to facilitate this, the interface
+`xyz.openbmc_project.Software.ActivationBlocksTransition` may be added to any
+object with `Software.Activation` to indicate this behavior. See that
+interface for more details.
+
+It is strongly suggested that any activations are completed prior to a managed
+BMC reboot. This could be facilitated with systemd service specifiers.
+
+### Software Versions
+
+All version identifiers are implementation specific strings. No format
+should be assumed.
+
+Some software versions are a collection of images, each with their own version
+identifiers. The `xyz.openbmc_project.Software.ExtendedVersion` interface
+can be added to any `Software.Version` to express the versioning of the
+aggregation.
+
+### Activation Progress
+
+The `xyz.openbmc_project.Software.ActivationProgress` interface is provided
+to show current progress while a software version is *Activating*. It is
+expected that an *ItemUpdater* will dynamically create this interface while
+the version is *Activating* and dynamically remove it when the activation is
+complete (or failed).
+
+### Handling Redundancy
+
+The `xyz.openbmc_project.Software.RedundancyPriority` interface is provided to
+express the relationship between two (or more) software versions activated for
+a single managed element. It is expected that all installed versions are listed
+as *Active* and the `Priority` shows which version is the primary and which are
+available for redundancy.
+
+## REST use-cases
+
+### Find all software versions on the system, either active or available.
+
+List `/xyz/openbmc_project/software/`. This list can be filtered to just
+active listing `.../software/active/` and following the `software_version`
+association to retrieve version information.
+
+### Find all software versions on a managed element.
+
+List `/xyz/openbmc_project/inventory/.../<item>/active_image` association.
+
+### Upload new version via REST
+
+HTTP PUT to `/xyz/openbmc_project/software/`. *ImageManager* will assign the
+`<id>` when called for Object.Add().
+
+### Upload new version via ???
+
+Need additional interfaces defined for alternative upload methods.
+
+### Activate a version.
+
+Modify `RequestedActivation` to *Active* on the desired `Activation`.
+
+### Switch primary image.
+
+Set `Priority` to 0 on the desired `RedundancyPriority` interface.
+
diff --git a/xyz/openbmc_project/Software/RedundancyPriority.interface.yaml b/xyz/openbmc_project/Software/RedundancyPriority.interface.yaml
new file mode 100644
index 0000000..4f7ba27
--- /dev/null
+++ b/xyz/openbmc_project/Software/RedundancyPriority.interface.yaml
@@ -0,0 +1,23 @@
+description: >
+ The priority, for redundancy purposes, of the associated
+ xyz.openbmc_project.Software.Version.
+properties:
+ - name: Priority
+ type: uint8
+ description: >
+ The priority order specified for the associated Software.Version,
+ represented as a value between 0 (High) and 127 (Low). Any value
+ above 127 has implementation-specific purpose.
+
+ Only one Software.Version, per associated device, may be at any
+ particular priority. A requested priority change may cause other
+ Software.Versions to change priority.
+
+ A dual-sided redundancy model could be represented by two
+ Software.Version associations, one of which is at priority 0 and the
+ other at priority 1. When a new image is Activated, the old
+ priority-1 association is deleted, the old priority-0 association
+ becomes priority-1, and the new image is assigned priority-0.
+# TODO: Specify "EAGAIN" type error when priority is unable to be modified
+# due to current system state. Currently, sdbusplus does not support
+# errors on properties.
diff --git a/xyz/openbmc_project/Software/Version.interface.yaml b/xyz/openbmc_project/Software/Version.interface.yaml
new file mode 100644
index 0000000..f655af0
--- /dev/null
+++ b/xyz/openbmc_project/Software/Version.interface.yaml
@@ -0,0 +1,32 @@
+description: >
+ Simple definition of a Software or Firmware version.
+properties:
+ - name: Version
+ type: string
+ description: >
+ The version identifier.
+ - name: Purpose
+ type: enum[self.VersionPurpose]
+ description: >
+ The purpose of the version. As in, what can it be used for or
+ applied to?
+enumerations:
+ - name: VersionPurpose
+ description: >
+ An enumeration of possible purposes of the version.
+ values:
+ - name: Unknown
+ description: >
+ The version is of unknown purpose.
+ - name: Other
+ description: >
+ The version is of some other purpose.
+ - name: System
+ description: >
+ The version is an aggregate for the system as a whole.
+ - name: BMC
+ description: >
+ The version is a version for the BMC.
+ - name: Host
+ description: >
+ The version is a version for a managed host.