From c552d8d53da49f9a133f246bf138139a5c406cdd Mon Sep 17 00:00:00 2001 From: Arne Broering Date: Fri, 31 Oct 2025 14:11:33 +0100 Subject: [PATCH 01/29] iniital commit to integrate SUP Signed-off-by: Arne Broering --- .../workloads/application-registry.md | 275 ++++++++++++++++-- 1 file changed, 258 insertions(+), 17 deletions(-) diff --git a/system-design/concepts/workloads/application-registry.md b/system-design/concepts/workloads/application-registry.md index bf33a90..9abb529 100644 --- a/system-design/concepts/workloads/application-registry.md +++ b/system-design/concepts/workloads/application-registry.md @@ -1,32 +1,273 @@ # Application Registry -This section describes the Application Registry and the exchange of an [application package](./application-package.md) from an Application Developer to the Workload Fleet Manager (WFM). +This section describes the Application Registry and the exchange of an [Application Package](./application-package-definition.md) from an Application Developer to the Workload Fleet Manager (WFM). -The Application Developer SHALL use a [Git repository](https://git-scm.com/) to share an [application package](./application-package.md). This Git repository is considered the Application Registry. +* `Application Registry` - Implemented as an `OCI Registry`, it serves [Application Packages](https://specification.margo.org/app-interoperability/application-package-definition/) defined through `Application Description` files. +* `Workload Fleet Manager`, or internal `Application Catalog`, acting as client to pull applications from the registry. +* `Authentication Service` - Manages access control for the registry. +* `App Developer` - The actor who uploads the application to the Application Registry. -The connectivity between the Workload Fleet Manager and the Application Registry SHALL be read-only. +```mermaid +flowchart + A[App Developer] -->|Upload margo Application Package| B[Application Registry = OCI Registry] + C[WFM, or internal Application Catalog] -->|Discover & pull in margo Application Package| B + B -->|validates token| D[Authentication Service] + B -->|hosts 0..*| E@{ shape: docs, label: "Application Packages"} + C -->|requests token| D + style D stroke-dasharray: 3 6 +``` -Upon installation request from the End User, the Workload Fleet Manager SHALL retrieve the [application package](./application-package.md) using a ``git pull`` request from the Application Registry. +#### Overview of API Endpoints -The Workload Fleet Manager reads in the application description file, ``margo.yaml``, and presents a user interface that allows the specification of parameters available according to ``margo.yaml``. +The Application Catalog / WFM will interact with the Application Registry using standard OCI Registry API endpoints: -The End User then specifies the configuration parameters for the [application package](./application-package.md). +* Tags: `/v2/{name}/tags/list` for listing available versions of the Application Package +* Manifest: `/v2/{name}/manifests/{reference}` for retrieving an image manifest that lists layers, wach pointing a part of the Application Package, which is identifed through the `{reference}`. +* Blob: `/v2/{name}/blobs/{digest}` for downloading parts of the Application Package -Then, the [application package](./application-package.md) is ready to be passed on to the installation process. +`{name}` is the namespace of the repository, which needs to be directly communicted by the App Developer to the WFM vendor. It could be for example a combination of the organization's and application's name. -> **Note** -> The specifics of the installation process are still under discussion: this could be for example a GitOps based approach. +Further details on how to use these API enspoints are specified below [towards App Developer](#margo-application-registry-api-endpoint-definitions-towards-app-developer-aligned-with-oci_spec) and [towards WFM](#margo-application-registry-api-endpoint-definitions-towards-wfm-aligned-with-oci_spec). -During this process the containers referenced in the application manifest ([Helm Chart](https://helm.sh/docs/) or [Compose](https://github.com/compose-spec/compose-spec/blob/master/03-compose-file.md)) are retrieved from container/Helm registries. +#### Authentication & Authorization & Security +This proposal recommends that margo centrally defines authentication & authorization (& ssecurity) mechanisms, e.g., recommending the use of OAuth 2.0 with the following workflow: -At a minimum, a Margo-compliant Workload Fleet Manager SHALL provide a way for an end user to manually set up a connection between the Workload Fleet Manager and an application registry. This is required so as not to prohibit an end user from being able to install any Margo-compliant application they wish, including applications developed by the end user. +* WFM obtains credentials during onboarding +* WFM requests a token from an Authentication Service +* WFM uses the token for subsequent API calls to the Application Registry +* Application Registry validates the token and enforces access control -The Workload Fleet Manager MAY provide enhanced user experience options such as the pre-configuring of application registries to monitor. These can include application registries from third-party application vendors or their own applications. +All communications should use TLS 1.3+ to ensure transport security. -## Secure Access to the Application Package +> However, Authentication & Authorization & Security mechanisms should be defined centrally and homogeneously across margo. Hence, it is out of scope of this proposal. -It is expected the connection between the Workload Fleet Manager and the Application developer’s application registry is secured using standard secure connectivity best practices. Some standard practices include the following: +Further, tools such as [cosign](https://github.com/sigstore/cosign) can be employed for signing artifacts uploaded to the Application Registry and storing the signatures alongside the artifacts they verify. -- Basic authentication via HTTPS -- Bearer token authentication -- TLS certifications \ No newline at end of file +#### Reference Implementation +A reference implementation can be found [here](https://github.com/margo/app-package-definition-wg/blob/main/application-registry-example/app_registry_as_oci_registry.md). It utilizes: + +* Application Registry: Docker Registry (open source OCI Registry) +* Client Library: ORAS (OCI Registry as Storage) tool +* Examples: Sample applications and configuration for demonstration + +#### Overview of Interactions + +```mermaid +sequenceDiagram + + Note over AppDeveloper: uploads margo artifacts as blobs and OCI image manifest: + AppDeveloper->>AppRegistry: POST /v2/{name}/blobs/uploads/ + + + Note over AppDeveloper: uses vendor-specific upload mechanism (e.g., UI) to enable WFM to find the application: + AppDeveloper->>+WFM: Application location is: repository {name} in Application Registry + + Note over WFM: ... later in time: + Note over WFM: discovers available versions of an application: + WFM->>+AppRegistry: GET /v2/{name}/tags/list + + Note over WFM: retrieves the OCI image manifest of the selected application version. {reference} is tag or digest.: + WFM->>+AppRegistry: GET /v2/{name}/manifests/{reference} + + AppRegistry-->>+WFM: OCI image manifest + + Note over WFM: downloads application artifacts as listed in retrieved OCI image manifest: + WFM->>AppRegistry: GET /v2/{name}/blobs/{digest} +``` + + + +### margo 'Application Registry' API Endpoint Definitions towards App Developer (aligned with OCI_spec) + +#### Upload a margo Application Package + +The Application Developer uploads the margo-compliant `Application Package` to the Application Registry. I.e., the parts of the Application Package are uploaded as blobs and an OCI image manifest is created via the [end-4a / end-4b](https://github.com/opencontainers/distribution-spec/blob/v1.1.0/spec.md#endpoints) endpoints. + +Thereby, the Application Developer needs to make sure the OCI image manifest will be adhering to the margo-specific constraints detailed [here](#manifest-as-response-from-application-registry). +Other than these constraints on the OCI image manifest format, there are no further margo-specific constraints regarding the upload of the Application Package and the OCI_spec applies to this interface of the Application Registry. + +This process of uploading a margo Application Package is described in the [reference implementation](https://github.com/margo/app-package-definition-wg/blob/main/application-registry-example/app_registry_as_oci_registry.md). + + + +### margo 'Application Registry' API Endpoint Definitions towards WFM (aligned with OCI_spec) + +#### List margo Application Package Versions + +This must be implemented according to OCI_spec endpoint [end-8a / end-8b](https://github.com/opencontainers/distribution-spec/blob/v1.1.0/spec.md#endpoints). +Use `tags` to discover available versions of a Margo application. +`{name}` is the namespace of the repository, which needs to be directly communicted by the App Developer to the WFM vendor. + +`GET /v2/{name}/tags/list` + +##### Headers: + +```Authorization: Bearer ``` +> However, security mechanism needs to be margo-centrally defined. + +##### Query Parameters: + +* n= (optional, limits results) +* last= (optional, pagination cursor) + +##### Success Response: + +200 OK with list of tags + +##### Example Response: + +```json +{ + "name": "organization/app1", + "tags": [ + "v1.0.0", + "v1.1.0", + "latest" + ] +} +``` + +#### Pull Application's OCI Image Manifest +This must be implemented according to OCI_spec endpoint [end-3](https://github.com/opencontainers/distribution-spec/blob/v1.1.0/spec.md#endpoints). +Pulls an OCI image manifest of a specified version, which belongs to a margo Application Package. +The `{reference}` is the `tag` of an OCI image manifest. The `tag` has been discovered via the [listing of app versions](#list-margo-application-versions). +`{name}` is the namespace of the repository. + +``` GET /v2/{name}/manifests/{reference} ``` + +##### Headers: + +`Authorization: Bearer ` +> However, security mechanism needs to be margo-centrally defined. + +`Accept: application/vnd.oci.image.manifest.v1+json` + +##### Success Response: + +200 OK with OCI image manifest content + +##### Fail Response: + +404 Not Found if OCI image manifest doesn't exist + +##### OCI Image Manifest as Response from Application Registry: + +In the margo context, OCI image manifests contain pointers to all parts of an Application Package within an Application Registry. + +Each ``version`` of an Application Pacakage has its own OCI image manifest. + +The ``schemaVersion`` of the OCI image manifest needs to be ``2``. + +The ``artifactType`` of the OCI image manifest must be ``application/vnd.margo.app.v1+json``. + +The ``config`` object must be declared as empty by defining its ``mediaType`` as ``application/vnd.oci.empty.v1+json``. + +Each element of the ``layers`` array contains a reference (so called `digests`) to an artifact (so called `blobs`) that is part of the Application Package. +Each artifact of an Application Package must be listed as an element of the ``layers`` array. + +The [Application Description](https://specification.margo.org/margo-api-reference/workload-api/application-package-api/application-description/) of the Application Package must be referred to in one element of the ``layers`` array. The ``mediaType`` of this layer/blob must be ``application/vnd.margo.app.description.v1+yaml``. + +Each [application resource](https://specification.margo.org/app-interoperability/application-package-definition/), which is an additional file associated with the application (e.g., manual, icon, release notes, license file, etc.), must be referred to in an element of the ``layers`` array and an ``annotation`` must be added to this element, which has the annotation key ``org.margo.app.resource``, and the annotation value must reflect the dotted path to the this resource in the Application Description. +E.g., an application icon stored as the file ``resources/margo.jpg`` will be referenced in the Application Description under ``metadata.catalog.application.icon: resources/margo.jpg`` and in the OCI image manifest, the respective layer of the icon resource has the annotation ``org.margo.app.resource`` with the value ``metadata.catalog.application.icon`` (see also OCI image manifest example below). + + + +The following response example is a margo-specific OCI image manifest following the [OCI Image Manifest Specification](https://github.com/opencontainers/image-spec/blob/v1.0.1/manifest.md) and the above defined specifics: + +```json +{ + "schemaVersion": 2, + "mediaType": "application/vnd.oci.image.manifest.v1+json", + "artifactType": "application/vnd.margo.app.v1+json" # this MUST be the artifactType of en OCI image manifest of a margo Application Package, + "config": { + "mediaType": "application/vnd.oci.empty.v1+json", # the 'config' object MUST be empty + "digest": "sha256:44136fa355b3678a1146ad16f7e8649e94fb4fc21fe77e8310c060f61caaff8a", + "size": 2, + "data": "e30=" + }, + "layers": [ + { + "mediaType": "application/vnd.margo.app.description.v1+yaml", # this MUST be the artifactType of a margo Application Description file + "digest": "sha256:f6b79149e6650b0064c146df7c045d157f3656b5ad1279b5ce9f4446b510bacf", + "size": 999, + "annotations": { + "org.opencontainers.image.title": "margo.yaml" + } + }, + { + "mediaType": "text/markdown", + "digest": "sha256:e373b123782a2b52483a9124cc9c578e0ed0300cb4131b73b0c79612122b8361", + "size": 1596, + "annotations": { + "org.margo.app.resource": "metadata.catalog.application.descriptionFile", # each margo application resource MUST be annotated with a dotted path to its definition in the Application Description file + "org.opencontainers.image.title": "resources/description.md" + } + }, + { + "mediaType": "text/markdown", + "digest": "sha256:af7db4ab9030533b6cda2325247920c3659bc67a7d49f3d5098ae54a64633ec7", + "size": 25, + "annotations": { + "org.margo.app.resource": "metadata.catalog.application.licenseFile", # each margo application resource MUST be annotated with a dotted path to its definition in the Application Description file + "org.opencontainers.image.title": "resources/license.md" + } + }, + { + "mediaType": "image/jpeg", + "digest": "sha256:451410b6adfdce1c974da2275290d9e207911a4023fafea0e283fad0502e5e56", + "size": 5065, + "annotations": { + "org.margo.app.resource": "metadata.catalog.application.icon", # each margo application resource MUST be annotated with a dotted path to its definition in the Application Description file + "org.opencontainers.image.title": "resources/margo.jpg" + } + }, + { + "mediaType": "text/markdown", + "digest": "sha256:c412d143084c3b051d7ea4b166a7bfffb4550f401d89cae8898991c65e90f736", + "size": 42, + "annotations": { + "org.margo.app.resource": "metadata.catalog.application.releaseNotes", # each margo application resource MUST be annotated with a dotted path to its definition in the Application Description file + "org.opencontainers.image.title": "resources/release-notes.md" + } + } + ], +} +``` + +##### Margo-Specific Media Types + +|Media Type|Description| +|----------|----------| +|``application/vnd.margo.app.v1+json`` | MUST be used as the **artifactType** to mark the OCI image manifest as the definition of a margo Application Package | +|``application/vnd.margo.app.description.v1+yaml`` | MUST be used to mark a layer in the OCI image manifest as pointing to the margo Application Description file | + + +##### Margo-Specific Annotation Keys + +|Annotation Key | Description| +|----------|----------| +|``org.margo.app.resource`` | This MUST be used to annotate a layer/blob that references a margo application resource | + + + +#### Get margo Application Description or Resource +This must be implemented according to OCI_spec endpoint [end-2](https://github.com/opencontainers/distribution-spec/blob/v1.1.0/spec.md#endpoints). +Retrieves a margo Application Description or Appliction Resource by pulling a blob. +`{digest}` is the blobs digest as listed in the application's OCI image manifest that has been [retrieved earlier](#pull-margo-application-manifest). +`{name}` is the namespace of the repository. + + +`GET /v2/{name}/blobs/{digest}` + +##### Headers: + +`Authorization: Bearer ` +> However, security mechanism needs to be margo-centrally defined. + +##### Success Response: + +`200 OK with blob content` + +##### Fail Response: + +`404 Not Found if blob doesn't exist` From 6c67ddc076cc4f534442b061e129ea5b362fda2e Mon Sep 17 00:00:00 2001 From: Arne Broering Date: Wed, 5 Nov 2025 11:54:32 +0100 Subject: [PATCH 02/29] integrating SUP decision Signed-off-by: Arne Broering --- doc-generation/generate-documentation.bash | 2 +- mkdocs.yml | 3 +- .../resources/index.md.jinja2 | 6 +- .../concepts/workloads/application-package.md | 9 +- .../workloads/application-registry.md | 289 ++---------------- .../concepts/workloads/local-registries.md | 31 +- system-design/overview/workloads.md | 50 +-- .../application-registry.md | 259 ++++++++++++++++ 8 files changed, 331 insertions(+), 318 deletions(-) create mode 100644 system-design/specification/application-package/application-registry.md diff --git a/doc-generation/generate-documentation.bash b/doc-generation/generate-documentation.bash index 801299c..43fc851 100755 --- a/doc-generation/generate-documentation.bash +++ b/doc-generation/generate-documentation.bash @@ -45,5 +45,5 @@ done ( cd "${ROOT_DIR}" - ${RUN} mkdocs build + ${RUN} mkdocs serve ) diff --git a/mkdocs.yml b/mkdocs.yml index 992af79..b2820e5 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -32,8 +32,9 @@ nav: - specification/margo-management-interface/device-capabilities.md - specification/margo-management-interface/desired-state.md - specification/margo-management-interface/deployment-status.md - - Application Package: + - Applications: - specification/application-package/application-description.md + - specification/application-package/application-registry.md - Margo Devices: - specification/margo-devices/device-requirements.md - Observability: diff --git a/src/specification/application-package/resources/index.md.jinja2 b/src/specification/application-package/resources/index.md.jinja2 index 3d3bd68..742cab5 100644 --- a/src/specification/application-package/resources/index.md.jinja2 +++ b/src/specification/application-package/resources/index.md.jinja2 @@ -1,4 +1,8 @@ -The application description has the purpose of presenting the application, e.g., on an application catalog or marketplace from where an end user selects an application to be installed. The end user defines an `ApplicationDeployment` by specifying [configuration parameters](#defining-configurable-application-parameters) for an `ApplicationDescription`. An `ApplicationDeployment` defines the [desired state](../margo-management-interface/desired-state.md) for an application. +# Application Description + +The application description has the purpose of presenting the application, e.g., on an application catalog or marketplace from where an end user selects an application to be installed. +The end user defines an `ApplicationDeployment` by specifying [configuration parameters](#defining-configurable-application-parameters) for an `ApplicationDescription`. +An `ApplicationDeployment` defines the [desired state](../margo-management-interface/desired-state.md) for an application. ### Top-level Attributes diff --git a/system-design/concepts/workloads/application-package.md b/system-design/concepts/workloads/application-package.md index dc1dc02..5d18014 100644 --- a/system-design/concepts/workloads/application-package.md +++ b/system-design/concepts/workloads/application-package.md @@ -13,15 +13,14 @@ The application package has the following file/folder structure: └── resources # OPTIONAL folder with application files (e.g., icon, license file, release notes) that may be used for displaying additional information about the application ``` -An application aggregates one or more [OCI Containers](https://github.com/opencontainers). While the application package is made available in an [application registry](./application-registry.md), the referenced OCI artifacts are stored in a remote or [local registry](../../concepts/workloads/local-registries.md). +An application aggregates one or more [components](../personas-and-definitions/software-composition.md), which comprise of one or more [OCI Containers](https://github.com/opencontainers). While the application package is made available in an [Application Registry](./application-registry.md), the referenced components are stored in a Component Registry, and the linked containers are provided via a OCI Container Registry. Registries can be remote or [local](../../concepts/workloads/local-registries.md). > **Note** > Application catalogs or marketplaces are out of scope for Margo. The exact requirements of the marketing material shall be defined by the application marketplace beyond outlined mandatory content. -The [deployment profiles](../../specification/application-package/application-description.md#deploymentprofile-attributes) specified in the application description SHALL be defined as Helm Chart components AND/OR Compose components. - -- To target devices, which run Kubernetes, applications must be packaged as Helm charts using [Helm (version 3)](https://helm.sh/docs/topics/charts/). -- To target devices, which deploy applications using [Compose](https://www.compose-spec.io/), applications must be packaged as what Margo calls a Compose Archive, i.e., a tarball file containing the `compose.yaml` file and any additional artifacts referenced by the Compose file (e.g., configuration files, environment variable files, etc.). Margo recommends to digitally sign this package and to specify the location of the public key in the `ApplicationDescription` (see `keyLocation` [here](../../specification/application-package/application-description.md#componentproperties-attributes)). When digitally signing the package PGP encryption MUST be used. +The [deployment profiles](../../specification/application-package/application-description.md#deploymentprofile-attributes) specified in the application description SHALL be defined as Helm Chart components AND/OR Compose Archive components: +- To target devices, which run Kubernetes, application components must be Helm charts using [Helm (version 3)](https://helm.sh/docs/topics/charts/). +- To target devices, which deploy applications using [Compose](https://www.compose-spec.io/), applications must be packaged as what Margo calls a *Compose Archive*, i.e., a tarball file containing the `compose.yaml` file and any additional artifacts referenced by the Compose file (e.g., configuration files, environment variable files, etc.). Margo recommends to digitally sign this package and to specify the location of the public key in the `ApplicationDescription` (see `keyLocation` [here](../../specification/application-package/application-description.md#componentproperties-attributes)). When digitally signing the package PGP encryption MUST be used. > **Investigation Needed**: Question: do we need to specify the location of a SHA256 hash for the Compose Archive also (similar to the PGP key) in the ApplicationDescription? > We will also discuss how we should handle secure container registries that require a username and password. diff --git a/system-design/concepts/workloads/application-registry.md b/system-design/concepts/workloads/application-registry.md index 9abb529..fd254df 100644 --- a/system-design/concepts/workloads/application-registry.md +++ b/system-design/concepts/workloads/application-registry.md @@ -1,273 +1,42 @@ # Application Registry -This section describes the Application Registry and the exchange of an [Application Package](./application-package-definition.md) from an Application Developer to the Workload Fleet Manager (WFM). +The margo specification differentiates 4 different kinds of registries: *Application Registries*, *Component Registries*, and *Container Registries* as well as *Marketplaces*. -* `Application Registry` - Implemented as an `OCI Registry`, it serves [Application Packages](https://specification.margo.org/app-interoperability/application-package-definition/) defined through `Application Description` files. -* `Workload Fleet Manager`, or internal `Application Catalog`, acting as client to pull applications from the registry. -* `Authentication Service` - Manages access control for the registry. -* `App Developer` - The actor who uploads the application to the Application Registry. +1. An **Application Registry** hosts Application Packages that define through their [Application Description](../../specification/application-package/application-description.md) the application as one or multiple Components. +2. A **Component Registry** hosts the Components (which are deployable as *workloads*) and are provided as **Helm Charts** or **Compose Archives**. +3. A **Container Registry** hosts container images referenced by those Components. +4. A **Marketplace** lists applications to advertise them and enable purchasing for end users. -```mermaid -flowchart - A[App Developer] -->|Upload margo Application Package| B[Application Registry = OCI Registry] - C[WFM, or internal Application Catalog] -->|Discover & pull in margo Application Package| B - B -->|validates token| D[Authentication Service] - B -->|hosts 0..*| E@{ shape: docs, label: "Application Packages"} - C -->|requests token| D - style D stroke-dasharray: 3 6 -``` - -#### Overview of API Endpoints - -The Application Catalog / WFM will interact with the Application Registry using standard OCI Registry API endpoints: - -* Tags: `/v2/{name}/tags/list` for listing available versions of the Application Package -* Manifest: `/v2/{name}/manifests/{reference}` for retrieving an image manifest that lists layers, wach pointing a part of the Application Package, which is identifed through the `{reference}`. -* Blob: `/v2/{name}/blobs/{digest}` for downloading parts of the Application Package - -`{name}` is the namespace of the repository, which needs to be directly communicted by the App Developer to the WFM vendor. It could be for example a combination of the organization's and application's name. - -Further details on how to use these API enspoints are specified below [towards App Developer](#margo-application-registry-api-endpoint-definitions-towards-app-developer-aligned-with-oci_spec) and [towards WFM](#margo-application-registry-api-endpoint-definitions-towards-wfm-aligned-with-oci_spec). - -#### Authentication & Authorization & Security -This proposal recommends that margo centrally defines authentication & authorization (& ssecurity) mechanisms, e.g., recommending the use of OAuth 2.0 with the following workflow: - -* WFM obtains credentials during onboarding -* WFM requests a token from an Authentication Service -* WFM uses the token for subsequent API calls to the Application Registry -* Application Registry validates the token and enforces access control +Out of these 4 registries, **only the Application Registry interface is in scope** of the margo specification and its API definition can be found [here](../../specification/application-package/application-registry.md). -All communications should use TLS 1.3+ to ensure transport security. - -> However, Authentication & Authorization & Security mechanisms should be defined centrally and homogeneously across margo. Hence, it is out of scope of this proposal. - -Further, tools such as [cosign](https://github.com/sigstore/cosign) can be employed for signing artifacts uploaded to the Application Registry and storing the signatures alongside the artifacts they verify. - -#### Reference Implementation -A reference implementation can be found [here](https://github.com/margo/app-package-definition-wg/blob/main/application-registry-example/app_registry_as_oci_registry.md). It utilizes: - -* Application Registry: Docker Registry (open source OCI Registry) -* Client Library: ORAS (OCI Registry as Storage) tool -* Examples: Sample applications and configuration for demonstration - -#### Overview of Interactions +The diagram below illustrates these functionalities and relationships of registries within margo. ```mermaid -sequenceDiagram - - Note over AppDeveloper: uploads margo artifacts as blobs and OCI image manifest: - AppDeveloper->>AppRegistry: POST /v2/{name}/blobs/uploads/ - - - Note over AppDeveloper: uses vendor-specific upload mechanism (e.g., UI) to enable WFM to find the application: - AppDeveloper->>+WFM: Application location is: repository {name} in Application Registry - - Note over WFM: ... later in time: - Note over WFM: discovers available versions of an application: - WFM->>+AppRegistry: GET /v2/{name}/tags/list - - Note over WFM: retrieves the OCI image manifest of the selected application version. {reference} is tag or digest.: - WFM->>+AppRegistry: GET /v2/{name}/manifests/{reference} - - AppRegistry-->>+WFM: OCI image manifest - - Note over WFM: downloads application artifacts as listed in retrieved OCI image manifest: - WFM->>AppRegistry: GET /v2/{name}/blobs/{digest} -``` - - - -### margo 'Application Registry' API Endpoint Definitions towards App Developer (aligned with OCI_spec) - -#### Upload a margo Application Package - -The Application Developer uploads the margo-compliant `Application Package` to the Application Registry. I.e., the parts of the Application Package are uploaded as blobs and an OCI image manifest is created via the [end-4a / end-4b](https://github.com/opencontainers/distribution-spec/blob/v1.1.0/spec.md#endpoints) endpoints. - -Thereby, the Application Developer needs to make sure the OCI image manifest will be adhering to the margo-specific constraints detailed [here](#manifest-as-response-from-application-registry). -Other than these constraints on the OCI image manifest format, there are no further margo-specific constraints regarding the upload of the Application Package and the OCI_spec applies to this interface of the Application Registry. - -This process of uploading a margo Application Package is described in the [reference implementation](https://github.com/margo/app-package-definition-wg/blob/main/application-registry-example/app_registry_as_oci_registry.md). - - - -### margo 'Application Registry' API Endpoint Definitions towards WFM (aligned with OCI_spec) - -#### List margo Application Package Versions - -This must be implemented according to OCI_spec endpoint [end-8a / end-8b](https://github.com/opencontainers/distribution-spec/blob/v1.1.0/spec.md#endpoints). -Use `tags` to discover available versions of a Margo application. -`{name}` is the namespace of the repository, which needs to be directly communicted by the App Developer to the WFM vendor. - -`GET /v2/{name}/tags/list` - -##### Headers: - -```Authorization: Bearer ``` -> However, security mechanism needs to be margo-centrally defined. - -##### Query Parameters: - -* n= (optional, limits results) -* last= (optional, pagination cursor) - -##### Success Response: - -200 OK with list of tags - -##### Example Response: - -```json -{ - "name": "organization/app1", - "tags": [ - "v1.0.0", - "v1.1.0", - "latest" - ] -} -``` - -#### Pull Application's OCI Image Manifest -This must be implemented according to OCI_spec endpoint [end-3](https://github.com/opencontainers/distribution-spec/blob/v1.1.0/spec.md#endpoints). -Pulls an OCI image manifest of a specified version, which belongs to a margo Application Package. -The `{reference}` is the `tag` of an OCI image manifest. The `tag` has been discovered via the [listing of app versions](#list-margo-application-versions). -`{name}` is the namespace of the repository. - -``` GET /v2/{name}/manifests/{reference} ``` - -##### Headers: - -`Authorization: Bearer ` -> However, security mechanism needs to be margo-centrally defined. - -`Accept: application/vnd.oci.image.manifest.v1+json` - -##### Success Response: - -200 OK with OCI image manifest content - -##### Fail Response: - -404 Not Found if OCI image manifest doesn't exist - -##### OCI Image Manifest as Response from Application Registry: - -In the margo context, OCI image manifests contain pointers to all parts of an Application Package within an Application Registry. - -Each ``version`` of an Application Pacakage has its own OCI image manifest. - -The ``schemaVersion`` of the OCI image manifest needs to be ``2``. - -The ``artifactType`` of the OCI image manifest must be ``application/vnd.margo.app.v1+json``. - -The ``config`` object must be declared as empty by defining its ``mediaType`` as ``application/vnd.oci.empty.v1+json``. - -Each element of the ``layers`` array contains a reference (so called `digests`) to an artifact (so called `blobs`) that is part of the Application Package. -Each artifact of an Application Package must be listed as an element of the ``layers`` array. - -The [Application Description](https://specification.margo.org/margo-api-reference/workload-api/application-package-api/application-description/) of the Application Package must be referred to in one element of the ``layers`` array. The ``mediaType`` of this layer/blob must be ``application/vnd.margo.app.description.v1+yaml``. - -Each [application resource](https://specification.margo.org/app-interoperability/application-package-definition/), which is an additional file associated with the application (e.g., manual, icon, release notes, license file, etc.), must be referred to in an element of the ``layers`` array and an ``annotation`` must be added to this element, which has the annotation key ``org.margo.app.resource``, and the annotation value must reflect the dotted path to the this resource in the Application Description. -E.g., an application icon stored as the file ``resources/margo.jpg`` will be referenced in the Application Description under ``metadata.catalog.application.icon: resources/margo.jpg`` and in the OCI image manifest, the respective layer of the icon resource has the annotation ``org.margo.app.resource`` with the value ``metadata.catalog.application.icon`` (see also OCI image manifest example below). - - - -The following response example is a margo-specific OCI image manifest following the [OCI Image Manifest Specification](https://github.com/opencontainers/image-spec/blob/v1.0.1/manifest.md) and the above defined specifics: - -```json -{ - "schemaVersion": 2, - "mediaType": "application/vnd.oci.image.manifest.v1+json", - "artifactType": "application/vnd.margo.app.v1+json" # this MUST be the artifactType of en OCI image manifest of a margo Application Package, - "config": { - "mediaType": "application/vnd.oci.empty.v1+json", # the 'config' object MUST be empty - "digest": "sha256:44136fa355b3678a1146ad16f7e8649e94fb4fc21fe77e8310c060f61caaff8a", - "size": 2, - "data": "e30=" - }, - "layers": [ - { - "mediaType": "application/vnd.margo.app.description.v1+yaml", # this MUST be the artifactType of a margo Application Description file - "digest": "sha256:f6b79149e6650b0064c146df7c045d157f3656b5ad1279b5ce9f4446b510bacf", - "size": 999, - "annotations": { - "org.opencontainers.image.title": "margo.yaml" - } - }, - { - "mediaType": "text/markdown", - "digest": "sha256:e373b123782a2b52483a9124cc9c578e0ed0300cb4131b73b0c79612122b8361", - "size": 1596, - "annotations": { - "org.margo.app.resource": "metadata.catalog.application.descriptionFile", # each margo application resource MUST be annotated with a dotted path to its definition in the Application Description file - "org.opencontainers.image.title": "resources/description.md" - } - }, - { - "mediaType": "text/markdown", - "digest": "sha256:af7db4ab9030533b6cda2325247920c3659bc67a7d49f3d5098ae54a64633ec7", - "size": 25, - "annotations": { - "org.margo.app.resource": "metadata.catalog.application.licenseFile", # each margo application resource MUST be annotated with a dotted path to its definition in the Application Description file - "org.opencontainers.image.title": "resources/license.md" - } - }, - { - "mediaType": "image/jpeg", - "digest": "sha256:451410b6adfdce1c974da2275290d9e207911a4023fafea0e283fad0502e5e56", - "size": 5065, - "annotations": { - "org.margo.app.resource": "metadata.catalog.application.icon", # each margo application resource MUST be annotated with a dotted path to its definition in the Application Description file - "org.opencontainers.image.title": "resources/margo.jpg" - } - }, - { - "mediaType": "text/markdown", - "digest": "sha256:c412d143084c3b051d7ea4b166a7bfffb4550f401d89cae8898991c65e90f736", - "size": 42, - "annotations": { - "org.margo.app.resource": "metadata.catalog.application.releaseNotes", # each margo application resource MUST be annotated with a dotted path to its definition in the Application Description file - "org.opencontainers.image.title": "resources/release-notes.md" - } - } - ], -} +flowchart + A[WFM, or internal Application Catalog] -- Application Descriptions link to --> B[Component Registry] + C[Application Registry] -- Application Descriptions link to --> B + B -- hosted Components links to --> D[Container Registry] + A -->|pulls Application Package | C + F[App Developer] -->|uploads Application Package to| C + G["Marketplace"] -- points to Application Package --> C + C -->|hosts 0..*| E@{ shape: docs, label: "Application Packages"} + C -->|validates token| H[Authentication Service] + A -->|requests token| H + style H stroke-dasharray: 3 6 + + style B fill:#ABC + style C fill:#ABC + style D fill:#ABC + style G fill:#ABC ``` -##### Margo-Specific Media Types - -|Media Type|Description| -|----------|----------| -|``application/vnd.margo.app.v1+json`` | MUST be used as the **artifactType** to mark the OCI image manifest as the definition of a margo Application Package | -|``application/vnd.margo.app.description.v1+yaml`` | MUST be used to mark a layer in the OCI image manifest as pointing to the margo Application Description file | - - -##### Margo-Specific Annotation Keys - -|Annotation Key | Description| -|----------|----------| -|``org.margo.app.resource`` | This MUST be used to annotate a layer/blob that references a margo application resource | - - - -#### Get margo Application Description or Resource -This must be implemented according to OCI_spec endpoint [end-2](https://github.com/opencontainers/distribution-spec/blob/v1.1.0/spec.md#endpoints). -Retrieves a margo Application Description or Appliction Resource by pulling a blob. -`{digest}` is the blobs digest as listed in the application's OCI image manifest that has been [retrieved earlier](#pull-margo-application-manifest). -`{name}` is the namespace of the repository. - - -`GET /v2/{name}/blobs/{digest}` - -##### Headers: - -`Authorization: Bearer ` -> However, security mechanism needs to be margo-centrally defined. +As shown in the figure above, an `Application Developer` uploads an [Application package](application-package.md) to an Application Registry. From there, it is available to a `Workload Fleet Manager` (WFM). +The WFM acts as a client to pull an [Application Package](application-package.md) from the Application Registry. It would then list this Application Package on its UI (e.g., an internal `Application Catalog`) to enable the usage on its managed devices. -##### Success Response: +An `Authentication Service` manages access control for the Application Registry. Hence, the WFM requests a token from there to include it into its requests to the Application Registry. The received token is then validated by the Application Registry through interaction with the Authentication Service. -`200 OK with blob content` +The Application Registry's API is compliant with the [OCI Registry API (v1.1.0)](https://github.com/opencontainers/distribution-spec/blob/v1.1.0/spec.md). A hosted Application Package is provided by listing its parts as layers in an [image manifests](https://github.com/opencontainers/image-spec/blob/v1.0.1/manifest.md)) that can be requested through the API. -##### Fail Response: -`404 Not Found if blob doesn't exist` +## Relevant Links +Please follow the following link to view the technical reference of the [Application Registry API](../../specification/application-package/application-registry.md). diff --git a/system-design/concepts/workloads/local-registries.md b/system-design/concepts/workloads/local-registries.md index 7cfa193..8958857 100644 --- a/system-design/concepts/workloads/local-registries.md +++ b/system-design/concepts/workloads/local-registries.md @@ -1,35 +1,16 @@ # Local Registries -The margo specification differentiates 3 different kinds of registries: Application, Component, and Container Registries. +The [Component Registry](application-registry.md) as well as the [Container Registry](application-registry.md) considered by margo are the registries that need to be accessed by devices to download components (i.e., Helm Charts or Compose Archives) or containers. This section describeds how to configure those as local registries to avoid reliance on public Internet-accessible registries. -1. A **Application Registry** hosts the Application Packages that defines through its [Application Description](../../specification/application-package/application-description.md) the application as one or multiple Components. -2. A **Component Registry** hosts the Components (which are deployable as *workloads*) and are provided as **Helm Charts** or **Compose Archives**. -3. A **Container Registry** hosts container images referenced by those Components. - -The diagram below illustrates these functionalities and relationships of registries within margo. - -```mermaid -flowchart - A[WFM, or internal Application Catalog] -- Application Description Links to --> B[Component Registry] - C[Application Registry] -- Application Description links to --> B - B -- Component links to --> D[Container Registry] - A -->|pulls in Application Package from| C - F[App Developer] -->|uploads Applications Packages to| C - G["Marketplace (outside Margo's scope)"] -- points to Application Package --> C - -``` - -This section investigates options for configuring the usage of local OCI-based Component and/or Container Registries. The goal of configuring such local registries is to avoid reliance on public, Internet-accessible registries. - -The reasons for not using such public registries are mainly twofold: (1) publicly hosted container images or Helm charts could become unavailable at some point, as the owner decides to take the container images or Helm charts off the public registry, (2) Internet connectivity may not be available to the device and hence public registries are not reachable, or (3) end-users want to host their own registries so they can do security scans and package validation. +The reasons for not using public registries are for example: (1) publicly hosted container images or Helm charts could become unavailable at some point, as the owner decides to take the container images or Helm charts off the public registry, (2) Internet connectivity may not be available to the device and hence public registries are not reachable, or (3) end-users want to host their own registries so they can do security scans and package validation. In terms of connectivity, we can thereby distinguish mainly between the following device categories: 1. **Fully connected device**, which means a device is deployed in the field (e.g., a factory shop floor) and has access to the Internet. 2. **Locally connected device**, i.e., the device has connectivity to a local network (e.g., factory- or enterprise-wide) and a local repository can be made reachable. -3. **Air-gapped device**, i.e., the device generally is not connected and must be configured by accessing it directly (via USB, Bluetooth, or a direct network link, e.g., via Ethernet cable, or similar) for example via a technician’s laptop. +3. **Air-gapped device**, i.e., the device generally is not connected and must be configured by accessing it directly (via direct network link with an Ethernet cable, or similar) for example through a technician’s laptop. -Local registries for container images and Helm Charts can be used for all three categories of devices. In case of **fully connected devices**, although the device could reach the Internet, a local registry can still be useful, e.g., as a cache for remote registries to save on bandwidth or to have container images and Helm Charts reliably available. In case of **locally connected devices**, a local registry is required to enable the Workload Fleet Management Client (WFMC) to install a margo application on the device, as the device/WFMC does not have Internet access. Thereby, the local registry can be set up as a *pull-through cache* where data (e.g., container images) are cached locally when they are first retrieved from a remote source and subsequent requests for the same data are served from the local cache rather than fetching it again from the remote source. In case of **air-gapped devices**, a local registry has to be accessible on the technician's laptop (or other directly connected device), which performs the application installation process. +Local Component Registries or Container Registries can be used for all three categories of devices. In case of **fully connected devices**, although the device could reach the Internet, a local registry can still be useful, e.g., as a cache for remote registries to save on bandwidth or to have container images or Helm Charts reliably available. In case of **locally connected devices**, a local registry is required to enable the Workload Fleet Management Client (WFMC) to install a margo application on the device, as the device/WFMC does not have Internet access. Thereby, the local registry can be set up as a *pull-through cache* where data (e.g., container images) are cached locally when they are first retrieved from a remote source and subsequent requests for the same data are served from the local cache rather than fetching it again from the remote source. In case of **air-gapped devices**, a local registry has to be accessible on the technician's laptop (or other directly connected device), which performs the application installation process. To setup local registries, different configuration options exist: @@ -51,7 +32,7 @@ configs: ## Option - Container Registry as Pull-through Cache on Docker Level -To configure a pull-through cache in Docker for the container registry, a Docker Registry can be setup that acts as caching proxy for a remote Docker registry. Such a Docker Registry container can be defined using the following `config.yml`: +To configure a pull-through cache in Docker for the Container Registry, a Docker Registry can be setup that acts as caching proxy for a remote Docker Registry. Such a Docker Registry can be defined using the following `config.yml`: ```yaml version: 0.1 @@ -88,7 +69,7 @@ Then, the Docker daemon needs to be configured to use the private registry as a ## Option - Helm Chart Component Registry as Pull-through Cache -Setting up a pull-through cache for Helm charts in combination with Kubernetes involves configuring a local Helm chart repository, e.g., ChartMuseum that can be installed with the `PROXY_CACHE` variable set to `true`: +Setting up a pull-through cache for Helm charts in combination with Kubernetes involves configuring a local Helm chart repository, e.g., ChartMuseum, that can be installed with the `PROXY_CACHE` variable set to `true`: ```bash helm repo add chartmuseum https://chartmuseum.github.io/charts diff --git a/system-design/overview/workloads.md b/system-design/overview/workloads.md index 9bfec45..fd58ba8 100644 --- a/system-design/overview/workloads.md +++ b/system-design/overview/workloads.md @@ -1,26 +1,26 @@ # Workloads -A [workload](../personas-and-definitions/technical-lexicon.md#workload) is software deployed to, and run on, Margo compliant [edge compute devices](../personas-and-definitions/technical-lexicon.md#edge-compute-device). +A [workload](../personas-and-definitions/technical-lexicon.md#workload) is running software. More specifically, a workload is a running [component](../personas-and-definitions/software-composition.md) of an application deployed to a Margo compliant [edge compute devices](../personas-and-definitions/technical-lexicon.md#edge-compute-device). -In order to help achieve Margo's interoperability [mission statement](../index.md#mission-statement) we are initially targeting [containerized](https://github.com/opencontainers) workloads capable of running on platforms like Kubernetes, Docker and Podman. The flexibility these platforms provide enables [workload suppliers](../personas-and-definitions/personas.md#workload-supplier) to define and package their workloads in a common way using [Helm](https://helm.sh/docs/) or the [Compose specification](https://github.com/compose-spec/compose-spec/blob/main/spec.md) so they can more easily be deployed to multiple compatible edge compute devices. +In order to help achieve Margo's interoperability [mission statement](../index.md#mission-statement) we are initially targeting [containerized](https://github.com/opencontainers) components/workloads capable of running on platforms like Kubernetes, Docker and Podman. The flexibility these platforms provide enables [workload suppliers](../personas-and-definitions/personas.md#workload-supplier) to define and package their components in a common way using [Helm](https://helm.sh/docs/) or the [Compose specification](https://github.com/compose-spec/compose-spec/blob/main/spec.md) so they can more easily be deployed to multiple compatible edge compute devices as workloads. While Margo is initially targeting deployments using Helm or Compose, we plan to support other deployment types in the future. One of our design goals is to make it easier for [workload fleet managers](../personas-and-definitions/technical-lexicon.md#workload-fleet-manager) to support the current and future deployment types without having to implement special logic for each type. In order to achieve this, Margo defines an [application description model](../concepts/workloads/application-package.md) to abstract away some of the details to make it easier for workload fleet managers to support the different deployment types. The three main goals of Margo's application description model is to allow workload fleet managers to do the following: -- Display information about the workloads the [OT user](../personas-and-definitions/personas.md#ot-user) can deploy (e.g., a [workload catalog](../personas-and-definitions/technical-lexicon.md#application-catalog)). -- Determine which edge compute devices are compatible with the workloads (e.g., processor types match, GPU present, etc.) -- Capture, and validate, configuration information from the OT user when deploying and updating workloads. +- Display information about available applications (e.g., via an [application catalog](../personas-and-definitions/technical-lexicon.md#application-catalog)), which the [OT user](../personas-and-definitions/personas.md#ot-user) can deploy as workloads. +- Determine which edge compute devices are compatible with an application (regarding processor type, GPU present, RAM available, etc.) +- Capture, and validate, configuration information from the OT user when deploying application components as workloads, or updating them. Another advantage of Margo's [application description model](../concepts/workloads/application-package.md) is to enable workload suppliers to define different deployment profiles in a single application description file to target deploying to different types of edge compute devices (e.g., Arm vs. x86, Kubernetes vs. Docker) instead of needing to maintain multiple application description files. -## Packaging +## Packaging & Distribution -To distribute one, or more, workloads they are wrapped in an [application package](../concepts/workloads/application-package.md) that is provided by the workload supplier who aims to provide it to Margo-compliant edge compute devices. Therefore, the workload supplier creates an application description YAML document containing information about the application and a reference on how to deploy the [OCI-containerized](https://github.com/opencontainers) workloads that make up the application. The application package is made available in an [application registry](../concepts/workloads/application-registry.md) and the OCI artifacts are stored in a remote or [local registry](../concepts/workloads/local-registries.md). +To distribute an application consisting of multiple components that are deployable as workloads, they are wrapped in an [application package](../concepts/workloads/application-package.md) defined by the workload supplier who aims to provide it to Margo-compliant edge compute devices. Therefore, the workload supplier creates an application description YAML document containing information about the application and references to its components. The application package is made available in an [application registry](../concepts/workloads/application-registry.md), its components (i.e., Helm Charts or Compose Archives) are stored in a remote or [local](../concepts/workloads/local-registries.md) component registry, and the linked [OCI containers](https://github.com/opencontainers) are provided through an OCI container registry. -## Example workflow +### Example workflow -The following diagram provides an example workflow showing one way a workload fleet manager might use the application description information: +The following diagram provides an example workflow showing one way a workload fleet manager may use the application description information: ```mermaid --- @@ -38,36 +38,36 @@ sequenceDiagram autonumber EndUser->>frontend: Visits Application Catalog - frontend->>fleetmgr: Get list of available workloads (=Apps) + frontend->>fleetmgr: Get list of available application packages alt - fleetmgr ->> registry: Get 'application description' from each known application registry. + fleetmgr ->> registry: Get application descriptions from each known application registry. else - fleetmgr ->> fleetmgr: Get 'application description' for all cached applications. + fleetmgr ->> fleetmgr: Get application descriptions for all cached applications. end - fleetmgr->>frontend: Return list of 'application description's + fleetmgr->>frontend: Return list of application descriptions - frontend ->> frontend: Read all 'application description's -> 'metadata' element + frontend ->> frontend: Read all application descriptions' 'metadata' element frontend ->> EndUser: Show UI with list of applications - EndUser->>frontend: Select workload (=App) to install - frontend ->> frontend: Read 'application description' -> 'configuration' element - frontend -->> EndUser: Show UI to fill App configuration - EndUser ->> frontend: Answer configurable questions to be applied to workload(s) + EndUser->>frontend: Select application / components to install + frontend ->> frontend: Read application descriptions' 'configuration' element + frontend -->> EndUser: Show UI to fill application configuration + EndUser ->> frontend: fills application configuration frontend ->> fleetmgr: Create 'ApplicationDeployment' definition ``` -1. An end user visits an [workload catalog](../personas-and-definitions/technical-lexicon.md#application-catalog) of the Workload Fleet Manager Frontend. -2. This frontend requests all workloads from the Workload Fleet Manager. -3. _Either_: the Workload Fleet Manager requests all application descriptions from each known Application Registry. +1. An end user visits the [application catalog](../personas-and-definitions/technical-lexicon.md#application-catalog) of a Workload Fleet Manager Frontend. +2. This frontend requests all installable [application packages](../concepts/workloads/application-package.md) from the Workload Fleet Manager. +3. _Either_: the Workload Fleet Manager requests all application descriptions from each known [application registry](../concepts/workloads/application-registry.md). 4. _Or_: the Workload Fleet Manager maintains a cache of application descriptions and services the request from there. -5. The Workload Fleet Manager returns the retrieved documents of application descriptions to the frontend. -6. The frontend parses the [metadata](../specification/application-package/application-description.md#metadata-attributes) element of all received application description documents. +5. The Workload Fleet Manager returns the retrieved application descriptions to the frontend. +6. The frontend parses the [metadata](../specification/application-package/application-description.md#metadata-attributes) element of all received application descriptions. 7. The frontend presents the parsed metadata in a UI to the end user. -8. The end user selects the workload to be installed. +8. The end user selects the application package to be installed. 9. The frontend parses the [configuration](../specification/application-package/application-description.md#configuration-attributes) element of the selected application description. 10. The frontend presents the parsed configuration to the user. -11. The end user fills out the [configurable application parameters](../specification/application-package/application-description.md#defining-configurable-application-parameters) to be applied to the workload. +11. The end user fills out the [configurable application parameters](../specification/application-package/application-description.md#defining-configurable-application-parameters). 12. The frontend creates an `ApplicationDeployment` definition (from the `ApplicationDescription` and the filled out parameters) and sends it to the Workload Fleet Manager, which executes it as the [desired state](../specification/margo-management-interface/desired-state.md). ## Relevant Links diff --git a/system-design/specification/application-package/application-registry.md b/system-design/specification/application-package/application-registry.md new file mode 100644 index 0000000..e16f22f --- /dev/null +++ b/system-design/specification/application-package/application-registry.md @@ -0,0 +1,259 @@ +# Application Registry + +This section specifies the API of the `Application Registry` and the exchange of an [Application Package](./application-package-definition.md), defined through an [Application Description](../../specification/application-package/) file, from an Application Developer to the Workload Fleet Manager (WFM). The `Application Registry` is designed as an `OCI Registry`, i.e., it offers an API compliant with the [OCI Registry API (v1.1.0)](https://github.com/opencontainers/distribution-spec/blob/v1.1.0/spec.md) for digital artifact distribution. This way, the Application Registry hosts the parts of an [Application Package](https://specification.margo.org/app-interoperability/application-package-definition/) in form of `blobs` and uses `image manifests` according to [OCI Image specification](https://github.com/opencontainers/image-spec/blob/v1.0.1/manifest.md)) to list a set of `layers`, each pointing at a blob. + + +## Overview of API Endpoints + +The Application Catalog / WFM interacts with the Application Registry using standard OCI Registry API endpoints: + +* Tags: `/v2/{name}/tags/list` for listing available versions of the Application Package +* Manifest: `/v2/{name}/manifests/{reference}` for retrieving an image manifest (identifed through the `{reference}`) that lists layers, which are part of the Application Package. +* Blob: `/v2/{name}/blobs/{digest}` for downloading parts of the Application Package + +`{name}` is the namespace of the repository, which needs to be directly communicted by the App Developer to the WFM vendor. It could be for example a combination of the organization's and application's name. + +Further details on how to use these API enspoints are specified below [towards App Developer](#margo-application-registry-api-endpoint-definitions-towards-app-developer-aligned-with-oci_spec) and [towards WFM](#margo-application-registry-api-endpoint-definitions-towards-wfm-aligned-with-oci_spec). + +## Authentication & Authorization & Security +This proposal recommends that margo centrally defines authentication & authorization (& ssecurity) mechanisms, e.g., recommending the use of OAuth 2.0 with the following workflow: + +* WFM obtains credentials during onboarding +* WFM requests a token from an Authentication Service +* WFM uses the token for subsequent API calls to the Application Registry +* Application Registry validates the token and enforces access control + +All communications should use TLS 1.3+ to ensure transport security. + +> However, Authentication & Authorization & Security mechanisms should be defined centrally and homogeneously across margo. Hence, it is out of scope of this proposal. + +Further, tools such as [cosign](https://github.com/sigstore/cosign) can be employed for signing artifacts uploaded to the Application Registry and storing the signatures alongside the artifacts they verify. + +## Reference Implementation +A reference implementation can be found [here](https://github.com/margo/app-package-definition-wg/blob/main/application-registry-example/app_registry_as_oci_registry.md). It utilizes: + +* Application Registry: Docker Registry (open source OCI Registry) +* Client Library: ORAS (OCI Registry as Storage) tool +* Examples: Sample applications and configuration for demonstration + +## Overview of Interactions + +```mermaid +sequenceDiagram + + Note over AppDeveloper: uploads margo artifacts as blobs and OCI image manifest: + AppDeveloper->>AppRegistry: POST /v2/{name}/blobs/uploads/ + + + Note over AppDeveloper: uses vendor-specific upload mechanism (e.g., UI) to enable WFM to find the application: + AppDeveloper->>+WFM: Application location is: repository {name} in Application Registry + + Note over WFM: ... later in time: + Note over WFM: discovers available versions of an application: + WFM->>+AppRegistry: GET /v2/{name}/tags/list + + Note over WFM: retrieves the OCI image manifest of the selected application version. {reference} is tag or digest.: + WFM->>+AppRegistry: GET /v2/{name}/manifests/{reference} + + AppRegistry-->>+WFM: OCI image manifest + + Note over WFM: downloads application artifacts as listed in retrieved OCI image manifest: + WFM->>AppRegistry: GET /v2/{name}/blobs/{digest} +``` + + + +## margo 'Application Registry' API Endpoint Definitions towards App Developer (aligned with OCI_spec) + +### Upload a margo Application Package + +The Application Developer uploads the margo-compliant `Application Package` to the Application Registry. I.e., the parts of the Application Package are uploaded as blobs and an OCI image manifest is created via the [end-4a / end-4b](https://github.com/opencontainers/distribution-spec/blob/v1.1.0/spec.md#endpoints) endpoints. + +Thereby, the Application Developer needs to make sure the OCI image manifest will be adhering to the margo-specific constraints detailed [here](#manifest-as-response-from-application-registry). +Other than these constraints on the OCI image manifest format, there are no further margo-specific constraints regarding the upload of the Application Package and the OCI_spec applies to this interface of the Application Registry. + +This process of uploading a margo Application Package is described in the [reference implementation](https://github.com/margo/app-package-definition-wg/blob/main/application-registry-example/app_registry_as_oci_registry.md). + + + +## margo 'Application Registry' API Endpoint Definitions towards WFM (aligned with OCI_spec) + +### List margo Application Package Versions + +This must be implemented according to OCI_spec endpoint [end-8a / end-8b](https://github.com/opencontainers/distribution-spec/blob/v1.1.0/spec.md#endpoints). +Use `tags` to discover available versions of a Margo application. +`{name}` is the namespace of the repository, which needs to be directly communicted by the App Developer to the WFM vendor. + +`GET /v2/{name}/tags/list` + +#### Headers: + +```Authorization: Bearer ``` +> However, security mechanism needs to be margo-centrally defined. + +#### Query Parameters: + +* n= (optional, limits results) +* last= (optional, pagination cursor) + +#### Success Response: + +200 OK with list of tags + +#### Example Response: + +```json +{ + "name": "organization/app1", + "tags": [ + "v1.0.0", + "v1.1.0", + "latest" + ] +} +``` + +####Pull Application's OCI Image Manifest +This must be implemented according to OCI_spec endpoint [end-3](https://github.com/opencontainers/distribution-spec/blob/v1.1.0/spec.md#endpoints). +Pulls an OCI image manifest of a specified version, which belongs to a margo Application Package. +The `{reference}` is the `tag` of an OCI image manifest. The `tag` has been discovered via the [listing of app versions](#list-margo-application-versions). +`{name}` is the namespace of the repository. + +``` GET /v2/{name}/manifests/{reference} ``` + +#### Headers: + +`Authorization: Bearer ` +> However, security mechanism needs to be margo-centrally defined. + +`Accept: application/vnd.oci.image.manifest.v1+json` + +#### Success Response: + +200 OK with OCI image manifest content + +#### Fail Response: + +404 Not Found if OCI image manifest doesn't exist + +#### OCI Image Manifest as Response from Application Registry: + +In the margo context, OCI image manifests contain pointers to all parts of an Application Package within an Application Registry. + +Each ``version`` of an Application Pacakage has its own OCI image manifest. + +The ``schemaVersion`` of the OCI image manifest needs to be ``2``. + +The ``artifactType`` of the OCI image manifest must be ``application/vnd.margo.app.v1+json``. + +The ``config`` object must be declared as empty by defining its ``mediaType`` as ``application/vnd.oci.empty.v1+json``. + +Each element of the ``layers`` array contains a reference (so called `digests`) to an artifact (so called `blobs`) that is part of the Application Package. +Each artifact of an Application Package must be listed as an element of the ``layers`` array. + +The [Application Description](https://specification.margo.org/margo-api-reference/workload-api/application-package-api/application-description/) of the Application Package must be referred to in one element of the ``layers`` array. The ``mediaType`` of this layer/blob must be ``application/vnd.margo.app.description.v1+yaml``. + +Each [application resource](https://specification.margo.org/app-interoperability/application-package-definition/), which is an additional file associated with the application (e.g., manual, icon, release notes, license file, etc.), must be referred to in an element of the ``layers`` array and an ``annotation`` must be added to this element, which has the annotation key ``org.margo.app.resource``, and the annotation value must reflect the dotted path to the this resource in the Application Description. +E.g., an application icon stored as the file ``resources/margo.jpg`` will be referenced in the Application Description under ``metadata.catalog.application.icon: resources/margo.jpg`` and in the OCI image manifest, the respective layer of the icon resource has the annotation ``org.margo.app.resource`` with the value ``metadata.catalog.application.icon`` (see also OCI image manifest example below). + + + +The following response example is a margo-specific OCI image manifest following the [OCI Image Manifest Specification](https://github.com/opencontainers/image-spec/blob/v1.0.1/manifest.md) and the above defined specifics: + +```json +{ + "schemaVersion": 2, + "mediaType": "application/vnd.oci.image.manifest.v1+json", + "artifactType": "application/vnd.margo.app.v1+json" # this MUST be the artifactType of en OCI image manifest of a margo Application Package, + "config": { + "mediaType": "application/vnd.oci.empty.v1+json", # the 'config' object MUST be empty + "digest": "sha256:44136fa355b3678a1146ad16f7e8649e94fb4fc21fe77e8310c060f61caaff8a", + "size": 2, + "data": "e30=" + }, + "layers": [ + { + "mediaType": "application/vnd.margo.app.description.v1+yaml", # this MUST be the artifactType of a margo Application Description file + "digest": "sha256:f6b79149e6650b0064c146df7c045d157f3656b5ad1279b5ce9f4446b510bacf", + "size": 999, + "annotations": { + "org.opencontainers.image.title": "margo.yaml" + } + }, + { + "mediaType": "text/markdown", + "digest": "sha256:e373b123782a2b52483a9124cc9c578e0ed0300cb4131b73b0c79612122b8361", + "size": 1596, + "annotations": { + "org.margo.app.resource": "metadata.catalog.application.descriptionFile", # each margo application resource MUST be annotated with a dotted path to its definition in the Application Description file + "org.opencontainers.image.title": "resources/description.md" + } + }, + { + "mediaType": "text/markdown", + "digest": "sha256:af7db4ab9030533b6cda2325247920c3659bc67a7d49f3d5098ae54a64633ec7", + "size": 25, + "annotations": { + "org.margo.app.resource": "metadata.catalog.application.licenseFile", # each margo application resource MUST be annotated with a dotted path to its definition in the Application Description file + "org.opencontainers.image.title": "resources/license.md" + } + }, + { + "mediaType": "image/jpeg", + "digest": "sha256:451410b6adfdce1c974da2275290d9e207911a4023fafea0e283fad0502e5e56", + "size": 5065, + "annotations": { + "org.margo.app.resource": "metadata.catalog.application.icon", # each margo application resource MUST be annotated with a dotted path to its definition in the Application Description file + "org.opencontainers.image.title": "resources/margo.jpg" + } + }, + { + "mediaType": "text/markdown", + "digest": "sha256:c412d143084c3b051d7ea4b166a7bfffb4550f401d89cae8898991c65e90f736", + "size": 42, + "annotations": { + "org.margo.app.resource": "metadata.catalog.application.releaseNotes", # each margo application resource MUST be annotated with a dotted path to its definition in the Application Description file + "org.opencontainers.image.title": "resources/release-notes.md" + } + } + ], +} +``` + +#### Margo-Specific Media Types + +|Media Type|Description| +|----------|----------| +|``application/vnd.margo.app.v1+json`` | MUST be used as the **artifactType** to mark the OCI image manifest as the definition of a margo Application Package | +|``application/vnd.margo.app.description.v1+yaml`` | MUST be used to mark a layer in the OCI image manifest as pointing to the margo Application Description file | + + +#### Margo-Specific Annotation Keys + +|Annotation Key | Description| +|----------|----------| +|``org.margo.app.resource`` | This MUST be used to annotate a layer/blob that references a margo application resource | + + + +### Get margo Application Description or Resource +This must be implemented according to OCI_spec endpoint [end-2](https://github.com/opencontainers/distribution-spec/blob/v1.1.0/spec.md#endpoints). +Retrieves a margo Application Description or Appliction Resource by pulling a blob. +`{digest}` is the blobs digest as listed in the application's OCI image manifest that has been [retrieved earlier](#pull-margo-application-manifest). +`{name}` is the namespace of the repository. + + +`GET /v2/{name}/blobs/{digest}` + +#### Headers: + +`Authorization: Bearer ` +> However, security mechanism needs to be margo-centrally defined. + +#### Success Response: + +`200 OK with blob content` + +#### Fail Response: + +`404 Not Found if blob doesn't exist` From 54ade4c94bedcef9f42a9a3821a8a79a62eb69f7 Mon Sep 17 00:00:00 2001 From: Arne Broering Date: Wed, 5 Nov 2025 12:47:58 +0100 Subject: [PATCH 03/29] editing formal App Registry spec Signed-off-by: Arne Broering --- .../workloads/application-registry.md | 2 +- .../application-registry.md | 19 +++++++++---------- 2 files changed, 10 insertions(+), 11 deletions(-) diff --git a/system-design/concepts/workloads/application-registry.md b/system-design/concepts/workloads/application-registry.md index fd254df..a4b773f 100644 --- a/system-design/concepts/workloads/application-registry.md +++ b/system-design/concepts/workloads/application-registry.md @@ -1,6 +1,6 @@ # Application Registry -The margo specification differentiates 4 different kinds of registries: *Application Registries*, *Component Registries*, and *Container Registries* as well as *Marketplaces*. +The margo specification differentiates 4 kinds of registries: *Application Registries*, *Component Registries*, and *Container Registries* as well as *Marketplaces*. 1. An **Application Registry** hosts Application Packages that define through their [Application Description](../../specification/application-package/application-description.md) the application as one or multiple Components. 2. A **Component Registry** hosts the Components (which are deployable as *workloads*) and are provided as **Helm Charts** or **Compose Archives**. diff --git a/system-design/specification/application-package/application-registry.md b/system-design/specification/application-package/application-registry.md index e16f22f..3fc994a 100644 --- a/system-design/specification/application-package/application-registry.md +++ b/system-design/specification/application-package/application-registry.md @@ -1,33 +1,32 @@ # Application Registry -This section specifies the API of the `Application Registry` and the exchange of an [Application Package](./application-package-definition.md), defined through an [Application Description](../../specification/application-package/) file, from an Application Developer to the Workload Fleet Manager (WFM). The `Application Registry` is designed as an `OCI Registry`, i.e., it offers an API compliant with the [OCI Registry API (v1.1.0)](https://github.com/opencontainers/distribution-spec/blob/v1.1.0/spec.md) for digital artifact distribution. This way, the Application Registry hosts the parts of an [Application Package](https://specification.margo.org/app-interoperability/application-package-definition/) in form of `blobs` and uses `image manifests` according to [OCI Image specification](https://github.com/opencontainers/image-spec/blob/v1.0.1/manifest.md)) to list a set of `layers`, each pointing at a blob. - +The interactions of an `Application Registry` are described [here](../../concepts/workloads/application-registry.md) from a conceptual view. This section formally specifies the API of the `Application Registry` and the exchange of an [Application Package](./application-package-definition.md), defined through an [Application Description](../../specification/application-package/) file, from an Application Developer to the Workload Fleet Manager (WFM). The `Application Registry` is designed as an `OCI Registry`, i.e., it offers an API compliant with the [OCI Registry API (v1.1.0)](https://github.com/opencontainers/distribution-spec/blob/v1.1.0/spec.md) for digital artifact distribution. This way, the Application Registry hosts the parts of an [Application Package](https://specification.margo.org/app-interoperability/application-package-definition/) in form of `blobs` and uses `image manifests` according to [OCI Image specification](https://github.com/opencontainers/image-spec/blob/v1.0.1/manifest.md)) to list a set of `layers`, each pointing at a blob. ## Overview of API Endpoints -The Application Catalog / WFM interacts with the Application Registry using standard OCI Registry API endpoints: +The WFM interacts with the Application Registry using standard OCI Registry API endpoints: -* Tags: `/v2/{name}/tags/list` for listing available versions of the Application Package -* Manifest: `/v2/{name}/manifests/{reference}` for retrieving an image manifest (identifed through the `{reference}`) that lists layers, which are part of the Application Package. +* Tags: `/v2/{name}/tags/list` for listing available versions of an Application Package +* Manifest: `/v2/{name}/manifests/{reference}` for retrieving an image manifest (identifed through the `{reference}`) that lists layers, which represent the parts of the Application Package. * Blob: `/v2/{name}/blobs/{digest}` for downloading parts of the Application Package `{name}` is the namespace of the repository, which needs to be directly communicted by the App Developer to the WFM vendor. It could be for example a combination of the organization's and application's name. -Further details on how to use these API enspoints are specified below [towards App Developer](#margo-application-registry-api-endpoint-definitions-towards-app-developer-aligned-with-oci_spec) and [towards WFM](#margo-application-registry-api-endpoint-definitions-towards-wfm-aligned-with-oci_spec). +Further details on how to use these API endpoints are specified below [towards App Developer](#margo-application-registry-api-endpoint-definitions-towards-app-developer-aligned-with-oci_spec) and [towards WFM](#margo-application-registry-api-endpoint-definitions-towards-wfm-aligned-with-oci_spec). ## Authentication & Authorization & Security -This proposal recommends that margo centrally defines authentication & authorization (& ssecurity) mechanisms, e.g., recommending the use of OAuth 2.0 with the following workflow: +Margo recommends the use of an Authentication Service within the interaction of WFM and Application Registry as conceptually described [here](../../concepts/workloads/application-registry.md), e.g., implemented using OAuth 2.0. This involves the following workflow: * WFM obtains credentials during onboarding * WFM requests a token from an Authentication Service * WFM uses the token for subsequent API calls to the Application Registry * Application Registry validates the token and enforces access control -All communications should use TLS 1.3+ to ensure transport security. +Thereby, all communications must use TLS 1.3+ to ensure transport security. -> However, Authentication & Authorization & Security mechanisms should be defined centrally and homogeneously across margo. Hence, it is out of scope of this proposal. +> Note: Authentication & Authorization & Security mechanisms should be defined centrally and homogeneously across margo. Hence, it is not further defined here. -Further, tools such as [cosign](https://github.com/sigstore/cosign) can be employed for signing artifacts uploaded to the Application Registry and storing the signatures alongside the artifacts they verify. +Further, tools such as [cosign](https://github.com/sigstore/cosign) may be employed for signing artifacts uploaded to the Application Registry and storing the signatures alongside the artifacts they verify. ## Reference Implementation A reference implementation can be found [here](https://github.com/margo/app-package-definition-wg/blob/main/application-registry-example/app_registry_as_oci_registry.md). It utilizes: From cf80f39db634f88436f991d426c171f9f0c2d400 Mon Sep 17 00:00:00 2001 From: Arne Broering Date: Wed, 5 Nov 2025 13:03:28 +0100 Subject: [PATCH 04/29] editing formal App Registry spec Signed-off-by: Arne Broering --- system-design/concepts/workloads/application-registry.md | 4 +++- .../application-package/application-registry.md | 7 ------- 2 files changed, 3 insertions(+), 8 deletions(-) diff --git a/system-design/concepts/workloads/application-registry.md b/system-design/concepts/workloads/application-registry.md index a4b773f..d24f4aa 100644 --- a/system-design/concepts/workloads/application-registry.md +++ b/system-design/concepts/workloads/application-registry.md @@ -39,4 +39,6 @@ The Application Registry's API is compliant with the [OCI Registry API (v1.1.0)] ## Relevant Links -Please follow the following link to view the technical reference of the [Application Registry API](../../specification/application-package/application-registry.md). +* The technical reference of the Application Registry API is defined [here](../../specification/application-package/application-registry.md). + +* A reference implementation of the Application Registry is described [here](https://github.com/margo/app-package-definition-wg/blob/main/application-registry-example/app_registry_as_oci_registry.md) and includes sample applications and configuration for demonstration. It utilizes an open source OCI Registry and the [ORAS tool](https://oras.land/docs/) as the client. diff --git a/system-design/specification/application-package/application-registry.md b/system-design/specification/application-package/application-registry.md index 3fc994a..7360f85 100644 --- a/system-design/specification/application-package/application-registry.md +++ b/system-design/specification/application-package/application-registry.md @@ -28,13 +28,6 @@ Thereby, all communications must use TLS 1.3+ to ensure transport security. Further, tools such as [cosign](https://github.com/sigstore/cosign) may be employed for signing artifacts uploaded to the Application Registry and storing the signatures alongside the artifacts they verify. -## Reference Implementation -A reference implementation can be found [here](https://github.com/margo/app-package-definition-wg/blob/main/application-registry-example/app_registry_as_oci_registry.md). It utilizes: - -* Application Registry: Docker Registry (open source OCI Registry) -* Client Library: ORAS (OCI Registry as Storage) tool -* Examples: Sample applications and configuration for demonstration - ## Overview of Interactions ```mermaid From 45f1e5c95803c46405743642b2f24a61aa6bfc44 Mon Sep 17 00:00:00 2001 From: Arne Broering Date: Wed, 5 Nov 2025 14:23:41 +0100 Subject: [PATCH 05/29] editing formal App Registry spec Signed-off-by: Arne Broering --- .../application-registry.md | 59 ++++++++++--------- 1 file changed, 32 insertions(+), 27 deletions(-) diff --git a/system-design/specification/application-package/application-registry.md b/system-design/specification/application-package/application-registry.md index 7360f85..8c84b66 100644 --- a/system-design/specification/application-package/application-registry.md +++ b/system-design/specification/application-package/application-registry.md @@ -28,47 +28,52 @@ Thereby, all communications must use TLS 1.3+ to ensure transport security. Further, tools such as [cosign](https://github.com/sigstore/cosign) may be employed for signing artifacts uploaded to the Application Registry and storing the signatures alongside the artifacts they verify. -## Overview of Interactions -```mermaid -sequenceDiagram - Note over AppDeveloper: uploads margo artifacts as blobs and OCI image manifest: - AppDeveloper->>AppRegistry: POST /v2/{name}/blobs/uploads/ +## Uploading an Application Package +As shown in the sequence diagram below, the Application Developer uploads the margo-compliant `Application Package` to the Application Registry. I.e., all parts of the Application Package MUST be pushed as blobs compliant with the [end-4a / end-4b](https://github.com/opencontainers/distribution-spec/blob/v1.1.0/spec.md#endpoints) endpoints of the OCI_spec. - Note over AppDeveloper: uses vendor-specific upload mechanism (e.g., UI) to enable WFM to find the application: - AppDeveloper->>+WFM: Application location is: repository {name} in Application Registry - - Note over WFM: ... later in time: - Note over WFM: discovers available versions of an application: - WFM->>+AppRegistry: GET /v2/{name}/tags/list - - Note over WFM: retrieves the OCI image manifest of the selected application version. {reference} is tag or digest.: - WFM->>+AppRegistry: GET /v2/{name}/manifests/{reference} - - AppRegistry-->>+WFM: OCI image manifest +Subsequently, the Application Developer creates an OCI image manifest that lists layers of which each links to an uploaded blob. Then the manifest MUST be pushed to the Application Registry compliant to the [end-7](https://github.com/opencontainers/distribution-spec/blob/v1.1.0/spec.md#endpoints) endpoint of the OCI_spec. - Note over WFM: downloads application artifacts as listed in retrieved OCI image manifest: - WFM->>AppRegistry: GET /v2/{name}/blobs/{digest} -``` +The uploaded OCI image manifest MUST be adhering to the margo-specific constraints detailed [here](#manifest-as-response-from-application-registry). + +Subsequently, the App Developer uses a UI or other vendor-specific mechanism to communicate (either directly or indirectly, e.g. via a Marketplace) to the WFM the namespace of the Application Package's repository. + +```mermaid +sequenceDiagram + Note over AppDeveloper: uploads parts of Application Package as blobs: + AppDeveloper->>AppRegistry: push blobs + AppDeveloper->>AppRegistry: push manifest -## margo 'Application Registry' API Endpoint Definitions towards App Developer (aligned with OCI_spec) + Note over AppDeveloper: uses vendor-specific upload mechanism (e.g., UI) to enable WFM to find the Application Package: + AppDeveloper->>+WFM: Application Package location is: repository name in Application Registry +``` -### Upload a margo Application Package +There are no further margo-specific constraints regarding the upload of the Application Package. The details defined in the [OCI_spec](https://github.com/opencontainers/distribution-spec) MUST be applied to this interface of the Application Registry. -The Application Developer uploads the margo-compliant `Application Package` to the Application Registry. I.e., the parts of the Application Package are uploaded as blobs and an OCI image manifest is created via the [end-4a / end-4b](https://github.com/opencontainers/distribution-spec/blob/v1.1.0/spec.md#endpoints) endpoints. -Thereby, the Application Developer needs to make sure the OCI image manifest will be adhering to the margo-specific constraints detailed [here](#manifest-as-response-from-application-registry). -Other than these constraints on the OCI image manifest format, there are no further margo-specific constraints regarding the upload of the Application Package and the OCI_spec applies to this interface of the Application Registry. -This process of uploading a margo Application Package is described in the [reference implementation](https://github.com/margo/app-package-definition-wg/blob/main/application-registry-example/app_registry_as_oci_registry.md). +## Retrieving an Application Package +The WFM has received the namespace of the repository of the Application Package at the Application Registry. +Next, as shown in the sequence diagram below, the WFM uses the OCI_spec defined endpoints to retrieve a list of application versions +```mermaid +sequenceDiagram + Note over WFM: retrieve available versions of an application: + WFM->>+AppRegistry: GET /v2/{name}/tags/list + + Note over WFM: retrieves the OCI image manifest of the selected application version. {reference} is tag or digest.: + WFM->>+AppRegistry: GET /v2/{name}/manifests/{reference} + + AppRegistry-->>+WFM: OCI image manifest -## margo 'Application Registry' API Endpoint Definitions towards WFM (aligned with OCI_spec) + Note over WFM: retrieves application artifacts as listed in OCI image manifest: + WFM->>AppRegistry: GET /v2/{name}/blobs/{digest} +``` ### List margo Application Package Versions @@ -105,7 +110,7 @@ Use `tags` to discover available versions of a Margo application. } ``` -####Pull Application's OCI Image Manifest +### Pull Application's OCI Image Manifest This must be implemented according to OCI_spec endpoint [end-3](https://github.com/opencontainers/distribution-spec/blob/v1.1.0/spec.md#endpoints). Pulls an OCI image manifest of a specified version, which belongs to a margo Application Package. The `{reference}` is the `tag` of an OCI image manifest. The `tag` has been discovered via the [listing of app versions](#list-margo-application-versions). From cb08b22299ca66457f3eec4123fc13c87765096c Mon Sep 17 00:00:00 2001 From: Arne Broering Date: Wed, 5 Nov 2025 14:42:19 +0100 Subject: [PATCH 06/29] editing formal App Registry spec Signed-off-by: Arne Broering --- .../application-registry.md | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/system-design/specification/application-package/application-registry.md b/system-design/specification/application-package/application-registry.md index 8c84b66..b3c8cb0 100644 --- a/system-design/specification/application-package/application-registry.md +++ b/system-design/specification/application-package/application-registry.md @@ -59,19 +59,24 @@ There are no further margo-specific constraints regarding the upload of the Appl ## Retrieving an Application Package The WFM has received the namespace of the repository of the Application Package at the Application Registry. -Next, as shown in the sequence diagram below, the WFM uses the OCI_spec defined endpoints to retrieve a list of application versions + +Next, as shown in the sequence diagram below, the WFM uses the API endpoints defined in the OCI_spec to retrieve a list of Application Package versions (as detailed [here](#list-margo-application-package-versions)). + +Then, the WFM pulls the OCI image manifest of the selected version of the Application Package, with the identifying reference being a tag or digest (as detailed [here](#pull-oci-image-manifest-of-application-package)). + +Finally, all parts (e.g., the Application Description file, the icon, the license, etc.) of the Application Package are retrieved by pulling the respective blobs listed as layers in the image manifest (as detailed [here](#get-parts-of-application-package)). ```mermaid sequenceDiagram - Note over WFM: retrieve available versions of an application: + Note over WFM: retrieve available versions of an Application Package: WFM->>+AppRegistry: GET /v2/{name}/tags/list - Note over WFM: retrieves the OCI image manifest of the selected application version. {reference} is tag or digest.: + Note over WFM: retrieves the OCI image manifest of the selected Application Package version. {reference} is tag or digest.: WFM->>+AppRegistry: GET /v2/{name}/manifests/{reference} AppRegistry-->>+WFM: OCI image manifest - Note over WFM: retrieves application artifacts as listed in OCI image manifest: + Note over WFM: retrieves parts of the Application Package as listed in OCI image manifest layers: WFM->>AppRegistry: GET /v2/{name}/blobs/{digest} ``` @@ -110,7 +115,7 @@ Use `tags` to discover available versions of a Margo application. } ``` -### Pull Application's OCI Image Manifest +### Pull OCI Image Manifest of Application Package This must be implemented according to OCI_spec endpoint [end-3](https://github.com/opencontainers/distribution-spec/blob/v1.1.0/spec.md#endpoints). Pulls an OCI image manifest of a specified version, which belongs to a margo Application Package. The `{reference}` is the `tag` of an OCI image manifest. The `tag` has been discovered via the [listing of app versions](#list-margo-application-versions). @@ -233,7 +238,8 @@ The following response example is a margo-specific OCI image manifest following -### Get margo Application Description or Resource +### Get Parts of Application Package + This must be implemented according to OCI_spec endpoint [end-2](https://github.com/opencontainers/distribution-spec/blob/v1.1.0/spec.md#endpoints). Retrieves a margo Application Description or Appliction Resource by pulling a blob. `{digest}` is the blobs digest as listed in the application's OCI image manifest that has been [retrieved earlier](#pull-margo-application-manifest). From 8a8ae181ffb982164345d090bf74e4fa49b2498f Mon Sep 17 00:00:00 2001 From: Arne Broering Date: Wed, 5 Nov 2025 16:20:15 +0100 Subject: [PATCH 07/29] editing formal App Registry spec Signed-off-by: Arne Broering --- .../application-registry.md | 47 +++++++++++-------- 1 file changed, 28 insertions(+), 19 deletions(-) diff --git a/system-design/specification/application-package/application-registry.md b/system-design/specification/application-package/application-registry.md index b3c8cb0..440182b 100644 --- a/system-design/specification/application-package/application-registry.md +++ b/system-design/specification/application-package/application-registry.md @@ -1,10 +1,10 @@ # Application Registry -The interactions of an `Application Registry` are described [here](../../concepts/workloads/application-registry.md) from a conceptual view. This section formally specifies the API of the `Application Registry` and the exchange of an [Application Package](./application-package-definition.md), defined through an [Application Description](../../specification/application-package/) file, from an Application Developer to the Workload Fleet Manager (WFM). The `Application Registry` is designed as an `OCI Registry`, i.e., it offers an API compliant with the [OCI Registry API (v1.1.0)](https://github.com/opencontainers/distribution-spec/blob/v1.1.0/spec.md) for digital artifact distribution. This way, the Application Registry hosts the parts of an [Application Package](https://specification.margo.org/app-interoperability/application-package-definition/) in form of `blobs` and uses `image manifests` according to [OCI Image specification](https://github.com/opencontainers/image-spec/blob/v1.0.1/manifest.md)) to list a set of `layers`, each pointing at a blob. +The interactions of an `Application Registry` are described [here](../../concepts/workloads/application-registry.md) from a conceptual view. This section formally specifies the API of the `Application Registry` and the exchange of an [Application Package](./application-package-definition.md), defined through an [Application Description](../../specification/application-package/) file, from an Application Developer to the Workload Fleet Manager (WFM). The `Application Registry` is designed as an `OCI Registry`, i.e., it offers an API compliant with the [OCI Registry API (v1.1.0)](https://github.com/opencontainers/distribution-spec/blob/v1.1.0/spec.md) (called here the "OCI_spec") for digital artifact distribution. This way, the Application Registry hosts the parts of an [Application Package](https://specification.margo.org/app-interoperability/application-package-definition/) in form of `blobs` and uses `image manifests` according to [OCI Image specification](https://github.com/opencontainers/image-spec/blob/v1.0.1/manifest.md)) to list a set of `layers`, each pointing at a blob. ## Overview of API Endpoints -The WFM interacts with the Application Registry using standard OCI Registry API endpoints: +The WFM MUST interact with the Application Registry compliant to the OCI Registry API endpoints defined in the [OCI_spec](https://github.com/opencontainers/distribution-spec/blob/v1.1.0/spec.md): * Tags: `/v2/{name}/tags/list` for listing available versions of an Application Package * Manifest: `/v2/{name}/manifests/{reference}` for retrieving an image manifest (identifed through the `{reference}`) that lists layers, which represent the parts of the Application Package. @@ -12,7 +12,7 @@ The WFM interacts with the Application Registry using standard OCI Registry API `{name}` is the namespace of the repository, which needs to be directly communicted by the App Developer to the WFM vendor. It could be for example a combination of the organization's and application's name. -Further details on how to use these API endpoints are specified below [towards App Developer](#margo-application-registry-api-endpoint-definitions-towards-app-developer-aligned-with-oci_spec) and [towards WFM](#margo-application-registry-api-endpoint-definitions-towards-wfm-aligned-with-oci_spec). +Further details on how to use these API endpoints are specified below [towards App Developer](#uploading-an-application-package) and [towards WFM](#retrieving-an-application-package). ## Authentication & Authorization & Security Margo recommends the use of an Authentication Service within the interaction of WFM and Application Registry as conceptually described [here](../../concepts/workloads/application-registry.md), e.g., implemented using OAuth 2.0. This involves the following workflow: @@ -52,7 +52,7 @@ sequenceDiagram AppDeveloper->>+WFM: Application Package location is: repository name in Application Registry ``` -There are no further margo-specific constraints regarding the upload of the Application Package. The details defined in the [OCI_spec](https://github.com/opencontainers/distribution-spec) MUST be applied to this interface of the Application Registry. +There are no further margo-specific constraints regarding the upload of the Application Package. The details defined in the [OCI_spec](https://github.com/opencontainers/distribution-spec/blob/v1.1.0/spec.md) MUST be applied to this interface of the Application Registry. @@ -82,33 +82,42 @@ sequenceDiagram ### List margo Application Package Versions -This must be implemented according to OCI_spec endpoint [end-8a / end-8b](https://github.com/opencontainers/distribution-spec/blob/v1.1.0/spec.md#endpoints). -Use `tags` to discover available versions of a Margo application. -`{name}` is the namespace of the repository, which needs to be directly communicted by the App Developer to the WFM vendor. +The interface to retrieve the list of versions of an Application Package MUST be implemented according to OCI_spec endpoint [end-8a](https://github.com/opencontainers/distribution-spec/blob/v1.1.0/spec.md#endpoints). -`GET /v2/{name}/tags/list` +To get a list of available versions of an Application Package, an HTTP ``GET`` request to a resource path MUST be performed in the following format: `/v2/{name}/tags/list`. The `{name}` variable is the namespace of the repository, which was communicted by the App Developer to the WFM vendor. -#### Headers: +The HTTP headers of the ``GET`` request MAY include ```Authorization: Bearer ``` for including the interaction with the [Authentication Service](/specification/system-design/concepts/workloads/application-registry.md). -```Authorization: Bearer ``` -> However, security mechanism needs to be margo-centrally defined. +To query a subset of tags, the following query parameters MUST be implemented by the Application Registry as defined by OCI_spec endpoint [end-8b](https://github.com/opencontainers/distribution-spec/blob/v1.1.0/spec.md#endpoints): -#### Query Parameters: +* ``n=`` (optional, limits results to n tags) +* ``last=`` (optional, starts list of tags after ````) -* n= (optional, limits results) -* last= (optional, pagination cursor) +#### Example A: -#### Success Response: +Request: GET ``http://famous-app-registry/v2/northstar-industrial-applications/app1/tags/list`` -200 OK with list of tags +Response: +```json +{ + "name": "northstar-industrial-applications/app1", + "tags": [ + "v1.0.0", + "v1.1.0", + "latest" + ] +} +``` + +#### Example B: -#### Example Response: +Request: GET ``http://famous-app-registry/v2/northstar-industrial-applications/app1/tags/list?n=2&last=v1.0.0`` +Response: ```json { - "name": "organization/app1", + "name": "northstar-industrial-applications/app1", "tags": [ - "v1.0.0", "v1.1.0", "latest" ] From ca68501045194dcfe6b811ab23472db9de1ce674 Mon Sep 17 00:00:00 2001 From: Arne Broering Date: Wed, 5 Nov 2025 16:39:21 +0100 Subject: [PATCH 08/29] editing formal App Registry spec Signed-off-by: Arne Broering --- .../application-registry.md | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/system-design/specification/application-package/application-registry.md b/system-design/specification/application-package/application-registry.md index 440182b..2665d7c 100644 --- a/system-design/specification/application-package/application-registry.md +++ b/system-design/specification/application-package/application-registry.md @@ -93,6 +93,21 @@ To query a subset of tags, the following query parameters MUST be implemented by * ``n=`` (optional, limits results to n tags) * ``last=`` (optional, starts list of tags after ````) +The response of the HTTP ``GET`` request according to [end-8a/end-8b](https://github.com/opencontainers/distribution-spec/blob/v1.1.0/spec.md#endpoints) is a list of tags, which comply with the versions of available Application Packages. According to OCI_spec, upon success, the response MUST be a json body in the following format: + +```json +{ + "name": "", + "tags": [ + "", # each tag MUST be the value of the 'metadata.version' of the associated Application Package's Application Description document. + "", + "" + ] +} +``` + +Thereby, a listed tag of an image manifest MUST be the same as the value of the key ``metadata.version`` as specified in the Application Description document of the associated Application Package. + #### Example A: Request: GET ``http://famous-app-registry/v2/northstar-industrial-applications/app1/tags/list`` @@ -125,8 +140,8 @@ Response: ``` ### Pull OCI Image Manifest of Application Package -This must be implemented according to OCI_spec endpoint [end-3](https://github.com/opencontainers/distribution-spec/blob/v1.1.0/spec.md#endpoints). -Pulls an OCI image manifest of a specified version, which belongs to a margo Application Package. + +The interface to retrieve the OCI image manifest of a specified version, which belongs to an Application Package, MUST be implemented according to OCI_spec endpoint [end-3](https://github.com/opencontainers/distribution-spec/blob/v1.1.0/spec.md#endpoints). The `{reference}` is the `tag` of an OCI image manifest. The `tag` has been discovered via the [listing of app versions](#list-margo-application-versions). `{name}` is the namespace of the repository. From 14c73a3de64bf483ee2f80435b394df19747786e Mon Sep 17 00:00:00 2001 From: Arne Broering Date: Wed, 5 Nov 2025 17:27:33 +0100 Subject: [PATCH 09/29] editing formal App Registry spec Signed-off-by: Arne Broering --- .../application-registry.md | 63 ++++++------------- 1 file changed, 18 insertions(+), 45 deletions(-) diff --git a/system-design/specification/application-package/application-registry.md b/system-design/specification/application-package/application-registry.md index 2665d7c..a3807dc 100644 --- a/system-design/specification/application-package/application-registry.md +++ b/system-design/specification/application-package/application-registry.md @@ -84,7 +84,7 @@ sequenceDiagram The interface to retrieve the list of versions of an Application Package MUST be implemented according to OCI_spec endpoint [end-8a](https://github.com/opencontainers/distribution-spec/blob/v1.1.0/spec.md#endpoints). -To get a list of available versions of an Application Package, an HTTP ``GET`` request to a resource path MUST be performed in the following format: `/v2/{name}/tags/list`. The `{name}` variable is the namespace of the repository, which was communicted by the App Developer to the WFM vendor. +To get a list of available versions of an Application Package, an HTTP ``GET`` request to a resource path MUST be performed in the following format: `/v2/{name}/tags/list`. The `{name}` variable is the namespace of the Application Package repository, which was communicted by the App Developer to the WFM vendor. The HTTP headers of the ``GET`` request MAY include ```Authorization: Bearer ``` for including the interaction with the [Authentication Service](/specification/system-design/concepts/workloads/application-registry.md). @@ -142,31 +142,19 @@ Response: ### Pull OCI Image Manifest of Application Package The interface to retrieve the OCI image manifest of a specified version, which belongs to an Application Package, MUST be implemented according to OCI_spec endpoint [end-3](https://github.com/opencontainers/distribution-spec/blob/v1.1.0/spec.md#endpoints). -The `{reference}` is the `tag` of an OCI image manifest. The `tag` has been discovered via the [listing of app versions](#list-margo-application-versions). -`{name}` is the namespace of the repository. - -``` GET /v2/{name}/manifests/{reference} ``` - -#### Headers: - -`Authorization: Bearer ` -> However, security mechanism needs to be margo-centrally defined. - -`Accept: application/vnd.oci.image.manifest.v1+json` -#### Success Response: - -200 OK with OCI image manifest content - -#### Fail Response: +To pull an Application Package, an HTTP ``GET`` request to a resource path MUST be performed in the following format: +`/v2/{name}/manifests/{reference}`. +The `{reference}` is the `tag` of an OCI image manifest. The `tag` has been discovered via the [listing of app versions](#list-margo-application-versions). +The `{name}` variable is the namespace of the Application Package repository. -404 Not Found if OCI image manifest doesn't exist +The HTTP headers of the ``GET`` request MAY include ```Authorization: Bearer ``` for including the interaction with the [Authentication Service](/specification/system-design/concepts/workloads/application-registry.md). #### OCI Image Manifest as Response from Application Registry: -In the margo context, OCI image manifests contain pointers to all parts of an Application Package within an Application Registry. +The sucessful response of the HTTP ``GET`` request is an OCI image manifest (as defined in the OCI_spec), which MUST contain pointers to all parts of an Application Package within the Application Registry. -Each ``version`` of an Application Pacakage has its own OCI image manifest. +Each version of an Application Package MUST have its own OCI image manifest. The ``schemaVersion`` of the OCI image manifest needs to be ``2``. @@ -174,15 +162,12 @@ The ``artifactType`` of the OCI image manifest must be ``application/vnd.margo.a The ``config`` object must be declared as empty by defining its ``mediaType`` as ``application/vnd.oci.empty.v1+json``. -Each element of the ``layers`` array contains a reference (so called `digests`) to an artifact (so called `blobs`) that is part of the Application Package. -Each artifact of an Application Package must be listed as an element of the ``layers`` array. - -The [Application Description](https://specification.margo.org/margo-api-reference/workload-api/application-package-api/application-description/) of the Application Package must be referred to in one element of the ``layers`` array. The ``mediaType`` of this layer/blob must be ``application/vnd.margo.app.description.v1+yaml``. - -Each [application resource](https://specification.margo.org/app-interoperability/application-package-definition/), which is an additional file associated with the application (e.g., manual, icon, release notes, license file, etc.), must be referred to in an element of the ``layers`` array and an ``annotation`` must be added to this element, which has the annotation key ``org.margo.app.resource``, and the annotation value must reflect the dotted path to the this resource in the Application Description. -E.g., an application icon stored as the file ``resources/margo.jpg`` will be referenced in the Application Description under ``metadata.catalog.application.icon: resources/margo.jpg`` and in the OCI image manifest, the respective layer of the icon resource has the annotation ``org.margo.app.resource`` with the value ``metadata.catalog.application.icon`` (see also OCI image manifest example below). +Each element of the ``layers`` array contains a reference (so called `digests`) to an artifact (so called `blobs`) that is a part of the Application Package. +Each Application Package part must be listed as an element of the ``layers`` array: +* The [Application Description](https://specification.margo.org/margo-api-reference/workload-api/application-package-api/application-description/) of the Application Package must be referred to in one element of the ``layers`` array, where the ``mediaType`` of this layer/blob must be ``application/vnd.margo.app.description.v1+yaml``. +* Each [application resource](https://specification.margo.org/app-interoperability/application-package-definition/), which is an additional file associated with the application (e.g., manual, icon, release notes, license file, etc.), must be referred to in an element of the ``layers`` array. Such a layer must have an ``annotation``, which has the annotation key ``org.margo.app.resource``, and the annotation value must reflect the dotted path to the this resource in the [Application Description file](https://specification.margo.org/margo-api-reference/workload-api/application-package-api/application-description/). E.g., an application icon stored as the file ``resources/margo.jpg`` is referenced in the Application Description under ``metadata.catalog.application.icon: resources/margo.jpg`` and in the OCI image manifest, the respective layer of the icon resource has the annotation ``org.margo.app.resource`` with the value ``metadata.catalog.application.icon`` (see also OCI image manifest example below). The following response example is a margo-specific OCI image manifest following the [OCI Image Manifest Specification](https://github.com/opencontainers/image-spec/blob/v1.0.1/manifest.md) and the above defined specifics: @@ -264,23 +249,11 @@ The following response example is a margo-specific OCI image manifest following ### Get Parts of Application Package -This must be implemented according to OCI_spec endpoint [end-2](https://github.com/opencontainers/distribution-spec/blob/v1.1.0/spec.md#endpoints). -Retrieves a margo Application Description or Appliction Resource by pulling a blob. -`{digest}` is the blobs digest as listed in the application's OCI image manifest that has been [retrieved earlier](#pull-margo-application-manifest). -`{name}` is the namespace of the repository. - - -`GET /v2/{name}/blobs/{digest}` - -#### Headers: +The interface to retrieve Application Package parts, i.e., Application Description or Appliction Resource (e.g., icon, license, etc.), MUST be implemented according to OCI_spec endpoint [end-2](https://github.com/opencontainers/distribution-spec/blob/v1.1.0/spec.md#endpoints) by pulling a blob. -`Authorization: Bearer ` -> However, security mechanism needs to be margo-centrally defined. +To pull such a blob, an HTTP ``GET`` request to a resource path MUST be performed in the following format: +`/v2/{name}/blobs/{digest}`. +The `{digest}` is the blobs digest as listed in the application's OCI image manifest that has been [retrieved earlier](#pull-margo-application-manifest). +The `{name}` variable is the namespace of the Application Package repository. -#### Success Response: - -`200 OK with blob content` - -#### Fail Response: - -`404 Not Found if blob doesn't exist` +The HTTP headers of the ``GET`` request MAY include ```Authorization: Bearer ``` for including the interaction with the [Authentication Service](/specification/system-design/concepts/workloads/application-registry.md). From 3ec997d4e9f04923b493c90538d15bc968f1e483 Mon Sep 17 00:00:00 2001 From: Arne Broering Date: Thu, 6 Nov 2025 09:02:59 +0100 Subject: [PATCH 10/29] editing formal App Registry spec Signed-off-by: Arne Broering --- doc-generation/generate-documentation.bash | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc-generation/generate-documentation.bash b/doc-generation/generate-documentation.bash index 43fc851..801299c 100755 --- a/doc-generation/generate-documentation.bash +++ b/doc-generation/generate-documentation.bash @@ -45,5 +45,5 @@ done ( cd "${ROOT_DIR}" - ${RUN} mkdocs serve + ${RUN} mkdocs build ) From 189817d3a1a61ff9b43682ab641cec7010027aee Mon Sep 17 00:00:00 2001 From: Arne Broering Date: Thu, 6 Nov 2025 10:24:44 +0100 Subject: [PATCH 11/29] editing formal App Registry spec Signed-off-by: Arne Broering --- doc-generation/generate-documentation.bash | 2 +- .../concepts/workloads/application-package.md | 2 +- .../workloads/application-registry.md | 4 +- system-design/overview/workloads.md | 2 +- .../technical-lexicon.md | 46 +++++++++++-------- 5 files changed, 32 insertions(+), 24 deletions(-) diff --git a/doc-generation/generate-documentation.bash b/doc-generation/generate-documentation.bash index 801299c..43fc851 100755 --- a/doc-generation/generate-documentation.bash +++ b/doc-generation/generate-documentation.bash @@ -45,5 +45,5 @@ done ( cd "${ROOT_DIR}" - ${RUN} mkdocs build + ${RUN} mkdocs serve ) diff --git a/system-design/concepts/workloads/application-package.md b/system-design/concepts/workloads/application-package.md index 5d18014..b347383 100644 --- a/system-design/concepts/workloads/application-package.md +++ b/system-design/concepts/workloads/application-package.md @@ -20,7 +20,7 @@ An application aggregates one or more [components](../personas-and-definitions/s The [deployment profiles](../../specification/application-package/application-description.md#deploymentprofile-attributes) specified in the application description SHALL be defined as Helm Chart components AND/OR Compose Archive components: - To target devices, which run Kubernetes, application components must be Helm charts using [Helm (version 3)](https://helm.sh/docs/topics/charts/). -- To target devices, which deploy applications using [Compose](https://www.compose-spec.io/), applications must be packaged as what Margo calls a *Compose Archive*, i.e., a tarball file containing the `compose.yaml` file and any additional artifacts referenced by the Compose file (e.g., configuration files, environment variable files, etc.). Margo recommends to digitally sign this package and to specify the location of the public key in the `ApplicationDescription` (see `keyLocation` [here](../../specification/application-package/application-description.md#componentproperties-attributes)). When digitally signing the package PGP encryption MUST be used. +- To target devices, which deploy applications using [Compose](https://www.compose-spec.io/), applications must be packaged as a [Compose Archive](../../personas-and-definitions/technical-lexicon.md#compose-archive), i.e., a tarball file containing the `compose.yaml` file and any additional artifacts referenced by the Compose file (e.g., configuration files, environment variable files, etc.). Margo recommends to digitally sign this package and to specify the location of the public key in the `ApplicationDescription` (see `keyLocation` [here](../../specification/application-package/application-description.md#componentproperties-attributes)). When digitally signing the package PGP encryption MUST be used. > **Investigation Needed**: Question: do we need to specify the location of a SHA256 hash for the Compose Archive also (similar to the PGP key) in the ApplicationDescription? > We will also discuss how we should handle secure container registries that require a username and password. diff --git a/system-design/concepts/workloads/application-registry.md b/system-design/concepts/workloads/application-registry.md index d24f4aa..cd2147a 100644 --- a/system-design/concepts/workloads/application-registry.md +++ b/system-design/concepts/workloads/application-registry.md @@ -2,8 +2,8 @@ The margo specification differentiates 4 kinds of registries: *Application Registries*, *Component Registries*, and *Container Registries* as well as *Marketplaces*. -1. An **Application Registry** hosts Application Packages that define through their [Application Description](../../specification/application-package/application-description.md) the application as one or multiple Components. -2. A **Component Registry** hosts the Components (which are deployable as *workloads*) and are provided as **Helm Charts** or **Compose Archives**. +1. An **Application Registry** hosts Application Packages that define through their [Application Description](../../specification/application-package/application-description.md) the application as one or multiple [Components](../../personas-and-definitions/technical-lexicon.md#component). +2. A **Component Registry** hosts the [Components](../../personas-and-definitions/technical-lexicon.md#component) (which are deployable as *workloads*) and are provided as **Helm Charts** or **Compose Archives**. 3. A **Container Registry** hosts container images referenced by those Components. 4. A **Marketplace** lists applications to advertise them and enable purchasing for end users. diff --git a/system-design/overview/workloads.md b/system-design/overview/workloads.md index fd58ba8..18935f4 100644 --- a/system-design/overview/workloads.md +++ b/system-design/overview/workloads.md @@ -1,6 +1,6 @@ # Workloads -A [workload](../personas-and-definitions/technical-lexicon.md#workload) is running software. More specifically, a workload is a running [component](../personas-and-definitions/software-composition.md) of an application deployed to a Margo compliant [edge compute devices](../personas-and-definitions/technical-lexicon.md#edge-compute-device). +A [workload](../personas-and-definitions/technical-lexicon.md#workload) is running software. More specifically, a workload is a running [Component](../personas-and-definitions/software-composition.md) of an [Application Package](../concepts/workloads/application-package.md) deployed to a Margo compliant [edge compute device](../personas-and-definitions/technical-lexicon.md#edge-compute-device). In order to help achieve Margo's interoperability [mission statement](../index.md#mission-statement) we are initially targeting [containerized](https://github.com/opencontainers) components/workloads capable of running on platforms like Kubernetes, Docker and Podman. The flexibility these platforms provide enables [workload suppliers](../personas-and-definitions/personas.md#workload-supplier) to define and package their components in a common way using [Helm](https://helm.sh/docs/) or the [Compose specification](https://github.com/compose-spec/compose-spec/blob/main/spec.md) so they can more easily be deployed to multiple compatible edge compute devices as workloads. diff --git a/system-design/personas-and-definitions/technical-lexicon.md b/system-design/personas-and-definitions/technical-lexicon.md index 0d86337..928732c 100644 --- a/system-design/personas-and-definitions/technical-lexicon.md +++ b/system-design/personas-and-definitions/technical-lexicon.md @@ -37,12 +37,11 @@ Current providers supported: #### Application -An application is a collection of one, or more, [Components](#component), as defined by an Application Description, and bundled within an [application package](#application-package). +An application is a collection of one, or more, [Components](#component), as defined by an [Application Description](../specification/application-package/application-description.md), and bundled within an [Application Package](#application-package). #### Application Package -An Application Package is used to distribute an [application](#application). -According the [specification](../concepts/workloads/application-package.md), it is a folder in a Git repository referenced by URL, which contains the Application Description (that refers to contained and deployable Components) as well as associated resources (e.g., icons). +An Application Package is used to distribute an [application](#application). The parts of an Application Package are: Application Description (that refers to contained and deployable Components) as well as associated resources (e.g., icons). While the application package is made available in an [Application Registry](./application-registry.md), the referenced components are stored in a Component Registry, and the linked containers are provided via a OCI Container Registry. #### Component @@ -52,6 +51,9 @@ Currently Margo-supported components are: - Helm Chart - Compose Archive +#### Compose Archive +A Compose Archive is a tarball file containing the Compose file, `compose.yaml`, which is formatted according the [Compose specification](https://www.compose-spec.io/), and any additional artifacts referenced by the Compose file (e.g., configuration files, environment variable files, etc.). + #### Workload A Workload is an instance of a [Component](#component) running within a customer's environment on a [Edge Compute Device](#edge-compute-device). @@ -79,36 +81,42 @@ Device Fleet Manager (DFM) represents a software offering that enables End Users > Note: The Device Fleet Manager is a future component of the Margo specification. This section will be expanded as the community defines device management functionality. -##### Application Registry -An Application Registry holds [Application](#application) Packages. -It is used by developers to make their applications available. -An Application Registries MUST be a Git repository. +#### Application Registry + +An [Application Registry](../concepts/workloads/application-registry.md) hosts [Application Packages](#application-package) that define, through their [Application Description](../../specification/application-package/application-description.md), the application as one or multiple [Components](#component). +It is used by application developers to make their applications available. +The [API of the Application Registry](../specification/application-package/application-registry.md) is compliant with the [OCI Registry API (v1.1.0)](https://github.com/opencontainers/distribution-spec/blob/v1.1.0/spec.md). -[Workload Fleet Managers](#workload-fleet-manager) cannot access Application Registries directly, they can only access [Application Catalogs](#application-catalog). +> To be clarified (Arne): +> +> [Workload Fleet Managers](#workload-fleet-manager) cannot access Application Registries directly, they can only access [Application Catalogs](#application-catalog). -##### Application Catalog +#### Application Catalog An Application Catalog holds Application Packages that were preselected to be install-ready for the edge environment of a [Workload Fleet Manager](#workload-fleet-manager) to deploy them to managed [Edge Compute Devices](#edge-compute-device). An Application Catalog obtains the offered [Applications](#application) from one or more [Application Registries](#application-registry). -##### Component Registry +#### Component Registry + +A Component Registry holds [Components](#component) (e.g., Helm Charts and Compose Archives) for [Application Packages](#application-package). +When an application gets deployed through a [Workload Fleet Manager](#workload-fleet-manager), the components (linked within an [Application Description](../../specification/application-package/application-description.md)) are requested from the Component Registry and then deployed as [workloads](#workload). Components link to containers that are typically provided through [Container Registries](#container-registry). +The Component Registry can be implemented, e.g., as an OCI Registry. -A Component Registry holds [Components](#component) (e.g., Helm Charts and Compose Archives) for Application Packages. -When an application gets deployed through a [Workload Fleet Manager](#workload-fleet-manager), the components (linked within an Application Description) are requested from the Component Registry. +#### Container Registry +A Container Registry hosts container images. [Components](#component) which are provided as Helm Charts or Compose Archives link to such container images. -This can be implemented, for example, as an OCI Registry. -#### Workload Marketplace +#### Marketplace -Workload Marketplace is the location where end users purchase the rights to access [Workloads](#workload) from a vendor. +A Marketplace is the location where end users discover and purchase the rights to access [Applications](#application) to be deployed as [Workloads](#workload) from a vendor. -Functional Requirements of the Workload Marketplace: +Functional Requirements of the Marketplace: -- Provide users with a list of Workloads available for purchase -- Enable users to purchase access rights to a Workload -- Enable users with the meta data to access associated Workload Registries/Repositories +- Provide users with a list of [Applications](#application) available for purchase. +- Enable users to purchase access rights to an [Application](#application) deployable as [workloads](#workload). +- Enable users with the metadata to access associated [Application Registries](#application-registry). > Note: The Workload Marketplace component is out of scope for Project Margo. However, it is necessary to define to clarify the full user workflow. From b0a4aeba4505bdc6034b6bc31e5db20d116f774f Mon Sep 17 00:00:00 2001 From: Arne Broering Date: Thu, 6 Nov 2025 12:54:06 +0100 Subject: [PATCH 12/29] adjusting rest of spec to latest adjustments on the Application Registry Signed-off-by: Arne Broering --- doc-generation/generate-documentation.bash | 2 +- mkdocs.yml | 2 +- .../resources/index.md.jinja2 | 3 ++- .../concepts/workloads/application-package.md | 19 +++++++++++-------- .../overview/envisioned-system-design.md | 2 +- system-design/overview/workloads.md | 2 +- .../software-composition.md | 6 +++--- .../technical-lexicon.md | 6 +++--- .../application-registry.md | 2 +- 9 files changed, 24 insertions(+), 20 deletions(-) diff --git a/doc-generation/generate-documentation.bash b/doc-generation/generate-documentation.bash index 43fc851..801299c 100755 --- a/doc-generation/generate-documentation.bash +++ b/doc-generation/generate-documentation.bash @@ -45,5 +45,5 @@ done ( cd "${ROOT_DIR}" - ${RUN} mkdocs serve + ${RUN} mkdocs build ) diff --git a/mkdocs.yml b/mkdocs.yml index b2820e5..4232048 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -15,7 +15,7 @@ nav: - overview/edge-compute-devices.md - overview/workload-observability.md - Concepts: - - Workloads: + - Applications: - concepts/workloads/application-package.md - concepts/workloads/application-registry.md - concepts/workloads/local-registries.md diff --git a/src/specification/application-package/resources/index.md.jinja2 b/src/specification/application-package/resources/index.md.jinja2 index 742cab5..027f0a7 100644 --- a/src/specification/application-package/resources/index.md.jinja2 +++ b/src/specification/application-package/resources/index.md.jinja2 @@ -1,6 +1,7 @@ # Application Description -The application description has the purpose of presenting the application, e.g., on an application catalog or marketplace from where an end user selects an application to be installed. +The Application Description has the purpose of presenting the application, e.g., on a WFM-internal [Application Catalog](../../personas-and-definitions/technical-lexicon.md#workload-fleet-manager)) +or on a public [Marketplace](../../personas-and-definitions/technical-lexicon.md#marketplace)) from where an end user selects an application to be installed. The end user defines an `ApplicationDeployment` by specifying [configuration parameters](#defining-configurable-application-parameters) for an `ApplicationDescription`. An `ApplicationDeployment` defines the [desired state](../margo-management-interface/desired-state.md) for an application. diff --git a/system-design/concepts/workloads/application-package.md b/system-design/concepts/workloads/application-package.md index b347383..b14d49b 100644 --- a/system-design/concepts/workloads/application-package.md +++ b/system-design/concepts/workloads/application-package.md @@ -1,11 +1,11 @@ # Application Package -The application package, which is used to [distribute an application](../../overview/workloads.md), comprises the following elements: +The Application Package, which is used to [distribute an application](../../overview/workloads.md) that shall be deployed as [workloads](../../personas-and-definitions/technical-lexicon.md#workload) on edge devices, comprises the following elements: -- The **application description**: a YAML document with the element `kind` defined as `ApplicationDescription`, which is stored in a file (for example named `margo.yaml`) and contains information about the application's [metadata](../../specification/application-package/application-description.md#metadata-attributes) (e.g., description, icon, release notes, license file, etc.), application supported [deployment configurations](../../specification/application-package/application-description.md#deploymentprofile-attributes) (e.g, Helm charts, Compose Archive), and [configurable application parameters](../../specification/application-package/application-description.md#defining-configurable-application-parameters). There SHALL be only one YAML file in the package root of kind `ApplicationDescription`. +- The **Application Description**: a YAML document with the element `kind` defined as `ApplicationDescription`, which is stored in a file (for example named `margo.yaml`) and contains information about the application's [metadata](../../specification/application-package/application-description.md#metadata-attributes) (e.g., description, icon, release notes, license file, etc.), the application [components](../../personas-and-definitions/technical-lexicon.md#component) (e.g, Helm charts, Compose Archive) which are defined in [deployment configurations](../../specification/application-package/application-description.md#deploymentprofile-attributes), and [configurable application parameters](../../specification/application-package/application-description.md#defining-configurable-application-parameters). There SHALL be only one YAML file in the package root of kind `ApplicationDescription`. - The **resources**, which are additional files associated with the application (e.g., manual, icon, release notes, license file, etc.) that may be used to display more information about the application in a UI such as an [application catalog](../../personas-and-definitions/technical-lexicon.md#application-catalog) or [marketplace](../../personas-and-definitions/technical-lexicon.md#workload-marketplace) or other informative outputs. -The application package has the following file/folder structure: +The Application Package SHALL follow a folder/file structure as such: ```yaml / # REQUIRED top-level directory @@ -13,14 +13,17 @@ The application package has the following file/folder structure: └── resources # OPTIONAL folder with application files (e.g., icon, license file, release notes) that may be used for displaying additional information about the application ``` -An application aggregates one or more [components](../personas-and-definitions/software-composition.md), which comprise of one or more [OCI Containers](https://github.com/opencontainers). While the application package is made available in an [Application Registry](./application-registry.md), the referenced components are stored in a Component Registry, and the linked containers are provided via a OCI Container Registry. Registries can be remote or [local](../../concepts/workloads/local-registries.md). +The Application Package SHALL be made available in an [Application Registry](./application-registry.md). + +An application aggregates one or more [components](../personas-and-definitions/software-composition.md), which each link to one or more [OCI Containers](https://github.com/opencontainers). The components referenced in the [Application Description](../../specification/application-package/application-description.md) are stored in a [Component Registry](../../personas-and-definitions/technical-lexicon.md#component-registry), and the linked containers are provided via a [Container Registry](../../personas-and-definitions/technical-lexicon.md#container-registry). Registries can be remote (i.e., Internet-accessible) or [local](../../concepts/workloads/local-registries.md) (i.e., accessible within a local network infrastructure of the devices). > **Note** -> Application catalogs or marketplaces are out of scope for Margo. The exact requirements of the marketing material shall be defined by the application marketplace beyond outlined mandatory content. +> Application catalogs and marketplaces are out of scope of the Margo specification. The exact requirements of the marketing material shall be defined by the application marketplace beyond outlined mandatory content. + +The [deployment profiles](../../specification/application-package/application-description.md#deploymentprofile-attributes) specified in the [Application Description](../../specification/application-package/application-description.md) SHALL be defined as Helm Chart components AND/OR [Compose Archive](../../personas-and-definitions/technical-lexicon.md#compose-archive) components. These components will be deployed as workloads on the edge devices: -The [deployment profiles](../../specification/application-package/application-description.md#deploymentprofile-attributes) specified in the application description SHALL be defined as Helm Chart components AND/OR Compose Archive components: -- To target devices, which run Kubernetes, application components must be Helm charts using [Helm (version 3)](https://helm.sh/docs/topics/charts/). -- To target devices, which deploy applications using [Compose](https://www.compose-spec.io/), applications must be packaged as a [Compose Archive](../../personas-and-definitions/technical-lexicon.md#compose-archive), i.e., a tarball file containing the `compose.yaml` file and any additional artifacts referenced by the Compose file (e.g., configuration files, environment variable files, etc.). Margo recommends to digitally sign this package and to specify the location of the public key in the `ApplicationDescription` (see `keyLocation` [here](../../specification/application-package/application-description.md#componentproperties-attributes)). When digitally signing the package PGP encryption MUST be used. +- To target devices, which deploy workloads using Kubernetes, components must be defined as Helm charts using [Helm (version 3)](https://helm.sh/docs/topics/charts/). +- To target devices, which deploy workloads using [Compose](https://www.compose-spec.io/), components must be packaged as [Compose Archives](../../personas-and-definitions/technical-lexicon.md#compose-archive), i.e., a tarball file containing the `compose.yaml` file and any additional artifacts referenced by the Compose file (e.g., configuration files, environment variable files, etc.). Margo recommends to digitally sign this package and to specify the location of the public key in the `ApplicationDescription` (see `keyLocation` [here](../../specification/application-package/application-description.md#componentproperties-attributes)). When digitally signing the package PGP encryption MUST be used. > **Investigation Needed**: Question: do we need to specify the location of a SHA256 hash for the Compose Archive also (similar to the PGP key) in the ApplicationDescription? > We will also discuss how we should handle secure container registries that require a username and password. diff --git a/system-design/overview/envisioned-system-design.md b/system-design/overview/envisioned-system-design.md index ed30e7c..dd03671 100644 --- a/system-design/overview/envisioned-system-design.md +++ b/system-design/overview/envisioned-system-design.md @@ -10,7 +10,7 @@ The envisioned system can be broken down into the following main components: ### Workloads -Workloads are the software deployed to Margo-compliant edge compute devices. See the [workloads overview](workloads.md) page to learn more Margo's supported workloads and how the are packaged. +Workloads are the software deployed to Margo-compliant edge compute devices. They are deployed [Components](../personas-and-definitions/technical-lexicon.md#component) of an [Application Pacakge](../personas-and-definitions/technical-lexicon.md#application-package). See the [workloads overview](workloads.md) page to learn more Margo's supported workloads and how they are packaged. ### Workload Observability diff --git a/system-design/overview/workloads.md b/system-design/overview/workloads.md index 18935f4..ac299fb 100644 --- a/system-design/overview/workloads.md +++ b/system-design/overview/workloads.md @@ -1,4 +1,4 @@ -# Workloads +# Applications & Workloads A [workload](../personas-and-definitions/technical-lexicon.md#workload) is running software. More specifically, a workload is a running [Component](../personas-and-definitions/software-composition.md) of an [Application Package](../concepts/workloads/application-package.md) deployed to a Margo compliant [edge compute device](../personas-and-definitions/technical-lexicon.md#edge-compute-device). diff --git a/system-design/personas-and-definitions/software-composition.md b/system-design/personas-and-definitions/software-composition.md index 5d205be..756aab3 100644 --- a/system-design/personas-and-definitions/software-composition.md +++ b/system-design/personas-and-definitions/software-composition.md @@ -61,7 +61,7 @@ Software at rest is made available as an Application Package, which is a folder [Application Packages][application-package] and [Components][component] are managed and hosted separately: -- [Application Registries][application-registry] store [Application Descriptions][application-description] and their associated application resources. An [Application Registry][application-registry] is implemented as a git repository. +- [Application Registries][application-registry] store [Application Descriptions][application-description] and their associated application resources. An [Application Registry][application-registry] is compliant with the [OCI Registry API (v1.1.0)](https://github.com/opencontainers/distribution-spec/blob/v1.1.0/spec.md). - [Component Registries][component-registry] store [Components][component] The following diagram shows, at hand of an example, the relationship between an [Application Package][application-package] and the [Components][component] listed within its [Deployment Profiles][deployment-profile]: @@ -70,7 +70,7 @@ The following diagram shows, at hand of an example, the relationship between an C4Component title Application Bundling: Example 1 - Helm and Compose deployment profiles provided - System_Boundary(ar, "Application Registry (Git)") { + System_Boundary(ar, "Application Registry") { System_Boundary(ab1, "Application Package 1") { Component(atb1, "Application Package", "Reference") @@ -124,7 +124,7 @@ C4Component UpdateLayoutConfig($c4BoundaryInRow="1", $c4ShapeInRow="3") - System_Boundary(ar, "Application Registry (Git)") { + System_Boundary(ar, "Application Registry") { System_Boundary(ab1, "Application Package 1") { Component(atb1, "Application Package") diff --git a/system-design/personas-and-definitions/technical-lexicon.md b/system-design/personas-and-definitions/technical-lexicon.md index 928732c..89f8f36 100644 --- a/system-design/personas-and-definitions/technical-lexicon.md +++ b/system-design/personas-and-definitions/technical-lexicon.md @@ -41,7 +41,7 @@ An application is a collection of one, or more, [Components](#component), as def #### Application Package -An Application Package is used to distribute an [application](#application). The parts of an Application Package are: Application Description (that refers to contained and deployable Components) as well as associated resources (e.g., icons). While the application package is made available in an [Application Registry](./application-registry.md), the referenced components are stored in a Component Registry, and the linked containers are provided via a OCI Container Registry. +An Application Package is used to distribute an [application](#application). The parts of an Application Package are: Application Description (that refers to contained and deployable Components) as well as associated resources (e.g., icons). While the application package is made available in an [Application Registry](./application-registry.md), the referenced [components](#component) are stored in a [Component Registry](#component-registry), and the linked containers are provided via a OCI [Container Registry](#container-registry). #### Component @@ -49,7 +49,7 @@ A Component is a piece of software tailored to be deployed within a customer's e Currently Margo-supported components are: - Helm Chart -- Compose Archive +- [Compose Archive](#compose-archive) #### Compose Archive A Compose Archive is a tarball file containing the Compose file, `compose.yaml`, which is formatted according the [Compose specification](https://www.compose-spec.io/), and any additional artifacts referenced by the Compose file (e.g., configuration files, environment variable files, etc.). @@ -94,7 +94,7 @@ The [API of the Application Registry](../specification/application-package/appli #### Application Catalog -An Application Catalog holds Application Packages that were preselected to be install-ready for the edge environment of a [Workload Fleet Manager](#workload-fleet-manager) to deploy them to managed [Edge Compute Devices](#edge-compute-device). +An Application Catalog resides inside or associated with a [WFM](#workload-fleet-manager) to hold [Application Packages](#application-package) that were preselected to be install-ready for the edge environment of a [Workload Fleet Manager](#workload-fleet-manager) to deploy them to managed [Edge Compute Devices](#edge-compute-device). An Application Catalog obtains the offered [Applications](#application) from one or more [Application Registries](#application-registry). diff --git a/system-design/specification/application-package/application-registry.md b/system-design/specification/application-package/application-registry.md index a3807dc..6dc44c6 100644 --- a/system-design/specification/application-package/application-registry.md +++ b/system-design/specification/application-package/application-registry.md @@ -1,6 +1,6 @@ # Application Registry -The interactions of an `Application Registry` are described [here](../../concepts/workloads/application-registry.md) from a conceptual view. This section formally specifies the API of the `Application Registry` and the exchange of an [Application Package](./application-package-definition.md), defined through an [Application Description](../../specification/application-package/) file, from an Application Developer to the Workload Fleet Manager (WFM). The `Application Registry` is designed as an `OCI Registry`, i.e., it offers an API compliant with the [OCI Registry API (v1.1.0)](https://github.com/opencontainers/distribution-spec/blob/v1.1.0/spec.md) (called here the "OCI_spec") for digital artifact distribution. This way, the Application Registry hosts the parts of an [Application Package](https://specification.margo.org/app-interoperability/application-package-definition/) in form of `blobs` and uses `image manifests` according to [OCI Image specification](https://github.com/opencontainers/image-spec/blob/v1.0.1/manifest.md)) to list a set of `layers`, each pointing at a blob. +The interactions of an `Application Registry` are described [here](../../concepts/workloads/application-registry.md) from a conceptual view. This section formally specifies the API of the `Application Registry` and the exchange of an [Application Package](./application-package-definition.md), defined through an [Application Description](../../specification/application-package/) file, from an Application Developer to the [Workload Fleet Manager](../../personas-and-definitions/technical-lexicon.md#workload-fleet-manager) (WFM). The `Application Registry` is designed as an `OCI Registry`, i.e., it offers an API compliant with the [OCI Registry API (v1.1.0)](https://github.com/opencontainers/distribution-spec/blob/v1.1.0/spec.md) (called here the "OCI_spec") for digital artifact distribution. This way, the Application Registry hosts the parts of an [Application Package](https://specification.margo.org/app-interoperability/application-package-definition/) in form of `blobs` and uses `image manifests` according to [OCI Image specification](https://github.com/opencontainers/image-spec/blob/v1.0.1/manifest.md)) to list a set of `layers`, each pointing at a blob. ## Overview of API Endpoints From 9aecef2e5c67ce0add92a91cb6dfedda60ef5016 Mon Sep 17 00:00:00 2001 From: Arne Broering Date: Thu, 6 Nov 2025 15:59:58 +0100 Subject: [PATCH 13/29] addressing PR comment about no specification language in concept section Signed-off-by: Arne Broering --- .../concepts/workloads/application-package.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/system-design/concepts/workloads/application-package.md b/system-design/concepts/workloads/application-package.md index b14d49b..8680d36 100644 --- a/system-design/concepts/workloads/application-package.md +++ b/system-design/concepts/workloads/application-package.md @@ -2,10 +2,10 @@ The Application Package, which is used to [distribute an application](../../overview/workloads.md) that shall be deployed as [workloads](../../personas-and-definitions/technical-lexicon.md#workload) on edge devices, comprises the following elements: -- The **Application Description**: a YAML document with the element `kind` defined as `ApplicationDescription`, which is stored in a file (for example named `margo.yaml`) and contains information about the application's [metadata](../../specification/application-package/application-description.md#metadata-attributes) (e.g., description, icon, release notes, license file, etc.), the application [components](../../personas-and-definitions/technical-lexicon.md#component) (e.g, Helm charts, Compose Archive) which are defined in [deployment configurations](../../specification/application-package/application-description.md#deploymentprofile-attributes), and [configurable application parameters](../../specification/application-package/application-description.md#defining-configurable-application-parameters). There SHALL be only one YAML file in the package root of kind `ApplicationDescription`. +- The **Application Description**: a YAML document with the element `kind` defined as `ApplicationDescription`, which is stored in a file (for example named `margo.yaml`) and contains information about the application's [metadata](../../specification/application-package/application-description.md#metadata-attributes) (e.g., description, icon, release notes, license file, etc.), the application [components](../../personas-and-definitions/technical-lexicon.md#component) (e.g, Helm charts, Compose Archive) which are defined in [deployment configurations](../../specification/application-package/application-description.md#deploymentprofile-attributes), and [configurable application parameters](../../specification/application-package/application-description.md#defining-configurable-application-parameters). There is only one YAML file in the package root of kind `ApplicationDescription`. - The **resources**, which are additional files associated with the application (e.g., manual, icon, release notes, license file, etc.) that may be used to display more information about the application in a UI such as an [application catalog](../../personas-and-definitions/technical-lexicon.md#application-catalog) or [marketplace](../../personas-and-definitions/technical-lexicon.md#workload-marketplace) or other informative outputs. -The Application Package SHALL follow a folder/file structure as such: +The Application Package has the following folder/file structure: ```yaml / # REQUIRED top-level directory @@ -13,17 +13,17 @@ The Application Package SHALL follow a folder/file structure as such: └── resources # OPTIONAL folder with application files (e.g., icon, license file, release notes) that may be used for displaying additional information about the application ``` -The Application Package SHALL be made available in an [Application Registry](./application-registry.md). +The Application Package is made available in an [Application Registry](./application-registry.md). An application aggregates one or more [components](../personas-and-definitions/software-composition.md), which each link to one or more [OCI Containers](https://github.com/opencontainers). The components referenced in the [Application Description](../../specification/application-package/application-description.md) are stored in a [Component Registry](../../personas-and-definitions/technical-lexicon.md#component-registry), and the linked containers are provided via a [Container Registry](../../personas-and-definitions/technical-lexicon.md#container-registry). Registries can be remote (i.e., Internet-accessible) or [local](../../concepts/workloads/local-registries.md) (i.e., accessible within a local network infrastructure of the devices). > **Note** > Application catalogs and marketplaces are out of scope of the Margo specification. The exact requirements of the marketing material shall be defined by the application marketplace beyond outlined mandatory content. -The [deployment profiles](../../specification/application-package/application-description.md#deploymentprofile-attributes) specified in the [Application Description](../../specification/application-package/application-description.md) SHALL be defined as Helm Chart components AND/OR [Compose Archive](../../personas-and-definitions/technical-lexicon.md#compose-archive) components. These components will be deployed as workloads on the edge devices: +The [deployment profiles](../../specification/application-package/application-description.md#deploymentprofile-attributes) specified in the [Application Description](../../specification/application-package/application-description.md) are defined as Helm Chart components AND/OR [Compose Archive](../../personas-and-definitions/technical-lexicon.md#compose-archive) components. These components are being deployed as workloads on the edge devices: -- To target devices, which deploy workloads using Kubernetes, components must be defined as Helm charts using [Helm (version 3)](https://helm.sh/docs/topics/charts/). -- To target devices, which deploy workloads using [Compose](https://www.compose-spec.io/), components must be packaged as [Compose Archives](../../personas-and-definitions/technical-lexicon.md#compose-archive), i.e., a tarball file containing the `compose.yaml` file and any additional artifacts referenced by the Compose file (e.g., configuration files, environment variable files, etc.). Margo recommends to digitally sign this package and to specify the location of the public key in the `ApplicationDescription` (see `keyLocation` [here](../../specification/application-package/application-description.md#componentproperties-attributes)). When digitally signing the package PGP encryption MUST be used. +- To target devices, which deploy workloads using Kubernetes, components need to be defined as Helm charts using [Helm (version 3)](https://helm.sh/docs/topics/charts/). +- To target devices, which deploy workloads using [Compose](https://www.compose-spec.io/), components need to be packaged as [Compose Archives](../../personas-and-definitions/technical-lexicon.md#compose-archive), i.e., a tarball file containing the `compose.yaml` file and any additional artifacts referenced by the Compose file (e.g., configuration files, environment variable files, etc.). Margo recommends to digitally sign this package and to specify the location of the public key in the `ApplicationDescription` (see `keyLocation` [here](../../specification/application-package/application-description.md#componentproperties-attributes)). When digitally signing the package PGP encryption MUST be used. > **Investigation Needed**: Question: do we need to specify the location of a SHA256 hash for the Compose Archive also (similar to the PGP key) in the ApplicationDescription? > We will also discuss how we should handle secure container registries that require a username and password. From af1b2e55e4a32698eb1d2475625e52efdc768382 Mon Sep 17 00:00:00 2001 From: Arne Broering Date: Fri, 7 Nov 2025 15:44:40 +0100 Subject: [PATCH 14/29] addressing PR review comments Signed-off-by: Arne Broering --- .../resources/index.md.jinja2 | 4 +- .../concepts/workloads/application-package.md | 10 ++-- .../workloads/application-registry.md | 4 +- .../concepts/workloads/local-registries.md | 4 +- system-design/overview/workloads.md | 4 +- .../software-composition.md | 12 ++-- .../technical-lexicon.md | 6 +- .../application-registry.md | 56 +++++++++---------- 8 files changed, 50 insertions(+), 50 deletions(-) diff --git a/src/specification/application-package/resources/index.md.jinja2 b/src/specification/application-package/resources/index.md.jinja2 index 027f0a7..bc1be7b 100644 --- a/src/specification/application-package/resources/index.md.jinja2 +++ b/src/specification/application-package/resources/index.md.jinja2 @@ -1,7 +1,7 @@ # Application Description -The Application Description has the purpose of presenting the application, e.g., on a WFM-internal [Application Catalog](../../personas-and-definitions/technical-lexicon.md#workload-fleet-manager)) -or on a public [Marketplace](../../personas-and-definitions/technical-lexicon.md#marketplace)) from where an end user selects an application to be installed. +The Application Description has the purpose of presenting the application (e.g., on a WFM-internal [Application Catalog](../../personas-and-definitions/technical-lexicon.md#workload-fleet-manager)) +or public [Marketplace](../../personas-and-definitions/technical-lexicon.md#marketplace)) from where an end user selects an application to be installed. The end user defines an `ApplicationDeployment` by specifying [configuration parameters](#defining-configurable-application-parameters) for an `ApplicationDescription`. An `ApplicationDeployment` defines the [desired state](../margo-management-interface/desired-state.md) for an application. diff --git a/system-design/concepts/workloads/application-package.md b/system-design/concepts/workloads/application-package.md index 8680d36..dfa0e25 100644 --- a/system-design/concepts/workloads/application-package.md +++ b/system-design/concepts/workloads/application-package.md @@ -1,9 +1,9 @@ # Application Package -The Application Package, which is used to [distribute an application](../../overview/workloads.md) that shall be deployed as [workloads](../../personas-and-definitions/technical-lexicon.md#workload) on edge devices, comprises the following elements: +The Application Package, which is used to [distribute an application](../../overview/workloads.md) to be deployed as [workloads](../../personas-and-definitions/technical-lexicon.md#workload) on edge devices, comprises the following elements: -- The **Application Description**: a YAML document with the element `kind` defined as `ApplicationDescription`, which is stored in a file (for example named `margo.yaml`) and contains information about the application's [metadata](../../specification/application-package/application-description.md#metadata-attributes) (e.g., description, icon, release notes, license file, etc.), the application [components](../../personas-and-definitions/technical-lexicon.md#component) (e.g, Helm charts, Compose Archive) which are defined in [deployment configurations](../../specification/application-package/application-description.md#deploymentprofile-attributes), and [configurable application parameters](../../specification/application-package/application-description.md#defining-configurable-application-parameters). There is only one YAML file in the package root of kind `ApplicationDescription`. -- The **resources**, which are additional files associated with the application (e.g., manual, icon, release notes, license file, etc.) that may be used to display more information about the application in a UI such as an [application catalog](../../personas-and-definitions/technical-lexicon.md#application-catalog) or [marketplace](../../personas-and-definitions/technical-lexicon.md#workload-marketplace) or other informative outputs. +- The **Application Description**: a YAML document with the element `kind` defined as `ApplicationDescription`, which is stored in a file (for example named `margo.yaml`) and contains information about the application's [metadata](../../specification/application-package/application-description.md#metadata-attributes) (e.g., description, icon, release notes, license file, etc.), the application [components](../../personas-and-definitions/technical-lexicon.md#component) (e.g., Helm charts, Compose Archive) which are defined in [deployment configurations](../../specification/application-package/application-description.md#deploymentprofile-attributes), and [configurable application parameters](../../specification/application-package/application-description.md#defining-configurable-application-parameters). There is only one YAML file in the package root of kind `ApplicationDescription`. +- The **resources**, which are additional files associated with the application (e.g., manual, icon, release notes, license file, etc.) that may be used to display more information about the application in a UI such as an [application catalog](../../personas-and-definitions/technical-lexicon.md#application-catalog) or [marketplace](../../personas-and-definitions/technical-lexicon.md#marketplace) or other informative outputs. The Application Package has the following folder/file structure: @@ -15,10 +15,10 @@ The Application Package has the following folder/file structure: The Application Package is made available in an [Application Registry](./application-registry.md). -An application aggregates one or more [components](../personas-and-definitions/software-composition.md), which each link to one or more [OCI Containers](https://github.com/opencontainers). The components referenced in the [Application Description](../../specification/application-package/application-description.md) are stored in a [Component Registry](../../personas-and-definitions/technical-lexicon.md#component-registry), and the linked containers are provided via a [Container Registry](../../personas-and-definitions/technical-lexicon.md#container-registry). Registries can be remote (i.e., Internet-accessible) or [local](../../concepts/workloads/local-registries.md) (i.e., accessible within a local network infrastructure of the devices). +An application aggregates one or more [components](../../personas-and-definitions/technical-lexicon.md#component), which each link to one or more [OCI Containers](https://github.com/opencontainers). The components referenced in the [Application Description](../../specification/application-package/application-description.md) are stored in a [Component Registry](../../personas-and-definitions/technical-lexicon.md#component-registry), and the linked containers are provided via a [Container Registry](../../personas-and-definitions/technical-lexicon.md#container-registry). Registries can be remote (i.e., Internet-accessible) or [local](../../concepts/workloads/local-registries.md) (i.e., accessible within a local network infrastructure of the devices). > **Note** -> Application catalogs and marketplaces are out of scope of the Margo specification. The exact requirements of the marketing material shall be defined by the application marketplace beyond outlined mandatory content. +> Application catalogs and marketplaces are out of scope of the Margo specification. The exact requirements of the marketing material need to be defined by the application marketplace beyond outlined mandatory content. The [deployment profiles](../../specification/application-package/application-description.md#deploymentprofile-attributes) specified in the [Application Description](../../specification/application-package/application-description.md) are defined as Helm Chart components AND/OR [Compose Archive](../../personas-and-definitions/technical-lexicon.md#compose-archive) components. These components are being deployed as workloads on the edge devices: diff --git a/system-design/concepts/workloads/application-registry.md b/system-design/concepts/workloads/application-registry.md index cd2147a..581c655 100644 --- a/system-design/concepts/workloads/application-registry.md +++ b/system-design/concepts/workloads/application-registry.md @@ -33,9 +33,9 @@ flowchart As shown in the figure above, an `Application Developer` uploads an [Application package](application-package.md) to an Application Registry. From there, it is available to a `Workload Fleet Manager` (WFM). The WFM acts as a client to pull an [Application Package](application-package.md) from the Application Registry. It would then list this Application Package on its UI (e.g., an internal `Application Catalog`) to enable the usage on its managed devices. -An `Authentication Service` manages access control for the Application Registry. Hence, the WFM requests a token from there to include it into its requests to the Application Registry. The received token is then validated by the Application Registry through interaction with the Authentication Service. +An `Authentication Service` manages access control for the Application Registry. The WFM requests a token from the Authentication Service to include in the requests to the Application Registry. The received token is then validated by the Application Registry through interaction with the Authentication Service. -The Application Registry's API is compliant with the [OCI Registry API (v1.1.0)](https://github.com/opencontainers/distribution-spec/blob/v1.1.0/spec.md). A hosted Application Package is provided by listing its parts as layers in an [image manifests](https://github.com/opencontainers/image-spec/blob/v1.0.1/manifest.md)) that can be requested through the API. +The Application Registry's API is compliant with the [OCI Registry API (v1.1.0)](https://github.com/opencontainers/distribution-spec/blob/v1.1.0/spec.md). A hosted Application Package is provided by listing its parts as layers in an [image manifests](https://github.com/opencontainers/image-spec/blob/v1.0.1/manifest.md) that can be requested through the API. ## Relevant Links diff --git a/system-design/concepts/workloads/local-registries.md b/system-design/concepts/workloads/local-registries.md index 8958857..b130b7c 100644 --- a/system-design/concepts/workloads/local-registries.md +++ b/system-design/concepts/workloads/local-registries.md @@ -1,6 +1,6 @@ # Local Registries -The [Component Registry](application-registry.md) as well as the [Container Registry](application-registry.md) considered by margo are the registries that need to be accessed by devices to download components (i.e., Helm Charts or Compose Archives) or containers. This section describeds how to configure those as local registries to avoid reliance on public Internet-accessible registries. +The [Component Registry](application-registry.md) as well as the [Container Registry](application-registry.md) considered by Margo are the registries that need to be accessed by devices to download components (i.e., Helm Charts or Compose Archives) or containers. This section describes how to configure those as local registries to avoid reliance on public Internet-accessible registries. The reasons for not using public registries are for example: (1) publicly hosted container images or Helm charts could become unavailable at some point, as the owner decides to take the container images or Helm charts off the public registry, (2) Internet connectivity may not be available to the device and hence public registries are not reachable, or (3) end-users want to host their own registries so they can do security scans and package validation. @@ -10,7 +10,7 @@ In terms of connectivity, we can thereby distinguish mainly between the followin 2. **Locally connected device**, i.e., the device has connectivity to a local network (e.g., factory- or enterprise-wide) and a local repository can be made reachable. 3. **Air-gapped device**, i.e., the device generally is not connected and must be configured by accessing it directly (via direct network link with an Ethernet cable, or similar) for example through a technician’s laptop. -Local Component Registries or Container Registries can be used for all three categories of devices. In case of **fully connected devices**, although the device could reach the Internet, a local registry can still be useful, e.g., as a cache for remote registries to save on bandwidth or to have container images or Helm Charts reliably available. In case of **locally connected devices**, a local registry is required to enable the Workload Fleet Management Client (WFMC) to install a margo application on the device, as the device/WFMC does not have Internet access. Thereby, the local registry can be set up as a *pull-through cache* where data (e.g., container images) are cached locally when they are first retrieved from a remote source and subsequent requests for the same data are served from the local cache rather than fetching it again from the remote source. In case of **air-gapped devices**, a local registry has to be accessible on the technician's laptop (or other directly connected device), which performs the application installation process. +Local Component Registries or Container Registries can be used for all device categories. In case of **fully connected devices**, although the device could reach the Internet, a local registry can still be useful (e.g., as a cache for remote registries to save on bandwidth or to have container images or Helm Charts reliably available). In case of **locally connected devices**, a local registry is required to enable the Workload Fleet Management Client (WFMC) to install a Margo application on the device, as the device/WFMC does not have Internet access. Thereby, the local registry can be set up as a *pull-through cache* where data (e.g., container images) is cached locally when they are first retrieved from a remote source and subsequent requests for the same data are served from the local cache rather than fetching it again from the remote source. In case of **air-gapped devices**, a local registry has to be accessible on the technician's laptop (or other directly connected device), which performs the application installation process. To setup local registries, different configuration options exist: diff --git a/system-design/overview/workloads.md b/system-design/overview/workloads.md index ac299fb..c7931e8 100644 --- a/system-design/overview/workloads.md +++ b/system-design/overview/workloads.md @@ -1,6 +1,6 @@ # Applications & Workloads -A [workload](../personas-and-definitions/technical-lexicon.md#workload) is running software. More specifically, a workload is a running [Component](../personas-and-definitions/software-composition.md) of an [Application Package](../concepts/workloads/application-package.md) deployed to a Margo compliant [edge compute device](../personas-and-definitions/technical-lexicon.md#edge-compute-device). +A [workload](../personas-and-definitions/technical-lexicon.md#workload) is running software. More specifically, a workload is a running [Component](../personas-and-definitions/technical-lexicon.md#component) of an [Application Package](../concepts/workloads/application-package.md) deployed to a Margo compliant [edge compute device](../personas-and-definitions/technical-lexicon.md#edge-compute-device). In order to help achieve Margo's interoperability [mission statement](../index.md#mission-statement) we are initially targeting [containerized](https://github.com/opencontainers) components/workloads capable of running on platforms like Kubernetes, Docker and Podman. The flexibility these platforms provide enables [workload suppliers](../personas-and-definitions/personas.md#workload-supplier) to define and package their components in a common way using [Helm](https://helm.sh/docs/) or the [Compose specification](https://github.com/compose-spec/compose-spec/blob/main/spec.md) so they can more easily be deployed to multiple compatible edge compute devices as workloads. @@ -50,7 +50,7 @@ sequenceDiagram frontend ->> frontend: Read all application descriptions' 'metadata' element frontend ->> EndUser: Show UI with list of applications EndUser->>frontend: Select application / components to install - frontend ->> frontend: Read application descriptions' 'configuration' element + frontend ->> frontend: Read application descriptions 'configuration' element frontend -->> EndUser: Show UI to fill application configuration EndUser ->> frontend: fills application configuration frontend ->> fleetmgr: Create 'ApplicationDeployment' definition diff --git a/system-design/personas-and-definitions/software-composition.md b/system-design/personas-and-definitions/software-composition.md index 756aab3..ae5eb4f 100644 --- a/system-design/personas-and-definitions/software-composition.md +++ b/system-design/personas-and-definitions/software-composition.md @@ -167,7 +167,7 @@ The application and contained components are typically configurable with the opt ### 2. Software Deployment -When a device gets the instruction to run an [Application][application] (over a desired-state specified with an [`ApplicationDeployment` object][deployment-definition]), its [Workload Fleet Management Agent][wfma] interacts with the [providers][provider-model]. +When a device gets the instruction to run an [Application][application] (over a desired-state specified with an [`ApplicationDeployment` object][deployment-definition]), its [Workload Fleet Management Client][wfmc] interacts with the [providers][provider-model]. That way all [Workloads][workload] needed for an [Application][application] should get started and the desired state should be reached. ```mermaid @@ -200,9 +200,9 @@ C4Context In this stage the [providers][provider-model] are responsible for managing the individual [Workloads][workload]. -On a Helm v3 [Deployment Profiles][deployment-profile], a [Workload Fleet Management Agent][wfma] implementation could utilize the Helm API to start the individual Helm Charts. +On a Helm v3 [Deployment Profiles][deployment-profile], a [Workload Fleet Management Client][wfmc] implementation could utilize the Helm API to start the individual Helm Charts. -On a Compose [Deployment Profiles][deployment-profile], a [Workload Fleet Management Agent][wfma] implementation could utilize the Compose CLI to start the individual [Workloads][workload]. +On a Compose [Deployment Profiles][deployment-profile], a [Workload Fleet Management Client][wfmc] implementation could utilize the Compose CLI to start the individual [Workloads][workload]. The following diagram shows the result of reaching the desired state for an [Application][application] with a Helm v3 [Deployment Profile][deployment-profile] (the result of `helm install`). @@ -213,7 +213,7 @@ C4Component UpdateLayoutConfig($c4BoundaryInRow="3", $c4ShapeInRow="1") System_Boundary(dev1, "Device 1") { - System_Boundary(woa1, "Workload Fleet Management Agent") { + System_Boundary(woa1, "Workload Fleet Management Client") { Component(atb1, "Application Deployment 1", "ApplicationDeployment", "YAML document") } @@ -248,7 +248,7 @@ C4Component UpdateLayoutConfig($c4BoundaryInRow="3", $c4ShapeInRow="1") System_Boundary(dev1, "Device 1") { - System_Boundary(woa1, "Workload Fleet Management Agent") { + System_Boundary(woa1, "Workload Fleet Management Client") { Component(atb1, "Application Deployment 1", "ApplicationDeployment", "YAML document") } @@ -281,5 +281,5 @@ C4Component [component-registry]: technical-lexicon.md#component-registry [deployment-definition]: ../../specification/margo-management-interface/desired-state/?h=applicationdeployment.md#applicationdeployment-definition [provider-model]: technical-lexicon.md#provider-model -[wfma]: technical-lexicon.md#workload-fleet-management-agent +[wfmc]: technical-lexicon.md#workload-fleet-management-client [deployment-profile]: ../specification/application-package/application-description.md#deploymentprofile-attributes diff --git a/system-design/personas-and-definitions/technical-lexicon.md b/system-design/personas-and-definitions/technical-lexicon.md index 89f8f36..097590a 100644 --- a/system-design/personas-and-definitions/technical-lexicon.md +++ b/system-design/personas-and-definitions/technical-lexicon.md @@ -41,7 +41,7 @@ An application is a collection of one, or more, [Components](#component), as def #### Application Package -An Application Package is used to distribute an [application](#application). The parts of an Application Package are: Application Description (that refers to contained and deployable Components) as well as associated resources (e.g., icons). While the application package is made available in an [Application Registry](./application-registry.md), the referenced [components](#component) are stored in a [Component Registry](#component-registry), and the linked containers are provided via a OCI [Container Registry](#container-registry). +An Application Package is used to distribute an [application](#application). The parts of an Application Package are: Application Description (that refers to contained and deployable Components) as well as associated resources (e.g., icons). While the application package is made available in an [Application Registry](../concepts/workloads/application-registry.md), the referenced [components](#component) are stored in a [Component Registry](#component-registry), and the linked containers are provided via a OCI [Container Registry](#container-registry). #### Component @@ -84,7 +84,7 @@ Device Fleet Manager (DFM) represents a software offering that enables End Users #### Application Registry -An [Application Registry](../concepts/workloads/application-registry.md) hosts [Application Packages](#application-package) that define, through their [Application Description](../../specification/application-package/application-description.md), the application as one or multiple [Components](#component). +An [Application Registry](../concepts/workloads/application-registry.md) hosts [Application Packages](#application-package) that define, through their [Application Description](../specification/application-package/application-description.md), the application as one or multiple [Components](#component). It is used by application developers to make their applications available. The [API of the Application Registry](../specification/application-package/application-registry.md) is compliant with the [OCI Registry API (v1.1.0)](https://github.com/opencontainers/distribution-spec/blob/v1.1.0/spec.md). @@ -102,7 +102,7 @@ An Application Catalog obtains the offered [Applications](#application) from one #### Component Registry A Component Registry holds [Components](#component) (e.g., Helm Charts and Compose Archives) for [Application Packages](#application-package). -When an application gets deployed through a [Workload Fleet Manager](#workload-fleet-manager), the components (linked within an [Application Description](../../specification/application-package/application-description.md)) are requested from the Component Registry and then deployed as [workloads](#workload). Components link to containers that are typically provided through [Container Registries](#container-registry). +When an application gets deployed through a [Workload Fleet Manager](#workload-fleet-manager), the components (linked within an [Application Description](../specification/application-package/application-description.md)) are requested from the Component Registry and then deployed as [workloads](#workload). Components link to containers that are typically provided through [Container Registries](#container-registry). The Component Registry can be implemented, e.g., as an OCI Registry. #### Container Registry diff --git a/system-design/specification/application-package/application-registry.md b/system-design/specification/application-package/application-registry.md index 6dc44c6..2961c1b 100644 --- a/system-design/specification/application-package/application-registry.md +++ b/system-design/specification/application-package/application-registry.md @@ -1,6 +1,6 @@ # Application Registry -The interactions of an `Application Registry` are described [here](../../concepts/workloads/application-registry.md) from a conceptual view. This section formally specifies the API of the `Application Registry` and the exchange of an [Application Package](./application-package-definition.md), defined through an [Application Description](../../specification/application-package/) file, from an Application Developer to the [Workload Fleet Manager](../../personas-and-definitions/technical-lexicon.md#workload-fleet-manager) (WFM). The `Application Registry` is designed as an `OCI Registry`, i.e., it offers an API compliant with the [OCI Registry API (v1.1.0)](https://github.com/opencontainers/distribution-spec/blob/v1.1.0/spec.md) (called here the "OCI_spec") for digital artifact distribution. This way, the Application Registry hosts the parts of an [Application Package](https://specification.margo.org/app-interoperability/application-package-definition/) in form of `blobs` and uses `image manifests` according to [OCI Image specification](https://github.com/opencontainers/image-spec/blob/v1.0.1/manifest.md)) to list a set of `layers`, each pointing at a blob. +The interactions of an `Application Registry` are described [here](../../concepts/workloads/application-registry.md) from a conceptual view. This section formally specifies the API of the `Application Registry` and the exchange of an [Application Package](../../concepts/workloads/application-package.md), defined through an [Application Description](../../specification/application-package/application-description.md) file, from an Application Developer to the [Workload Fleet Manager](../../personas-and-definitions/technical-lexicon.md#workload-fleet-manager) (WFM). The `Application Registry` is designed as an `OCI Registry`, i.e., it offers an API compliant with the [OCI Registry API (v1.1.0)](https://github.com/opencontainers/distribution-spec/blob/v1.1.0/spec.md) (called here the "OCI_spec") for digital artifact distribution. This way, the Application Registry hosts the parts of an [Application Package](../../concepts/workloads/application-package.md) in the form of `blobs` and uses `image manifests` according to [OCI Image specification](https://github.com/opencontainers/image-spec/blob/v1.0.1/manifest.md) to list a set of `layers`, each pointing at a blob. ## Overview of API Endpoints @@ -14,8 +14,8 @@ The WFM MUST interact with the Application Registry compliant to the OCI Registr Further details on how to use these API endpoints are specified below [towards App Developer](#uploading-an-application-package) and [towards WFM](#retrieving-an-application-package). -## Authentication & Authorization & Security -Margo recommends the use of an Authentication Service within the interaction of WFM and Application Registry as conceptually described [here](../../concepts/workloads/application-registry.md), e.g., implemented using OAuth 2.0. This involves the following workflow: +## Authentication, Authorization & Security +Margo recommends the use of an Authentication Service for the interactions between the WFM and Application Registry as conceptually described [here](../../concepts/workloads/application-registry.md), e.g., implemented using OAuth 2.0. This involves the following workflow: * WFM obtains credentials during onboarding * WFM requests a token from an Authentication Service @@ -24,7 +24,7 @@ Margo recommends the use of an Authentication Service within the interaction of Thereby, all communications must use TLS 1.3+ to ensure transport security. -> Note: Authentication & Authorization & Security mechanisms should be defined centrally and homogeneously across margo. Hence, it is not further defined here. +> Note: Authentication, Authorization & Security mechanisms should be defined centrally and homogeneously across Margo. Hence, it is not further defined here. Further, tools such as [cosign](https://github.com/sigstore/cosign) may be employed for signing artifacts uploaded to the Application Registry and storing the signatures alongside the artifacts they verify. @@ -32,11 +32,11 @@ Further, tools such as [cosign](https://github.com/sigstore/cosign) may be emplo ## Uploading an Application Package -As shown in the sequence diagram below, the Application Developer uploads the margo-compliant `Application Package` to the Application Registry. I.e., all parts of the Application Package MUST be pushed as blobs compliant with the [end-4a / end-4b](https://github.com/opencontainers/distribution-spec/blob/v1.1.0/spec.md#endpoints) endpoints of the OCI_spec. +As shown in the sequence diagram below, the Application Developer uploads the Margo-compliant `Application Package` to the Application Registry. I.e., all parts of the Application Package MUST be pushed as blobs compliant with the [end-4a / end-4b](https://github.com/opencontainers/distribution-spec/blob/v1.1.0/spec.md#endpoints) endpoints of the OCI_spec. -Subsequently, the Application Developer creates an OCI image manifest that lists layers of which each links to an uploaded blob. Then the manifest MUST be pushed to the Application Registry compliant to the [end-7](https://github.com/opencontainers/distribution-spec/blob/v1.1.0/spec.md#endpoints) endpoint of the OCI_spec. +Subsequently, the Application Developer creates an OCI image manifest that lists layers, each of which links to an uploaded blob. Then the manifest MUST be pushed to the Application Registry compliant to the [end-7](https://github.com/opencontainers/distribution-spec/blob/v1.1.0/spec.md#endpoints) endpoint of the OCI_spec. -The uploaded OCI image manifest MUST be adhering to the margo-specific constraints detailed [here](#manifest-as-response-from-application-registry). +The uploaded OCI image manifest MUST adhere to the Margo-specific constraints detailed [here](#oci-image-manifest-as-response-from-application-registry). Subsequently, the App Developer uses a UI or other vendor-specific mechanism to communicate (either directly or indirectly, e.g. via a Marketplace) to the WFM the namespace of the Application Package's repository. @@ -52,7 +52,7 @@ sequenceDiagram AppDeveloper->>+WFM: Application Package location is: repository name in Application Registry ``` -There are no further margo-specific constraints regarding the upload of the Application Package. The details defined in the [OCI_spec](https://github.com/opencontainers/distribution-spec/blob/v1.1.0/spec.md) MUST be applied to this interface of the Application Registry. +There are no further Margo-specific constraints regarding the upload of the Application Package. The details defined in the [OCI_spec](https://github.com/opencontainers/distribution-spec/blob/v1.1.0/spec.md) MUST be applied to this interface of the Application Registry. @@ -60,7 +60,7 @@ There are no further margo-specific constraints regarding the upload of the Appl The WFM has received the namespace of the repository of the Application Package at the Application Registry. -Next, as shown in the sequence diagram below, the WFM uses the API endpoints defined in the OCI_spec to retrieve a list of Application Package versions (as detailed [here](#list-margo-application-package-versions)). +Next, as shown in the sequence diagram below, the WFM uses the API endpoints defined in the OCI_spec to retrieve a list of Application Package versions (as detailed [here](#list-Margo-application-package-versions)). Then, the WFM pulls the OCI image manifest of the selected version of the Application Package, with the identifying reference being a tag or digest (as detailed [here](#pull-oci-image-manifest-of-application-package)). @@ -80,13 +80,13 @@ sequenceDiagram WFM->>AppRegistry: GET /v2/{name}/blobs/{digest} ``` -### List margo Application Package Versions +### List Margo Application Package Versions The interface to retrieve the list of versions of an Application Package MUST be implemented according to OCI_spec endpoint [end-8a](https://github.com/opencontainers/distribution-spec/blob/v1.1.0/spec.md#endpoints). To get a list of available versions of an Application Package, an HTTP ``GET`` request to a resource path MUST be performed in the following format: `/v2/{name}/tags/list`. The `{name}` variable is the namespace of the Application Package repository, which was communicted by the App Developer to the WFM vendor. -The HTTP headers of the ``GET`` request MAY include ```Authorization: Bearer ``` for including the interaction with the [Authentication Service](/specification/system-design/concepts/workloads/application-registry.md). +The HTTP headers of the ``GET`` request MAY include ```Authorization: Bearer ``` for including the interaction with the [Authentication Service](../../concepts/workloads/application-registry.md). To query a subset of tags, the following query parameters MUST be implemented by the Application Registry as defined by OCI_spec endpoint [end-8b](https://github.com/opencontainers/distribution-spec/blob/v1.1.0/spec.md#endpoints): @@ -145,10 +145,10 @@ The interface to retrieve the OCI image manifest of a specified version, which b To pull an Application Package, an HTTP ``GET`` request to a resource path MUST be performed in the following format: `/v2/{name}/manifests/{reference}`. -The `{reference}` is the `tag` of an OCI image manifest. The `tag` has been discovered via the [listing of app versions](#list-margo-application-versions). +The `{reference}` is the `tag` of an OCI image manifest. The `tag` has been discovered via the [listing of application package versions](#list-margo-application-package-versions). The `{name}` variable is the namespace of the Application Package repository. -The HTTP headers of the ``GET`` request MAY include ```Authorization: Bearer ``` for including the interaction with the [Authentication Service](/specification/system-design/concepts/workloads/application-registry.md). +The HTTP headers of the ``GET`` request MAY include ```Authorization: Bearer ``` for including the interaction with the [Authentication Service](../../concepts/workloads/application-registry.md). #### OCI Image Manifest as Response from Application Registry: @@ -166,16 +166,16 @@ Each element of the ``layers`` array contains a reference (so called `digests`) Each Application Package part must be listed as an element of the ``layers`` array: -* The [Application Description](https://specification.margo.org/margo-api-reference/workload-api/application-package-api/application-description/) of the Application Package must be referred to in one element of the ``layers`` array, where the ``mediaType`` of this layer/blob must be ``application/vnd.margo.app.description.v1+yaml``. -* Each [application resource](https://specification.margo.org/app-interoperability/application-package-definition/), which is an additional file associated with the application (e.g., manual, icon, release notes, license file, etc.), must be referred to in an element of the ``layers`` array. Such a layer must have an ``annotation``, which has the annotation key ``org.margo.app.resource``, and the annotation value must reflect the dotted path to the this resource in the [Application Description file](https://specification.margo.org/margo-api-reference/workload-api/application-package-api/application-description/). E.g., an application icon stored as the file ``resources/margo.jpg`` is referenced in the Application Description under ``metadata.catalog.application.icon: resources/margo.jpg`` and in the OCI image manifest, the respective layer of the icon resource has the annotation ``org.margo.app.resource`` with the value ``metadata.catalog.application.icon`` (see also OCI image manifest example below). +* The [Application Description](../../specification/application-package/application-description.md) of the Application Package must be referred to in one element of the ``layers`` array, where the ``mediaType`` of this layer/blob must be ``application/vnd.margo.app.description.v1+yaml``. +* Each [application resource](../../concepts/workloads/application-package.md), which is an additional file associated with the application (e.g., manual, icon, release notes, license file, etc.), must be referred to in an element of the ``layers`` array. Such a layer must have an ``annotation``, which has the annotation key ``org.margo.app.resource``, and the annotation value must reflect the dotted path to the this resource in the [Application Description file](../../specification/application-package/application-description.md). E.g., an application icon stored as the file ``resources/margo.jpg`` is referenced in the Application Description under ``metadata.catalog.application.icon: resources/margo.jpg`` and in the OCI image manifest, the respective layer of the icon resource has the annotation ``org.margo.app.resource`` with the value ``metadata.catalog.application.icon`` (see also OCI image manifest example below). -The following response example is a margo-specific OCI image manifest following the [OCI Image Manifest Specification](https://github.com/opencontainers/image-spec/blob/v1.0.1/manifest.md) and the above defined specifics: +The following response example is a Margo-specific OCI image manifest following the [OCI Image Manifest Specification](https://github.com/opencontainers/image-spec/blob/v1.0.1/manifest.md) and the above defined specifics: ```json { "schemaVersion": 2, "mediaType": "application/vnd.oci.image.manifest.v1+json", - "artifactType": "application/vnd.margo.app.v1+json" # this MUST be the artifactType of en OCI image manifest of a margo Application Package, + "artifactType": "application/vnd.margo.app.v1+json" # this MUST be the artifactType of en OCI image manifest of a Margo Application Package, "config": { "mediaType": "application/vnd.oci.empty.v1+json", # the 'config' object MUST be empty "digest": "sha256:44136fa355b3678a1146ad16f7e8649e94fb4fc21fe77e8310c060f61caaff8a", @@ -184,7 +184,7 @@ The following response example is a margo-specific OCI image manifest following }, "layers": [ { - "mediaType": "application/vnd.margo.app.description.v1+yaml", # this MUST be the artifactType of a margo Application Description file + "mediaType": "application/vnd.margo.app.description.v1+yaml", # this MUST be the artifactType of a Margo Application Description file "digest": "sha256:f6b79149e6650b0064c146df7c045d157f3656b5ad1279b5ce9f4446b510bacf", "size": 999, "annotations": { @@ -196,7 +196,7 @@ The following response example is a margo-specific OCI image manifest following "digest": "sha256:e373b123782a2b52483a9124cc9c578e0ed0300cb4131b73b0c79612122b8361", "size": 1596, "annotations": { - "org.margo.app.resource": "metadata.catalog.application.descriptionFile", # each margo application resource MUST be annotated with a dotted path to its definition in the Application Description file + "org.margo.app.resource": "metadata.catalog.application.descriptionFile", # each Margo application resource MUST be annotated with a dotted path to its definition in the Application Description file "org.opencontainers.image.title": "resources/description.md" } }, @@ -205,7 +205,7 @@ The following response example is a margo-specific OCI image manifest following "digest": "sha256:af7db4ab9030533b6cda2325247920c3659bc67a7d49f3d5098ae54a64633ec7", "size": 25, "annotations": { - "org.margo.app.resource": "metadata.catalog.application.licenseFile", # each margo application resource MUST be annotated with a dotted path to its definition in the Application Description file + "org.margo.app.resource": "metadata.catalog.application.licenseFile", # each Margo application resource MUST be annotated with a dotted path to its definition in the Application Description file "org.opencontainers.image.title": "resources/license.md" } }, @@ -214,7 +214,7 @@ The following response example is a margo-specific OCI image manifest following "digest": "sha256:451410b6adfdce1c974da2275290d9e207911a4023fafea0e283fad0502e5e56", "size": 5065, "annotations": { - "org.margo.app.resource": "metadata.catalog.application.icon", # each margo application resource MUST be annotated with a dotted path to its definition in the Application Description file + "org.margo.app.resource": "metadata.catalog.application.icon", # each Margo application resource MUST be annotated with a dotted path to its definition in the Application Description file "org.opencontainers.image.title": "resources/margo.jpg" } }, @@ -223,7 +223,7 @@ The following response example is a margo-specific OCI image manifest following "digest": "sha256:c412d143084c3b051d7ea4b166a7bfffb4550f401d89cae8898991c65e90f736", "size": 42, "annotations": { - "org.margo.app.resource": "metadata.catalog.application.releaseNotes", # each margo application resource MUST be annotated with a dotted path to its definition in the Application Description file + "org.margo.app.resource": "metadata.catalog.application.releaseNotes", # each Margo application resource MUST be annotated with a dotted path to its definition in the Application Description file "org.opencontainers.image.title": "resources/release-notes.md" } } @@ -235,25 +235,25 @@ The following response example is a margo-specific OCI image manifest following |Media Type|Description| |----------|----------| -|``application/vnd.margo.app.v1+json`` | MUST be used as the **artifactType** to mark the OCI image manifest as the definition of a margo Application Package | -|``application/vnd.margo.app.description.v1+yaml`` | MUST be used to mark a layer in the OCI image manifest as pointing to the margo Application Description file | +|``application/vnd.margo.app.v1+json`` | MUST be used as the **artifactType** to mark the OCI image manifest as the definition of a Margo Application Package | +|``application/vnd.margo.app.description.v1+yaml`` | MUST be used to mark a layer in the OCI image manifest as pointing to the Margo Application Description file | #### Margo-Specific Annotation Keys |Annotation Key | Description| |----------|----------| -|``org.margo.app.resource`` | This MUST be used to annotate a layer/blob that references a margo application resource | +|``org.margo.app.resource`` | MUST be used to annotate a layer/blob that references a Margo application resource | ### Get Parts of Application Package -The interface to retrieve Application Package parts, i.e., Application Description or Appliction Resource (e.g., icon, license, etc.), MUST be implemented according to OCI_spec endpoint [end-2](https://github.com/opencontainers/distribution-spec/blob/v1.1.0/spec.md#endpoints) by pulling a blob. +The interface to retrieve Application Package parts, i.e., Application Description or Application Resource (e.g., icon, license, etc.), MUST be implemented according to OCI_spec endpoint [end-2](https://github.com/opencontainers/distribution-spec/blob/v1.1.0/spec.md#endpoints) by pulling a blob. To pull such a blob, an HTTP ``GET`` request to a resource path MUST be performed in the following format: `/v2/{name}/blobs/{digest}`. -The `{digest}` is the blobs digest as listed in the application's OCI image manifest that has been [retrieved earlier](#pull-margo-application-manifest). +The `{digest}` is the blob's digest as listed in the application's OCI image manifest that has been [retrieved earlier](#pull-oci-image-manifest-of-application-package). The `{name}` variable is the namespace of the Application Package repository. -The HTTP headers of the ``GET`` request MAY include ```Authorization: Bearer ``` for including the interaction with the [Authentication Service](/specification/system-design/concepts/workloads/application-registry.md). +The HTTP headers of the ``GET`` request MAY include ```Authorization: Bearer ``` for including the interaction with the [Authentication Service](../../concepts/workloads/application-registry.md). From 59620e55c4b4c8250c86911ca0a0cc20f31c06f1 Mon Sep 17 00:00:00 2001 From: Arne Broering Date: Fri, 7 Nov 2025 16:00:16 +0100 Subject: [PATCH 15/29] addressing PR review comments Signed-off-by: Arne Broering --- .../concepts/workloads/application-registry.md | 6 +++--- .../application-package/application-registry.md | 14 +++++++------- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/system-design/concepts/workloads/application-registry.md b/system-design/concepts/workloads/application-registry.md index 581c655..2b14375 100644 --- a/system-design/concepts/workloads/application-registry.md +++ b/system-design/concepts/workloads/application-registry.md @@ -1,15 +1,15 @@ # Application Registry -The margo specification differentiates 4 kinds of registries: *Application Registries*, *Component Registries*, and *Container Registries* as well as *Marketplaces*. +The Margo specification differentiates 4 kinds of registries: *Application Registries*, *Component Registries*, and *Container Registries* as well as *Marketplaces*. 1. An **Application Registry** hosts Application Packages that define through their [Application Description](../../specification/application-package/application-description.md) the application as one or multiple [Components](../../personas-and-definitions/technical-lexicon.md#component). 2. A **Component Registry** hosts the [Components](../../personas-and-definitions/technical-lexicon.md#component) (which are deployable as *workloads*) and are provided as **Helm Charts** or **Compose Archives**. 3. A **Container Registry** hosts container images referenced by those Components. 4. A **Marketplace** lists applications to advertise them and enable purchasing for end users. -Out of these 4 registries, **only the Application Registry interface is in scope** of the margo specification and its API definition can be found [here](../../specification/application-package/application-registry.md). +Out of these 4 registries, **only the Application Registry interface is in scope** of the Margo specification and its API definition can be found [here](../../specification/application-package/application-registry.md). -The diagram below illustrates these functionalities and relationships of registries within margo. +The diagram below illustrates these functionalities and relationships of registries within Margo. ```mermaid flowchart diff --git a/system-design/specification/application-package/application-registry.md b/system-design/specification/application-package/application-registry.md index 2961c1b..c9cdc05 100644 --- a/system-design/specification/application-package/application-registry.md +++ b/system-design/specification/application-package/application-registry.md @@ -38,7 +38,7 @@ Subsequently, the Application Developer creates an OCI image manifest that lists The uploaded OCI image manifest MUST adhere to the Margo-specific constraints detailed [here](#oci-image-manifest-as-response-from-application-registry). -Subsequently, the App Developer uses a UI or other vendor-specific mechanism to communicate (either directly or indirectly, e.g. via a Marketplace) to the WFM the namespace of the Application Package's repository. +Subsequently, the App Developer uses a UI or other vendor-specific mechanism to communicate (either directly or indirectly, e.g., via a Marketplace) to the WFM the namespace of the Application Package's repository. ```mermaid sequenceDiagram @@ -71,7 +71,7 @@ sequenceDiagram Note over WFM: retrieve available versions of an Application Package: WFM->>+AppRegistry: GET /v2/{name}/tags/list - Note over WFM: retrieves the OCI image manifest of the selected Application Package version. {reference} is tag or digest.: + Note over WFM: retrieves the OCI image manifest of the selected Application Package version. {reference} is a tag or a digest: WFM->>+AppRegistry: GET /v2/{name}/manifests/{reference} AppRegistry-->>+WFM: OCI image manifest @@ -84,7 +84,7 @@ sequenceDiagram The interface to retrieve the list of versions of an Application Package MUST be implemented according to OCI_spec endpoint [end-8a](https://github.com/opencontainers/distribution-spec/blob/v1.1.0/spec.md#endpoints). -To get a list of available versions of an Application Package, an HTTP ``GET`` request to a resource path MUST be performed in the following format: `/v2/{name}/tags/list`. The `{name}` variable is the namespace of the Application Package repository, which was communicted by the App Developer to the WFM vendor. +To get a list of available versions of an Application Package, an HTTP ``GET`` request to a resource path MUST be performed in the following format: `/v2/{name}/tags/list`. The `{name}` variable is the namespace of the Application Package repository, which was communicated by the App Developer to the WFM vendor. The HTTP headers of the ``GET`` request MAY include ```Authorization: Bearer ``` for including the interaction with the [Authentication Service](../../concepts/workloads/application-registry.md). @@ -93,7 +93,7 @@ To query a subset of tags, the following query parameters MUST be implemented by * ``n=`` (optional, limits results to n tags) * ``last=`` (optional, starts list of tags after ````) -The response of the HTTP ``GET`` request according to [end-8a/end-8b](https://github.com/opencontainers/distribution-spec/blob/v1.1.0/spec.md#endpoints) is a list of tags, which comply with the versions of available Application Packages. According to OCI_spec, upon success, the response MUST be a json body in the following format: +The response of the HTTP ``GET`` request according to [end-8a/end-8b](https://github.com/opencontainers/distribution-spec/blob/v1.1.0/spec.md#endpoints) is a list of tags, which comply with the versions of available Application Packages. According to OCI_spec, upon success, the response MUST be a JSON body in the following format: ```json { @@ -152,7 +152,7 @@ The HTTP headers of the ``GET`` request MAY include ```Authorization: Bearer Date: Fri, 7 Nov 2025 16:56:17 +0100 Subject: [PATCH 16/29] renamed the files & folders which were renamed in the nav Signed-off-by: Arne Broering --- .github/workflows/pages.yml | 2 +- .gitignore | 4 +- .../application-package-api.json | 2 +- mkdocs.yml | 12 +- .../application-description.linkml.yaml | 766 ------------------ .../resources/class.md.jinja2 | 0 .../valid/ApplicationDescription-001.yaml | 59 -- .../valid/ApplicationDescription-002.yaml | 208 ----- .../resources/index.md.jinja2 | 157 ---- .../concepts/workloads/application-package.md | 43 - .../workloads/application-registry.md | 44 - .../concepts/workloads/local-registries.md | 88 -- system-design/overview/workloads.md | 78 -- .../software-composition.md | 6 +- .../technical-lexicon.md | 10 +- .../application-package/.gitkeep | 0 .../application-registry.md | 259 ------ 17 files changed, 18 insertions(+), 1720 deletions(-) delete mode 100644 src/specification/application-package/application-description.linkml.yaml delete mode 100644 src/specification/application-package/resources/class.md.jinja2 delete mode 100644 src/specification/application-package/resources/examples/valid/ApplicationDescription-001.yaml delete mode 100644 src/specification/application-package/resources/examples/valid/ApplicationDescription-002.yaml delete mode 100644 src/specification/application-package/resources/index.md.jinja2 delete mode 100644 system-design/concepts/workloads/application-package.md delete mode 100644 system-design/concepts/workloads/application-registry.md delete mode 100644 system-design/concepts/workloads/local-registries.md delete mode 100644 system-design/overview/workloads.md delete mode 100644 system-design/specification/application-package/.gitkeep delete mode 100644 system-design/specification/application-package/application-registry.md diff --git a/.github/workflows/pages.yml b/.github/workflows/pages.yml index e722042..fb22756 100644 --- a/.github/workflows/pages.yml +++ b/.github/workflows/pages.yml @@ -99,7 +99,7 @@ jobs: with: name: generated-documentation path: | - system-design/specification/application-package/application-description.md + system-design/specification/applications/application-description.md system-design/specification/margo-management-interface/desired-state.md pages: diff --git a/.gitignore b/.gitignore index e228571..d687d21 100644 --- a/.gitignore +++ b/.gitignore @@ -6,7 +6,7 @@ myenv # Ignore the generated files: system-design/specification/margo-management-interface/desired-state.md -system-design/specification/application-package/application-description.md -src/specification/application-package/docs +system-design/specification/applications/application-description.md +src/specification/applications/docs src/specification/margo-management-interface/docs *.code-workspace diff --git a/doc-generation/configurations/application-package-api.json b/doc-generation/configurations/application-package-api.json index fdc1e0c..c6fe0e4 100644 --- a/doc-generation/configurations/application-package-api.json +++ b/doc-generation/configurations/application-package-api.json @@ -1,5 +1,5 @@ { - "root": "src/specification/application-package", + "root": "src/specification/applications", "targetclass": "ApplicationDescription", "schemafile": "application-description.linkml.yaml", "markdowndoc": "application-description.md" diff --git a/mkdocs.yml b/mkdocs.yml index 4232048..437ba6a 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -10,15 +10,15 @@ nav: - personas-and-definitions/software-composition.md - Overview: - overview/envisioned-system-design.md - - overview/workloads.md + - overview/applications-and-workloads.md - overview/workload-fleet-management.md - overview/edge-compute-devices.md - overview/workload-observability.md - Concepts: - Applications: - - concepts/workloads/application-package.md - - concepts/workloads/application-registry.md - - concepts/workloads/local-registries.md + - concepts/applications/application-package.md + - concepts/applications/application-registry.md + - concepts/applications/local-registries.md - Workload Fleet Managers: - concepts/workload-fleet-managers/device-capabilities.md - concepts/workload-fleet-managers/workload-deployment.md @@ -33,8 +33,8 @@ nav: - specification/margo-management-interface/desired-state.md - specification/margo-management-interface/deployment-status.md - Applications: - - specification/application-package/application-description.md - - specification/application-package/application-registry.md + - specification/applications/application-description.md + - specification/applications/application-registry.md - Margo Devices: - specification/margo-devices/device-requirements.md - Observability: diff --git a/src/specification/application-package/application-description.linkml.yaml b/src/specification/application-package/application-description.linkml.yaml deleted file mode 100644 index c95170b..0000000 --- a/src/specification/application-package/application-description.linkml.yaml +++ /dev/null @@ -1,766 +0,0 @@ -# yaml-language-server: $schema=https://linkml.io/linkml-model/linkml_model/jsonschema/meta.schema.json -id: http://specification.margo.org/application-schema -name: ApplicationDescription -title: Application Description Schema -description: >- - Schema for defining application metadata, deployment profiles, parameters, and configuration. - The purpose of this file is to present the application on an application catalog or marketplace - from where an end user selects the application to hand it over to the Workload Orchestration Software, - which configures it and makes it available for installation on the edge device. -version: 1.0 -prefixes: - linkml: https://w3id.org/linkml/ - margo: https://specification.margo.org/ -imports: - - linkml:types - -default_prefix: margo - - -# Class Definitions -classes: - ApplicationDescription: - description: Root class for an application description. - attributes: - apiVersion: - description: Identifier of the version of the API the object definition follows. - required: true - range: string - rank: 10 - kind: - description: Specifies the object type; must be `ApplicationDescription`. - range: string - required: true - equals_string: "ApplicationDescription" - rank: 20 - metadata: - description: >- - Metadata element specifying characteristics about the application deployment. - See the [Metadata Attributes](#metadata-attributes) section below. - range: Metadata - required: true - rank: 30 - deploymentProfiles: - description: >- - Deployment profiles element specifying the types of deployments the application supports. - See the [Deployment](#deploymentprofile-attributes) section below. - range: DeploymentProfile - multivalued: true - inlined: true - inlined_as_list: true - required: true - rank: 40 - parameters: - description: >- - Parameters element specifying the configurable parameters to use when installing, or updating, the application. - See the [Parameter](#parameter-attributes) section below. - range: Parameter - multivalued: true - inlined: true - inlined_as_list: false - rank: 50 - configuration: - description: >- - Configuration element specifying how parameters should be displayed to the user for setting the value - as well as the rules to use to validate the user's input. - See the [Configuration](#configuration-attributes) section below. - range: Configuration - rank: 60 - - Metadata: - description: Metadata about the application. - rank: 10 - attributes: - id: - description: >- - An identifier for the application. The id is used to help create unique identifiers where required, - such as namespaces. The id must be lower case letters and numbers and MAY contain dashes. - Uppercase letters, underscores and periods MUST NOT be used. The id MUST NOT be more than 200 characters. - rank: 10 - range: string - required: true - pattern: ^[a-z0-9-]{1,200}$ - name: - description: >- - The application's official name. - This name is for display purposes only and can container whitespace and special characters. - rank: 20 - range: string - required: true - description: - range: string - rank: 25 - version: - description: The application's version. - rank: 30 - range: string - required: true - catalog: - description: >- - Catalog element specifying the application catalog details used to display the application - in an application catalog or marketplace. - See the [Catalog](#catalog-attributes) section below. - rank: 40 - range: Catalog - required: true - - Catalog: - description: Catalog metadata for displaying the application. - rank: 20 - attributes: - application: - description: >- - Application element specifying the application specific metadata. - See the [Application Metadata](#applicationmetadata-attributes) section below. - rank: 10 - range: ApplicationMetadata - author: - description: >- - Author element specifying metadata about the application's author. - See the [Author Metadata](#author-attributes) section below. - rank: 20 - range: Author - multivalued: true - inlined: true - inlined_as_list: true - organization: - description: >- - Organization element specifying metadata about the organization/company providing the application. - See the [Organization Metadata](#organization-attributes) section below. - rank: 30 - range: Organization - multivalued: true - required: true - inlined: true - inlined_as_list: true - - ApplicationMetadata: - description: Metadata specific to the application. - rank: 30 - attributes: - descriptionFile: - description: Link to the file containing the application's full description. The file should be a markdown file. - rank: 10 - range: string - icon: - description: Link to the icon file (e.g., in PNG format). - rank: 20 - range: string - licenseFile: - description: Link to the file that details the application's license. The file should either be a plain text, markdown or PDF file. - rank: 30 - range: string - releaseNotes: - description: Statement about the changes for this application's release. The file should either be a markdown or PDF file. - rank: 40 - range: string - site: - description: Link to the application's website. - rank: 50 - range: string - tagline: - description: The application's slogan. - rank: 60 - range: string - tags: - description: An array of strings that can be used to provide additional context for the application in a user interface to assist with task such as categorizing, searching, etc. - rank: 70 - range: string - multivalued: true - inlined: true - inlined_as_list: true - - Author: - description: Information about the application's author. - rank: 40 - attributes: - name: - description: The name of the application's creator. - rank: 10 - range: string - email: - description: Email address of the application's creator. - rank: 20 - range: string - pattern: .*@[a-z0-9.-]* - - Organization: - description: Information about the providing organization. - rank: 50 - attributes: - name: - description: Organization responsible for the application's development and distribution. - rank: 10 - range: string - required: true - site: - description: Link to the organization's website. - rank: 20 - range: string - - DeploymentProfile: - description: Represents a deployment configuration for the application. - rank: 60 - attributes: - id: - description: >- - An identifier for the deployment profile, given by the application developer, used to uniquely identify this deployment profile from others within this application description's scope. - rank: 10 - range: string - required: true - description: - description: >- - This human-readable description of a deployment profile allows for providing additional context about the deployment profile. E.g., the application developer can use this to describe the deployment profile's purpose, - such as the intended use case. Additionally, the application developer can use this to provide further details about the resources, peripherals, and interfaces required to run the application. - rank: 20 - range: string - required: false - requiredResources: - description: >- - Required resources element specifying the resources required to install the application. - See the [Required Resources](#requiredresources-attributes) section below. - The consequences (e.g., aborting / blocking the installation or execution of the application) of not meeting these required resources are not defined (yet) by margo. - rank: 30 - range: RequiredResources - required: false - slots: - - type - - components - - RequiredResources: - description: >- - Required resources element specifying the resources required to install the application. - rank: 61 - attributes: - cpu: - description: >- - CPU element specifying the CPU requirements for the application. - See the [CPU](#cpu-attributes) section below. - range: CPU - required: false - rank: 10 - memory: - description: The minimum amount of memory required. - The value is given in binary units (`Ki` = Kibibytes, `Mi` = Mebibytes, `Gi` = Gibibytes). - This is defined by the application developer. - After deployment of the application, the device MUST provide this amount of memory for the application. - rank: 20 - range: string - pattern: ^[0-9]+(Mi|Gi|Ki)$ - required: false - storage: - description: The amount of storage required for the application to run. This encompasses the installed application and the data it needs to store. - The value is given in binary units (`Ki` = Kibibytes, `Mi` = Mebibytes, `Gi` = Gibibytes, `Ti` Tebibytes, `Pi` = Pebibytes, `Ei` = Exbibytes). - This is defined by the application developer. - After deployment of the application, the device MUST provide this amount of storage for the application - rank: 30 - range: string - pattern: ^[0-9]+(Mi|Gi|Ki|Ti|Pi|Ei)$ - required: false - peripherals: - description: >- - Peripherals element specifying the peripherals required to run the application. - See the [Peripheral](#peripheral-attributes) section below. - range: Peripheral - rank: 40 - multivalued: true - inlined: true - inlined_as_list: true - required: false - interfaces: - description: >- - Interfaces element specifying the communication interfaces required to run the application. - See the [Communication Interfaces](#communicationinterface-attributes) section below. - range: CommunicationInterface - rank: 40 - multivalued: true - inlined: true - inlined_as_list: true - required: false - - CPU: - description: >- - CPU element specifying the CPU requirements for the application. - rank: 62 - attributes: - cores: - description: The required amount of CPU cores the application must use to run in its full functionality. - Specified as decimal units of CPU cores (e.g., `0.5` is half a core). - This is defined by the application developer. - After deployment of the application, the device MUST provide this number of CPU cores for the application. - rank: 10 - range: double - required: true - architectures: - description: The CPU architectures supported by the application. This can be e.g. amd64, x86_64, arm64, arm. - See the [CpuArchitectureType](#cpuarchitecturetype) definition for all permissible values. - Multiple arcitecture types can be specified, as the deployment profile may support multiple CPU architectures. - rank: 20 - range: CpuArchitectureType - required: false - multivalued: true - inlined: true - inlined_as_list: true - - Peripheral: - description: Peripheral hardware of a device. - rank: 65 - attributes: - type: - description: The type of peripheral. This can be e.g. GPU, display, camera, microphone, speaker. - See the [PeriperalType](#peripheraltype) definition for all permissible values. - rank: 20 - range: PeripheralType - required: true - manufacturer: - description: The name of the manufacturer. If `manufacturer` is specified as a requirement here, it may be difficult to find devices that can host the application. Please use these requirements with caution. - rank: 30 - range: string - required: false - model: - description: The model of the peripheral. If `model` is specified as a requirement here, it may be difficult to find devices that can host the application. Please use these requirements with caution. - rank: 40 - range: string - required: false - - CommunicationInterface: - description: >- - Communication interface of a device. - rank: 66 - attributes: - type: - description: The type of a communication interface. This can be e.g. Ethernet, WiFi, Cellular, Bluetooth, USB, CANBus, RS232. - See the [CommunicationInterfaceType](#communicationinterfacetype) definition for all permissible values. - rank: 30 - range: CommunicationInterfaceType - required: true - - HelmDeploymentProfile: - is_a: DeploymentProfile - #rank: 63 - slot_usage: - type: - equals_string: "helm.v3" - rank: 10 - components: - range: HelmComponent - rank: 20 - - ComposeDeploymentProfile: - is_a: DeploymentProfile - #rank: 66 - slot_usage: - type: - equals_string: "compose" - rank: 10 - components: - range: ComposeComponent - rank: 20 - - Component: - description: A class representing a component of a deployment profile. - rank: 70 - attributes: - name: - description: >- - A unique name used to identify the component package. For helm installations the name will be used as the chart name. - The name must be lower case letters and numbers and MAY contain dashes. - Uppercase letters, underscores and periods MUST NOT be used. - required: true - range: string - rank: 10 - properties: - description: >- - A dictionary element specifying the component packages's deployment details. - See the [Component Properties](#componentproperties-attributes) section below. - range: ComponentProperties - required: true - rank: 20 - - HelmComponent: - is_a: Component - #rank: 73 - - ComposeComponent: - is_a: Component - #rank: 76 - - ComponentProperties: - description: Properties dictionary for component deployment details. - rank: 80 - attributes: - repository: - description: Repository location for the component. - rank: 10 - range: string - revision: - description: Revision version for the component. - rank: 20 - range: string - wait: - description: If True, indicates the device waits for the component installation to complete. - rank: 30 - range: boolean - timeout: - description: Time to wait for component installation to complete, formatted as "##m##s". - rank: 40 - range: string - packageLocation: - description: URL indicating the Compose package's location. - rank: 50 - range: string - keyLocation: - description: URL for the public key used to validate a digitally signed package. - rank: 60 - range: string - - Parameter: - description: Defines a configurable parameter for the application. - rank: 90 - attributes: - name: - description: Name of the parameter. - rank: 10 - identifier: true - required: true - range: string - value: - description: >- - The parameter's default value. - Accepted data types are string, integer, double, boolean, array[string], array[integer], array[double], array[boolean]. - rank: 20 - any_of: #support for arrays still TBD - - range: boolean - - range: integer - - range: double - - range: string - targets: - description: >- - Used to indicate which component the value should be applied to when installing, or updating, the application. - See the [Target](#target-attributes) section below. - rank: 30 - range: Target - required: true - multivalued: true - inlined: true - inlined_as_list: true - - Target: - description: Specifies where the parameter applies in the deployment. - rank: 100 - attributes: - pointer: - description: >- - The name of the parameter in the deployment configuration. - For Helm deployments, this is the dot notation for the matching element in the `values.yaml` file. This follows the same naming convention you would use with the `--set` command line argument with the `helm install` command. - For compose deployments, this is the name of the environment variable to set. - rank: 10 - range: string - required: true - components: - description: >- - Indicates which deployment profile [component](#component-attributes the parameter target applies to. - The component name specified here MUST match a component name in the [deployment profiles](#deploymentprofile-attributes) section. - rank: 20 - range: string - multivalued: true - required: true - - Configuration: - description: Configuration layout and validation rules. - rank: 110 - attributes: - sections: - description: >- - Sections are used to group related parameters together, - so it is possible to present a user interface with a logical grouping of the parameters in each section. - See the [Section](#section-attributes) section below. - rank: 10 - range: Section - multivalued: true - inlined: true - inlined_as_list: true - required: true - schema: - description: >- - Schema is used to provide details about how to validate each parameter value. - At a minimum, the parameter value must be validated to match the schema's data type. - The schema indicates additional rules the provided value must satisfy to be considered valid input. - See the [Schema](#schema-attributes) section below. - rank: 20 - range: Schema - multivalued: true - inlined: true - inlined_as_list: true - required: true - - Section: - description: Named sections within the configuration layout. - rank: 120 - attributes: - name: - description: >- - The name of the section. This may be used in the user interface to show the grouping of the associated parameters within the section. - rank: 10 - range: string - required: true - settings: - description: >- - Settings are used to provide instructions to the workload orchestration software vendor for displaying parameters to the user. - A user MUST be able to provide values for all settings. - See the [Setting](#setting-attributes) section below. - rank: 20 - range: Setting - multivalued: true - inlined: true - inlined_as_list: true - required: true - - Setting: - description: Individual configuration settings. - rank: 130 - attributes: - parameter: - description: The name of the [parameter](#parameter-attributes) the setting is associated with. - rank: 10 - range: string - required: true - name: - description: The parameter's display name to show in the user interface. - rank: 20 - range: string - required: true - description: - description: The parameters's short description to provide additional context to the user in the user interface about what the parameter is for. - rank: 30 - range: string - immutable: - description: If true, indicates the parameter value MUST not be changed once it has been set and used to install the application. Default is false if not provided. - rank: 40 - range: boolean - schema: - description: The name of the schema definition to use to validate the parameter's value. See the [Schema](#schema-attributes) section below. - rank: 50 - range: string - required: true - - Schema: - description: Defines data type and rules for validating user provided parameter values. Subclasses (see below) define for each data type their own set of validation rules that can be used. The value MUST be validated against all rules defined in the schema. - rank: 140 - attributes: - name: - description: The name of the schema rule. This used in the [setting](#setting-attributes) to link the setting to the schema rule. - rank: 10 - range: string - required: true - dataType: - description: >- - Indicates the expected data type for the user provided value. - Accepted values are string, integer, double, boolean, array[string], array[integer], array[double], array[boolean]. - At a minimum, the provided parameter value MUST match the schema's data type if no other validation rules are provided. - rank: 20 - range: string - required: true - #validationRule: - # description: >- - # Defines the validation rules to use to validate the user provided parameter value. - # The rules are based on the schema's data type and are listed below. - # The value MUST be validated against any validation rules defined in the schema. - # rank: 30 - # range: ValidationRule - # required: false - - TextValidationSchema: - is_a: Schema - description: Extends schema to define a string/text-specific set of validation rules that can be used. - rank: 150 - attributes: - allowEmpty: - description: >- - If true, indicates a value must be provided. Default is false if not provided. - rank: 30 - range: boolean - required: false - minLength: - description: If set, indicates the minimum number of characters the value must have to be considered valid. - rank: 40 - range: integer - required: false - maxLength: - description: If set, indicates the maximum number of characters the value must have to be considered valid. - rank: 50 - range: integer - required: false - regexMatch: - description: If set, indicates a regular expression to use to validate the value. - rank: 55 - range: string - required: false - - BooleanValidationSchema: - is_a: Schema - description: Extends schema to define a boolean-specific set of validation rules that can be used. - rank: 160 - attributes: - allowEmpty: - description: >- - If true, indicates a value must be provided. Default is false if not provided. - rank: 30 - range: boolean - required: false - - NumericIntegerValidationSchema: - is_a: Schema - description: Extends schema to define a integer-specific set of validation rules that can be used. - rank: 170 - attributes: - allowEmpty: - description: >- - If true, indicates a value must be provided. Default is false if not provided. - rank: 30 - range: boolean - required: false - minValue: - description: If set, indicates the minimum allowed integer value the value must have to be considered valid. - rank: 50 - range: integer - required: false - maxValue: - description: If set, indicates the maximum allowed integer value the value must have to be considered valid. - rank: 50 - range: integer - required: false - - NumericDoubleValidationSchema: - is_a: Schema - description: Extends schema to define a double-specific set of validation rules that can be used. - rank: 180 - attributes: - allowEmpty: - description: >- - If true, indicates a value must be provided. Default is false if not provided. - rank: 30 - range: boolean - required: false - minValue: - description: If set, indicates the minimum value to be considered valid. - rank: 50 - range: float - required: false - maxValue: - description: If set, indicates the maximum value to be considered valid. - rank: 50 - range: float - required: false - minPrecision: - description: If set, indicates the minimum level of precision the value must have to be considered valid. - rank: 50 - range: integer - required: false - maxPrecision: - description: If set, indicates the maximum level of precision the value must have to be considered valid. - rank: 50 - range: integer - required: false - - SelectValidationSchema: - is_a: Schema - description: Extends schema to define a specific set of validation rules that can be used for select options. - rank: 190 - attributes: - allowEmpty: - description: >- - If true, indicates a value must be provided. Default is false if not provided. - rank: 30 - range: boolean - required: false - multiselect: - description: If true, indicates multiple values can be selected. If multiple values can be selected the resulting value is an array of the selected values. The default is false if not provided. - rank: 80 - range: boolean - required: false - options: - description: This provides the list of acceptable options the user can select from. The data type for each option must match the parameter setting’s data type. - rank: 80 - range: string - multivalued: true - required: true - -slots: - type: - description: >- - Defines the type of this deployment configuration for the application. - The allowed values are `helm.v3`, to indicate the deployment profile's format is Helm version 3, - and `compose` to indicate the deployment profile's format is a Compose file. - When installing the application on a device supporting the Kubernetes platform, all `helm.v3` components, - and only `helm.v3` components, will be provided to the device in same order they are listed in the application description file. - When installing the application on a device supporting Compose, all `compose` components, - and only `compose` components, will be provided to the device in the same order they are listed in the application description file. - The device will install the components in the same order they are listed in the application description file. - range: string - required: true - pattern: ^(helm\.v3|compose)$ - rank: 10 - - components: - description: >- - Component element indicating the components to deploy when installing the application. - See the [Component](#component-attributes) section below. - range: Component - multivalued: true - required: true - inlined: true - inlined_as_list: true - rank: 20 - -enums: - CpuArchitectureType: - permissible_values: - amd64: - description: AMD 64-bit architecture. - x86_64: - description: x86 64-bit architecture. - arm64: - description: ARM 64-bit architecture. - arm: - description: ARM 32-bit architecture. - riscv64: - description: RISC-V 64-bit architecture. - other: - description: >- - Any other CPU architecture not listed here. The application developer MUST provide a description of the architecture in the deployment profile's `description` field. - - CommunicationInterfaceType: - permissible_values: - ethernet: - description: This type stands for an Ethernet interface. - wifi: - description: This type stands for an WiFi interface. - cellular: - description: This type stands for cellular communication technologies such as 5G, LTE, 3G, 2G, .... - bluetooth: - description: This type stands for a Bluetooth or Bluetooth Low-Energy (BLE) interface. - usb: - description: This type stands for a USB interface. - canbus: - description: This type stands for a CANBus interface. - rs232: - description: This type stands for a RS232 interface. - other: - description: This type stands for any other communication interface not listed here. The application developer MUST provide a description of the interface in the deployment profile's `description` field. - - PeripheralType: - permissible_values: - gpu: - description: This type stands for a Graphics Processing Unit (GPU) peripheral. - display: - description: This type stands for a display peripheral. - camera: - description: This type stands for a camera peripheral. - microphone: - description: This type stands for a microphone peripheral. - speaker: - description: This type stands for a speaker peripheral. - other: - description: This type stands for any other peripheral not listed here. The application developer MUST provide a description of the peripheral in the deployment profile's `description` field. - diff --git a/src/specification/application-package/resources/class.md.jinja2 b/src/specification/application-package/resources/class.md.jinja2 deleted file mode 100644 index e69de29..0000000 diff --git a/src/specification/application-package/resources/examples/valid/ApplicationDescription-001.yaml b/src/specification/application-package/resources/examples/valid/ApplicationDescription-001.yaml deleted file mode 100644 index 5eef610..0000000 --- a/src/specification/application-package/resources/examples/valid/ApplicationDescription-001.yaml +++ /dev/null @@ -1,59 +0,0 @@ -apiVersion: margo.org/v1-alpha1 -kind: ApplicationDescription -metadata: - id: com-northstartida-hello-world - name: Hello World - description: A basic hello world application - version: "1.0" - catalog: - application: - icon: ./resources/hw-logo.png - tagline: Northstar Industrial Application's hello world application. - descriptionFile: ./resources/description.md - releaseNotes: ./resources/release-notes.md - licenseFile: ./resources/license.pdf - site: http://www.northstar-ida.com - tags: ["monitoring"] - author: - - name: Roger Wilkershank - email: rpwilkershank@northstar-ida.com - organization: - - name: Northstar Industrial Applications - site: http://northstar-ida.com -deploymentProfiles: - - type: helm.v3 - id: com-northstartida-hello-world-helm.v3-a - components: - - name: hello-world - properties: - repository: oci://northstarida.azurecr.io/charts/hello-world - revision: 1.0.1 - wait: true -parameters: - greeting: - value: Hello - targets: - - pointer: global.config.appGreeting - components: ["hello-world"] - greetingAddressee: - value: World - targets: - - pointer: global.config.appGreetingAddressee - components: ["hello-world"] -configuration: - sections: - - name: General Settings - settings: - - parameter: greeting - name: Greeting - description: The greeting to use. - schema: requireText - - parameter: greetingAddressee - name: Greeting Addressee - description: The person, or group, the greeting addresses. - schema: requireText - schema: - - name: requireText - dataType: string - maxLength: 45 - allowEmpty: false diff --git a/src/specification/application-package/resources/examples/valid/ApplicationDescription-002.yaml b/src/specification/application-package/resources/examples/valid/ApplicationDescription-002.yaml deleted file mode 100644 index c21c8d9..0000000 --- a/src/specification/application-package/resources/examples/valid/ApplicationDescription-002.yaml +++ /dev/null @@ -1,208 +0,0 @@ -apiVersion: margo.org/v1-alpha1 -kind: ApplicationDescription -metadata: - id: com-northstartida-digitron-orchestrator - name: Digitron orchestrator - description: The Digitron orchestrator application - version: 1.2.1 - catalog: - application: - icon: ./resources/ndo-logo.png - tagline: Northstar Industrial Application's next-gen, AI driven, Digitron instrument orchestrator. - descriptionFile: ./resources/description.md - releaseNotes: ./resources/release-notes.md - licenseFile: ./resources/license.pdf - site: http://www.northstar-ida.com - tags: ["optimization", "instrumentation"] - author: - - name: Roger Wilkershank - email: rpwilkershank@northstar-ida.com - organization: - - name: Northstar Industrial Applications - site: http://northstar-ida.com -deploymentProfiles: - - type: helm.v3 - id: com-northstartida-digitron-orchestrator-helm.v3-a - description: This allows to install / run the application as a Helm chart deployment. - The device where this application is installed needs to have a screen and a keyboard (as indicated in the required peripherals). - components: - - name: database-services - properties: - repository: oci://quay.io/charts/realtime-database-services - revision: 2.3.7 - wait: true - timeout: 8m30s - - name: digitron-orchestrator - properties: - repository: oci://northstarida.azurecr.io/charts/northstarida-digitron-orchestrator - revision: 1.0.9 - wait: true - requiredResources: - cpu: - cores: 1.5 - architectures: - - amd64 - - x86_64 - memory: 1024Mi - storage: 10Gi - peripherals: - - type: gpu - manufacturer: NVIDIA - - type: display - interfaces: - - type: ethernet - - type: bluetooth - - type: compose - id: com-northstartida-digitron-orchestrator-compose-a - components: - - name: digitron-orchestrator-docker - properties: - packageLocation: https://northsitarida.com/digitron/docker/digitron-orchestrator.tar.gz - keyLocation: https://northsitarida.com/digitron/docker/public-key.asc -parameters: - idpName: - targets: - - pointer: idp.name - components: ["digitron-orchestrator"] - - pointer: ENV.IDP_NAME - components: ["digitron-orchestrator-docker"] - idpProvider: - targets: - - pointer: idp.provider - components: ["digitron-orchestrator"] - - pointer: ENV.IDP_PROVIDER - components: ["digitron-orchestrator-docker"] - idpClientId: - targets: - - pointer: idp.clientId - components: ["digitron-orchestrator"] - - pointer: ENV.IDP_CLIENT_ID - components: ["digitron-orchestrator-docker"] - idpUrl: - targets: - - pointer: idp.providerUrl - components: ["digitron-orchestrator"] - - pointer: idp.providerMetadata - components: ["digitron-orchestrator"] - - pointer: ENV.IDP_URL - components: ["digitron-orchestrator-docker"] - adminName: - targets: - - pointer: administrator.name - components: ["digitron-orchestrator"] - - pointer: ENV.ADMIN_NAME - components: ["digitron-orchestrator-docker"] - adminPrincipalName: - targets: - - pointer: administrator.userPrincipalName - components: ["digitron-orchestrator"] - - pointer: ENV.ADMIN_PRINCIPALNAME - components: ["digitron-orchestrator-docker"] - pollFrequency: - value: 30 - targets: - - pointer: settings.pollFrequency - components: ["digitron-orchestrator", "database-services"] - - pointer: ENV.POLL_FREQUENCY - components: ["digitron-orchestrator-docker"] - siteId: - targets: - - pointer: settings.siteId - components: ["digitron-orchestrator", "database-services"] - - pointer: ENV.SITE_ID - components: ["digitron-orchestrator-docker"] - cpuLimit: - value: 1 - targets: - - pointer: settings.limits.cpu - components: ["digitron-orchestrator"] - memoryLimit: - value: 16384 - targets: - - pointer: settings.limits.memory - components: ["digitron-orchestrator"] -configuration: - sections: - - name: General - settings: - - parameter: pollFrequency - name: Poll Frequency - description: How often the service polls for updated data in seconds - schema: pollRange - - parameter: siteId - name: Site Id - description: Special identifier for the site (optional) - schema: optionalText - - name: Identity Provider - settings: - - parameter: idpName - name: Name - description: The name of the Identity Provider to use - immutable: true - schema: requiredText - - parameter: idpProvider - name: Provider - description: Provider something something - immutable: true - schema: requiredText - - parameter: idpClientId - name: Client ID - description: The client id - immutable: true - schema: requiredText - - parameter: idpUrl - name: Provider URL - description: The url of the Identity Provider - immutable: true - schema: url - - name: Administrator - settings: - - parameter: adminName - name: Presentation Name - description: The presentation name of the administrator - schema: requiredText - - parameter: adminPrincipalName - name: Principal Name - description: The principal name of the administrator - schema: email - - name: Resource Limits - settings: - - parameter: cpuLimit - name: CPU Limit - description: Maximum number of CPU cores to allow the application to consume - schema: cpuRange - - parameter: memoryLimit - name: Memory Limit - description: Maximum number of memory to allow the application to consume - schema: memoryRange - schema: - - name: requiredText - dataType: string - maxLength: 45 - allowEmpty: false - - name: email - dataType: string - allowEmpty: false - regexMatch: .*@[a-z0-9.-]* - - name: url - dataType: string - allowEmpty: false - regexMatch: ^(http(s):\/\/.)[-a-zA-Z0-9@:%._\+~#=]{2,256}\.[a-z]{2,6}\b([-a-zA-Z0-9@:%_\+.~#?&//=]*)$ - - name: pollRange - dataType: integer - minValue: 30 - maxValue: 360 - allowEmpty: false - - name: optionalText - dataType: string - minLength: 5 - allowEmpty: true - - name: cpuRange - dataType: double - minValue: 0.5 - maxPrecision: 1 - allowEmpty: false - - name: memoryRange - dataType: integer - minValue: 16384 - allowEmpty: false \ No newline at end of file diff --git a/src/specification/application-package/resources/index.md.jinja2 b/src/specification/application-package/resources/index.md.jinja2 deleted file mode 100644 index bc1be7b..0000000 --- a/src/specification/application-package/resources/index.md.jinja2 +++ /dev/null @@ -1,157 +0,0 @@ -# Application Description - -The Application Description has the purpose of presenting the application (e.g., on a WFM-internal [Application Catalog](../../personas-and-definitions/technical-lexicon.md#workload-fleet-manager)) -or public [Marketplace](../../personas-and-definitions/technical-lexicon.md#marketplace)) from where an end user selects an application to be installed. -The end user defines an `ApplicationDeployment` by specifying [configuration parameters](#defining-configurable-application-parameters) for an `ApplicationDescription`. -An `ApplicationDeployment` defines the [desired state](../margo-management-interface/desired-state.md) for an application. - -### Top-level Attributes - -{% macro abort(error) %} - {{ None['[ERROR] ' ~ error][0] }} -{% endmacro %} - -{%- macro format_range(slot) -%} - {%- if slot.multivalued -%} - {%- if slot.inlined -%} - {%- if slot.inlined_as_list -%} - []{{ slot.range }} - {%- else -%} - {%- if slot.name == "properties" -%} - map[string][string] - {%- else -%} - map[string][{{ slot.range }}] - {%- endif -%} - {%- endif -%} - {%- else -%} - []string - {%- endif -%} - {%- else -%} - {{ slot.range }} - {%- endif -%} -{%- endmacro -%} - -| Attribute | Type | Required? | Description | -| --- | --- | --- | --- | -{% for slot in schemaview.class_slots("ApplicationDescription")|sort(attribute='rank') -%} -| {{ slot }} | {{ format_range(schemaview.get_slot(slot)) }} | {% if schemaview.get_slot(slot).required == True %} Y {% else %} N {% endif %} | {{ schemaview.get_slot(slot).description }}| -{% endfor -%} - -{% for c in gen.all_class_objects()|sort(attribute='rank') %} -{%- if c.name != "ApplicationDescription" and not c.name.startswith("ComponentProperties") and not c.name.startswith("Helm") and not c.name.startswith("Compose") %} - -{# if c is a subclass of any: #} - -{%- if c.is_a -%} -* #### {{ c.name }} Attributes
-(Subclass of {{ c.is_a }})
-{%- else -%} -### {{ c.name }} Attributes
-{%- endif %} - -{%- if c.description -%} -
-{{ c.description }}
-{%- endif %} - -| Attribute | Type | Required? | Description | -| --- | --- | --- | --- | -{% for slot in gen.get_direct_slots(c)|sort(attribute='rank') -%} -{%- if slot.name != "value" -%} -| {{ slot.name }} | {{ format_range(slot) }} | {% if slot.required == True %} Y {% else %} N {% endif %} | {{ slot.description }}| -{%- else -%} -| {{ slot.name }} | <*see description*> | {% if slot.required == True %} Y {% else %} N {% endif %} | {{ slot.description }}| -{%- endif %} -{% endfor %} - -{%- endif %} - - - - -{%- if c.name.startswith("ComponentProperties") %} - -### ComponentProperties Attributes -The expected properties for the suppported deployment types are indicated below. - -- Properties for `helm.v3` components - -| Attribute | Type | Required? | Description | -| --- | --- | --- | --- | -| repository | string | Y | The URL indicating the helm chart's location.| -| revision | string | Y | The helm chart's full version.| -| wait | bool | N | If `True`, indicates the device MUST wait until the helm chart has finished installing before installing the next helm chart. The default is `True`. The Workload Fleet Management Client MUST support `True` and MAY support `False`. Only applies if multiple `helm.v3` components are provided.| -| timeout | string | N | The time to wait for the component's installation to complete. If the installation does not completed before the timeout occurs the installation process fails. The format is "##m##s" indicating the total number of minutes and seconds to wait. | - -- Properties for `compose` components - -> **Investigation Needed**: We need to have more discussion about how Compose should be handled and what is required here. - -| Attribute | Type | Required? | Description | -| --- | --- | --- | --- | -| packageLocation | string | Y | The URL indicating the Compose package's location. | -| keyLocation | string | N | The public key used to validated the digitally signed package. It is highly recommend to digitally sign the package. When signing the package PGP MUST be used.| -| wait | bool | N | If `True`, indicates the device MUST wait until the Compose file has finished starting up before starting the next Compose file. The default is `True`. The Workload Fleet Management Client MUST support `True` and MAY support `False`. Only applies if multiple `compose` components are provided.| -| timeout | string | N | The time to wait for the component's installation to complete. If the installation does not completed before the timeout occurs the installation process fails. The format is "##m##s" indicating the total number of minutes and seconds to wait.| - -## Defining configurable application parameters - -To allow customizable configuration values when installing an application, the *application description* defines the parameters and configuration sections giving the application vendor control over what can be configured when installing, or updating, an application. The [configuration](#configuration-attributes) section describes how the workload orchestration software vendor must display parameters to the user to allow them to specify the values. The [schema](#schema-attributes) section describes how the workload orchestration software vendor must validate the values provided by the user before the application is installed or updated. - -> **Note:** At this point the specification only deals with parameter values provided by the user as part of installing, or updating, the application. We anticipate parameter values to come from other sources, such as the device, in the future and not only from the user. - -{%- endif %} -{%- endfor %} - - -## Enumerations -These enumerations are used as vocabularies for attribute values of the `ApplicationDescription`. - -### CpuArchitectureType - -| Permissible Values | Description | -| --- | --- | -| amd64 | AMD 64-bit architecture.| -| x86_64 | x86 64-bit architecture.| -| arm64 | ARM 64-bit architecture.| -| arm | ARM 32-bit architecture. | - -### CommunicationInterfaceType - -| Permissible Values | Description | -| --- | --- | -| ethernet | This type stands for an Ethernet interface.| -| wifi | This type stands for an WiFi interface.| -| cellular | This type stands for cellular communication technologies such as 5G, LTE, 3G, 2G, ....| -| bluetooth | This type stands for a Bluetooth or Bluetooth Low-Energy (BLE) interface. | -| usb | This type stands for a USB interface.| -| canbus | This type stands for a CANBus interface.| -| rs232 | This type stands for a RS232 interface. | - -### PeripheralType - -| Permissible Values | Description | -| --- | --- | -| gpu | This type stands for a Graphics Processing Unit (GPU) peripheral.| -| display | This type stands for a display peripheral.| -| camera | This type stands for a camera peripheral.| -| microphone | This type stands for a microphone peripheral. | -| speaker | This type stands for a speaker peripheral. | - - - -## Application Description Examples - -### Example 1: Simple Application Description -A simple hello-world example of an `ApplicationDescription` is shown below: - -```yaml -{% include 'examples/valid/ApplicationDescription-001.yaml' %} -``` - -### Example 2: Application Description with Deployment Profiles for Helm and Compose -An example of an `ApplicationDescription` defining [deployment profiles](#deploymentprofile-attributes) for both cases, Helm chart as well as Compose, is shown below. - -```yaml -{% include 'examples/valid/ApplicationDescription-002.yaml' %} -``` \ No newline at end of file diff --git a/system-design/concepts/workloads/application-package.md b/system-design/concepts/workloads/application-package.md deleted file mode 100644 index dfa0e25..0000000 --- a/system-design/concepts/workloads/application-package.md +++ /dev/null @@ -1,43 +0,0 @@ -# Application Package - -The Application Package, which is used to [distribute an application](../../overview/workloads.md) to be deployed as [workloads](../../personas-and-definitions/technical-lexicon.md#workload) on edge devices, comprises the following elements: - -- The **Application Description**: a YAML document with the element `kind` defined as `ApplicationDescription`, which is stored in a file (for example named `margo.yaml`) and contains information about the application's [metadata](../../specification/application-package/application-description.md#metadata-attributes) (e.g., description, icon, release notes, license file, etc.), the application [components](../../personas-and-definitions/technical-lexicon.md#component) (e.g., Helm charts, Compose Archive) which are defined in [deployment configurations](../../specification/application-package/application-description.md#deploymentprofile-attributes), and [configurable application parameters](../../specification/application-package/application-description.md#defining-configurable-application-parameters). There is only one YAML file in the package root of kind `ApplicationDescription`. -- The **resources**, which are additional files associated with the application (e.g., manual, icon, release notes, license file, etc.) that may be used to display more information about the application in a UI such as an [application catalog](../../personas-and-definitions/technical-lexicon.md#application-catalog) or [marketplace](../../personas-and-definitions/technical-lexicon.md#marketplace) or other informative outputs. - -The Application Package has the following folder/file structure: - -```yaml -/ # REQUIRED top-level directory -└── .yaml # REQUIRED a YAML document with element 'kind' as 'ApplicationDescription' stored in a file (e.g., 'margo.yaml') -└── resources # OPTIONAL folder with application files (e.g., icon, license file, release notes) that may be used for displaying additional information about the application -``` - -The Application Package is made available in an [Application Registry](./application-registry.md). - -An application aggregates one or more [components](../../personas-and-definitions/technical-lexicon.md#component), which each link to one or more [OCI Containers](https://github.com/opencontainers). The components referenced in the [Application Description](../../specification/application-package/application-description.md) are stored in a [Component Registry](../../personas-and-definitions/technical-lexicon.md#component-registry), and the linked containers are provided via a [Container Registry](../../personas-and-definitions/technical-lexicon.md#container-registry). Registries can be remote (i.e., Internet-accessible) or [local](../../concepts/workloads/local-registries.md) (i.e., accessible within a local network infrastructure of the devices). - -> **Note** -> Application catalogs and marketplaces are out of scope of the Margo specification. The exact requirements of the marketing material need to be defined by the application marketplace beyond outlined mandatory content. - -The [deployment profiles](../../specification/application-package/application-description.md#deploymentprofile-attributes) specified in the [Application Description](../../specification/application-package/application-description.md) are defined as Helm Chart components AND/OR [Compose Archive](../../personas-and-definitions/technical-lexicon.md#compose-archive) components. These components are being deployed as workloads on the edge devices: - -- To target devices, which deploy workloads using Kubernetes, components need to be defined as Helm charts using [Helm (version 3)](https://helm.sh/docs/topics/charts/). -- To target devices, which deploy workloads using [Compose](https://www.compose-spec.io/), components need to be packaged as [Compose Archives](../../personas-and-definitions/technical-lexicon.md#compose-archive), i.e., a tarball file containing the `compose.yaml` file and any additional artifacts referenced by the Compose file (e.g., configuration files, environment variable files, etc.). Margo recommends to digitally sign this package and to specify the location of the public key in the `ApplicationDescription` (see `keyLocation` [here](../../specification/application-package/application-description.md#componentproperties-attributes)). When digitally signing the package PGP encryption MUST be used. - -> **Investigation Needed**: Question: do we need to specify the location of a SHA256 hash for the Compose Archive also (similar to the PGP key) in the ApplicationDescription? -> We will also discuss how we should handle secure container registries that require a username and password. -> -> **Investigation Needed**: We need to determine what impact, if any, using 3rd party helm charts has on being Margo compliant. -> -> **Investigation Needed**: Missing in the current specification are ways to define dependencies (e.g., application dependencies) as well as required infrastructure services such as storage, message queues/bus, reverse proxy, or authentication/authorization/accounting. - -If either one cannot be implemented it MAY be omitted but Margo RECOMMENDS defining [deployment profiles](../../specification/application-package/application-description.md#deploymentprofile-attributes) as both Helm chart **AND** Compose components to strengthen interoperability and applicability. - -> **Note** -> A device running the application will only install the application using either the Compose Archives or the Helm Charts, but not both. - -## Relevant Links -Please follow the subsequent link to view the technical reference of the `ApplicationDescription` format: - -- [Application Description](../../specification/application-package/application-description.md) diff --git a/system-design/concepts/workloads/application-registry.md b/system-design/concepts/workloads/application-registry.md deleted file mode 100644 index 2b14375..0000000 --- a/system-design/concepts/workloads/application-registry.md +++ /dev/null @@ -1,44 +0,0 @@ -# Application Registry - -The Margo specification differentiates 4 kinds of registries: *Application Registries*, *Component Registries*, and *Container Registries* as well as *Marketplaces*. - -1. An **Application Registry** hosts Application Packages that define through their [Application Description](../../specification/application-package/application-description.md) the application as one or multiple [Components](../../personas-and-definitions/technical-lexicon.md#component). -2. A **Component Registry** hosts the [Components](../../personas-and-definitions/technical-lexicon.md#component) (which are deployable as *workloads*) and are provided as **Helm Charts** or **Compose Archives**. -3. A **Container Registry** hosts container images referenced by those Components. -4. A **Marketplace** lists applications to advertise them and enable purchasing for end users. - -Out of these 4 registries, **only the Application Registry interface is in scope** of the Margo specification and its API definition can be found [here](../../specification/application-package/application-registry.md). - -The diagram below illustrates these functionalities and relationships of registries within Margo. - -```mermaid -flowchart - A[WFM, or internal Application Catalog] -- Application Descriptions link to --> B[Component Registry] - C[Application Registry] -- Application Descriptions link to --> B - B -- hosted Components links to --> D[Container Registry] - A -->|pulls Application Package | C - F[App Developer] -->|uploads Application Package to| C - G["Marketplace"] -- points to Application Package --> C - C -->|hosts 0..*| E@{ shape: docs, label: "Application Packages"} - C -->|validates token| H[Authentication Service] - A -->|requests token| H - style H stroke-dasharray: 3 6 - - style B fill:#ABC - style C fill:#ABC - style D fill:#ABC - style G fill:#ABC -``` - -As shown in the figure above, an `Application Developer` uploads an [Application package](application-package.md) to an Application Registry. From there, it is available to a `Workload Fleet Manager` (WFM). -The WFM acts as a client to pull an [Application Package](application-package.md) from the Application Registry. It would then list this Application Package on its UI (e.g., an internal `Application Catalog`) to enable the usage on its managed devices. - -An `Authentication Service` manages access control for the Application Registry. The WFM requests a token from the Authentication Service to include in the requests to the Application Registry. The received token is then validated by the Application Registry through interaction with the Authentication Service. - -The Application Registry's API is compliant with the [OCI Registry API (v1.1.0)](https://github.com/opencontainers/distribution-spec/blob/v1.1.0/spec.md). A hosted Application Package is provided by listing its parts as layers in an [image manifests](https://github.com/opencontainers/image-spec/blob/v1.0.1/manifest.md) that can be requested through the API. - - -## Relevant Links -* The technical reference of the Application Registry API is defined [here](../../specification/application-package/application-registry.md). - -* A reference implementation of the Application Registry is described [here](https://github.com/margo/app-package-definition-wg/blob/main/application-registry-example/app_registry_as_oci_registry.md) and includes sample applications and configuration for demonstration. It utilizes an open source OCI Registry and the [ORAS tool](https://oras.land/docs/) as the client. diff --git a/system-design/concepts/workloads/local-registries.md b/system-design/concepts/workloads/local-registries.md deleted file mode 100644 index b130b7c..0000000 --- a/system-design/concepts/workloads/local-registries.md +++ /dev/null @@ -1,88 +0,0 @@ -# Local Registries - -The [Component Registry](application-registry.md) as well as the [Container Registry](application-registry.md) considered by Margo are the registries that need to be accessed by devices to download components (i.e., Helm Charts or Compose Archives) or containers. This section describes how to configure those as local registries to avoid reliance on public Internet-accessible registries. - -The reasons for not using public registries are for example: (1) publicly hosted container images or Helm charts could become unavailable at some point, as the owner decides to take the container images or Helm charts off the public registry, (2) Internet connectivity may not be available to the device and hence public registries are not reachable, or (3) end-users want to host their own registries so they can do security scans and package validation. - -In terms of connectivity, we can thereby distinguish mainly between the following device categories: - -1. **Fully connected device**, which means a device is deployed in the field (e.g., a factory shop floor) and has access to the Internet. -2. **Locally connected device**, i.e., the device has connectivity to a local network (e.g., factory- or enterprise-wide) and a local repository can be made reachable. -3. **Air-gapped device**, i.e., the device generally is not connected and must be configured by accessing it directly (via direct network link with an Ethernet cable, or similar) for example through a technician’s laptop. - -Local Component Registries or Container Registries can be used for all device categories. In case of **fully connected devices**, although the device could reach the Internet, a local registry can still be useful (e.g., as a cache for remote registries to save on bandwidth or to have container images or Helm Charts reliably available). In case of **locally connected devices**, a local registry is required to enable the Workload Fleet Management Client (WFMC) to install a Margo application on the device, as the device/WFMC does not have Internet access. Thereby, the local registry can be set up as a *pull-through cache* where data (e.g., container images) is cached locally when they are first retrieved from a remote source and subsequent requests for the same data are served from the local cache rather than fetching it again from the remote source. In case of **air-gapped devices**, a local registry has to be accessible on the technician's laptop (or other directly connected device), which performs the application installation process. - -To setup local registries, different configuration options exist: - -## Option - Container Registry Mirror on Kubernetes Level - -Kubernetes supports the configuration of registry mirrors. How this is configured depends on the distribution and the underlying container runtime. Distributions that utilize **containerd** as runtime (e.g., k3s or microk8s) allow the definition of mirrors in a configuration file. For example, in k3s the file `/etc/rancher/k3s/registries.yaml` can be used to set up a mirror for each device's Kubernetes environment: - -```yaml -mirrors: - "docker.io": - endpoint: - - "http://:5000" -configs: - "docker.io": - auth: - username: "" - password: "" -``` - -## Option - Container Registry as Pull-through Cache on Docker Level - -To configure a pull-through cache in Docker for the Container Registry, a Docker Registry can be setup that acts as caching proxy for a remote Docker Registry. Such a Docker Registry can be defined using the following `config.yml`: - -```yaml -version: 0.1 -log: - fields: - service: registry -storage: - filesystem: - rootdirectory: /var/lib/registry -http: - addr: :5000 - headers: - X-Content-Type-Options: [nosniff] -health: - storagedriver: - enabled: true - interval: 10s - threshold: 3 -proxy: - remoteurl: https://registry-1.docker.io -``` - -This registry can be started uing the following command: -`docker run -d -p 5000:5000 --restart unless-stopped --name registry -v $(pwd)/config.yml:/etc/docker/registry/config.yml registry:2` - -Then, the Docker daemon needs to be configured to use the private registry as a mirror in the `/etc/docker/daemon.json` file: - -```json -{ - "registry-mirrors": ["http://10.100.2.102:5000"], - "insecure-registries": ["10.100.2.102:5000"] -} -``` - -## Option - Helm Chart Component Registry as Pull-through Cache - -Setting up a pull-through cache for Helm charts in combination with Kubernetes involves configuring a local Helm chart repository, e.g., ChartMuseum, that can be installed with the `PROXY_CACHE` variable set to `true`: - -```bash -helm repo add chartmuseum https://chartmuseum.github.io/charts -helm repo update -helm install my-chartmuseum chartmuseum/chartmuseum --set env.open.DISABLE_API=false --set env.open.PROXY_CACHE=true -``` - -Then, this Helm Chart repository can be added to Helm and chart releases can be installed there: - -```bash -helm repo add my-cached-repo http://:8080 -helm repo update -helm install my-release my-cached-repo/ -``` - -Now, when deploying applications in Kubernetes using Helm, the cached repository is used to serve charts rather than the remote repository. diff --git a/system-design/overview/workloads.md b/system-design/overview/workloads.md deleted file mode 100644 index c7931e8..0000000 --- a/system-design/overview/workloads.md +++ /dev/null @@ -1,78 +0,0 @@ -# Applications & Workloads - -A [workload](../personas-and-definitions/technical-lexicon.md#workload) is running software. More specifically, a workload is a running [Component](../personas-and-definitions/technical-lexicon.md#component) of an [Application Package](../concepts/workloads/application-package.md) deployed to a Margo compliant [edge compute device](../personas-and-definitions/technical-lexicon.md#edge-compute-device). - -In order to help achieve Margo's interoperability [mission statement](../index.md#mission-statement) we are initially targeting [containerized](https://github.com/opencontainers) components/workloads capable of running on platforms like Kubernetes, Docker and Podman. The flexibility these platforms provide enables [workload suppliers](../personas-and-definitions/personas.md#workload-supplier) to define and package their components in a common way using [Helm](https://helm.sh/docs/) or the [Compose specification](https://github.com/compose-spec/compose-spec/blob/main/spec.md) so they can more easily be deployed to multiple compatible edge compute devices as workloads. - -While Margo is initially targeting deployments using Helm or Compose, we plan to support other deployment types in the future. One of our design goals is to make it easier for [workload fleet managers](../personas-and-definitions/technical-lexicon.md#workload-fleet-manager) to support the current and future deployment types without having to implement special logic for each type. In order to achieve this, Margo defines an [application description model](../concepts/workloads/application-package.md) to abstract away some of the details to make it easier for workload fleet managers to support the different deployment types. - -The three main goals of Margo's application description model is to allow workload fleet managers to do the following: - -- Display information about available applications (e.g., via an [application catalog](../personas-and-definitions/technical-lexicon.md#application-catalog)), which the [OT user](../personas-and-definitions/personas.md#ot-user) can deploy as workloads. -- Determine which edge compute devices are compatible with an application (regarding processor type, GPU present, RAM available, etc.) -- Capture, and validate, configuration information from the OT user when deploying application components as workloads, or updating them. - -Another advantage of Margo's [application description model](../concepts/workloads/application-package.md) is to enable workload suppliers to define different deployment profiles in a single application description file to target deploying to different types of edge compute devices (e.g., Arm vs. x86, Kubernetes vs. Docker) instead of needing to maintain multiple application description files. - -## Packaging & Distribution - -To distribute an application consisting of multiple components that are deployable as workloads, they are wrapped in an [application package](../concepts/workloads/application-package.md) defined by the workload supplier who aims to provide it to Margo-compliant edge compute devices. Therefore, the workload supplier creates an application description YAML document containing information about the application and references to its components. The application package is made available in an [application registry](../concepts/workloads/application-registry.md), its components (i.e., Helm Charts or Compose Archives) are stored in a remote or [local](../concepts/workloads/local-registries.md) component registry, and the linked [OCI containers](https://github.com/opencontainers) are provided through an OCI container registry. - -### Example workflow - -The following diagram provides an example workflow showing one way a workload fleet manager may use the application description information: - -```mermaid ---- -config: - layout: elk - - ---- -sequenceDiagram - actor EndUser as End User - participant frontend as Workload Fleet Manager Frontend - participant fleetmgr as Workload Fleet Manager - participant registry as Application Registry - - autonumber - - EndUser->>frontend: Visits Application Catalog - frontend->>fleetmgr: Get list of available application packages - - alt - fleetmgr ->> registry: Get application descriptions from each known application registry. - else - fleetmgr ->> fleetmgr: Get application descriptions for all cached applications. - end - fleetmgr->>frontend: Return list of application descriptions - - frontend ->> frontend: Read all application descriptions' 'metadata' element - frontend ->> EndUser: Show UI with list of applications - EndUser->>frontend: Select application / components to install - frontend ->> frontend: Read application descriptions 'configuration' element - frontend -->> EndUser: Show UI to fill application configuration - EndUser ->> frontend: fills application configuration - frontend ->> fleetmgr: Create 'ApplicationDeployment' definition - -``` - -1. An end user visits the [application catalog](../personas-and-definitions/technical-lexicon.md#application-catalog) of a Workload Fleet Manager Frontend. -2. This frontend requests all installable [application packages](../concepts/workloads/application-package.md) from the Workload Fleet Manager. -3. _Either_: the Workload Fleet Manager requests all application descriptions from each known [application registry](../concepts/workloads/application-registry.md). -4. _Or_: the Workload Fleet Manager maintains a cache of application descriptions and services the request from there. -5. The Workload Fleet Manager returns the retrieved application descriptions to the frontend. -6. The frontend parses the [metadata](../specification/application-package/application-description.md#metadata-attributes) element of all received application descriptions. -7. The frontend presents the parsed metadata in a UI to the end user. -8. The end user selects the application package to be installed. -9. The frontend parses the [configuration](../specification/application-package/application-description.md#configuration-attributes) element of the selected application description. -10. The frontend presents the parsed configuration to the user. -11. The end user fills out the [configurable application parameters](../specification/application-package/application-description.md#defining-configurable-application-parameters). -12. The frontend creates an `ApplicationDeployment` definition (from the `ApplicationDescription` and the filled out parameters) and sends it to the Workload Fleet Manager, which executes it as the [desired state](../specification/margo-management-interface/desired-state.md). - -## Relevant Links - -Please follow the subsequent links to view more technical information regarding Margo application packaging: - -- [Application Package](../concepts/workloads/application-package.md) -- [Application Registry](../concepts/workloads/application-registry.md) diff --git a/system-design/personas-and-definitions/software-composition.md b/system-design/personas-and-definitions/software-composition.md index ae5eb4f..e7ef5b9 100644 --- a/system-design/personas-and-definitions/software-composition.md +++ b/system-design/personas-and-definitions/software-composition.md @@ -272,8 +272,8 @@ C4Component UpdateElementStyle(atb1, $fontColor="white", $bgColor="blue", $borderColor="grey") ``` -[application-description]: ../specification/application-package/application-description.md -[application-package]: ../concepts/workloads/application-package.md +[application-description]: ../specification/applications/application-description.md +[application-package]: ../concepts/applications/application-package.md [application-registry]: technical-lexicon.md#application-registry [component]: technical-lexicon.md#component [workload]: technical-lexicon.md#workload @@ -282,4 +282,4 @@ C4Component [deployment-definition]: ../../specification/margo-management-interface/desired-state/?h=applicationdeployment.md#applicationdeployment-definition [provider-model]: technical-lexicon.md#provider-model [wfmc]: technical-lexicon.md#workload-fleet-management-client -[deployment-profile]: ../specification/application-package/application-description.md#deploymentprofile-attributes +[deployment-profile]: ../specification/applications/application-description.md#deploymentprofile-attributes diff --git a/system-design/personas-and-definitions/technical-lexicon.md b/system-design/personas-and-definitions/technical-lexicon.md index 097590a..eb5f032 100644 --- a/system-design/personas-and-definitions/technical-lexicon.md +++ b/system-design/personas-and-definitions/technical-lexicon.md @@ -37,11 +37,11 @@ Current providers supported: #### Application -An application is a collection of one, or more, [Components](#component), as defined by an [Application Description](../specification/application-package/application-description.md), and bundled within an [Application Package](#application-package). +An application is a collection of one, or more, [Components](#component), as defined by an [Application Description](../specification/applications/application-description.md), and bundled within an [Application Package](#application-package). #### Application Package -An Application Package is used to distribute an [application](#application). The parts of an Application Package are: Application Description (that refers to contained and deployable Components) as well as associated resources (e.g., icons). While the application package is made available in an [Application Registry](../concepts/workloads/application-registry.md), the referenced [components](#component) are stored in a [Component Registry](#component-registry), and the linked containers are provided via a OCI [Container Registry](#container-registry). +An Application Package is used to distribute an [application](#application). The parts of an Application Package are: Application Description (that refers to contained and deployable Components) as well as associated resources (e.g., icons). While the application package is made available in an [Application Registry](../concepts/applications/application-registry.md), the referenced [components](#component) are stored in a [Component Registry](#component-registry), and the linked containers are provided via a OCI [Container Registry](#container-registry). #### Component @@ -84,9 +84,9 @@ Device Fleet Manager (DFM) represents a software offering that enables End Users #### Application Registry -An [Application Registry](../concepts/workloads/application-registry.md) hosts [Application Packages](#application-package) that define, through their [Application Description](../specification/application-package/application-description.md), the application as one or multiple [Components](#component). +An [Application Registry](../concepts/applications/application-registry.md) hosts [Application Packages](#application-package) that define, through their [Application Description](../specification/applications/application-description.md), the application as one or multiple [Components](#component). It is used by application developers to make their applications available. -The [API of the Application Registry](../specification/application-package/application-registry.md) is compliant with the [OCI Registry API (v1.1.0)](https://github.com/opencontainers/distribution-spec/blob/v1.1.0/spec.md). +The [API of the Application Registry](../specification/applications/application-registry.md) is compliant with the [OCI Registry API (v1.1.0)](https://github.com/opencontainers/distribution-spec/blob/v1.1.0/spec.md). > To be clarified (Arne): > @@ -102,7 +102,7 @@ An Application Catalog obtains the offered [Applications](#application) from one #### Component Registry A Component Registry holds [Components](#component) (e.g., Helm Charts and Compose Archives) for [Application Packages](#application-package). -When an application gets deployed through a [Workload Fleet Manager](#workload-fleet-manager), the components (linked within an [Application Description](../specification/application-package/application-description.md)) are requested from the Component Registry and then deployed as [workloads](#workload). Components link to containers that are typically provided through [Container Registries](#container-registry). +When an application gets deployed through a [Workload Fleet Manager](#workload-fleet-manager), the components (linked within an [Application Description](../specification/applications/application-description.md)) are requested from the Component Registry and then deployed as [workloads](#workload). Components link to containers that are typically provided through [Container Registries](#container-registry). The Component Registry can be implemented, e.g., as an OCI Registry. #### Container Registry diff --git a/system-design/specification/application-package/.gitkeep b/system-design/specification/application-package/.gitkeep deleted file mode 100644 index e69de29..0000000 diff --git a/system-design/specification/application-package/application-registry.md b/system-design/specification/application-package/application-registry.md deleted file mode 100644 index c9cdc05..0000000 --- a/system-design/specification/application-package/application-registry.md +++ /dev/null @@ -1,259 +0,0 @@ -# Application Registry - -The interactions of an `Application Registry` are described [here](../../concepts/workloads/application-registry.md) from a conceptual view. This section formally specifies the API of the `Application Registry` and the exchange of an [Application Package](../../concepts/workloads/application-package.md), defined through an [Application Description](../../specification/application-package/application-description.md) file, from an Application Developer to the [Workload Fleet Manager](../../personas-and-definitions/technical-lexicon.md#workload-fleet-manager) (WFM). The `Application Registry` is designed as an `OCI Registry`, i.e., it offers an API compliant with the [OCI Registry API (v1.1.0)](https://github.com/opencontainers/distribution-spec/blob/v1.1.0/spec.md) (called here the "OCI_spec") for digital artifact distribution. This way, the Application Registry hosts the parts of an [Application Package](../../concepts/workloads/application-package.md) in the form of `blobs` and uses `image manifests` according to [OCI Image specification](https://github.com/opencontainers/image-spec/blob/v1.0.1/manifest.md) to list a set of `layers`, each pointing at a blob. - -## Overview of API Endpoints - -The WFM MUST interact with the Application Registry compliant to the OCI Registry API endpoints defined in the [OCI_spec](https://github.com/opencontainers/distribution-spec/blob/v1.1.0/spec.md): - -* Tags: `/v2/{name}/tags/list` for listing available versions of an Application Package -* Manifest: `/v2/{name}/manifests/{reference}` for retrieving an image manifest (identifed through the `{reference}`) that lists layers, which represent the parts of the Application Package. -* Blob: `/v2/{name}/blobs/{digest}` for downloading parts of the Application Package - -`{name}` is the namespace of the repository, which needs to be directly communicted by the App Developer to the WFM vendor. It could be for example a combination of the organization's and application's name. - -Further details on how to use these API endpoints are specified below [towards App Developer](#uploading-an-application-package) and [towards WFM](#retrieving-an-application-package). - -## Authentication, Authorization & Security -Margo recommends the use of an Authentication Service for the interactions between the WFM and Application Registry as conceptually described [here](../../concepts/workloads/application-registry.md), e.g., implemented using OAuth 2.0. This involves the following workflow: - -* WFM obtains credentials during onboarding -* WFM requests a token from an Authentication Service -* WFM uses the token for subsequent API calls to the Application Registry -* Application Registry validates the token and enforces access control - -Thereby, all communications must use TLS 1.3+ to ensure transport security. - -> Note: Authentication, Authorization & Security mechanisms should be defined centrally and homogeneously across Margo. Hence, it is not further defined here. - -Further, tools such as [cosign](https://github.com/sigstore/cosign) may be employed for signing artifacts uploaded to the Application Registry and storing the signatures alongside the artifacts they verify. - - - -## Uploading an Application Package - -As shown in the sequence diagram below, the Application Developer uploads the Margo-compliant `Application Package` to the Application Registry. I.e., all parts of the Application Package MUST be pushed as blobs compliant with the [end-4a / end-4b](https://github.com/opencontainers/distribution-spec/blob/v1.1.0/spec.md#endpoints) endpoints of the OCI_spec. - -Subsequently, the Application Developer creates an OCI image manifest that lists layers, each of which links to an uploaded blob. Then the manifest MUST be pushed to the Application Registry compliant to the [end-7](https://github.com/opencontainers/distribution-spec/blob/v1.1.0/spec.md#endpoints) endpoint of the OCI_spec. - -The uploaded OCI image manifest MUST adhere to the Margo-specific constraints detailed [here](#oci-image-manifest-as-response-from-application-registry). - -Subsequently, the App Developer uses a UI or other vendor-specific mechanism to communicate (either directly or indirectly, e.g., via a Marketplace) to the WFM the namespace of the Application Package's repository. - -```mermaid -sequenceDiagram - - Note over AppDeveloper: uploads parts of Application Package as blobs: - AppDeveloper->>AppRegistry: push blobs - - AppDeveloper->>AppRegistry: push manifest - - Note over AppDeveloper: uses vendor-specific upload mechanism (e.g., UI) to enable WFM to find the Application Package: - AppDeveloper->>+WFM: Application Package location is: repository name in Application Registry -``` - -There are no further Margo-specific constraints regarding the upload of the Application Package. The details defined in the [OCI_spec](https://github.com/opencontainers/distribution-spec/blob/v1.1.0/spec.md) MUST be applied to this interface of the Application Registry. - - - -## Retrieving an Application Package - -The WFM has received the namespace of the repository of the Application Package at the Application Registry. - -Next, as shown in the sequence diagram below, the WFM uses the API endpoints defined in the OCI_spec to retrieve a list of Application Package versions (as detailed [here](#list-Margo-application-package-versions)). - -Then, the WFM pulls the OCI image manifest of the selected version of the Application Package, with the identifying reference being a tag or digest (as detailed [here](#pull-oci-image-manifest-of-application-package)). - -Finally, all parts (e.g., the Application Description file, the icon, the license, etc.) of the Application Package are retrieved by pulling the respective blobs listed as layers in the image manifest (as detailed [here](#get-parts-of-application-package)). - -```mermaid -sequenceDiagram - Note over WFM: retrieve available versions of an Application Package: - WFM->>+AppRegistry: GET /v2/{name}/tags/list - - Note over WFM: retrieves the OCI image manifest of the selected Application Package version. {reference} is a tag or a digest: - WFM->>+AppRegistry: GET /v2/{name}/manifests/{reference} - - AppRegistry-->>+WFM: OCI image manifest - - Note over WFM: retrieves parts of the Application Package as listed in OCI image manifest layers: - WFM->>AppRegistry: GET /v2/{name}/blobs/{digest} -``` - -### List Margo Application Package Versions - -The interface to retrieve the list of versions of an Application Package MUST be implemented according to OCI_spec endpoint [end-8a](https://github.com/opencontainers/distribution-spec/blob/v1.1.0/spec.md#endpoints). - -To get a list of available versions of an Application Package, an HTTP ``GET`` request to a resource path MUST be performed in the following format: `/v2/{name}/tags/list`. The `{name}` variable is the namespace of the Application Package repository, which was communicated by the App Developer to the WFM vendor. - -The HTTP headers of the ``GET`` request MAY include ```Authorization: Bearer ``` for including the interaction with the [Authentication Service](../../concepts/workloads/application-registry.md). - -To query a subset of tags, the following query parameters MUST be implemented by the Application Registry as defined by OCI_spec endpoint [end-8b](https://github.com/opencontainers/distribution-spec/blob/v1.1.0/spec.md#endpoints): - -* ``n=`` (optional, limits results to n tags) -* ``last=`` (optional, starts list of tags after ````) - -The response of the HTTP ``GET`` request according to [end-8a/end-8b](https://github.com/opencontainers/distribution-spec/blob/v1.1.0/spec.md#endpoints) is a list of tags, which comply with the versions of available Application Packages. According to OCI_spec, upon success, the response MUST be a JSON body in the following format: - -```json -{ - "name": "", - "tags": [ - "", # each tag MUST be the value of the 'metadata.version' of the associated Application Package's Application Description document. - "", - "" - ] -} -``` - -Thereby, a listed tag of an image manifest MUST be the same as the value of the key ``metadata.version`` as specified in the Application Description document of the associated Application Package. - -#### Example A: - -Request: GET ``http://famous-app-registry/v2/northstar-industrial-applications/app1/tags/list`` - -Response: -```json -{ - "name": "northstar-industrial-applications/app1", - "tags": [ - "v1.0.0", - "v1.1.0", - "latest" - ] -} -``` - -#### Example B: - -Request: GET ``http://famous-app-registry/v2/northstar-industrial-applications/app1/tags/list?n=2&last=v1.0.0`` - -Response: -```json -{ - "name": "northstar-industrial-applications/app1", - "tags": [ - "v1.1.0", - "latest" - ] -} -``` - -### Pull OCI Image Manifest of Application Package - -The interface to retrieve the OCI image manifest of a specified version, which belongs to an Application Package, MUST be implemented according to OCI_spec endpoint [end-3](https://github.com/opencontainers/distribution-spec/blob/v1.1.0/spec.md#endpoints). - -To pull an Application Package, an HTTP ``GET`` request to a resource path MUST be performed in the following format: -`/v2/{name}/manifests/{reference}`. -The `{reference}` is the `tag` of an OCI image manifest. The `tag` has been discovered via the [listing of application package versions](#list-margo-application-package-versions). -The `{name}` variable is the namespace of the Application Package repository. - -The HTTP headers of the ``GET`` request MAY include ```Authorization: Bearer ``` for including the interaction with the [Authentication Service](../../concepts/workloads/application-registry.md). - -#### OCI Image Manifest as Response from Application Registry: - -The successful response of the HTTP ``GET`` request is an OCI image manifest (as defined in the OCI_spec), which MUST contain pointers to all parts of an Application Package within the Application Registry. - -Each version of an Application Package MUST have its own OCI image manifest. - -The ``schemaVersion`` of the OCI image manifest needs to be ``2``. - -The ``artifactType`` of the OCI image manifest must be ``application/vnd.margo.app.v1+json``. - -The ``config`` object must be declared as empty by defining its ``mediaType`` as ``application/vnd.oci.empty.v1+json``. - -Each element of the ``layers`` array contains a reference (so-called `digests`) to an artifact (so-called `blobs`) that is a part of the Application Package. - -Each Application Package part must be listed as an element of the ``layers`` array: - -* The [Application Description](../../specification/application-package/application-description.md) of the Application Package must be referred to in one element of the ``layers`` array, where the ``mediaType`` of this layer/blob must be ``application/vnd.margo.app.description.v1+yaml``. -* Each [application resource](../../concepts/workloads/application-package.md), which is an additional file associated with the application (e.g., manual, icon, release notes, license file, etc.), must be referred to in an element of the ``layers`` array. Such a layer must have an ``annotation``, which has the annotation key ``org.margo.app.resource``, and the annotation value must reflect the dotted path to the this resource in the [Application Description file](../../specification/application-package/application-description.md). E.g., an application icon stored as the file ``resources/margo.jpg`` is referenced in the Application Description under ``metadata.catalog.application.icon: resources/margo.jpg`` and in the OCI image manifest, the respective layer of the icon resource has the annotation ``org.margo.app.resource`` with the value ``metadata.catalog.application.icon`` (see also OCI image manifest example below). - -The following response example is a Margo-specific OCI image manifest following the [OCI Image Manifest Specification](https://github.com/opencontainers/image-spec/blob/v1.0.1/manifest.md) and the above defined specifics: - -```json -{ - "schemaVersion": 2, - "mediaType": "application/vnd.oci.image.manifest.v1+json", - "artifactType": "application/vnd.margo.app.v1+json" # this MUST be the artifactType of an OCI image manifest of a Margo Application Package, - "config": { - "mediaType": "application/vnd.oci.empty.v1+json", # the 'config' object MUST be empty - "digest": "sha256:44136fa355b3678a1146ad16f7e8649e94fb4fc21fe77e8310c060f61caaff8a", - "size": 2, - "data": "e30=" - }, - "layers": [ - { - "mediaType": "application/vnd.margo.app.description.v1+yaml", # this MUST be the artifactType of a Margo Application Description file - "digest": "sha256:f6b79149e6650b0064c146df7c045d157f3656b5ad1279b5ce9f4446b510bacf", - "size": 999, - "annotations": { - "org.opencontainers.image.title": "margo.yaml" - } - }, - { - "mediaType": "text/markdown", - "digest": "sha256:e373b123782a2b52483a9124cc9c578e0ed0300cb4131b73b0c79612122b8361", - "size": 1596, - "annotations": { - "org.margo.app.resource": "metadata.catalog.application.descriptionFile", # each Margo application resource MUST be annotated with a dotted path to its definition in the Application Description file - "org.opencontainers.image.title": "resources/description.md" - } - }, - { - "mediaType": "text/markdown", - "digest": "sha256:af7db4ab9030533b6cda2325247920c3659bc67a7d49f3d5098ae54a64633ec7", - "size": 25, - "annotations": { - "org.margo.app.resource": "metadata.catalog.application.licenseFile", # each Margo application resource MUST be annotated with a dotted path to its definition in the Application Description file - "org.opencontainers.image.title": "resources/license.md" - } - }, - { - "mediaType": "image/jpeg", - "digest": "sha256:451410b6adfdce1c974da2275290d9e207911a4023fafea0e283fad0502e5e56", - "size": 5065, - "annotations": { - "org.margo.app.resource": "metadata.catalog.application.icon", # each Margo application resource MUST be annotated with a dotted path to its definition in the Application Description file - "org.opencontainers.image.title": "resources/margo.jpg" - } - }, - { - "mediaType": "text/markdown", - "digest": "sha256:c412d143084c3b051d7ea4b166a7bfffb4550f401d89cae8898991c65e90f736", - "size": 42, - "annotations": { - "org.margo.app.resource": "metadata.catalog.application.releaseNotes", # each Margo application resource MUST be annotated with a dotted path to its definition in the Application Description file - "org.opencontainers.image.title": "resources/release-notes.md" - } - } - ], -} -``` - -#### Margo-Specific Media Types - -|Media Type|Description| -|----------|----------| -|``application/vnd.margo.app.v1+json`` | MUST be used as the **artifactType** to mark the OCI image manifest as the definition of a Margo Application Package | -|``application/vnd.margo.app.description.v1+yaml`` | MUST be used to mark a layer in the OCI image manifest as pointing to the Margo Application Description file | - - -#### Margo-Specific Annotation Keys - -|Annotation Key | Description| -|----------|----------| -|``org.margo.app.resource`` | MUST be used to annotate a layer/blob that references a Margo application resource | - - - -### Get Parts of Application Package - -The interface to retrieve Application Package parts, i.e., Application Description or Application Resource (e.g., icon, license, etc.), MUST be implemented according to OCI_spec endpoint [end-2](https://github.com/opencontainers/distribution-spec/blob/v1.1.0/spec.md#endpoints) by pulling a blob. - -To pull such a blob, an HTTP ``GET`` request to a resource path MUST be performed in the following format: -`/v2/{name}/blobs/{digest}`. -The `{digest}` is the blob's digest as listed in the application's OCI image manifest that has been [retrieved earlier](#pull-oci-image-manifest-of-application-package). -The `{name}` variable is the namespace of the Application Package repository. - -The HTTP headers of the ``GET`` request MAY include ```Authorization: Bearer ``` for including the interaction with the [Authentication Service](../../concepts/workloads/application-registry.md). From 5528706fe2690eebe9c896ed67c40b55d11f9794 Mon Sep 17 00:00:00 2001 From: Arne Broering Date: Fri, 7 Nov 2025 16:56:43 +0100 Subject: [PATCH 17/29] renamed the files & folders which were renamed in the nav Signed-off-by: Arne Broering --- .../application-description.linkml.yaml | 766 ++++++++++++++++++ .../applications/resources/class.md.jinja2 | 0 .../valid/ApplicationDescription-001.yaml | 59 ++ .../valid/ApplicationDescription-002.yaml | 208 +++++ .../applications/resources/index.md.jinja2 | 157 ++++ .../applications/application-package.md | 43 + .../applications/application-registry.md | 44 + .../concepts/applications/local-registries.md | 88 ++ .../overview/applications-and-workloads.md | 78 ++ .../specification/applications/.gitkeep | 0 .../applications/application-registry.md | 259 ++++++ 11 files changed, 1702 insertions(+) create mode 100644 src/specification/applications/application-description.linkml.yaml create mode 100644 src/specification/applications/resources/class.md.jinja2 create mode 100644 src/specification/applications/resources/examples/valid/ApplicationDescription-001.yaml create mode 100644 src/specification/applications/resources/examples/valid/ApplicationDescription-002.yaml create mode 100644 src/specification/applications/resources/index.md.jinja2 create mode 100644 system-design/concepts/applications/application-package.md create mode 100644 system-design/concepts/applications/application-registry.md create mode 100644 system-design/concepts/applications/local-registries.md create mode 100644 system-design/overview/applications-and-workloads.md create mode 100644 system-design/specification/applications/.gitkeep create mode 100644 system-design/specification/applications/application-registry.md diff --git a/src/specification/applications/application-description.linkml.yaml b/src/specification/applications/application-description.linkml.yaml new file mode 100644 index 0000000..c95170b --- /dev/null +++ b/src/specification/applications/application-description.linkml.yaml @@ -0,0 +1,766 @@ +# yaml-language-server: $schema=https://linkml.io/linkml-model/linkml_model/jsonschema/meta.schema.json +id: http://specification.margo.org/application-schema +name: ApplicationDescription +title: Application Description Schema +description: >- + Schema for defining application metadata, deployment profiles, parameters, and configuration. + The purpose of this file is to present the application on an application catalog or marketplace + from where an end user selects the application to hand it over to the Workload Orchestration Software, + which configures it and makes it available for installation on the edge device. +version: 1.0 +prefixes: + linkml: https://w3id.org/linkml/ + margo: https://specification.margo.org/ +imports: + - linkml:types + +default_prefix: margo + + +# Class Definitions +classes: + ApplicationDescription: + description: Root class for an application description. + attributes: + apiVersion: + description: Identifier of the version of the API the object definition follows. + required: true + range: string + rank: 10 + kind: + description: Specifies the object type; must be `ApplicationDescription`. + range: string + required: true + equals_string: "ApplicationDescription" + rank: 20 + metadata: + description: >- + Metadata element specifying characteristics about the application deployment. + See the [Metadata Attributes](#metadata-attributes) section below. + range: Metadata + required: true + rank: 30 + deploymentProfiles: + description: >- + Deployment profiles element specifying the types of deployments the application supports. + See the [Deployment](#deploymentprofile-attributes) section below. + range: DeploymentProfile + multivalued: true + inlined: true + inlined_as_list: true + required: true + rank: 40 + parameters: + description: >- + Parameters element specifying the configurable parameters to use when installing, or updating, the application. + See the [Parameter](#parameter-attributes) section below. + range: Parameter + multivalued: true + inlined: true + inlined_as_list: false + rank: 50 + configuration: + description: >- + Configuration element specifying how parameters should be displayed to the user for setting the value + as well as the rules to use to validate the user's input. + See the [Configuration](#configuration-attributes) section below. + range: Configuration + rank: 60 + + Metadata: + description: Metadata about the application. + rank: 10 + attributes: + id: + description: >- + An identifier for the application. The id is used to help create unique identifiers where required, + such as namespaces. The id must be lower case letters and numbers and MAY contain dashes. + Uppercase letters, underscores and periods MUST NOT be used. The id MUST NOT be more than 200 characters. + rank: 10 + range: string + required: true + pattern: ^[a-z0-9-]{1,200}$ + name: + description: >- + The application's official name. + This name is for display purposes only and can container whitespace and special characters. + rank: 20 + range: string + required: true + description: + range: string + rank: 25 + version: + description: The application's version. + rank: 30 + range: string + required: true + catalog: + description: >- + Catalog element specifying the application catalog details used to display the application + in an application catalog or marketplace. + See the [Catalog](#catalog-attributes) section below. + rank: 40 + range: Catalog + required: true + + Catalog: + description: Catalog metadata for displaying the application. + rank: 20 + attributes: + application: + description: >- + Application element specifying the application specific metadata. + See the [Application Metadata](#applicationmetadata-attributes) section below. + rank: 10 + range: ApplicationMetadata + author: + description: >- + Author element specifying metadata about the application's author. + See the [Author Metadata](#author-attributes) section below. + rank: 20 + range: Author + multivalued: true + inlined: true + inlined_as_list: true + organization: + description: >- + Organization element specifying metadata about the organization/company providing the application. + See the [Organization Metadata](#organization-attributes) section below. + rank: 30 + range: Organization + multivalued: true + required: true + inlined: true + inlined_as_list: true + + ApplicationMetadata: + description: Metadata specific to the application. + rank: 30 + attributes: + descriptionFile: + description: Link to the file containing the application's full description. The file should be a markdown file. + rank: 10 + range: string + icon: + description: Link to the icon file (e.g., in PNG format). + rank: 20 + range: string + licenseFile: + description: Link to the file that details the application's license. The file should either be a plain text, markdown or PDF file. + rank: 30 + range: string + releaseNotes: + description: Statement about the changes for this application's release. The file should either be a markdown or PDF file. + rank: 40 + range: string + site: + description: Link to the application's website. + rank: 50 + range: string + tagline: + description: The application's slogan. + rank: 60 + range: string + tags: + description: An array of strings that can be used to provide additional context for the application in a user interface to assist with task such as categorizing, searching, etc. + rank: 70 + range: string + multivalued: true + inlined: true + inlined_as_list: true + + Author: + description: Information about the application's author. + rank: 40 + attributes: + name: + description: The name of the application's creator. + rank: 10 + range: string + email: + description: Email address of the application's creator. + rank: 20 + range: string + pattern: .*@[a-z0-9.-]* + + Organization: + description: Information about the providing organization. + rank: 50 + attributes: + name: + description: Organization responsible for the application's development and distribution. + rank: 10 + range: string + required: true + site: + description: Link to the organization's website. + rank: 20 + range: string + + DeploymentProfile: + description: Represents a deployment configuration for the application. + rank: 60 + attributes: + id: + description: >- + An identifier for the deployment profile, given by the application developer, used to uniquely identify this deployment profile from others within this application description's scope. + rank: 10 + range: string + required: true + description: + description: >- + This human-readable description of a deployment profile allows for providing additional context about the deployment profile. E.g., the application developer can use this to describe the deployment profile's purpose, + such as the intended use case. Additionally, the application developer can use this to provide further details about the resources, peripherals, and interfaces required to run the application. + rank: 20 + range: string + required: false + requiredResources: + description: >- + Required resources element specifying the resources required to install the application. + See the [Required Resources](#requiredresources-attributes) section below. + The consequences (e.g., aborting / blocking the installation or execution of the application) of not meeting these required resources are not defined (yet) by margo. + rank: 30 + range: RequiredResources + required: false + slots: + - type + - components + + RequiredResources: + description: >- + Required resources element specifying the resources required to install the application. + rank: 61 + attributes: + cpu: + description: >- + CPU element specifying the CPU requirements for the application. + See the [CPU](#cpu-attributes) section below. + range: CPU + required: false + rank: 10 + memory: + description: The minimum amount of memory required. + The value is given in binary units (`Ki` = Kibibytes, `Mi` = Mebibytes, `Gi` = Gibibytes). + This is defined by the application developer. + After deployment of the application, the device MUST provide this amount of memory for the application. + rank: 20 + range: string + pattern: ^[0-9]+(Mi|Gi|Ki)$ + required: false + storage: + description: The amount of storage required for the application to run. This encompasses the installed application and the data it needs to store. + The value is given in binary units (`Ki` = Kibibytes, `Mi` = Mebibytes, `Gi` = Gibibytes, `Ti` Tebibytes, `Pi` = Pebibytes, `Ei` = Exbibytes). + This is defined by the application developer. + After deployment of the application, the device MUST provide this amount of storage for the application + rank: 30 + range: string + pattern: ^[0-9]+(Mi|Gi|Ki|Ti|Pi|Ei)$ + required: false + peripherals: + description: >- + Peripherals element specifying the peripherals required to run the application. + See the [Peripheral](#peripheral-attributes) section below. + range: Peripheral + rank: 40 + multivalued: true + inlined: true + inlined_as_list: true + required: false + interfaces: + description: >- + Interfaces element specifying the communication interfaces required to run the application. + See the [Communication Interfaces](#communicationinterface-attributes) section below. + range: CommunicationInterface + rank: 40 + multivalued: true + inlined: true + inlined_as_list: true + required: false + + CPU: + description: >- + CPU element specifying the CPU requirements for the application. + rank: 62 + attributes: + cores: + description: The required amount of CPU cores the application must use to run in its full functionality. + Specified as decimal units of CPU cores (e.g., `0.5` is half a core). + This is defined by the application developer. + After deployment of the application, the device MUST provide this number of CPU cores for the application. + rank: 10 + range: double + required: true + architectures: + description: The CPU architectures supported by the application. This can be e.g. amd64, x86_64, arm64, arm. + See the [CpuArchitectureType](#cpuarchitecturetype) definition for all permissible values. + Multiple arcitecture types can be specified, as the deployment profile may support multiple CPU architectures. + rank: 20 + range: CpuArchitectureType + required: false + multivalued: true + inlined: true + inlined_as_list: true + + Peripheral: + description: Peripheral hardware of a device. + rank: 65 + attributes: + type: + description: The type of peripheral. This can be e.g. GPU, display, camera, microphone, speaker. + See the [PeriperalType](#peripheraltype) definition for all permissible values. + rank: 20 + range: PeripheralType + required: true + manufacturer: + description: The name of the manufacturer. If `manufacturer` is specified as a requirement here, it may be difficult to find devices that can host the application. Please use these requirements with caution. + rank: 30 + range: string + required: false + model: + description: The model of the peripheral. If `model` is specified as a requirement here, it may be difficult to find devices that can host the application. Please use these requirements with caution. + rank: 40 + range: string + required: false + + CommunicationInterface: + description: >- + Communication interface of a device. + rank: 66 + attributes: + type: + description: The type of a communication interface. This can be e.g. Ethernet, WiFi, Cellular, Bluetooth, USB, CANBus, RS232. + See the [CommunicationInterfaceType](#communicationinterfacetype) definition for all permissible values. + rank: 30 + range: CommunicationInterfaceType + required: true + + HelmDeploymentProfile: + is_a: DeploymentProfile + #rank: 63 + slot_usage: + type: + equals_string: "helm.v3" + rank: 10 + components: + range: HelmComponent + rank: 20 + + ComposeDeploymentProfile: + is_a: DeploymentProfile + #rank: 66 + slot_usage: + type: + equals_string: "compose" + rank: 10 + components: + range: ComposeComponent + rank: 20 + + Component: + description: A class representing a component of a deployment profile. + rank: 70 + attributes: + name: + description: >- + A unique name used to identify the component package. For helm installations the name will be used as the chart name. + The name must be lower case letters and numbers and MAY contain dashes. + Uppercase letters, underscores and periods MUST NOT be used. + required: true + range: string + rank: 10 + properties: + description: >- + A dictionary element specifying the component packages's deployment details. + See the [Component Properties](#componentproperties-attributes) section below. + range: ComponentProperties + required: true + rank: 20 + + HelmComponent: + is_a: Component + #rank: 73 + + ComposeComponent: + is_a: Component + #rank: 76 + + ComponentProperties: + description: Properties dictionary for component deployment details. + rank: 80 + attributes: + repository: + description: Repository location for the component. + rank: 10 + range: string + revision: + description: Revision version for the component. + rank: 20 + range: string + wait: + description: If True, indicates the device waits for the component installation to complete. + rank: 30 + range: boolean + timeout: + description: Time to wait for component installation to complete, formatted as "##m##s". + rank: 40 + range: string + packageLocation: + description: URL indicating the Compose package's location. + rank: 50 + range: string + keyLocation: + description: URL for the public key used to validate a digitally signed package. + rank: 60 + range: string + + Parameter: + description: Defines a configurable parameter for the application. + rank: 90 + attributes: + name: + description: Name of the parameter. + rank: 10 + identifier: true + required: true + range: string + value: + description: >- + The parameter's default value. + Accepted data types are string, integer, double, boolean, array[string], array[integer], array[double], array[boolean]. + rank: 20 + any_of: #support for arrays still TBD + - range: boolean + - range: integer + - range: double + - range: string + targets: + description: >- + Used to indicate which component the value should be applied to when installing, or updating, the application. + See the [Target](#target-attributes) section below. + rank: 30 + range: Target + required: true + multivalued: true + inlined: true + inlined_as_list: true + + Target: + description: Specifies where the parameter applies in the deployment. + rank: 100 + attributes: + pointer: + description: >- + The name of the parameter in the deployment configuration. + For Helm deployments, this is the dot notation for the matching element in the `values.yaml` file. This follows the same naming convention you would use with the `--set` command line argument with the `helm install` command. + For compose deployments, this is the name of the environment variable to set. + rank: 10 + range: string + required: true + components: + description: >- + Indicates which deployment profile [component](#component-attributes the parameter target applies to. + The component name specified here MUST match a component name in the [deployment profiles](#deploymentprofile-attributes) section. + rank: 20 + range: string + multivalued: true + required: true + + Configuration: + description: Configuration layout and validation rules. + rank: 110 + attributes: + sections: + description: >- + Sections are used to group related parameters together, + so it is possible to present a user interface with a logical grouping of the parameters in each section. + See the [Section](#section-attributes) section below. + rank: 10 + range: Section + multivalued: true + inlined: true + inlined_as_list: true + required: true + schema: + description: >- + Schema is used to provide details about how to validate each parameter value. + At a minimum, the parameter value must be validated to match the schema's data type. + The schema indicates additional rules the provided value must satisfy to be considered valid input. + See the [Schema](#schema-attributes) section below. + rank: 20 + range: Schema + multivalued: true + inlined: true + inlined_as_list: true + required: true + + Section: + description: Named sections within the configuration layout. + rank: 120 + attributes: + name: + description: >- + The name of the section. This may be used in the user interface to show the grouping of the associated parameters within the section. + rank: 10 + range: string + required: true + settings: + description: >- + Settings are used to provide instructions to the workload orchestration software vendor for displaying parameters to the user. + A user MUST be able to provide values for all settings. + See the [Setting](#setting-attributes) section below. + rank: 20 + range: Setting + multivalued: true + inlined: true + inlined_as_list: true + required: true + + Setting: + description: Individual configuration settings. + rank: 130 + attributes: + parameter: + description: The name of the [parameter](#parameter-attributes) the setting is associated with. + rank: 10 + range: string + required: true + name: + description: The parameter's display name to show in the user interface. + rank: 20 + range: string + required: true + description: + description: The parameters's short description to provide additional context to the user in the user interface about what the parameter is for. + rank: 30 + range: string + immutable: + description: If true, indicates the parameter value MUST not be changed once it has been set and used to install the application. Default is false if not provided. + rank: 40 + range: boolean + schema: + description: The name of the schema definition to use to validate the parameter's value. See the [Schema](#schema-attributes) section below. + rank: 50 + range: string + required: true + + Schema: + description: Defines data type and rules for validating user provided parameter values. Subclasses (see below) define for each data type their own set of validation rules that can be used. The value MUST be validated against all rules defined in the schema. + rank: 140 + attributes: + name: + description: The name of the schema rule. This used in the [setting](#setting-attributes) to link the setting to the schema rule. + rank: 10 + range: string + required: true + dataType: + description: >- + Indicates the expected data type for the user provided value. + Accepted values are string, integer, double, boolean, array[string], array[integer], array[double], array[boolean]. + At a minimum, the provided parameter value MUST match the schema's data type if no other validation rules are provided. + rank: 20 + range: string + required: true + #validationRule: + # description: >- + # Defines the validation rules to use to validate the user provided parameter value. + # The rules are based on the schema's data type and are listed below. + # The value MUST be validated against any validation rules defined in the schema. + # rank: 30 + # range: ValidationRule + # required: false + + TextValidationSchema: + is_a: Schema + description: Extends schema to define a string/text-specific set of validation rules that can be used. + rank: 150 + attributes: + allowEmpty: + description: >- + If true, indicates a value must be provided. Default is false if not provided. + rank: 30 + range: boolean + required: false + minLength: + description: If set, indicates the minimum number of characters the value must have to be considered valid. + rank: 40 + range: integer + required: false + maxLength: + description: If set, indicates the maximum number of characters the value must have to be considered valid. + rank: 50 + range: integer + required: false + regexMatch: + description: If set, indicates a regular expression to use to validate the value. + rank: 55 + range: string + required: false + + BooleanValidationSchema: + is_a: Schema + description: Extends schema to define a boolean-specific set of validation rules that can be used. + rank: 160 + attributes: + allowEmpty: + description: >- + If true, indicates a value must be provided. Default is false if not provided. + rank: 30 + range: boolean + required: false + + NumericIntegerValidationSchema: + is_a: Schema + description: Extends schema to define a integer-specific set of validation rules that can be used. + rank: 170 + attributes: + allowEmpty: + description: >- + If true, indicates a value must be provided. Default is false if not provided. + rank: 30 + range: boolean + required: false + minValue: + description: If set, indicates the minimum allowed integer value the value must have to be considered valid. + rank: 50 + range: integer + required: false + maxValue: + description: If set, indicates the maximum allowed integer value the value must have to be considered valid. + rank: 50 + range: integer + required: false + + NumericDoubleValidationSchema: + is_a: Schema + description: Extends schema to define a double-specific set of validation rules that can be used. + rank: 180 + attributes: + allowEmpty: + description: >- + If true, indicates a value must be provided. Default is false if not provided. + rank: 30 + range: boolean + required: false + minValue: + description: If set, indicates the minimum value to be considered valid. + rank: 50 + range: float + required: false + maxValue: + description: If set, indicates the maximum value to be considered valid. + rank: 50 + range: float + required: false + minPrecision: + description: If set, indicates the minimum level of precision the value must have to be considered valid. + rank: 50 + range: integer + required: false + maxPrecision: + description: If set, indicates the maximum level of precision the value must have to be considered valid. + rank: 50 + range: integer + required: false + + SelectValidationSchema: + is_a: Schema + description: Extends schema to define a specific set of validation rules that can be used for select options. + rank: 190 + attributes: + allowEmpty: + description: >- + If true, indicates a value must be provided. Default is false if not provided. + rank: 30 + range: boolean + required: false + multiselect: + description: If true, indicates multiple values can be selected. If multiple values can be selected the resulting value is an array of the selected values. The default is false if not provided. + rank: 80 + range: boolean + required: false + options: + description: This provides the list of acceptable options the user can select from. The data type for each option must match the parameter setting’s data type. + rank: 80 + range: string + multivalued: true + required: true + +slots: + type: + description: >- + Defines the type of this deployment configuration for the application. + The allowed values are `helm.v3`, to indicate the deployment profile's format is Helm version 3, + and `compose` to indicate the deployment profile's format is a Compose file. + When installing the application on a device supporting the Kubernetes platform, all `helm.v3` components, + and only `helm.v3` components, will be provided to the device in same order they are listed in the application description file. + When installing the application on a device supporting Compose, all `compose` components, + and only `compose` components, will be provided to the device in the same order they are listed in the application description file. + The device will install the components in the same order they are listed in the application description file. + range: string + required: true + pattern: ^(helm\.v3|compose)$ + rank: 10 + + components: + description: >- + Component element indicating the components to deploy when installing the application. + See the [Component](#component-attributes) section below. + range: Component + multivalued: true + required: true + inlined: true + inlined_as_list: true + rank: 20 + +enums: + CpuArchitectureType: + permissible_values: + amd64: + description: AMD 64-bit architecture. + x86_64: + description: x86 64-bit architecture. + arm64: + description: ARM 64-bit architecture. + arm: + description: ARM 32-bit architecture. + riscv64: + description: RISC-V 64-bit architecture. + other: + description: >- + Any other CPU architecture not listed here. The application developer MUST provide a description of the architecture in the deployment profile's `description` field. + + CommunicationInterfaceType: + permissible_values: + ethernet: + description: This type stands for an Ethernet interface. + wifi: + description: This type stands for an WiFi interface. + cellular: + description: This type stands for cellular communication technologies such as 5G, LTE, 3G, 2G, .... + bluetooth: + description: This type stands for a Bluetooth or Bluetooth Low-Energy (BLE) interface. + usb: + description: This type stands for a USB interface. + canbus: + description: This type stands for a CANBus interface. + rs232: + description: This type stands for a RS232 interface. + other: + description: This type stands for any other communication interface not listed here. The application developer MUST provide a description of the interface in the deployment profile's `description` field. + + PeripheralType: + permissible_values: + gpu: + description: This type stands for a Graphics Processing Unit (GPU) peripheral. + display: + description: This type stands for a display peripheral. + camera: + description: This type stands for a camera peripheral. + microphone: + description: This type stands for a microphone peripheral. + speaker: + description: This type stands for a speaker peripheral. + other: + description: This type stands for any other peripheral not listed here. The application developer MUST provide a description of the peripheral in the deployment profile's `description` field. + diff --git a/src/specification/applications/resources/class.md.jinja2 b/src/specification/applications/resources/class.md.jinja2 new file mode 100644 index 0000000..e69de29 diff --git a/src/specification/applications/resources/examples/valid/ApplicationDescription-001.yaml b/src/specification/applications/resources/examples/valid/ApplicationDescription-001.yaml new file mode 100644 index 0000000..5eef610 --- /dev/null +++ b/src/specification/applications/resources/examples/valid/ApplicationDescription-001.yaml @@ -0,0 +1,59 @@ +apiVersion: margo.org/v1-alpha1 +kind: ApplicationDescription +metadata: + id: com-northstartida-hello-world + name: Hello World + description: A basic hello world application + version: "1.0" + catalog: + application: + icon: ./resources/hw-logo.png + tagline: Northstar Industrial Application's hello world application. + descriptionFile: ./resources/description.md + releaseNotes: ./resources/release-notes.md + licenseFile: ./resources/license.pdf + site: http://www.northstar-ida.com + tags: ["monitoring"] + author: + - name: Roger Wilkershank + email: rpwilkershank@northstar-ida.com + organization: + - name: Northstar Industrial Applications + site: http://northstar-ida.com +deploymentProfiles: + - type: helm.v3 + id: com-northstartida-hello-world-helm.v3-a + components: + - name: hello-world + properties: + repository: oci://northstarida.azurecr.io/charts/hello-world + revision: 1.0.1 + wait: true +parameters: + greeting: + value: Hello + targets: + - pointer: global.config.appGreeting + components: ["hello-world"] + greetingAddressee: + value: World + targets: + - pointer: global.config.appGreetingAddressee + components: ["hello-world"] +configuration: + sections: + - name: General Settings + settings: + - parameter: greeting + name: Greeting + description: The greeting to use. + schema: requireText + - parameter: greetingAddressee + name: Greeting Addressee + description: The person, or group, the greeting addresses. + schema: requireText + schema: + - name: requireText + dataType: string + maxLength: 45 + allowEmpty: false diff --git a/src/specification/applications/resources/examples/valid/ApplicationDescription-002.yaml b/src/specification/applications/resources/examples/valid/ApplicationDescription-002.yaml new file mode 100644 index 0000000..c21c8d9 --- /dev/null +++ b/src/specification/applications/resources/examples/valid/ApplicationDescription-002.yaml @@ -0,0 +1,208 @@ +apiVersion: margo.org/v1-alpha1 +kind: ApplicationDescription +metadata: + id: com-northstartida-digitron-orchestrator + name: Digitron orchestrator + description: The Digitron orchestrator application + version: 1.2.1 + catalog: + application: + icon: ./resources/ndo-logo.png + tagline: Northstar Industrial Application's next-gen, AI driven, Digitron instrument orchestrator. + descriptionFile: ./resources/description.md + releaseNotes: ./resources/release-notes.md + licenseFile: ./resources/license.pdf + site: http://www.northstar-ida.com + tags: ["optimization", "instrumentation"] + author: + - name: Roger Wilkershank + email: rpwilkershank@northstar-ida.com + organization: + - name: Northstar Industrial Applications + site: http://northstar-ida.com +deploymentProfiles: + - type: helm.v3 + id: com-northstartida-digitron-orchestrator-helm.v3-a + description: This allows to install / run the application as a Helm chart deployment. + The device where this application is installed needs to have a screen and a keyboard (as indicated in the required peripherals). + components: + - name: database-services + properties: + repository: oci://quay.io/charts/realtime-database-services + revision: 2.3.7 + wait: true + timeout: 8m30s + - name: digitron-orchestrator + properties: + repository: oci://northstarida.azurecr.io/charts/northstarida-digitron-orchestrator + revision: 1.0.9 + wait: true + requiredResources: + cpu: + cores: 1.5 + architectures: + - amd64 + - x86_64 + memory: 1024Mi + storage: 10Gi + peripherals: + - type: gpu + manufacturer: NVIDIA + - type: display + interfaces: + - type: ethernet + - type: bluetooth + - type: compose + id: com-northstartida-digitron-orchestrator-compose-a + components: + - name: digitron-orchestrator-docker + properties: + packageLocation: https://northsitarida.com/digitron/docker/digitron-orchestrator.tar.gz + keyLocation: https://northsitarida.com/digitron/docker/public-key.asc +parameters: + idpName: + targets: + - pointer: idp.name + components: ["digitron-orchestrator"] + - pointer: ENV.IDP_NAME + components: ["digitron-orchestrator-docker"] + idpProvider: + targets: + - pointer: idp.provider + components: ["digitron-orchestrator"] + - pointer: ENV.IDP_PROVIDER + components: ["digitron-orchestrator-docker"] + idpClientId: + targets: + - pointer: idp.clientId + components: ["digitron-orchestrator"] + - pointer: ENV.IDP_CLIENT_ID + components: ["digitron-orchestrator-docker"] + idpUrl: + targets: + - pointer: idp.providerUrl + components: ["digitron-orchestrator"] + - pointer: idp.providerMetadata + components: ["digitron-orchestrator"] + - pointer: ENV.IDP_URL + components: ["digitron-orchestrator-docker"] + adminName: + targets: + - pointer: administrator.name + components: ["digitron-orchestrator"] + - pointer: ENV.ADMIN_NAME + components: ["digitron-orchestrator-docker"] + adminPrincipalName: + targets: + - pointer: administrator.userPrincipalName + components: ["digitron-orchestrator"] + - pointer: ENV.ADMIN_PRINCIPALNAME + components: ["digitron-orchestrator-docker"] + pollFrequency: + value: 30 + targets: + - pointer: settings.pollFrequency + components: ["digitron-orchestrator", "database-services"] + - pointer: ENV.POLL_FREQUENCY + components: ["digitron-orchestrator-docker"] + siteId: + targets: + - pointer: settings.siteId + components: ["digitron-orchestrator", "database-services"] + - pointer: ENV.SITE_ID + components: ["digitron-orchestrator-docker"] + cpuLimit: + value: 1 + targets: + - pointer: settings.limits.cpu + components: ["digitron-orchestrator"] + memoryLimit: + value: 16384 + targets: + - pointer: settings.limits.memory + components: ["digitron-orchestrator"] +configuration: + sections: + - name: General + settings: + - parameter: pollFrequency + name: Poll Frequency + description: How often the service polls for updated data in seconds + schema: pollRange + - parameter: siteId + name: Site Id + description: Special identifier for the site (optional) + schema: optionalText + - name: Identity Provider + settings: + - parameter: idpName + name: Name + description: The name of the Identity Provider to use + immutable: true + schema: requiredText + - parameter: idpProvider + name: Provider + description: Provider something something + immutable: true + schema: requiredText + - parameter: idpClientId + name: Client ID + description: The client id + immutable: true + schema: requiredText + - parameter: idpUrl + name: Provider URL + description: The url of the Identity Provider + immutable: true + schema: url + - name: Administrator + settings: + - parameter: adminName + name: Presentation Name + description: The presentation name of the administrator + schema: requiredText + - parameter: adminPrincipalName + name: Principal Name + description: The principal name of the administrator + schema: email + - name: Resource Limits + settings: + - parameter: cpuLimit + name: CPU Limit + description: Maximum number of CPU cores to allow the application to consume + schema: cpuRange + - parameter: memoryLimit + name: Memory Limit + description: Maximum number of memory to allow the application to consume + schema: memoryRange + schema: + - name: requiredText + dataType: string + maxLength: 45 + allowEmpty: false + - name: email + dataType: string + allowEmpty: false + regexMatch: .*@[a-z0-9.-]* + - name: url + dataType: string + allowEmpty: false + regexMatch: ^(http(s):\/\/.)[-a-zA-Z0-9@:%._\+~#=]{2,256}\.[a-z]{2,6}\b([-a-zA-Z0-9@:%_\+.~#?&//=]*)$ + - name: pollRange + dataType: integer + minValue: 30 + maxValue: 360 + allowEmpty: false + - name: optionalText + dataType: string + minLength: 5 + allowEmpty: true + - name: cpuRange + dataType: double + minValue: 0.5 + maxPrecision: 1 + allowEmpty: false + - name: memoryRange + dataType: integer + minValue: 16384 + allowEmpty: false \ No newline at end of file diff --git a/src/specification/applications/resources/index.md.jinja2 b/src/specification/applications/resources/index.md.jinja2 new file mode 100644 index 0000000..bc1be7b --- /dev/null +++ b/src/specification/applications/resources/index.md.jinja2 @@ -0,0 +1,157 @@ +# Application Description + +The Application Description has the purpose of presenting the application (e.g., on a WFM-internal [Application Catalog](../../personas-and-definitions/technical-lexicon.md#workload-fleet-manager)) +or public [Marketplace](../../personas-and-definitions/technical-lexicon.md#marketplace)) from where an end user selects an application to be installed. +The end user defines an `ApplicationDeployment` by specifying [configuration parameters](#defining-configurable-application-parameters) for an `ApplicationDescription`. +An `ApplicationDeployment` defines the [desired state](../margo-management-interface/desired-state.md) for an application. + +### Top-level Attributes + +{% macro abort(error) %} + {{ None['[ERROR] ' ~ error][0] }} +{% endmacro %} + +{%- macro format_range(slot) -%} + {%- if slot.multivalued -%} + {%- if slot.inlined -%} + {%- if slot.inlined_as_list -%} + []{{ slot.range }} + {%- else -%} + {%- if slot.name == "properties" -%} + map[string][string] + {%- else -%} + map[string][{{ slot.range }}] + {%- endif -%} + {%- endif -%} + {%- else -%} + []string + {%- endif -%} + {%- else -%} + {{ slot.range }} + {%- endif -%} +{%- endmacro -%} + +| Attribute | Type | Required? | Description | +| --- | --- | --- | --- | +{% for slot in schemaview.class_slots("ApplicationDescription")|sort(attribute='rank') -%} +| {{ slot }} | {{ format_range(schemaview.get_slot(slot)) }} | {% if schemaview.get_slot(slot).required == True %} Y {% else %} N {% endif %} | {{ schemaview.get_slot(slot).description }}| +{% endfor -%} + +{% for c in gen.all_class_objects()|sort(attribute='rank') %} +{%- if c.name != "ApplicationDescription" and not c.name.startswith("ComponentProperties") and not c.name.startswith("Helm") and not c.name.startswith("Compose") %} + +{# if c is a subclass of any: #} + +{%- if c.is_a -%} +* #### {{ c.name }} Attributes
+(Subclass of {{ c.is_a }})
+{%- else -%} +### {{ c.name }} Attributes
+{%- endif %} + +{%- if c.description -%} +
+{{ c.description }}
+{%- endif %} + +| Attribute | Type | Required? | Description | +| --- | --- | --- | --- | +{% for slot in gen.get_direct_slots(c)|sort(attribute='rank') -%} +{%- if slot.name != "value" -%} +| {{ slot.name }} | {{ format_range(slot) }} | {% if slot.required == True %} Y {% else %} N {% endif %} | {{ slot.description }}| +{%- else -%} +| {{ slot.name }} | <*see description*> | {% if slot.required == True %} Y {% else %} N {% endif %} | {{ slot.description }}| +{%- endif %} +{% endfor %} + +{%- endif %} + + + + +{%- if c.name.startswith("ComponentProperties") %} + +### ComponentProperties Attributes +The expected properties for the suppported deployment types are indicated below. + +- Properties for `helm.v3` components + +| Attribute | Type | Required? | Description | +| --- | --- | --- | --- | +| repository | string | Y | The URL indicating the helm chart's location.| +| revision | string | Y | The helm chart's full version.| +| wait | bool | N | If `True`, indicates the device MUST wait until the helm chart has finished installing before installing the next helm chart. The default is `True`. The Workload Fleet Management Client MUST support `True` and MAY support `False`. Only applies if multiple `helm.v3` components are provided.| +| timeout | string | N | The time to wait for the component's installation to complete. If the installation does not completed before the timeout occurs the installation process fails. The format is "##m##s" indicating the total number of minutes and seconds to wait. | + +- Properties for `compose` components + +> **Investigation Needed**: We need to have more discussion about how Compose should be handled and what is required here. + +| Attribute | Type | Required? | Description | +| --- | --- | --- | --- | +| packageLocation | string | Y | The URL indicating the Compose package's location. | +| keyLocation | string | N | The public key used to validated the digitally signed package. It is highly recommend to digitally sign the package. When signing the package PGP MUST be used.| +| wait | bool | N | If `True`, indicates the device MUST wait until the Compose file has finished starting up before starting the next Compose file. The default is `True`. The Workload Fleet Management Client MUST support `True` and MAY support `False`. Only applies if multiple `compose` components are provided.| +| timeout | string | N | The time to wait for the component's installation to complete. If the installation does not completed before the timeout occurs the installation process fails. The format is "##m##s" indicating the total number of minutes and seconds to wait.| + +## Defining configurable application parameters + +To allow customizable configuration values when installing an application, the *application description* defines the parameters and configuration sections giving the application vendor control over what can be configured when installing, or updating, an application. The [configuration](#configuration-attributes) section describes how the workload orchestration software vendor must display parameters to the user to allow them to specify the values. The [schema](#schema-attributes) section describes how the workload orchestration software vendor must validate the values provided by the user before the application is installed or updated. + +> **Note:** At this point the specification only deals with parameter values provided by the user as part of installing, or updating, the application. We anticipate parameter values to come from other sources, such as the device, in the future and not only from the user. + +{%- endif %} +{%- endfor %} + + +## Enumerations +These enumerations are used as vocabularies for attribute values of the `ApplicationDescription`. + +### CpuArchitectureType + +| Permissible Values | Description | +| --- | --- | +| amd64 | AMD 64-bit architecture.| +| x86_64 | x86 64-bit architecture.| +| arm64 | ARM 64-bit architecture.| +| arm | ARM 32-bit architecture. | + +### CommunicationInterfaceType + +| Permissible Values | Description | +| --- | --- | +| ethernet | This type stands for an Ethernet interface.| +| wifi | This type stands for an WiFi interface.| +| cellular | This type stands for cellular communication technologies such as 5G, LTE, 3G, 2G, ....| +| bluetooth | This type stands for a Bluetooth or Bluetooth Low-Energy (BLE) interface. | +| usb | This type stands for a USB interface.| +| canbus | This type stands for a CANBus interface.| +| rs232 | This type stands for a RS232 interface. | + +### PeripheralType + +| Permissible Values | Description | +| --- | --- | +| gpu | This type stands for a Graphics Processing Unit (GPU) peripheral.| +| display | This type stands for a display peripheral.| +| camera | This type stands for a camera peripheral.| +| microphone | This type stands for a microphone peripheral. | +| speaker | This type stands for a speaker peripheral. | + + + +## Application Description Examples + +### Example 1: Simple Application Description +A simple hello-world example of an `ApplicationDescription` is shown below: + +```yaml +{% include 'examples/valid/ApplicationDescription-001.yaml' %} +``` + +### Example 2: Application Description with Deployment Profiles for Helm and Compose +An example of an `ApplicationDescription` defining [deployment profiles](#deploymentprofile-attributes) for both cases, Helm chart as well as Compose, is shown below. + +```yaml +{% include 'examples/valid/ApplicationDescription-002.yaml' %} +``` \ No newline at end of file diff --git a/system-design/concepts/applications/application-package.md b/system-design/concepts/applications/application-package.md new file mode 100644 index 0000000..2f0bde3 --- /dev/null +++ b/system-design/concepts/applications/application-package.md @@ -0,0 +1,43 @@ +# Application Package + +The Application Package, which is used to [distribute an application](../../overview/applications-and-workloads.md) to be deployed as [workloads](../../personas-and-definitions/technical-lexicon.md#workload) on edge devices, comprises the following elements: + +- The **Application Description**: a YAML document with the element `kind` defined as `ApplicationDescription`, which is stored in a file (for example named `margo.yaml`) and contains information about the application's [metadata](../../specification/applications/application-description.md#metadata-attributes) (e.g., description, icon, release notes, license file, etc.), the application [components](../../personas-and-definitions/technical-lexicon.md#component) (e.g., Helm charts, Compose Archive) which are defined in [deployment configurations](../../specification/applications/application-description.md#deploymentprofile-attributes), and [configurable application parameters](../../specification/applications/application-description.md#defining-configurable-application-parameters). There is only one YAML file in the package root of kind `ApplicationDescription`. +- The **resources**, which are additional files associated with the application (e.g., manual, icon, release notes, license file, etc.) that may be used to display more information about the application in a UI such as an [application catalog](../../personas-and-definitions/technical-lexicon.md#application-catalog) or [marketplace](../../personas-and-definitions/technical-lexicon.md#marketplace) or other informative outputs. + +The Application Package has the following folder/file structure: + +```yaml +/ # REQUIRED top-level directory +└── .yaml # REQUIRED a YAML document with element 'kind' as 'ApplicationDescription' stored in a file (e.g., 'margo.yaml') +└── resources # OPTIONAL folder with application files (e.g., icon, license file, release notes) that may be used for displaying additional information about the application +``` + +The Application Package is made available in an [Application Registry](./application-registry.md). + +An application aggregates one or more [components](../../personas-and-definitions/technical-lexicon.md#component), which each link to one or more [OCI Containers](https://github.com/opencontainers). The components referenced in the [Application Description](../../specification/applications/application-description.md) are stored in a [Component Registry](../../personas-and-definitions/technical-lexicon.md#component-registry), and the linked containers are provided via a [Container Registry](../../personas-and-definitions/technical-lexicon.md#container-registry). Registries can be remote (i.e., Internet-accessible) or [local](../../concepts/applications/local-registries.md) (i.e., accessible within a local network infrastructure of the devices). + +> **Note** +> Application catalogs and marketplaces are out of scope of the Margo specification. The exact requirements of the marketing material need to be defined by the application marketplace beyond outlined mandatory content. + +The [deployment profiles](../../specification/applications/application-description.md#deploymentprofile-attributes) specified in the [Application Description](../../specification/applications/application-description.md) are defined as Helm Chart components AND/OR [Compose Archive](../../personas-and-definitions/technical-lexicon.md#compose-archive) components. These components are being deployed as workloads on the edge devices: + +- To target devices, which deploy workloads using Kubernetes, components need to be defined as Helm charts using [Helm (version 3)](https://helm.sh/docs/topics/charts/). +- To target devices, which deploy workloads using [Compose](https://www.compose-spec.io/), components need to be packaged as [Compose Archives](../../personas-and-definitions/technical-lexicon.md#compose-archive), i.e., a tarball file containing the `compose.yaml` file and any additional artifacts referenced by the Compose file (e.g., configuration files, environment variable files, etc.). Margo recommends to digitally sign this package and to specify the location of the public key in the `ApplicationDescription` (see `keyLocation` [here](../../specification/applications/application-description.md#componentproperties-attributes)). When digitally signing the package PGP encryption MUST be used. + +> **Investigation Needed**: Question: do we need to specify the location of a SHA256 hash for the Compose Archive also (similar to the PGP key) in the ApplicationDescription? +> We will also discuss how we should handle secure container registries that require a username and password. +> +> **Investigation Needed**: We need to determine what impact, if any, using 3rd party helm charts has on being Margo compliant. +> +> **Investigation Needed**: Missing in the current specification are ways to define dependencies (e.g., application dependencies) as well as required infrastructure services such as storage, message queues/bus, reverse proxy, or authentication/authorization/accounting. + +If either one cannot be implemented it MAY be omitted but Margo RECOMMENDS defining [deployment profiles](../../specification/applications/application-description.md#deploymentprofile-attributes) as both Helm chart **AND** Compose components to strengthen interoperability and applicability. + +> **Note** +> A device running the application will only install the application using either the Compose Archives or the Helm Charts, but not both. + +## Relevant Links +Please follow the subsequent link to view the technical reference of the `ApplicationDescription` format: + +- [Application Description](../../specification/applications/application-description.md) diff --git a/system-design/concepts/applications/application-registry.md b/system-design/concepts/applications/application-registry.md new file mode 100644 index 0000000..a7d4d2b --- /dev/null +++ b/system-design/concepts/applications/application-registry.md @@ -0,0 +1,44 @@ +# Application Registry + +The Margo specification differentiates 4 kinds of registries: *Application Registries*, *Component Registries*, and *Container Registries* as well as *Marketplaces*. + +1. An **Application Registry** hosts Application Packages that define through their [Application Description](../../specification/applications/application-description.md) the application as one or multiple [Components](../../personas-and-definitions/technical-lexicon.md#component). +2. A **Component Registry** hosts the [Components](../../personas-and-definitions/technical-lexicon.md#component) (which are deployable as *workloads*) and are provided as **Helm Charts** or **Compose Archives**. +3. A **Container Registry** hosts container images referenced by those Components. +4. A **Marketplace** lists applications to advertise them and enable purchasing for end users. + +Out of these 4 registries, **only the Application Registry interface is in scope** of the Margo specification and its API definition can be found [here](../../specification/applications/application-registry.md). + +The diagram below illustrates these functionalities and relationships of registries within Margo. + +```mermaid +flowchart + A[WFM, or internal Application Catalog] -- Application Descriptions link to --> B[Component Registry] + C[Application Registry] -- Application Descriptions link to --> B + B -- hosted Components links to --> D[Container Registry] + A -->|pulls Application Package | C + F[App Developer] -->|uploads Application Package to| C + G["Marketplace"] -- points to Application Package --> C + C -->|hosts 0..*| E@{ shape: docs, label: "Application Packages"} + C -->|validates token| H[Authentication Service] + A -->|requests token| H + style H stroke-dasharray: 3 6 + + style B fill:#ABC + style C fill:#ABC + style D fill:#ABC + style G fill:#ABC +``` + +As shown in the figure above, an `Application Developer` uploads an [Application package](application-package.md) to an Application Registry. From there, it is available to a `Workload Fleet Manager` (WFM). +The WFM acts as a client to pull an [Application Package](application-package.md) from the Application Registry. It would then list this Application Package on its UI (e.g., an internal `Application Catalog`) to enable the usage on its managed devices. + +An `Authentication Service` manages access control for the Application Registry. The WFM requests a token from the Authentication Service to include in the requests to the Application Registry. The received token is then validated by the Application Registry through interaction with the Authentication Service. + +The Application Registry's API is compliant with the [OCI Registry API (v1.1.0)](https://github.com/opencontainers/distribution-spec/blob/v1.1.0/spec.md). A hosted Application Package is provided by listing its parts as layers in an [image manifests](https://github.com/opencontainers/image-spec/blob/v1.0.1/manifest.md) that can be requested through the API. + + +## Relevant Links +* The technical reference of the Application Registry API is defined [here](../../specification/applications/application-registry.md). + +* A reference implementation of the Application Registry is described [here](https://github.com/margo/app-package-definition-wg/blob/main/application-registry-example/app_registry_as_oci_registry.md) and includes sample applications and configuration for demonstration. It utilizes an open source OCI Registry and the [ORAS tool](https://oras.land/docs/) as the client. diff --git a/system-design/concepts/applications/local-registries.md b/system-design/concepts/applications/local-registries.md new file mode 100644 index 0000000..b130b7c --- /dev/null +++ b/system-design/concepts/applications/local-registries.md @@ -0,0 +1,88 @@ +# Local Registries + +The [Component Registry](application-registry.md) as well as the [Container Registry](application-registry.md) considered by Margo are the registries that need to be accessed by devices to download components (i.e., Helm Charts or Compose Archives) or containers. This section describes how to configure those as local registries to avoid reliance on public Internet-accessible registries. + +The reasons for not using public registries are for example: (1) publicly hosted container images or Helm charts could become unavailable at some point, as the owner decides to take the container images or Helm charts off the public registry, (2) Internet connectivity may not be available to the device and hence public registries are not reachable, or (3) end-users want to host their own registries so they can do security scans and package validation. + +In terms of connectivity, we can thereby distinguish mainly between the following device categories: + +1. **Fully connected device**, which means a device is deployed in the field (e.g., a factory shop floor) and has access to the Internet. +2. **Locally connected device**, i.e., the device has connectivity to a local network (e.g., factory- or enterprise-wide) and a local repository can be made reachable. +3. **Air-gapped device**, i.e., the device generally is not connected and must be configured by accessing it directly (via direct network link with an Ethernet cable, or similar) for example through a technician’s laptop. + +Local Component Registries or Container Registries can be used for all device categories. In case of **fully connected devices**, although the device could reach the Internet, a local registry can still be useful (e.g., as a cache for remote registries to save on bandwidth or to have container images or Helm Charts reliably available). In case of **locally connected devices**, a local registry is required to enable the Workload Fleet Management Client (WFMC) to install a Margo application on the device, as the device/WFMC does not have Internet access. Thereby, the local registry can be set up as a *pull-through cache* where data (e.g., container images) is cached locally when they are first retrieved from a remote source and subsequent requests for the same data are served from the local cache rather than fetching it again from the remote source. In case of **air-gapped devices**, a local registry has to be accessible on the technician's laptop (or other directly connected device), which performs the application installation process. + +To setup local registries, different configuration options exist: + +## Option - Container Registry Mirror on Kubernetes Level + +Kubernetes supports the configuration of registry mirrors. How this is configured depends on the distribution and the underlying container runtime. Distributions that utilize **containerd** as runtime (e.g., k3s or microk8s) allow the definition of mirrors in a configuration file. For example, in k3s the file `/etc/rancher/k3s/registries.yaml` can be used to set up a mirror for each device's Kubernetes environment: + +```yaml +mirrors: + "docker.io": + endpoint: + - "http://:5000" +configs: + "docker.io": + auth: + username: "" + password: "" +``` + +## Option - Container Registry as Pull-through Cache on Docker Level + +To configure a pull-through cache in Docker for the Container Registry, a Docker Registry can be setup that acts as caching proxy for a remote Docker Registry. Such a Docker Registry can be defined using the following `config.yml`: + +```yaml +version: 0.1 +log: + fields: + service: registry +storage: + filesystem: + rootdirectory: /var/lib/registry +http: + addr: :5000 + headers: + X-Content-Type-Options: [nosniff] +health: + storagedriver: + enabled: true + interval: 10s + threshold: 3 +proxy: + remoteurl: https://registry-1.docker.io +``` + +This registry can be started uing the following command: +`docker run -d -p 5000:5000 --restart unless-stopped --name registry -v $(pwd)/config.yml:/etc/docker/registry/config.yml registry:2` + +Then, the Docker daemon needs to be configured to use the private registry as a mirror in the `/etc/docker/daemon.json` file: + +```json +{ + "registry-mirrors": ["http://10.100.2.102:5000"], + "insecure-registries": ["10.100.2.102:5000"] +} +``` + +## Option - Helm Chart Component Registry as Pull-through Cache + +Setting up a pull-through cache for Helm charts in combination with Kubernetes involves configuring a local Helm chart repository, e.g., ChartMuseum, that can be installed with the `PROXY_CACHE` variable set to `true`: + +```bash +helm repo add chartmuseum https://chartmuseum.github.io/charts +helm repo update +helm install my-chartmuseum chartmuseum/chartmuseum --set env.open.DISABLE_API=false --set env.open.PROXY_CACHE=true +``` + +Then, this Helm Chart repository can be added to Helm and chart releases can be installed there: + +```bash +helm repo add my-cached-repo http://:8080 +helm repo update +helm install my-release my-cached-repo/ +``` + +Now, when deploying applications in Kubernetes using Helm, the cached repository is used to serve charts rather than the remote repository. diff --git a/system-design/overview/applications-and-workloads.md b/system-design/overview/applications-and-workloads.md new file mode 100644 index 0000000..82a29f3 --- /dev/null +++ b/system-design/overview/applications-and-workloads.md @@ -0,0 +1,78 @@ +# Applications & Workloads + +A [workload](../personas-and-definitions/technical-lexicon.md#workload) is running software. More specifically, a workload is a running [Component](../personas-and-definitions/technical-lexicon.md#component) of an [Application Package](../concepts/applications/application-package.md) deployed to a Margo compliant [edge compute device](../personas-and-definitions/technical-lexicon.md#edge-compute-device). + +In order to help achieve Margo's interoperability [mission statement](../index.md#mission-statement) we are initially targeting [containerized](https://github.com/opencontainers) components/workloads capable of running on platforms like Kubernetes, Docker and Podman. The flexibility these platforms provide enables [workload suppliers](../personas-and-definitions/personas.md#workload-supplier) to define and package their components in a common way using [Helm](https://helm.sh/docs/) or the [Compose specification](https://github.com/compose-spec/compose-spec/blob/main/spec.md) so they can more easily be deployed to multiple compatible edge compute devices as workloads. + +While Margo is initially targeting deployments using Helm or Compose, we plan to support other deployment types in the future. One of our design goals is to make it easier for [workload fleet managers](../personas-and-definitions/technical-lexicon.md#workload-fleet-manager) to support the current and future deployment types without having to implement special logic for each type. In order to achieve this, Margo defines an [application description model](../concepts/applications/application-package.md) to abstract away some of the details to make it easier for workload fleet managers to support the different deployment types. + +The three main goals of Margo's application description model is to allow workload fleet managers to do the following: + +- Display information about available applications (e.g., via an [application catalog](../personas-and-definitions/technical-lexicon.md#application-catalog)), which the [OT user](../personas-and-definitions/personas.md#ot-user) can deploy as workloads. +- Determine which edge compute devices are compatible with an application (regarding processor type, GPU present, RAM available, etc.) +- Capture, and validate, configuration information from the OT user when deploying application components as workloads, or updating them. + +Another advantage of Margo's [application description model](../concepts/applications/application-package.md) is to enable workload suppliers to define different deployment profiles in a single application description file to target deploying to different types of edge compute devices (e.g., Arm vs. x86, Kubernetes vs. Docker) instead of needing to maintain multiple application description files. + +## Packaging & Distribution + +To distribute an application consisting of multiple components that are deployable as workloads, they are wrapped in an [application package](../concepts/applications/application-package.md) defined by the workload supplier who aims to provide it to Margo-compliant edge compute devices. Therefore, the workload supplier creates an application description YAML document containing information about the application and references to its components. The application package is made available in an [application registry](../concepts/applications/application-registry.md), its components (i.e., Helm Charts or Compose Archives) are stored in a remote or [local](../concepts/applications/local-registries.md) component registry, and the linked [OCI containers](https://github.com/opencontainers) are provided through an OCI container registry. + +### Example workflow + +The following diagram provides an example workflow showing one way a workload fleet manager may use the application description information: + +```mermaid +--- +config: + layout: elk + + +--- +sequenceDiagram + actor EndUser as End User + participant frontend as Workload Fleet Manager Frontend + participant fleetmgr as Workload Fleet Manager + participant registry as Application Registry + + autonumber + + EndUser->>frontend: Visits Application Catalog + frontend->>fleetmgr: Get list of available application packages + + alt + fleetmgr ->> registry: Get application descriptions from each known application registry. + else + fleetmgr ->> fleetmgr: Get application descriptions for all cached applications. + end + fleetmgr->>frontend: Return list of application descriptions + + frontend ->> frontend: Read all application descriptions' 'metadata' element + frontend ->> EndUser: Show UI with list of applications + EndUser->>frontend: Select application / components to install + frontend ->> frontend: Read application descriptions 'configuration' element + frontend -->> EndUser: Show UI to fill application configuration + EndUser ->> frontend: fills application configuration + frontend ->> fleetmgr: Create 'ApplicationDeployment' definition + +``` + +1. An end user visits the [application catalog](../personas-and-definitions/technical-lexicon.md#application-catalog) of a Workload Fleet Manager Frontend. +2. This frontend requests all installable [application packages](../concepts/applications/application-package.md) from the Workload Fleet Manager. +3. _Either_: the Workload Fleet Manager requests all application descriptions from each known [application registry](../concepts/applications/application-registry.md). +4. _Or_: the Workload Fleet Manager maintains a cache of application descriptions and services the request from there. +5. The Workload Fleet Manager returns the retrieved application descriptions to the frontend. +6. The frontend parses the [metadata](../specification/applications/application-description.md#metadata-attributes) element of all received application descriptions. +7. The frontend presents the parsed metadata in a UI to the end user. +8. The end user selects the application package to be installed. +9. The frontend parses the [configuration](../specification/applications/application-description.md#configuration-attributes) element of the selected application description. +10. The frontend presents the parsed configuration to the user. +11. The end user fills out the [configurable application parameters](../specification/applications/application-description.md#defining-configurable-application-parameters). +12. The frontend creates an `ApplicationDeployment` definition (from the `ApplicationDescription` and the filled out parameters) and sends it to the Workload Fleet Manager, which executes it as the [desired state](../specification/margo-management-interface/desired-state.md). + +## Relevant Links + +Please follow the subsequent links to view more technical information regarding Margo application packaging: + +- [Application Package](../concepts/applications/application-package.md) +- [Application Registry](../concepts/applications/application-registry.md) diff --git a/system-design/specification/applications/.gitkeep b/system-design/specification/applications/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/system-design/specification/applications/application-registry.md b/system-design/specification/applications/application-registry.md new file mode 100644 index 0000000..3f23340 --- /dev/null +++ b/system-design/specification/applications/application-registry.md @@ -0,0 +1,259 @@ +# Application Registry + +The interactions of an `Application Registry` are described [here](../../concepts/applications/application-registry.md) from a conceptual view. This section formally specifies the API of the `Application Registry` and the exchange of an [Application Package](../../concepts/applications/application-package.md), defined through an [Application Description](../../specification/applications/application-description.md) file, from an Application Developer to the [Workload Fleet Manager](../../personas-and-definitions/technical-lexicon.md#workload-fleet-manager) (WFM). The `Application Registry` is designed as an `OCI Registry`, i.e., it offers an API compliant with the [OCI Registry API (v1.1.0)](https://github.com/opencontainers/distribution-spec/blob/v1.1.0/spec.md) (called here the "OCI_spec") for digital artifact distribution. This way, the Application Registry hosts the parts of an [Application Package](../../concepts/applications/application-package.md) in the form of `blobs` and uses `image manifests` according to [OCI Image specification](https://github.com/opencontainers/image-spec/blob/v1.0.1/manifest.md) to list a set of `layers`, each pointing at a blob. + +## Overview of API Endpoints + +The WFM MUST interact with the Application Registry compliant to the OCI Registry API endpoints defined in the [OCI_spec](https://github.com/opencontainers/distribution-spec/blob/v1.1.0/spec.md): + +* Tags: `/v2/{name}/tags/list` for listing available versions of an Application Package +* Manifest: `/v2/{name}/manifests/{reference}` for retrieving an image manifest (identifed through the `{reference}`) that lists layers, which represent the parts of the Application Package. +* Blob: `/v2/{name}/blobs/{digest}` for downloading parts of the Application Package + +`{name}` is the namespace of the repository, which needs to be directly communicted by the App Developer to the WFM vendor. It could be for example a combination of the organization's and application's name. + +Further details on how to use these API endpoints are specified below [towards App Developer](#uploading-an-application-package) and [towards WFM](#retrieving-an-application-package). + +## Authentication, Authorization & Security +Margo recommends the use of an Authentication Service for the interactions between the WFM and Application Registry as conceptually described [here](../../concepts/applications/application-registry.md), e.g., implemented using OAuth 2.0. This involves the following workflow: + +* WFM obtains credentials during onboarding +* WFM requests a token from an Authentication Service +* WFM uses the token for subsequent API calls to the Application Registry +* Application Registry validates the token and enforces access control + +Thereby, all communications must use TLS 1.3+ to ensure transport security. + +> Note: Authentication, Authorization & Security mechanisms should be defined centrally and homogeneously across Margo. Hence, it is not further defined here. + +Further, tools such as [cosign](https://github.com/sigstore/cosign) may be employed for signing artifacts uploaded to the Application Registry and storing the signatures alongside the artifacts they verify. + + + +## Uploading an Application Package + +As shown in the sequence diagram below, the Application Developer uploads the Margo-compliant `Application Package` to the Application Registry. I.e., all parts of the Application Package MUST be pushed as blobs compliant with the [end-4a / end-4b](https://github.com/opencontainers/distribution-spec/blob/v1.1.0/spec.md#endpoints) endpoints of the OCI_spec. + +Subsequently, the Application Developer creates an OCI image manifest that lists layers, each of which links to an uploaded blob. Then the manifest MUST be pushed to the Application Registry compliant to the [end-7](https://github.com/opencontainers/distribution-spec/blob/v1.1.0/spec.md#endpoints) endpoint of the OCI_spec. + +The uploaded OCI image manifest MUST adhere to the Margo-specific constraints detailed [here](#oci-image-manifest-as-response-from-application-registry). + +Subsequently, the App Developer uses a UI or other vendor-specific mechanism to communicate (either directly or indirectly, e.g., via a Marketplace) to the WFM the namespace of the Application Package's repository. + +```mermaid +sequenceDiagram + + Note over AppDeveloper: uploads parts of Application Package as blobs: + AppDeveloper->>AppRegistry: push blobs + + AppDeveloper->>AppRegistry: push manifest + + Note over AppDeveloper: uses vendor-specific upload mechanism (e.g., UI) to enable WFM to find the Application Package: + AppDeveloper->>+WFM: Application Package location is: repository name in Application Registry +``` + +There are no further Margo-specific constraints regarding the upload of the Application Package. The details defined in the [OCI_spec](https://github.com/opencontainers/distribution-spec/blob/v1.1.0/spec.md) MUST be applied to this interface of the Application Registry. + + + +## Retrieving an Application Package + +The WFM has received the namespace of the repository of the Application Package at the Application Registry. + +Next, as shown in the sequence diagram below, the WFM uses the API endpoints defined in the OCI_spec to retrieve a list of Application Package versions (as detailed [here](#list-margo-application-package-versions)). + +Then, the WFM pulls the OCI image manifest of the selected version of the Application Package, with the identifying reference being a tag or digest (as detailed [here](#pull-oci-image-manifest-of-application-package)). + +Finally, all parts (e.g., the Application Description file, the icon, the license, etc.) of the Application Package are retrieved by pulling the respective blobs listed as layers in the image manifest (as detailed [here](#get-parts-of-application-package)). + +```mermaid +sequenceDiagram + Note over WFM: retrieve available versions of an Application Package: + WFM->>+AppRegistry: GET /v2/{name}/tags/list + + Note over WFM: retrieves the OCI image manifest of the selected Application Package version. {reference} is a tag or a digest: + WFM->>+AppRegistry: GET /v2/{name}/manifests/{reference} + + AppRegistry-->>+WFM: OCI image manifest + + Note over WFM: retrieves parts of the Application Package as listed in OCI image manifest layers: + WFM->>AppRegistry: GET /v2/{name}/blobs/{digest} +``` + +### List Margo Application Package Versions + +The interface to retrieve the list of versions of an Application Package MUST be implemented according to OCI_spec endpoint [end-8a](https://github.com/opencontainers/distribution-spec/blob/v1.1.0/spec.md#endpoints). + +To get a list of available versions of an Application Package, an HTTP ``GET`` request to a resource path MUST be performed in the following format: `/v2/{name}/tags/list`. The `{name}` variable is the namespace of the Application Package repository, which was communicated by the App Developer to the WFM vendor. + +The HTTP headers of the ``GET`` request MAY include ```Authorization: Bearer ``` for including the interaction with the [Authentication Service](../../concepts/applications/application-registry.md). + +To query a subset of tags, the following query parameters MUST be implemented by the Application Registry as defined by OCI_spec endpoint [end-8b](https://github.com/opencontainers/distribution-spec/blob/v1.1.0/spec.md#endpoints): + +* ``n=`` (optional, limits results to n tags) +* ``last=`` (optional, starts list of tags after ````) + +The response of the HTTP ``GET`` request according to [end-8a/end-8b](https://github.com/opencontainers/distribution-spec/blob/v1.1.0/spec.md#endpoints) is a list of tags, which comply with the versions of available Application Packages. According to OCI_spec, upon success, the response MUST be a JSON body in the following format: + +```json +{ + "name": "", + "tags": [ + "", # each tag MUST be the value of the 'metadata.version' of the associated Application Package's Application Description document. + "", + "" + ] +} +``` + +Thereby, a listed tag of an image manifest MUST be the same as the value of the key ``metadata.version`` as specified in the Application Description document of the associated Application Package. + +#### Example A: + +Request: GET ``http://famous-app-registry/v2/northstar-industrial-applications/app1/tags/list`` + +Response: +```json +{ + "name": "northstar-industrial-applications/app1", + "tags": [ + "v1.0.0", + "v1.1.0", + "latest" + ] +} +``` + +#### Example B: + +Request: GET ``http://famous-app-registry/v2/northstar-industrial-applications/app1/tags/list?n=2&last=v1.0.0`` + +Response: +```json +{ + "name": "northstar-industrial-applications/app1", + "tags": [ + "v1.1.0", + "latest" + ] +} +``` + +### Pull OCI Image Manifest of Application Package + +The interface to retrieve the OCI image manifest of a specified version, which belongs to an Application Package, MUST be implemented according to OCI_spec endpoint [end-3](https://github.com/opencontainers/distribution-spec/blob/v1.1.0/spec.md#endpoints). + +To pull an Application Package, an HTTP ``GET`` request to a resource path MUST be performed in the following format: +`/v2/{name}/manifests/{reference}`. +The `{reference}` is the `tag` of an OCI image manifest. The `tag` has been discovered via the [listing of application package versions](#list-margo-application-package-versions). +The `{name}` variable is the namespace of the Application Package repository. + +The HTTP headers of the ``GET`` request MAY include ```Authorization: Bearer ``` for including the interaction with the [Authentication Service](../../concepts/applications/application-registry.md). + +#### OCI Image Manifest as Response from Application Registry: + +The successful response of the HTTP ``GET`` request is an OCI image manifest (as defined in the OCI_spec), which MUST contain pointers to all parts of an Application Package within the Application Registry. + +Each version of an Application Package MUST have its own OCI image manifest. + +The ``schemaVersion`` of the OCI image manifest needs to be ``2``. + +The ``artifactType`` of the OCI image manifest must be ``application/vnd.margo.app.v1+json``. + +The ``config`` object must be declared as empty by defining its ``mediaType`` as ``application/vnd.oci.empty.v1+json``. + +Each element of the ``layers`` array contains a reference (so-called `digests`) to an artifact (so-called `blobs`) that is a part of the Application Package. + +Each Application Package part must be listed as an element of the ``layers`` array: + +* The [Application Description](../../specification/applications/application-description.md) of the Application Package must be referred to in one element of the ``layers`` array, where the ``mediaType`` of this layer/blob must be ``application/vnd.margo.app.description.v1+yaml``. +* Each [application resource](../../concepts/applications/application-package.md), which is an additional file associated with the application (e.g., manual, icon, release notes, license file, etc.), must be referred to in an element of the ``layers`` array. Such a layer must have an ``annotation``, which has the annotation key ``org.margo.app.resource``, and the annotation value must reflect the dotted path to the this resource in the [Application Description file](../../specification/applications/application-description.md). E.g., an application icon stored as the file ``resources/margo.jpg`` is referenced in the Application Description under ``metadata.catalog.application.icon: resources/margo.jpg`` and in the OCI image manifest, the respective layer of the icon resource has the annotation ``org.margo.app.resource`` with the value ``metadata.catalog.application.icon`` (see also OCI image manifest example below). + +The following response example is a Margo-specific OCI image manifest following the [OCI Image Manifest Specification](https://github.com/opencontainers/image-spec/blob/v1.0.1/manifest.md) and the above defined specifics: + +```json +{ + "schemaVersion": 2, + "mediaType": "application/vnd.oci.image.manifest.v1+json", + "artifactType": "application/vnd.margo.app.v1+json" # this MUST be the artifactType of an OCI image manifest of a Margo Application Package, + "config": { + "mediaType": "application/vnd.oci.empty.v1+json", # the 'config' object MUST be empty + "digest": "sha256:44136fa355b3678a1146ad16f7e8649e94fb4fc21fe77e8310c060f61caaff8a", + "size": 2, + "data": "e30=" + }, + "layers": [ + { + "mediaType": "application/vnd.margo.app.description.v1+yaml", # this MUST be the artifactType of a Margo Application Description file + "digest": "sha256:f6b79149e6650b0064c146df7c045d157f3656b5ad1279b5ce9f4446b510bacf", + "size": 999, + "annotations": { + "org.opencontainers.image.title": "margo.yaml" + } + }, + { + "mediaType": "text/markdown", + "digest": "sha256:e373b123782a2b52483a9124cc9c578e0ed0300cb4131b73b0c79612122b8361", + "size": 1596, + "annotations": { + "org.margo.app.resource": "metadata.catalog.application.descriptionFile", # each Margo application resource MUST be annotated with a dotted path to its definition in the Application Description file + "org.opencontainers.image.title": "resources/description.md" + } + }, + { + "mediaType": "text/markdown", + "digest": "sha256:af7db4ab9030533b6cda2325247920c3659bc67a7d49f3d5098ae54a64633ec7", + "size": 25, + "annotations": { + "org.margo.app.resource": "metadata.catalog.application.licenseFile", # each Margo application resource MUST be annotated with a dotted path to its definition in the Application Description file + "org.opencontainers.image.title": "resources/license.md" + } + }, + { + "mediaType": "image/jpeg", + "digest": "sha256:451410b6adfdce1c974da2275290d9e207911a4023fafea0e283fad0502e5e56", + "size": 5065, + "annotations": { + "org.margo.app.resource": "metadata.catalog.application.icon", # each Margo application resource MUST be annotated with a dotted path to its definition in the Application Description file + "org.opencontainers.image.title": "resources/margo.jpg" + } + }, + { + "mediaType": "text/markdown", + "digest": "sha256:c412d143084c3b051d7ea4b166a7bfffb4550f401d89cae8898991c65e90f736", + "size": 42, + "annotations": { + "org.margo.app.resource": "metadata.catalog.application.releaseNotes", # each Margo application resource MUST be annotated with a dotted path to its definition in the Application Description file + "org.opencontainers.image.title": "resources/release-notes.md" + } + } + ], +} +``` + +#### Margo-Specific Media Types + +|Media Type|Description| +|----------|----------| +|``application/vnd.margo.app.v1+json`` | MUST be used as the **artifactType** to mark the OCI image manifest as the definition of a Margo Application Package | +|``application/vnd.margo.app.description.v1+yaml`` | MUST be used to mark a layer in the OCI image manifest as pointing to the Margo Application Description file | + + +#### Margo-Specific Annotation Keys + +|Annotation Key | Description| +|----------|----------| +|``org.margo.app.resource`` | MUST be used to annotate a layer/blob that references a Margo application resource | + + + +### Get Parts of Application Package + +The interface to retrieve Application Package parts, i.e., Application Description or Application Resource (e.g., icon, license, etc.), MUST be implemented according to OCI_spec endpoint [end-2](https://github.com/opencontainers/distribution-spec/blob/v1.1.0/spec.md#endpoints) by pulling a blob. + +To pull such a blob, an HTTP ``GET`` request to a resource path MUST be performed in the following format: +`/v2/{name}/blobs/{digest}`. +The `{digest}` is the blob's digest as listed in the application's OCI image manifest that has been [retrieved earlier](#pull-oci-image-manifest-of-application-package). +The `{name}` variable is the namespace of the Application Package repository. + +The HTTP headers of the ``GET`` request MAY include ```Authorization: Bearer ``` for including the interaction with the [Authentication Service](../../concepts/applications/application-registry.md). From 92b2e42dc0b3c4ff6d73c2a478a6398c81d6b7c3 Mon Sep 17 00:00:00 2001 From: Arne Broering Date: Fri, 7 Nov 2025 16:59:17 +0100 Subject: [PATCH 18/29] removed incorrect sentence from technical lexicon Signed-off-by: Arne Broering --- system-design/personas-and-definitions/technical-lexicon.md | 3 --- 1 file changed, 3 deletions(-) diff --git a/system-design/personas-and-definitions/technical-lexicon.md b/system-design/personas-and-definitions/technical-lexicon.md index eb5f032..50a8f4b 100644 --- a/system-design/personas-and-definitions/technical-lexicon.md +++ b/system-design/personas-and-definitions/technical-lexicon.md @@ -88,9 +88,6 @@ An [Application Registry](../concepts/applications/application-registry.md) host It is used by application developers to make their applications available. The [API of the Application Registry](../specification/applications/application-registry.md) is compliant with the [OCI Registry API (v1.1.0)](https://github.com/opencontainers/distribution-spec/blob/v1.1.0/spec.md). -> To be clarified (Arne): -> -> [Workload Fleet Managers](#workload-fleet-manager) cannot access Application Registries directly, they can only access [Application Catalogs](#application-catalog). #### Application Catalog From 171d87b8f59594ff55f89ef8e5f04009df07b426 Mon Sep 17 00:00:00 2001 From: Arne Broering Date: Fri, 7 Nov 2025 17:44:08 +0100 Subject: [PATCH 19/29] changed overview figure Signed-off-by: Arne Broering --- .../figures/System-design.drawio.svg | 1525 +---------------- 1 file changed, 4 insertions(+), 1521 deletions(-) diff --git a/system-design/figures/System-design.drawio.svg b/system-design/figures/System-design.drawio.svg index a9fcda0..be45435 100644 --- a/system-design/figures/System-design.drawio.svg +++ b/system-design/figures/System-design.drawio.svg @@ -1,1521 +1,4 @@ - - - - - - - - - - - - - - - - - - - - - - -
-
-
- - - Component Registry - - -
-
-
-
- - Component Registry - -
-
-
- - - - - - - - - - - - - -
-
-
- Standalone Cluster(Leader and/or Worker) -
-
-
-
- - Standalone Cluster(Leader and/or Worker) - -
-
-
- - - - - - - - - - - - - - -
-
-
- WORKLOAD FLEET MANAGER -
-
-
-
- - WORKLOAD FLEET MANAGER - -
-
-
- - - - - - - - - - -
-
-
- DEVICE FLEET MANAGER -
-
-
-
- - DEVICE FLEET MANAGER - -
-
-
- - - - - - - - - - - - - - -
-
-
- KUBERNETES -
-
-
-
- - KUBERNETES - -
-
-
- - - - - - - -
-
-
- OBSERVABILITY PLATFORM -
-
-
-
- - OBSERVABILITY PLATFORM - -
-
-
- - - - - - - - - - - - - - -
-
-
- Cluster Worker -
-
-
-
- - Cluster Worker - -
-
-
- - - - - - - -
-
-
- Kubelet -
-
-
-
- - Kubelet - -
-
-
- - - - - - - - - - - - - - - -
-
-
- Standalone Device -
-
-
-
- - Standalone Device - -
-
-
- - - - - - - -
-
-
- OTEL Collector -
-
-
-
- - OTEL Collector - -
-
-
- - - - - - - - - - -
-
-
- WORKLOAD FLEET MANAGEMENT CLIENT -
-
-
-
- - WORKLOAD FLEET MANAGEMENT C... - -
-
-
- - - - - - - - - - - - - -
-
-
- Policy Agent -
-
-
-
- - Policy Agent - -
-
-
- - - - - - - -
-
-
- OTEL Collector -
-
-
-
- - OTEL Collector - -
-
-
- - - - - - - -
-
-
- WORKLOAD FLEET MANAGEMENT CLIENT -
-
-
-
- - WORKLOAD FLEET MANAGEMENT C... - -
-
-
- - - - - - - - - - - - - - - - - -
-
-
- DEVICE FLEET -
- MANAGEMENT -
- CLIENT -
-
-
-
- - DEVICE FLEET... - -
-
-
- - - - - - - -
-
-
- ONBOARDING SERVICE -
-
-
-
- - ONBOARDING S... - -
-
-
- - - - - - - - - - - - - - - - - - - - - - -
-
-
- - - Kubernetes Cluster - - -
-
-
-
- - Kubernetes Cluster - -
-
-
- - - - - - - - - - - -
-
-
- Device Supplier -
-
-
-
- - Device Supplier - -
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
-
- Cloud or -
- On Prem -
- Datacenter -
-
-
-
- - Cloud or... - -
-
-
- - - - - - - -
-
-
- Shop Floor -
-
-
-
- - Shop Floor - -
-
-
- - - - - - - - - -
-
-
- Application -
- Deployment -
-
-
-
-
- - Application... - -
-
-
- - - - - - - - - - - - - -
-
-
- DEVICE FLEET -
- MANAGEMENT -
- CLIENT -
-
-
-
- - DEVICE FLEET... - -
-
-
- - - - - - - -
-
-
- ONBOARDING SERVICE -
-
-
-
- - ONBOARDING S... - -
-
-
- - - - - - - -
-
-
- Policy Agent -
-
-
-
- - Policy Agent - -
-
-
- - - - - - - -
-
-
- Device Option 1 -
-
-
-
- - Device Option 1 - -
-
-
- - - - - - - -
-
-
- Device Option 2 -
-
-
-
- - Device Option 2 - -
-
-
- - - - - - - - -
-
-
- OS -
-
-
-
- - OS - -
-
-
- - - - - - - -
-
-
- OCI CONTAINER RUNTIME -
-
-
-
- - OCI CONTAINER RUNTIME - -
-
-
- - - - - - - -
-
-
- Deployed -
- Workload(s) -
-
-
-
-
- - Deployed... - -
-
-
- - - - - - - - -
-
-
- OS -
-
-
-
- - OS - -
-
-
- - - - - - - -
-
-
- OCI CONTAINER RUNTIME(Docker/Podman/...) -
-
-
-
- - OCI CONTAINER RUNTIME(Docker/Podman/...) - -
-
-
- - - - - - - -
-
-
- Deployed -
- Workload(s) -
-
-
-
-
- - Deployed... - -
-
-
- - - - - - - - -
-
-
- OS -
-
-
-
- - OS - -
-
-
- - - - - - - -
-
-
- OCI CONTAINER RUNTIME -
-
-
-
- - OCI CONTAINER RUNTIME - -
-
-
- - - - - - - - - - - - - - - - - - - - - -
-
-
- LEGEND -
-
-
-
- - LEGEND - -
-
-
- - - - - - - - - - - - - -
-
-
- App Developer -
- Private -
-
-
-
- - App Developer... - -
-
-
- - - - - - - -
-
-
- Margo Envisioned Communication Mechanisms -
-
-
-
- - Margo Envisioned Communicatio... - -
-
-
- - - - - - - - - - -
-
-
- Device Manufacturer -
- Private -
-
-
-
- - Device Manufacturer... - -
-
-
- - - - - - - - - - -
-
-
- Fleet Management Platform Provider -
-
-
-
- - Fleet Management Platform Pro... - -
-
-
- - - - - - - - - -
-
-
- xxxxx -
-
-
-
- - xxxxx - -
-
-
- - - - - - - -
-
-
- Margo Defined File format -
-
-
-
- - Margo Defined File format - -
-
-
- - - - - - - - - - -
-
-
- Communication Mechanisms  Not defined via Margo -
-
-
-
- - Communication Mechanisms  Not... - -
-
-
- - - - - - - - - - -
-
-
- Observability Platform -
- Provider -
-
-
-
- - Observability Platform... - -
-
-
- - - - - - - -
-
-
- Deployed -
- Workload(s) -
-
-
-
-
- - Deployed... - -
-
-
- - - - - - - - - -
-
-
- Application Artifact(s) -
-
-
-
- - Application Art... - -
-
-
- - - - - - - - - -
-
-
- Application Manifest(s) -
-
-
-
- - Application Man... - -
-
-
- - - - - - - -
-
-
- - - Git Repository - - -
-
-
-
- - Git Repository - -
-
-
- - - - - - - - - - - - - - - - - - - - - -
-
-
- Application Description -
-
-
-
- - Application Des... - -
-
-
- - - - - - - - - -
-
-
- Metadata -
- File(s) -
-
-
-
-
- - Metadata... - -
-
-
- - - - - - - -
-
-
- - - Application Package - - -
-
-
-
- - Application Package - -
-
-
- - - - - - - - - -
-
-
- - Metadata - -
- - File(s) - -
-
-
-
-
- - Metadata... - -
-
-
- - - - - - - -
-
-
- - Fleet Management - -
- - Supplier - -
-
-
-
-
- - Fleet Management... - -
-
-
- - - - - - - -
-
-
- - - Device Manifests / Components - - -
- - - TDB - - -
-
-
-
-
-
- - Device Manifests / Components... - -
-
-
- - - - - - - -
-
-
- - Device Supplier - -
-
-
-
- - Device Supplier - -
-
-
- - - - - - - - - -
-
-
- xxxxx -
-
-
-
- - xxxxx - -
-
-
- - - - - - - -
-
-
- Non Margo Defined File format -
-
-
-
- - Non Margo Defined File format - -
-
-
- - - - - - - -
-
-
- - - Application Supplier - - -
-
-
-
- - Application Supplier - -
-
-
- - - - - - - - - -
-
-
- Application Manifest(s) -
-
-
-
- - Application Man... - -
-
-
- - - - - - - - - -
-
-
- Application Artifact(s) -
-
-
-
- - Application Art... - -
-
-
- - - - -
- - - - - Text is not SVG - cannot display - - - -
\ No newline at end of file + + + +
Standalone Cluster(Leader and/or Worker)
Standalone Cluster(Leader and/or Worker)
WORKLOAD FLEET MANAGER
WORKLOAD FLEET MANAGER
DEVICE FLEET MANAGER
DEVICE FLEET MANAGER
KUBERNETES 
KUBERNETES 
OBSERVABILITY PLATFORM
OBSERVABILITY PLATFORM
Cluster Worker
Cluster Worker
Kubelet
Kubelet
Standalone Device
Standalone Device
OTEL Collector
OTEL Collector
WORKLOAD FLEET MANAGEMENT CLIENT
WORKLOAD FLEET MANAGEMENT C...
Policy Agent
Policy Agent
OTEL Collector
OTEL Collector
WORKLOAD FLEET MANAGEMENT CLIENT
WORKLOAD FLEET MANAGEMENT C...
DEVICE FLEET 
MANAGEMENT
CLIENT
DEVICE FLEET...
ONBOARDING SERVICE
ONBOARDING S...
Kubernetes Cluster
Kubernetes Cluster
Device Supplier
Device Supplier
Cloud or 
On Prem
Datacenter
Cloud or...
Shop Floor
Shop Floor
Application
Deployment
Application...
DEVICE FLEET 
MANAGEMENT
CLIENT
DEVICE FLEET...
ONBOARDING SERVICE
ONBOARDING S...
Policy Agent
Policy Agent
Device Option 1
Device Option 1
Device Option 2
Device Option 2
OS
OS
OCI CONTAINER RUNTIME
OCI CONTAINER RUNTIME
Deployed
Workload(s)
Deployed...
OS
OS
OCI CONTAINER RUNTIME(Docker/Podman/...)
OCI CONTAINER RUNTIME(Docker/Podman/...)
Deployed
Workload(s)
Deployed...
OS
OS
OCI CONTAINER RUNTIME
OCI CONTAINER RUNTIME
LEGEND
LEGEND
App Developer
Private
App Developer...
Margo Envisioned Communication Mechanisms
Margo Envisioned Communicatio...
Device Manufacturer
Private
Device Manufacturer...
Fleet Management Platform Provider
Fleet Management Platform Pro...
xxxxx
xxxxx
Margo Defined File format
Margo Defined File format
Communication Mechanisms  Not defined via Margo
Communication Mechanisms  Not...
Observability Platform
Provider
Observability Platform...
Deployed
Workload(s)
Deployed...
Application Registry
Application Registry
Application Description
Application Des...
Metadata
File(s)
Metadata...
Application Package
Application Package
Resource
File(s)
Resource...
Fleet Management
Supplier
Fleet Management...
Device Manifests / Components
TDB
Device Manifests / Components...
Device Supplier
Device Supplier
xxxxx
xxxxx
Non Margo Defined File format
Non Margo Defined File format
Application Supplier
Application Supplier
Component Registry
Component Registry
Component
(e.g., Helm Chart or Compse Archive)
Component...
Container Registry
Container Registry
Container Image
Container Image
Text is not SVG - cannot display
\ No newline at end of file From 1e57df55921d354a9bcd369204e33293db619cea Mon Sep 17 00:00:00 2001 From: Arne Broering Date: Mon, 10 Nov 2025 09:19:49 +0100 Subject: [PATCH 20/29] Removed 'Marketplace' term and adjusted 'Application Catalog' term usage Signed-off-by: Arne Broering --- .../application-description.linkml.yaml | 9 +++------ .../applications/resources/index.md.jinja2 | 8 ++++---- .../applications/application-package.md | 5 +---- .../applications/application-registry.md | 7 ++----- .../technical-lexicon.md | 17 +---------------- .../applications/application-registry.md | 2 +- 6 files changed, 12 insertions(+), 36 deletions(-) diff --git a/src/specification/applications/application-description.linkml.yaml b/src/specification/applications/application-description.linkml.yaml index c95170b..84567be 100644 --- a/src/specification/applications/application-description.linkml.yaml +++ b/src/specification/applications/application-description.linkml.yaml @@ -3,10 +3,8 @@ id: http://specification.margo.org/application-schema name: ApplicationDescription title: Application Description Schema description: >- - Schema for defining application metadata, deployment profiles, parameters, and configuration. - The purpose of this file is to present the application on an application catalog or marketplace - from where an end user selects the application to hand it over to the Workload Orchestration Software, - which configures it and makes it available for installation on the edge device. + Schema for defining application metadata, deployment profiles, and parameters. + The purpose of the Application Description is to enable an application's discovery, configuration, and deployment on edge devices. version: 1.0 prefixes: linkml: https://w3id.org/linkml/ @@ -97,8 +95,7 @@ classes: required: true catalog: description: >- - Catalog element specifying the application catalog details used to display the application - in an application catalog or marketplace. + Catalog element specifying the application's metadata for enabling its discovery. See the [Catalog](#catalog-attributes) section below. rank: 40 range: Catalog diff --git a/src/specification/applications/resources/index.md.jinja2 b/src/specification/applications/resources/index.md.jinja2 index bc1be7b..7e4e1b3 100644 --- a/src/specification/applications/resources/index.md.jinja2 +++ b/src/specification/applications/resources/index.md.jinja2 @@ -1,9 +1,9 @@ # Application Description -The Application Description has the purpose of presenting the application (e.g., on a WFM-internal [Application Catalog](../../personas-and-definitions/technical-lexicon.md#workload-fleet-manager)) -or public [Marketplace](../../personas-and-definitions/technical-lexicon.md#marketplace)) from where an end user selects an application to be installed. -The end user defines an `ApplicationDeployment` by specifying [configuration parameters](#defining-configurable-application-parameters) for an `ApplicationDescription`. -An `ApplicationDeployment` defines the [desired state](../margo-management-interface/desired-state.md) for an application. +The purpose of the Application Description is to enable an application's discovery, configuration, and deployment on edge devices. +To deploy an application the end user specifies values for the [parameters](#defining-configurable-application-parameters) given in +an Application Description (e.g., through a UI of the WFM) to instantiate an `ApplicationDeployment`, +which defines the [desired state](../margo-management-interface/desired-state.md) for an application. ### Top-level Attributes diff --git a/system-design/concepts/applications/application-package.md b/system-design/concepts/applications/application-package.md index 2f0bde3..08664db 100644 --- a/system-design/concepts/applications/application-package.md +++ b/system-design/concepts/applications/application-package.md @@ -3,7 +3,7 @@ The Application Package, which is used to [distribute an application](../../overview/applications-and-workloads.md) to be deployed as [workloads](../../personas-and-definitions/technical-lexicon.md#workload) on edge devices, comprises the following elements: - The **Application Description**: a YAML document with the element `kind` defined as `ApplicationDescription`, which is stored in a file (for example named `margo.yaml`) and contains information about the application's [metadata](../../specification/applications/application-description.md#metadata-attributes) (e.g., description, icon, release notes, license file, etc.), the application [components](../../personas-and-definitions/technical-lexicon.md#component) (e.g., Helm charts, Compose Archive) which are defined in [deployment configurations](../../specification/applications/application-description.md#deploymentprofile-attributes), and [configurable application parameters](../../specification/applications/application-description.md#defining-configurable-application-parameters). There is only one YAML file in the package root of kind `ApplicationDescription`. -- The **resources**, which are additional files associated with the application (e.g., manual, icon, release notes, license file, etc.) that may be used to display more information about the application in a UI such as an [application catalog](../../personas-and-definitions/technical-lexicon.md#application-catalog) or [marketplace](../../personas-and-definitions/technical-lexicon.md#marketplace) or other informative outputs. +- The **resources**, which are additional files associated with the application (e.g., manual, icon, release notes, license file, etc.) that may be used to provide more information about the application (e.g., in a UI such as an [application catalog](../../personas-and-definitions/technical-lexicon.md#application-catalog) of a [WFM](../../personas-and-definitions/technical-lexicon.md#workload-fleet-manager)). The Application Package has the following folder/file structure: @@ -17,9 +17,6 @@ The Application Package is made available in an [Application Registry](./applica An application aggregates one or more [components](../../personas-and-definitions/technical-lexicon.md#component), which each link to one or more [OCI Containers](https://github.com/opencontainers). The components referenced in the [Application Description](../../specification/applications/application-description.md) are stored in a [Component Registry](../../personas-and-definitions/technical-lexicon.md#component-registry), and the linked containers are provided via a [Container Registry](../../personas-and-definitions/technical-lexicon.md#container-registry). Registries can be remote (i.e., Internet-accessible) or [local](../../concepts/applications/local-registries.md) (i.e., accessible within a local network infrastructure of the devices). -> **Note** -> Application catalogs and marketplaces are out of scope of the Margo specification. The exact requirements of the marketing material need to be defined by the application marketplace beyond outlined mandatory content. - The [deployment profiles](../../specification/applications/application-description.md#deploymentprofile-attributes) specified in the [Application Description](../../specification/applications/application-description.md) are defined as Helm Chart components AND/OR [Compose Archive](../../personas-and-definitions/technical-lexicon.md#compose-archive) components. These components are being deployed as workloads on the edge devices: - To target devices, which deploy workloads using Kubernetes, components need to be defined as Helm charts using [Helm (version 3)](https://helm.sh/docs/topics/charts/). diff --git a/system-design/concepts/applications/application-registry.md b/system-design/concepts/applications/application-registry.md index a7d4d2b..959ae46 100644 --- a/system-design/concepts/applications/application-registry.md +++ b/system-design/concepts/applications/application-registry.md @@ -1,13 +1,12 @@ # Application Registry -The Margo specification differentiates 4 kinds of registries: *Application Registries*, *Component Registries*, and *Container Registries* as well as *Marketplaces*. +The Margo specification differentiates 3 kinds of registries: *Application Registries*, *Component Registries*, and *Container Registries*. 1. An **Application Registry** hosts Application Packages that define through their [Application Description](../../specification/applications/application-description.md) the application as one or multiple [Components](../../personas-and-definitions/technical-lexicon.md#component). 2. A **Component Registry** hosts the [Components](../../personas-and-definitions/technical-lexicon.md#component) (which are deployable as *workloads*) and are provided as **Helm Charts** or **Compose Archives**. 3. A **Container Registry** hosts container images referenced by those Components. -4. A **Marketplace** lists applications to advertise them and enable purchasing for end users. -Out of these 4 registries, **only the Application Registry interface is in scope** of the Margo specification and its API definition can be found [here](../../specification/applications/application-registry.md). +Out of these 3 registries, **only the Application Registry interface is in scope** of the Margo specification and its API definition can be found [here](../../specification/applications/application-registry.md). The diagram below illustrates these functionalities and relationships of registries within Margo. @@ -18,7 +17,6 @@ flowchart B -- hosted Components links to --> D[Container Registry] A -->|pulls Application Package | C F[App Developer] -->|uploads Application Package to| C - G["Marketplace"] -- points to Application Package --> C C -->|hosts 0..*| E@{ shape: docs, label: "Application Packages"} C -->|validates token| H[Authentication Service] A -->|requests token| H @@ -27,7 +25,6 @@ flowchart style B fill:#ABC style C fill:#ABC style D fill:#ABC - style G fill:#ABC ``` As shown in the figure above, an `Application Developer` uploads an [Application package](application-package.md) to an Application Registry. From there, it is available to a `Workload Fleet Manager` (WFM). diff --git a/system-design/personas-and-definitions/technical-lexicon.md b/system-design/personas-and-definitions/technical-lexicon.md index 50a8f4b..8313eff 100644 --- a/system-design/personas-and-definitions/technical-lexicon.md +++ b/system-design/personas-and-definitions/technical-lexicon.md @@ -91,9 +91,7 @@ The [API of the Application Registry](../specification/applications/application- #### Application Catalog -An Application Catalog resides inside or associated with a [WFM](#workload-fleet-manager) to hold [Application Packages](#application-package) that were preselected to be install-ready for the edge environment of a [Workload Fleet Manager](#workload-fleet-manager) to deploy them to managed [Edge Compute Devices](#edge-compute-device). - -An Application Catalog obtains the offered [Applications](#application) from one or more [Application Registries](#application-registry). +An Application Catalog is a visual representation of preselected, install-ready applications, the user of the [WFM](#workload-fleet-manager) can deploy to it's managed [Edge Compute Devices](#edge-compute-device). Application Catalogs and how they function within the WFM are out of scope for Margo. #### Component Registry @@ -104,16 +102,3 @@ The Component Registry can be implemented, e.g., as an OCI Registry. #### Container Registry A Container Registry hosts container images. [Components](#component) which are provided as Helm Charts or Compose Archives link to such container images. - - -#### Marketplace - -A Marketplace is the location where end users discover and purchase the rights to access [Applications](#application) to be deployed as [Workloads](#workload) from a vendor. - -Functional Requirements of the Marketplace: - -- Provide users with a list of [Applications](#application) available for purchase. -- Enable users to purchase access rights to an [Application](#application) deployable as [workloads](#workload). -- Enable users with the metadata to access associated [Application Registries](#application-registry). - -> Note: The Workload Marketplace component is out of scope for Project Margo. However, it is necessary to define to clarify the full user workflow. diff --git a/system-design/specification/applications/application-registry.md b/system-design/specification/applications/application-registry.md index 3f23340..0a94554 100644 --- a/system-design/specification/applications/application-registry.md +++ b/system-design/specification/applications/application-registry.md @@ -38,7 +38,7 @@ Subsequently, the Application Developer creates an OCI image manifest that lists The uploaded OCI image manifest MUST adhere to the Margo-specific constraints detailed [here](#oci-image-manifest-as-response-from-application-registry). -Subsequently, the App Developer uses a UI or other vendor-specific mechanism to communicate (either directly or indirectly, e.g., via a Marketplace) to the WFM the namespace of the Application Package's repository. +Subsequently, the App Developer uses a UI or other vendor-specific mechanism to communicate (either directly or indirectly) to the WFM the namespace of the Application Package's repository. ```mermaid sequenceDiagram From 1030d8c49a51daaa188b934139ae640b6b2d0575 Mon Sep 17 00:00:00 2001 From: Arne Broering Date: Tue, 2 Dec 2025 16:21:01 +0100 Subject: [PATCH 21/29] added note for authentication Signed-off-by: Arne Broering --- .../concepts/applications/application-registry.md | 10 ++++++---- system-design/overview/applications-and-workloads.md | 3 ++- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/system-design/concepts/applications/application-registry.md b/system-design/concepts/applications/application-registry.md index 959ae46..3baa357 100644 --- a/system-design/concepts/applications/application-registry.md +++ b/system-design/concepts/applications/application-registry.md @@ -18,19 +18,21 @@ flowchart A -->|pulls Application Package | C F[App Developer] -->|uploads Application Package to| C C -->|hosts 0..*| E@{ shape: docs, label: "Application Packages"} - C -->|validates token| H[Authentication Service] - A -->|requests token| H + C s1@-->|validates token| H[Authentication Service] + A s2@-->|requests token| H style H stroke-dasharray: 3 6 - style B fill:#ABC style C fill:#ABC style D fill:#ABC + classDef dashed stroke-dasharray: 3,6, stroke-dashoffset: 900; + class s1 dashed + class s2 dashed ``` As shown in the figure above, an `Application Developer` uploads an [Application package](application-package.md) to an Application Registry. From there, it is available to a `Workload Fleet Manager` (WFM). The WFM acts as a client to pull an [Application Package](application-package.md) from the Application Registry. It would then list this Application Package on its UI (e.g., an internal `Application Catalog`) to enable the usage on its managed devices. -An `Authentication Service` manages access control for the Application Registry. The WFM requests a token from the Authentication Service to include in the requests to the Application Registry. The received token is then validated by the Application Registry through interaction with the Authentication Service. +> Note: The figure above shows an `Authentication Service` that manages access control for the Application Registry. This service and interactions with it are not yet formally defined by Margo and needs to be further discussed in the future. The idea here is that the WFM requests a token from the Authentication Service to include in requests to the Application Registry. The received token is then validated by the Application Registry through interaction with the Authentication Service. The Application Registry's API is compliant with the [OCI Registry API (v1.1.0)](https://github.com/opencontainers/distribution-spec/blob/v1.1.0/spec.md). A hosted Application Package is provided by listing its parts as layers in an [image manifests](https://github.com/opencontainers/image-spec/blob/v1.0.1/manifest.md) that can be requested through the API. diff --git a/system-design/overview/applications-and-workloads.md b/system-design/overview/applications-and-workloads.md index 82a29f3..6d84254 100644 --- a/system-design/overview/applications-and-workloads.md +++ b/system-design/overview/applications-and-workloads.md @@ -1,4 +1,5 @@ -# Applications & Workloads +# Applications + A [workload](../personas-and-definitions/technical-lexicon.md#workload) is running software. More specifically, a workload is a running [Component](../personas-and-definitions/technical-lexicon.md#component) of an [Application Package](../concepts/applications/application-package.md) deployed to a Margo compliant [edge compute device](../personas-and-definitions/technical-lexicon.md#edge-compute-device). From 43a53a3ad1e17230f269562705bb1dbdb3527a2a Mon Sep 17 00:00:00 2001 From: Arne Broering Date: Tue, 2 Dec 2025 16:32:40 +0100 Subject: [PATCH 22/29] changed application overview Signed-off-by: Arne Broering --- mkdocs.yml | 2 +- system-design/concepts/applications/application-package.md | 2 +- .../{applications-and-workloads.md => applications.md} | 3 +-- 3 files changed, 3 insertions(+), 4 deletions(-) rename system-design/overview/{applications-and-workloads.md => applications.md} (91%) diff --git a/mkdocs.yml b/mkdocs.yml index 437ba6a..b03aa33 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -10,7 +10,7 @@ nav: - personas-and-definitions/software-composition.md - Overview: - overview/envisioned-system-design.md - - overview/applications-and-workloads.md + - overview/applications.md - overview/workload-fleet-management.md - overview/edge-compute-devices.md - overview/workload-observability.md diff --git a/system-design/concepts/applications/application-package.md b/system-design/concepts/applications/application-package.md index 08664db..cca2159 100644 --- a/system-design/concepts/applications/application-package.md +++ b/system-design/concepts/applications/application-package.md @@ -1,6 +1,6 @@ # Application Package -The Application Package, which is used to [distribute an application](../../overview/applications-and-workloads.md) to be deployed as [workloads](../../personas-and-definitions/technical-lexicon.md#workload) on edge devices, comprises the following elements: +The Application Package, which is used to [distribute an application](../../overview/applications.md) to be deployed as [workloads](../../personas-and-definitions/technical-lexicon.md#workload) on edge devices, comprises the following elements: - The **Application Description**: a YAML document with the element `kind` defined as `ApplicationDescription`, which is stored in a file (for example named `margo.yaml`) and contains information about the application's [metadata](../../specification/applications/application-description.md#metadata-attributes) (e.g., description, icon, release notes, license file, etc.), the application [components](../../personas-and-definitions/technical-lexicon.md#component) (e.g., Helm charts, Compose Archive) which are defined in [deployment configurations](../../specification/applications/application-description.md#deploymentprofile-attributes), and [configurable application parameters](../../specification/applications/application-description.md#defining-configurable-application-parameters). There is only one YAML file in the package root of kind `ApplicationDescription`. - The **resources**, which are additional files associated with the application (e.g., manual, icon, release notes, license file, etc.) that may be used to provide more information about the application (e.g., in a UI such as an [application catalog](../../personas-and-definitions/technical-lexicon.md#application-catalog) of a [WFM](../../personas-and-definitions/technical-lexicon.md#workload-fleet-manager)). diff --git a/system-design/overview/applications-and-workloads.md b/system-design/overview/applications.md similarity index 91% rename from system-design/overview/applications-and-workloads.md rename to system-design/overview/applications.md index 6d84254..8f6e13f 100644 --- a/system-design/overview/applications-and-workloads.md +++ b/system-design/overview/applications.md @@ -1,7 +1,6 @@ # Applications - -A [workload](../personas-and-definitions/technical-lexicon.md#workload) is running software. More specifically, a workload is a running [Component](../personas-and-definitions/technical-lexicon.md#component) of an [Application Package](../concepts/applications/application-package.md) deployed to a Margo compliant [edge compute device](../personas-and-definitions/technical-lexicon.md#edge-compute-device). +An application is defined as an [Application Package](../concepts/applications/application-package.md) described through an [Application Description](../specification/applications/application-description.md) and consists of deployable [components](../personas-and-definitions/technical-lexicon.md#component). A running [component](../personas-and-definitions/technical-lexicon.md#component) is called a [workload](../personas-and-definitions/technical-lexicon.md#workload). A workload runs on a Margo compliant [edge compute device](../personas-and-definitions/technical-lexicon.md#edge-compute-device). In order to help achieve Margo's interoperability [mission statement](../index.md#mission-statement) we are initially targeting [containerized](https://github.com/opencontainers) components/workloads capable of running on platforms like Kubernetes, Docker and Podman. The flexibility these platforms provide enables [workload suppliers](../personas-and-definitions/personas.md#workload-supplier) to define and package their components in a common way using [Helm](https://helm.sh/docs/) or the [Compose specification](https://github.com/compose-spec/compose-spec/blob/main/spec.md) so they can more easily be deployed to multiple compatible edge compute devices as workloads. From 056331a316684525b2be799b2ffc24b0a18f5537 Mon Sep 17 00:00:00 2001 From: Arne Broering Date: Tue, 2 Dec 2025 17:28:05 +0100 Subject: [PATCH 23/29] add digest option Signed-off-by: Arne Broering --- .../specification/applications/application-registry.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/system-design/specification/applications/application-registry.md b/system-design/specification/applications/application-registry.md index 0a94554..d7e703b 100644 --- a/system-design/specification/applications/application-registry.md +++ b/system-design/specification/applications/application-registry.md @@ -145,7 +145,7 @@ The interface to retrieve the OCI image manifest of a specified version, which b To pull an Application Package, an HTTP ``GET`` request to a resource path MUST be performed in the following format: `/v2/{name}/manifests/{reference}`. -The `{reference}` is the `tag` of an OCI image manifest. The `tag` has been discovered via the [listing of application package versions](#list-margo-application-package-versions). +The `{reference}` MUST be the `tag` or `digest` of an OCI image manifest. The respective `tag` can discovered via the [listing of application package versions](#list-margo-application-package-versions). The `{name}` variable is the namespace of the Application Package repository. The HTTP headers of the ``GET`` request MAY include ```Authorization: Bearer ``` for including the interaction with the [Authentication Service](../../concepts/applications/application-registry.md). From 7033e13b6f47e61a89528e891b10adc73cd0e844 Mon Sep 17 00:00:00 2001 From: Arne Broering Date: Wed, 3 Dec 2025 12:33:39 +0100 Subject: [PATCH 24/29] removing folder structure requirement Signed-off-by: Arne Broering --- .../applications/application-package.md | 36 ++++++++++++++----- .../applications/application-registry.md | 2 +- .../overview/envisioned-system-design.md | 2 +- .../software-composition.md | 4 +-- 4 files changed, 32 insertions(+), 12 deletions(-) diff --git a/system-design/concepts/applications/application-package.md b/system-design/concepts/applications/application-package.md index cca2159..bd45217 100644 --- a/system-design/concepts/applications/application-package.md +++ b/system-design/concepts/applications/application-package.md @@ -2,18 +2,38 @@ The Application Package, which is used to [distribute an application](../../overview/applications.md) to be deployed as [workloads](../../personas-and-definitions/technical-lexicon.md#workload) on edge devices, comprises the following elements: -- The **Application Description**: a YAML document with the element `kind` defined as `ApplicationDescription`, which is stored in a file (for example named `margo.yaml`) and contains information about the application's [metadata](../../specification/applications/application-description.md#metadata-attributes) (e.g., description, icon, release notes, license file, etc.), the application [components](../../personas-and-definitions/technical-lexicon.md#component) (e.g., Helm charts, Compose Archive) which are defined in [deployment configurations](../../specification/applications/application-description.md#deploymentprofile-attributes), and [configurable application parameters](../../specification/applications/application-description.md#defining-configurable-application-parameters). There is only one YAML file in the package root of kind `ApplicationDescription`. +- The **Application Description**: a YAML document with the element `kind` defined as `ApplicationDescription`, which is stored in a file (for example named `margo.yaml`) and contains information about the application's [metadata](../../specification/applications/application-description.md#metadata-attributes) (e.g., description, icon, release notes, license file, etc.), the application [components](../../personas-and-definitions/technical-lexicon.md#component) (e.g., Helm charts, Compose Archive), which are defined in [deployment configurations](../../specification/applications/application-description.md#deploymentprofile-attributes), and [configurable application parameters](../../specification/applications/application-description.md#defining-configurable-application-parameters). There is only one YAML file in the package root of kind `ApplicationDescription`. - The **resources**, which are additional files associated with the application (e.g., manual, icon, release notes, license file, etc.) that may be used to provide more information about the application (e.g., in a UI such as an [application catalog](../../personas-and-definitions/technical-lexicon.md#application-catalog) of a [WFM](../../personas-and-definitions/technical-lexicon.md#workload-fleet-manager)). -The Application Package has the following folder/file structure: - -```yaml -/ # REQUIRED top-level directory -└── .yaml # REQUIRED a YAML document with element 'kind' as 'ApplicationDescription' stored in a file (e.g., 'margo.yaml') -└── resources # OPTIONAL folder with application files (e.g., icon, license file, release notes) that may be used for displaying additional information about the application +The Application Package is distributed via an [Application Registry](./application-registry.md) and is bundled within a **repository**, according to [OCI distribution specification](https://github.com/opencontainers/distribution-spec/blob/v1.1.0/spec.md). All files (i.e., Application Description and resource files) belonging to the Application Package are referenced as **layers** by a **manifest** inside the repository. The layer of the Application Description file is marked with a **mediaType** value as "application/vnd.margo.app.description.v1+yaml". The layers of resource files are marked with an **annotation** called "org.margo.app.resource" and a value that indicates the kind of resource (e.g., "metadata.catalog.application.icon"). +This is illustrated in the figure below and formally defined [here](../../specification/applications/application-registry.md). + + +``` mermaid +classDiagram +direction LR + class `my-application-description: Layer` { + mediaType: "application/vnd.margo.app.description.v1+yaml" + digest: "sha256:f6b7914..." + size: 999 + } + + class `my-resources-icon: Layer` { + mediaType: "image/jpeg" + digest: "sha256:sha256:451410b6adfdce..." + size: 5065 + annotations: ["org.margo.app.resource": "metadata.catalog.application.icon", ...] + } + + class `my-margo-app-manifest: Manifest` { + mediaType: "application/vnd.oci.image.manifest.v1+json" + artifactType: "application/vnd.org.margo.app.v1+json" + } + + `my-margo-app-manifest: Manifest` o-- `my-application-description: Layer` + `my-margo-app-manifest: Manifest` o-- `my-resources-icon: Layer` ``` -The Application Package is made available in an [Application Registry](./application-registry.md). An application aggregates one or more [components](../../personas-and-definitions/technical-lexicon.md#component), which each link to one or more [OCI Containers](https://github.com/opencontainers). The components referenced in the [Application Description](../../specification/applications/application-description.md) are stored in a [Component Registry](../../personas-and-definitions/technical-lexicon.md#component-registry), and the linked containers are provided via a [Container Registry](../../personas-and-definitions/technical-lexicon.md#container-registry). Registries can be remote (i.e., Internet-accessible) or [local](../../concepts/applications/local-registries.md) (i.e., accessible within a local network infrastructure of the devices). diff --git a/system-design/concepts/applications/application-registry.md b/system-design/concepts/applications/application-registry.md index 3baa357..9d2a485 100644 --- a/system-design/concepts/applications/application-registry.md +++ b/system-design/concepts/applications/application-registry.md @@ -29,7 +29,7 @@ flowchart class s2 dashed ``` -As shown in the figure above, an `Application Developer` uploads an [Application package](application-package.md) to an Application Registry. From there, it is available to a `Workload Fleet Manager` (WFM). +As shown in the figure above, an `Application Developer` uploads an [Application Package](application-package.md) to an Application Registry. From there, it is available to a `Workload Fleet Manager` (WFM). The WFM acts as a client to pull an [Application Package](application-package.md) from the Application Registry. It would then list this Application Package on its UI (e.g., an internal `Application Catalog`) to enable the usage on its managed devices. > Note: The figure above shows an `Authentication Service` that manages access control for the Application Registry. This service and interactions with it are not yet formally defined by Margo and needs to be further discussed in the future. The idea here is that the WFM requests a token from the Authentication Service to include in requests to the Application Registry. The received token is then validated by the Application Registry through interaction with the Authentication Service. diff --git a/system-design/overview/envisioned-system-design.md b/system-design/overview/envisioned-system-design.md index dd03671..e08c4b7 100644 --- a/system-design/overview/envisioned-system-design.md +++ b/system-design/overview/envisioned-system-design.md @@ -10,7 +10,7 @@ The envisioned system can be broken down into the following main components: ### Workloads -Workloads are the software deployed to Margo-compliant edge compute devices. They are deployed [Components](../personas-and-definitions/technical-lexicon.md#component) of an [Application Pacakge](../personas-and-definitions/technical-lexicon.md#application-package). See the [workloads overview](workloads.md) page to learn more Margo's supported workloads and how they are packaged. +Workloads are the software deployed to Margo-compliant edge compute devices. They are deployed [Components](../personas-and-definitions/technical-lexicon.md#component) of an [Application Pacakge](../personas-and-definitions/technical-lexicon.md#application-package). See the [Applications overview](applications.md) page to learn more Margo's supported workloads and how they are packaged. ### Workload Observability diff --git a/system-design/personas-and-definitions/software-composition.md b/system-design/personas-and-definitions/software-composition.md index e7ef5b9..ab0c582 100644 --- a/system-design/personas-and-definitions/software-composition.md +++ b/system-design/personas-and-definitions/software-composition.md @@ -279,7 +279,7 @@ C4Component [workload]: technical-lexicon.md#workload [application]: technical-lexicon.md#application [component-registry]: technical-lexicon.md#component-registry -[deployment-definition]: ../../specification/margo-management-interface/desired-state/?h=applicationdeployment.md#applicationdeployment-definition +[deployment-definition]: ../specification/margo-management-interface/desired-state.md/?h=applicationdeployment.md#applicationdeployment-definition [provider-model]: technical-lexicon.md#provider-model [wfmc]: technical-lexicon.md#workload-fleet-management-client -[deployment-profile]: ../specification/applications/application-description.md#deploymentprofile-attributes +[deployment-profile]: ../specification/applications/application-description.md#deploymentprofile-attributes From a632556dffc54f96939c1dae4759d64076f5b63e Mon Sep 17 00:00:00 2001 From: Arne Broering Date: Wed, 3 Dec 2025 14:48:19 +0100 Subject: [PATCH 25/29] fixing pages error Signed-off-by: Arne Broering --- .github/workflows/pages.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/pages.yml b/.github/workflows/pages.yml index fb22756..605d8a6 100644 --- a/.github/workflows/pages.yml +++ b/.github/workflows/pages.yml @@ -114,7 +114,7 @@ jobs: - name: Setup Python uses: actions/setup-python@v4 with: - python-version: 3.x + python-version: '3.12' - name: Install poetry uses: abatilo/actions-poetry@v2 From 0ae0969c0d7b613f52969ce97ee82444beb6a7ff Mon Sep 17 00:00:00 2001 From: Arne Broering Date: Wed, 3 Dec 2025 15:19:32 +0100 Subject: [PATCH 26/29] removed link to private GitHub repo Signed-off-by: Arne Broering --- system-design/concepts/applications/application-registry.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/system-design/concepts/applications/application-registry.md b/system-design/concepts/applications/application-registry.md index 9d2a485..28cd906 100644 --- a/system-design/concepts/applications/application-registry.md +++ b/system-design/concepts/applications/application-registry.md @@ -39,5 +39,3 @@ The Application Registry's API is compliant with the [OCI Registry API (v1.1.0)] ## Relevant Links * The technical reference of the Application Registry API is defined [here](../../specification/applications/application-registry.md). - -* A reference implementation of the Application Registry is described [here](https://github.com/margo/app-package-definition-wg/blob/main/application-registry-example/app_registry_as_oci_registry.md) and includes sample applications and configuration for demonstration. It utilizes an open source OCI Registry and the [ORAS tool](https://oras.land/docs/) as the client. From 631ee9f03207194d6536852f545bc2ca8c7190c3 Mon Sep 17 00:00:00 2001 From: Arne Broering Date: Wed, 10 Dec 2025 13:39:36 +0100 Subject: [PATCH 27/29] addressing various view comments from Sivanoc Signed-off-by: Arne Broering --- .../applications/application-package.md | 21 ++-- .../applications/application-registry.md | 9 +- .../concepts/applications/local-registries.md | 15 ++- system-design/overview/applications.md | 4 +- .../overview/envisioned-system-design.md | 4 +- .../technical-lexicon.md | 6 +- .../applications/application-registry.md | 101 ++++++++++-------- 7 files changed, 93 insertions(+), 67 deletions(-) diff --git a/system-design/concepts/applications/application-package.md b/system-design/concepts/applications/application-package.md index bd45217..737a1e2 100644 --- a/system-design/concepts/applications/application-package.md +++ b/system-design/concepts/applications/application-package.md @@ -5,24 +5,27 @@ The Application Package, which is used to [distribute an application](../../over - The **Application Description**: a YAML document with the element `kind` defined as `ApplicationDescription`, which is stored in a file (for example named `margo.yaml`) and contains information about the application's [metadata](../../specification/applications/application-description.md#metadata-attributes) (e.g., description, icon, release notes, license file, etc.), the application [components](../../personas-and-definitions/technical-lexicon.md#component) (e.g., Helm charts, Compose Archive), which are defined in [deployment configurations](../../specification/applications/application-description.md#deploymentprofile-attributes), and [configurable application parameters](../../specification/applications/application-description.md#defining-configurable-application-parameters). There is only one YAML file in the package root of kind `ApplicationDescription`. - The **resources**, which are additional files associated with the application (e.g., manual, icon, release notes, license file, etc.) that may be used to provide more information about the application (e.g., in a UI such as an [application catalog](../../personas-and-definitions/technical-lexicon.md#application-catalog) of a [WFM](../../personas-and-definitions/technical-lexicon.md#workload-fleet-manager)). -The Application Package is distributed via an [Application Registry](./application-registry.md) and is bundled within a **repository**, according to [OCI distribution specification](https://github.com/opencontainers/distribution-spec/blob/v1.1.0/spec.md). All files (i.e., Application Description and resource files) belonging to the Application Package are referenced as **layers** by a **manifest** inside the repository. The layer of the Application Description file is marked with a **mediaType** value as "application/vnd.margo.app.description.v1+yaml". The layers of resource files are marked with an **annotation** called "org.margo.app.resource" and a value that indicates the kind of resource (e.g., "metadata.catalog.application.icon"). +The Application Package is distributed via an [Application Registry](./application-registry.md) and is bundled within a **repository**, according to [OCI distribution specification](https://github.com/opencontainers/distribution-spec/blob/v1.1.0/spec.md). +The Application Package is distributed via an [Application Registry](./application-registry.md) and is bundled within a **repository**, according to [OCI distribution specification](https://github.com/opencontainers/distribution-spec/blob/v1.1.0/spec.md). +All files (i.e., Application Description and resource files) belonging to the Application Package are referenced as *layers* (the equivalent term **blobs** is nowadays preferred and will be used in the rest of this document) by a **manifest** inside the repository. +The blob of the Application Description file is marked with a **mediaType** value as `application/vnd.margo.app.description.v1+yaml`. +The blobs of resource files are marked with an according **mediaType** (see list [here](../../specification/applications/application-registry.md#margo-specific-media-types)) called `application/vnd.margo.app.icon.v1+jpeg`. This is illustrated in the figure below and formally defined [here](../../specification/applications/application-registry.md). ``` mermaid classDiagram direction LR - class `my-application-description: Layer` { + class `my-application-description: Blob` { mediaType: "application/vnd.margo.app.description.v1+yaml" digest: "sha256:f6b7914..." size: 999 } - class `my-resources-icon: Layer` { - mediaType: "image/jpeg" + class `my-resources-icon: Blob` { + mediaType: "application/vnd.margo.app.icon.v1+jpeg" digest: "sha256:sha256:451410b6adfdce..." size: 5065 - annotations: ["org.margo.app.resource": "metadata.catalog.application.icon", ...] } class `my-margo-app-manifest: Manifest` { @@ -30,12 +33,14 @@ direction LR artifactType: "application/vnd.org.margo.app.v1+json" } - `my-margo-app-manifest: Manifest` o-- `my-application-description: Layer` - `my-margo-app-manifest: Manifest` o-- `my-resources-icon: Layer` + `my-margo-app-manifest: Manifest` o-- `my-application-description: Blob` + `my-margo-app-manifest: Manifest` o-- `my-resources-icon: Blob` ``` -An application aggregates one or more [components](../../personas-and-definitions/technical-lexicon.md#component), which each link to one or more [OCI Containers](https://github.com/opencontainers). The components referenced in the [Application Description](../../specification/applications/application-description.md) are stored in a [Component Registry](../../personas-and-definitions/technical-lexicon.md#component-registry), and the linked containers are provided via a [Container Registry](../../personas-and-definitions/technical-lexicon.md#container-registry). Registries can be remote (i.e., Internet-accessible) or [local](../../concepts/applications/local-registries.md) (i.e., accessible within a local network infrastructure of the devices). +An application aggregates one or more [components](../../personas-and-definitions/technical-lexicon.md#component), which each link to one or more [OCI Container Images](https://github.com/opencontainers/image-spec). +The components referenced in the [Application Description](../../specification/applications/application-description.md) are stored in a [Component Registry](../../personas-and-definitions/technical-lexicon.md#component-registry), and the linked container images are provided via a [Container Registry](../../personas-and-definitions/technical-lexicon.md#container-registry). +Registries can be remote (i.e., Internet-accessible) or [local](../../concepts/applications/local-registries.md) (i.e., accessible within a local network infrastructure of the devices). The [deployment profiles](../../specification/applications/application-description.md#deploymentprofile-attributes) specified in the [Application Description](../../specification/applications/application-description.md) are defined as Helm Chart components AND/OR [Compose Archive](../../personas-and-definitions/technical-lexicon.md#compose-archive) components. These components are being deployed as workloads on the edge devices: diff --git a/system-design/concepts/applications/application-registry.md b/system-design/concepts/applications/application-registry.md index 28cd906..9fa3b77 100644 --- a/system-design/concepts/applications/application-registry.md +++ b/system-design/concepts/applications/application-registry.md @@ -1,10 +1,10 @@ # Application Registry -The Margo specification differentiates 3 kinds of registries: *Application Registries*, *Component Registries*, and *Container Registries*. +The Margo specification differentiates 3 kinds of registries: *Application Registries*, *Component Registries*, and *Container Image Registries*. 1. An **Application Registry** hosts Application Packages that define through their [Application Description](../../specification/applications/application-description.md) the application as one or multiple [Components](../../personas-and-definitions/technical-lexicon.md#component). 2. A **Component Registry** hosts the [Components](../../personas-and-definitions/technical-lexicon.md#component) (which are deployable as *workloads*) and are provided as **Helm Charts** or **Compose Archives**. -3. A **Container Registry** hosts container images referenced by those Components. +3. A **Container Image Registry** hosts container images referenced by those Components. Out of these 3 registries, **only the Application Registry interface is in scope** of the Margo specification and its API definition can be found [here](../../specification/applications/application-registry.md). @@ -14,7 +14,7 @@ The diagram below illustrates these functionalities and relationships of registr flowchart A[WFM, or internal Application Catalog] -- Application Descriptions link to --> B[Component Registry] C[Application Registry] -- Application Descriptions link to --> B - B -- hosted Components links to --> D[Container Registry] + B -- hosted Components links to --> D[Container Image Registry] A -->|pulls Application Package | C F[App Developer] -->|uploads Application Package to| C C -->|hosts 0..*| E@{ shape: docs, label: "Application Packages"} @@ -34,7 +34,8 @@ The WFM acts as a client to pull an [Application Package](application-package.md > Note: The figure above shows an `Authentication Service` that manages access control for the Application Registry. This service and interactions with it are not yet formally defined by Margo and needs to be further discussed in the future. The idea here is that the WFM requests a token from the Authentication Service to include in requests to the Application Registry. The received token is then validated by the Application Registry through interaction with the Authentication Service. -The Application Registry's API is compliant with the [OCI Registry API (v1.1.0)](https://github.com/opencontainers/distribution-spec/blob/v1.1.0/spec.md). A hosted Application Package is provided by listing its parts as layers in an [image manifests](https://github.com/opencontainers/image-spec/blob/v1.0.1/manifest.md) that can be requested through the API. +The Application Registry's API is compliant with the [OCI Registry API (v1.1.0)](https://github.com/opencontainers/distribution-spec/blob/v1.1.0/spec.md). +A hosted Application Package is provided by listing its parts as blobs in an [image manifests](https://github.com/opencontainers/image-spec/blob/v1.0.1/manifest.md) that can be requested through the API. ## Relevant Links diff --git a/system-design/concepts/applications/local-registries.md b/system-design/concepts/applications/local-registries.md index b130b7c..8bd9fe3 100644 --- a/system-design/concepts/applications/local-registries.md +++ b/system-design/concepts/applications/local-registries.md @@ -1,6 +1,7 @@ # Local Registries -The [Component Registry](application-registry.md) as well as the [Container Registry](application-registry.md) considered by Margo are the registries that need to be accessed by devices to download components (i.e., Helm Charts or Compose Archives) or containers. This section describes how to configure those as local registries to avoid reliance on public Internet-accessible registries. +The [Component Registry](application-registry.md) as well as the [Container Image Registry](application-registry.md) considered by Margo are the registries that need to be accessed by devices to download components (i.e., Helm Charts or Compose Archives) or container images. +This section describes how to configure those as local registries to avoid reliance on public Internet-accessible registries. The reasons for not using public registries are for example: (1) publicly hosted container images or Helm charts could become unavailable at some point, as the owner decides to take the container images or Helm charts off the public registry, (2) Internet connectivity may not be available to the device and hence public registries are not reachable, or (3) end-users want to host their own registries so they can do security scans and package validation. @@ -10,11 +11,15 @@ In terms of connectivity, we can thereby distinguish mainly between the followin 2. **Locally connected device**, i.e., the device has connectivity to a local network (e.g., factory- or enterprise-wide) and a local repository can be made reachable. 3. **Air-gapped device**, i.e., the device generally is not connected and must be configured by accessing it directly (via direct network link with an Ethernet cable, or similar) for example through a technician’s laptop. -Local Component Registries or Container Registries can be used for all device categories. In case of **fully connected devices**, although the device could reach the Internet, a local registry can still be useful (e.g., as a cache for remote registries to save on bandwidth or to have container images or Helm Charts reliably available). In case of **locally connected devices**, a local registry is required to enable the Workload Fleet Management Client (WFMC) to install a Margo application on the device, as the device/WFMC does not have Internet access. Thereby, the local registry can be set up as a *pull-through cache* where data (e.g., container images) is cached locally when they are first retrieved from a remote source and subsequent requests for the same data are served from the local cache rather than fetching it again from the remote source. In case of **air-gapped devices**, a local registry has to be accessible on the technician's laptop (or other directly connected device), which performs the application installation process. +Local Component Registries or Container Image Registries can be used for all device categories. +In case of **fully connected devices**, although the device could reach the Internet, a local registry can still be useful (e.g., as a cache for remote registries to save on bandwidth or to have container images or Helm Charts reliably available). +In case of **locally connected devices**, a local registry is required to enable the Workload Fleet Management Client (WFMC) to install a Margo application on the device, as the device/WFMC does not have Internet access. +Thereby, the local registry can be set up as a *pull-through cache* where data (e.g., container images) is cached locally when they are first retrieved from a remote source and subsequent requests for the same data are served from the local cache rather than fetching it again from the remote source. +In case of **air-gapped devices**, a local registry has to be accessible on the technician's laptop (or other directly connected device), which performs the application installation process. To setup local registries, different configuration options exist: -## Option - Container Registry Mirror on Kubernetes Level +## Option - Container Image Registry Mirror on Kubernetes Level Kubernetes supports the configuration of registry mirrors. How this is configured depends on the distribution and the underlying container runtime. Distributions that utilize **containerd** as runtime (e.g., k3s or microk8s) allow the definition of mirrors in a configuration file. For example, in k3s the file `/etc/rancher/k3s/registries.yaml` can be used to set up a mirror for each device's Kubernetes environment: @@ -30,9 +35,9 @@ configs: password: "" ``` -## Option - Container Registry as Pull-through Cache on Docker Level +## Option - Container Image Registry as Pull-through Cache on Docker Level -To configure a pull-through cache in Docker for the Container Registry, a Docker Registry can be setup that acts as caching proxy for a remote Docker Registry. Such a Docker Registry can be defined using the following `config.yml`: +To configure a pull-through cache in Docker for the Container Image Registry, a Docker Registry can be setup that acts as caching proxy for a remote Docker Registry. Such a Docker Registry can be defined using the following `config.yml`: ```yaml version: 0.1 diff --git a/system-design/overview/applications.md b/system-design/overview/applications.md index 8f6e13f..2ba6bc4 100644 --- a/system-design/overview/applications.md +++ b/system-design/overview/applications.md @@ -16,7 +16,9 @@ Another advantage of Margo's [application description model](../concepts/applica ## Packaging & Distribution -To distribute an application consisting of multiple components that are deployable as workloads, they are wrapped in an [application package](../concepts/applications/application-package.md) defined by the workload supplier who aims to provide it to Margo-compliant edge compute devices. Therefore, the workload supplier creates an application description YAML document containing information about the application and references to its components. The application package is made available in an [application registry](../concepts/applications/application-registry.md), its components (i.e., Helm Charts or Compose Archives) are stored in a remote or [local](../concepts/applications/local-registries.md) component registry, and the linked [OCI containers](https://github.com/opencontainers) are provided through an OCI container registry. +To distribute an application consisting of multiple components that are deployable as workloads, they are wrapped in an [application package](../concepts/applications/application-package.md) defined by the workload supplier who aims to provide it to Margo-compliant edge compute devices. +Therefore, the workload supplier creates an application description YAML document containing information about the application and references to its components. +The application package is made available in an [application registry](../concepts/applications/application-registry.md), its components (i.e., Helm Charts or Compose Archives) are stored in a remote or [local](../concepts/applications/local-registries.md) component registry, and the linked container images are provided through an container image registry. ### Example workflow diff --git a/system-design/overview/envisioned-system-design.md b/system-design/overview/envisioned-system-design.md index e08c4b7..f155f35 100644 --- a/system-design/overview/envisioned-system-design.md +++ b/system-design/overview/envisioned-system-design.md @@ -10,7 +10,9 @@ The envisioned system can be broken down into the following main components: ### Workloads -Workloads are the software deployed to Margo-compliant edge compute devices. They are deployed [Components](../personas-and-definitions/technical-lexicon.md#component) of an [Application Pacakge](../personas-and-definitions/technical-lexicon.md#application-package). See the [Applications overview](applications.md) page to learn more Margo's supported workloads and how they are packaged. +Workloads are the software deployed to Margo-compliant edge compute devices. +They are deployed [Components](../personas-and-definitions/technical-lexicon.md#component) of an [Application Package](../personas-and-definitions/technical-lexicon.md#application-package). +See the [Applications overview](applications.md) page to learn more Margo's supported workloads and how they are packaged. ### Workload Observability diff --git a/system-design/personas-and-definitions/technical-lexicon.md b/system-design/personas-and-definitions/technical-lexicon.md index 8313eff..98f2e92 100644 --- a/system-design/personas-and-definitions/technical-lexicon.md +++ b/system-design/personas-and-definitions/technical-lexicon.md @@ -41,7 +41,7 @@ An application is a collection of one, or more, [Components](#component), as def #### Application Package -An Application Package is used to distribute an [application](#application). The parts of an Application Package are: Application Description (that refers to contained and deployable Components) as well as associated resources (e.g., icons). While the application package is made available in an [Application Registry](../concepts/applications/application-registry.md), the referenced [components](#component) are stored in a [Component Registry](#component-registry), and the linked containers are provided via a OCI [Container Registry](#container-registry). +An Application Package is used to distribute an [application](#application). The parts of an Application Package are: Application Description (that refers to contained and deployable Components) as well as associated resources (e.g., icons). While the application package is made available in an [Application Registry](../concepts/applications/application-registry.md), the referenced [components](#component) are stored in a [Component Registry](#component-registry), and the linked containers are provided via a OCI [Container Image Registry](#container-image-registry). #### Component @@ -100,5 +100,5 @@ A Component Registry holds [Components](#component) (e.g., Helm Charts and Compo When an application gets deployed through a [Workload Fleet Manager](#workload-fleet-manager), the components (linked within an [Application Description](../specification/applications/application-description.md)) are requested from the Component Registry and then deployed as [workloads](#workload). Components link to containers that are typically provided through [Container Registries](#container-registry). The Component Registry can be implemented, e.g., as an OCI Registry. -#### Container Registry -A Container Registry hosts container images. [Components](#component) which are provided as Helm Charts or Compose Archives link to such container images. +#### Container Image Registry +A Container Image Registry hosts container images. [Components](#component) which are provided as Helm Charts or Compose Archives link to such container images. diff --git a/system-design/specification/applications/application-registry.md b/system-design/specification/applications/application-registry.md index d7e703b..e1771da 100644 --- a/system-design/specification/applications/application-registry.md +++ b/system-design/specification/applications/application-registry.md @@ -10,31 +10,43 @@ The WFM MUST interact with the Application Registry compliant to the OCI Registr * Manifest: `/v2/{name}/manifests/{reference}` for retrieving an image manifest (identifed through the `{reference}`) that lists layers, which represent the parts of the Application Package. * Blob: `/v2/{name}/blobs/{digest}` for downloading parts of the Application Package -`{name}` is the namespace of the repository, which needs to be directly communicted by the App Developer to the WFM vendor. It could be for example a combination of the organization's and application's name. +`{name}` is the namespace of the repository, which needs to be directly communicated by the App Developer to the WFM vendor. It could be for example a combination of the organization's and application's name. Further details on how to use these API endpoints are specified below [towards App Developer](#uploading-an-application-package) and [towards WFM](#retrieving-an-application-package). ## Authentication, Authorization & Security -Margo recommends the use of an Authentication Service for the interactions between the WFM and Application Registry as conceptually described [here](../../concepts/applications/application-registry.md), e.g., implemented using OAuth 2.0. This involves the following workflow: +Margo recommends the use of an Authentication Service for the interactions between the WFM and Application Registry as conceptually described [here](../../concepts/applications/application-registry.md), e.g., implemented using OAuth 2.0 (see the [Token Authentication Specification](https://distribution.github.io/distribution/spec/auth/token/) provided by the reference implementation of the spec for more information). +This involves the following workflow: * WFM obtains credentials during onboarding * WFM requests a token from an Authentication Service * WFM uses the token for subsequent API calls to the Application Registry * Application Registry validates the token and enforces access control -Thereby, all communications must use TLS 1.3+ to ensure transport security. - > Note: Authentication, Authorization & Security mechanisms should be defined centrally and homogeneously across Margo. Hence, it is not further defined here. -Further, tools such as [cosign](https://github.com/sigstore/cosign) may be employed for signing artifacts uploaded to the Application Registry and storing the signatures alongside the artifacts they verify. - +Further, it is recommendable to sign the Application Package. +To do so, the Application Package can be signed as an OCI artifact (with tools such as [cosign](https://github.com/sigstore/cosign)). +Any OCI registry can host those signatures alongside the Application Packages. +Local storing (inside of an archive or in a directory) is also supported over the [OCI Layout](https://github.com/opencontainers/image-spec/blob/main/image-layout.md). +Distributing the signatures alongside the Application Packages they validate can be done with multiple tools available in the OCI ecosystem. ## Uploading an Application Package -As shown in the sequence diagram below, the Application Developer uploads the Margo-compliant `Application Package` to the Application Registry. I.e., all parts of the Application Package MUST be pushed as blobs compliant with the [end-4a / end-4b](https://github.com/opencontainers/distribution-spec/blob/v1.1.0/spec.md#endpoints) endpoints of the OCI_spec. +This section describes the upload workflow. + +However this is an application of the [standard artifact push workflow according the OCI Distribution Specification](https://github.com/opencontainers/distribution-spec/blob/main/spec.md#push) and therefore technical details are to be obtained from that specification. + +There are multiple libraries (e.g., [regclient](https://pkg.go.dev/github.com/regclient/regclient) or [oras](https://pkg.go.dev/oras.land/oras-go/v2) for Go, [oras](https://pypi.org/project/oras/) for Python) and tools (e.g., [regctl](https://github.com/regclient/regclient), [skopeo](https://github.com/containers/skopeo), [oras](https://github.com/oras-project/oras), [crane](https://github.com/google/go-containerregistry/tree/main/cmd/crane)) to realize this workflow. + +As shown in the sequence diagram below, the Application Developer uploads the Margo-compliant `Application Package` to the Application Registry. -Subsequently, the Application Developer creates an OCI image manifest that lists layers, each of which links to an uploaded blob. Then the manifest MUST be pushed to the Application Registry compliant to the [end-7](https://github.com/opencontainers/distribution-spec/blob/v1.1.0/spec.md#endpoints) endpoint of the OCI_spec. +I.e., all parts of the Application Package MUST be pushed as blobs according the ["Pushing Blobs" section of the OCI_spec](https://github.com/opencontainers/distribution-spec/blob/main/spec.md#pushing-blobs). + +Subsequently, the Application Developer creates an OCI image manifest that lists layers, each of which links to an uploaded blob. + +Then the manifest MUST be pushed to the Application Registry according the ["Pushing Manifests" section of the OCI_spec](https://github.com/opencontainers/distribution-spec/blob/main/spec.md#pushing-manifests). The uploaded OCI image manifest MUST adhere to the Margo-specific constraints detailed [here](#oci-image-manifest-as-response-from-application-registry). @@ -42,42 +54,42 @@ Subsequently, the App Developer uses a UI or other vendor-specific mechanism to ```mermaid sequenceDiagram - Note over AppDeveloper: uploads parts of Application Package as blobs: AppDeveloper->>AppRegistry: push blobs - AppDeveloper->>AppRegistry: push manifest - Note over AppDeveloper: uses vendor-specific upload mechanism (e.g., UI) to enable WFM to find the Application Package: AppDeveloper->>+WFM: Application Package location is: repository name in Application Registry ``` -There are no further Margo-specific constraints regarding the upload of the Application Package. The details defined in the [OCI_spec](https://github.com/opencontainers/distribution-spec/blob/v1.1.0/spec.md) MUST be applied to this interface of the Application Registry. - ## Retrieving an Application Package +This section describes the retrieval workflow. + +However this is an application of the [standard artifact pull workflow according the OCI Distribution Specification](https://github.com/opencontainers/distribution-spec/blob/main/spec.md#pull) and therefore technical details are to be obtained from that specification. + The WFM has received the namespace of the repository of the Application Package at the Application Registry. Next, as shown in the sequence diagram below, the WFM uses the API endpoints defined in the OCI_spec to retrieve a list of Application Package versions (as detailed [here](#list-margo-application-package-versions)). Then, the WFM pulls the OCI image manifest of the selected version of the Application Package, with the identifying reference being a tag or digest (as detailed [here](#pull-oci-image-manifest-of-application-package)). +If high trust requirements apply on the acquisition of the application package versions, state-of-the-art mechanisms can be applied to ensure that sophisticated attacks are not possible (for example a [TUF](https://theupdateframework.com/) implementation). + Finally, all parts (e.g., the Application Description file, the icon, the license, etc.) of the Application Package are retrieved by pulling the respective blobs listed as layers in the image manifest (as detailed [here](#get-parts-of-application-package)). ```mermaid sequenceDiagram Note over WFM: retrieve available versions of an Application Package: - WFM->>+AppRegistry: GET /v2/{name}/tags/list + WFM->>+AppRegistry: pull tags list Note over WFM: retrieves the OCI image manifest of the selected Application Package version. {reference} is a tag or a digest: - WFM->>+AppRegistry: GET /v2/{name}/manifests/{reference} + WFM->>+AppRegistry: pull manifest AppRegistry-->>+WFM: OCI image manifest - Note over WFM: retrieves parts of the Application Package as listed in OCI image manifest layers: - WFM->>AppRegistry: GET /v2/{name}/blobs/{digest} + WFM->>AppRegistry: pull blobs ``` ### List Margo Application Package Versions @@ -108,7 +120,7 @@ The response of the HTTP ``GET`` request according to [end-8a/end-8b](https://gi Thereby, a listed tag of an image manifest MUST be the same as the value of the key ``metadata.version`` as specified in the Application Description document of the associated Application Package. -#### Example A: +#### Example A (no filtering): Request: GET ``http://famous-app-registry/v2/northstar-industrial-applications/app1/tags/list`` @@ -124,7 +136,7 @@ Response: } ``` -#### Example B: +#### Example B (filtering to hide versions below v1.0.0): Request: GET ``http://famous-app-registry/v2/northstar-industrial-applications/app1/tags/list?n=2&last=v1.0.0`` @@ -139,37 +151,36 @@ Response: } ``` -### Pull OCI Image Manifest of Application Package +### Retrieving OCI Image Manifest of Application Package Manifest -The interface to retrieve the OCI image manifest of a specified version, which belongs to an Application Package, MUST be implemented according to OCI_spec endpoint [end-3](https://github.com/opencontainers/distribution-spec/blob/v1.1.0/spec.md#endpoints). +The Application Package OCI Manifest is a JSON document that conforms the [OCI Manifest specification](https://github.com/opencontainers/image-spec/blob/main/manifest.md) and provides metadata required for the distribution of the Application Package (from pushing to pulling) according the OCI specification. -To pull an Application Package, an HTTP ``GET`` request to a resource path MUST be performed in the following format: -`/v2/{name}/manifests/{reference}`. -The `{reference}` MUST be the `tag` or `digest` of an OCI image manifest. The respective `tag` can discovered via the [listing of application package versions](#list-margo-application-package-versions). -The `{name}` variable is the namespace of the Application Package repository. +Therefore retrieving an Application Package OCI Manifest MUST be implemented according the ["Pulling manifests" section of the OCISpec](https://github.com/opencontainers/distribution-spec/blob/main/spec.md#pulling-manifests). -The HTTP headers of the ``GET`` request MAY include ```Authorization: Bearer ``` for including the interaction with the [Authentication Service](../../concepts/applications/application-registry.md). +As mentioned before, different libraries and tools do the heavylifting of implementing these workflow. -#### OCI Image Manifest as Response from Application Registry: +An implementation without any of those tools or libraries is possible and MUST rely on the OCI_spec to do so. -The successful response of the HTTP ``GET`` request is an OCI image manifest (as defined in the OCI_spec), which MUST contain pointers to all parts of an Application Package within the Application Registry. +#### Application Package OCI Manifest -Each version of an Application Package MUST have its own OCI image manifest. +An Application Package OCI Manifest conforms to the [OCI Image Manifest Specification](https://github.com/opencontainers/image-spec/blob/v1.1.0/manifest.md) MUST contain pointers to all parts of an Application Package within the Application Registry. +This section specifies the Margo requirements on these kind of manifests. +Please refer to the [OCI Image Manifest Specification](https://github.com/opencontainers/image-spec/blob/v1.1.0/manifest.md) for all other technical details that are not Margo specific. -The ``schemaVersion`` of the OCI image manifest needs to be ``2``. +Each version of an Application Package MUST have its own OCI manifest. The ``artifactType`` of the OCI image manifest must be ``application/vnd.margo.app.v1+json``. -The ``config`` object must be declared as empty by defining its ``mediaType`` as ``application/vnd.oci.empty.v1+json``. +The ``config`` MUST be a so-called "empty config" and be specified in the manifest according the ["Guidance for an empty descriptor" section of the OCI Image specification](https://github.com/opencontainers/image-spec/blob/main/manifest.md#guidance-for-an-empty-descriptor). Each element of the ``layers`` array contains a reference (so-called `digests`) to an artifact (so-called `blobs`) that is a part of the Application Package. -Each Application Package part must be listed as an element of the ``layers`` array: - -* The [Application Description](../../specification/applications/application-description.md) of the Application Package must be referred to in one element of the ``layers`` array, where the ``mediaType`` of this layer/blob must be ``application/vnd.margo.app.description.v1+yaml``. -* Each [application resource](../../concepts/applications/application-package.md), which is an additional file associated with the application (e.g., manual, icon, release notes, license file, etc.), must be referred to in an element of the ``layers`` array. Such a layer must have an ``annotation``, which has the annotation key ``org.margo.app.resource``, and the annotation value must reflect the dotted path to the this resource in the [Application Description file](../../specification/applications/application-description.md). E.g., an application icon stored as the file ``resources/margo.jpg`` is referenced in the Application Description under ``metadata.catalog.application.icon: resources/margo.jpg`` and in the OCI image manifest, the respective layer of the icon resource has the annotation ``org.margo.app.resource`` with the value ``metadata.catalog.application.icon`` (see also OCI image manifest example below). +Each Application Package part (file) MUST be listed as an element of the ``layers`` array: +* The [Application Description](../../specification/applications/application-description.md) of the Application Package must be referred to in one element of the ``layers`` array, where the ``mediaType`` of this blob must be ``application/vnd.margo.app.description.v1+yaml``. +* Each [application resource](../../concepts/applications/application-package.md), which is an additional file associated with the application, must be referred to as a blob listed in the ``layers`` array. + The blobs of resource files must be marked with a **mediaType** specific to the kind of resource file (currently four possible resource files: ``icon``, ``releaseNotes``, ``descriptionFile``, ``licenseFile``), as listed in the [table below](../../specification/applications/application-registry.md#margo-specific-media-types)). E.g., the blob representing the icon file (e.g., in ``jpeg`` format) of an application is marked with the mediaType `application/vnd.margo.app.icon.v1+jpeg`. The [Application Description file](../../specification/applications/application-description.md) lists these resource files in the ```metadata.catalog.application`` element. -The following response example is a Margo-specific OCI image manifest following the [OCI Image Manifest Specification](https://github.com/opencontainers/image-spec/blob/v1.0.1/manifest.md) and the above defined specifics: +The following response example is a Margo-specific OCI manifest following the [OCI Image Manifest Specification](https://github.com/opencontainers/image-spec/blob/v1.0.1/manifest.md) and the above defined specifics: ```json { @@ -184,7 +195,7 @@ The following response example is a Margo-specific OCI image manifest following }, "layers": [ { - "mediaType": "application/vnd.margo.app.description.v1+yaml", # this MUST be the artifactType of a Margo Application Description file + "mediaType": "application/vnd.margo.app.description.v1+yaml", # this MUST be the artifactType of a Margo Application Description "digest": "sha256:f6b79149e6650b0064c146df7c045d157f3656b5ad1279b5ce9f4446b510bacf", "size": 999, "annotations": { @@ -192,38 +203,34 @@ The following response example is a Margo-specific OCI image manifest following } }, { - "mediaType": "text/markdown", + "mediaType": "application/vnd.margo.app.descriptionFile.v1+markdown", # this MUST be the correct mediaType for this resource as defined below "digest": "sha256:e373b123782a2b52483a9124cc9c578e0ed0300cb4131b73b0c79612122b8361", "size": 1596, "annotations": { - "org.margo.app.resource": "metadata.catalog.application.descriptionFile", # each Margo application resource MUST be annotated with a dotted path to its definition in the Application Description file "org.opencontainers.image.title": "resources/description.md" } }, { - "mediaType": "text/markdown", + "mediaType": "application/vnd.margo.app.licenseFile.v1+markdown", # this MUST be the correct mediaType for this resource as defined below "digest": "sha256:af7db4ab9030533b6cda2325247920c3659bc67a7d49f3d5098ae54a64633ec7", "size": 25, "annotations": { - "org.margo.app.resource": "metadata.catalog.application.licenseFile", # each Margo application resource MUST be annotated with a dotted path to its definition in the Application Description file "org.opencontainers.image.title": "resources/license.md" } }, { - "mediaType": "image/jpeg", + "mediaType": "application/vnd.margo.app.icon.v1+jpeg", # this MUST be the correct mediaType for this resource as defined below "digest": "sha256:451410b6adfdce1c974da2275290d9e207911a4023fafea0e283fad0502e5e56", "size": 5065, "annotations": { - "org.margo.app.resource": "metadata.catalog.application.icon", # each Margo application resource MUST be annotated with a dotted path to its definition in the Application Description file "org.opencontainers.image.title": "resources/margo.jpg" } }, { - "mediaType": "text/markdown", + "mediaType": "application/vnd.margo.app.releaseNotes.v1+markdown", # this MUST be the correct mediaType for this resource as defined below "digest": "sha256:c412d143084c3b051d7ea4b166a7bfffb4550f401d89cae8898991c65e90f736", "size": 42, "annotations": { - "org.margo.app.resource": "metadata.catalog.application.releaseNotes", # each Margo application resource MUST be annotated with a dotted path to its definition in the Application Description file "org.opencontainers.image.title": "resources/release-notes.md" } } @@ -237,6 +244,10 @@ The following response example is a Margo-specific OCI image manifest following |----------|----------| |``application/vnd.margo.app.v1+json`` | MUST be used as the **artifactType** to mark the OCI image manifest as the definition of a Margo Application Package | |``application/vnd.margo.app.description.v1+yaml`` | MUST be used to mark a layer in the OCI image manifest as pointing to the Margo Application Description file | +|``application/vnd.margo.app.icon.v1+{file format}``| MUST be used to mark a layer in the OCI image manifest as pointing to the icon of a Margo Application Package | +|``application/vnd.margo.app.descriptionFile.v1+{file format}``| MUST be used to mark a layer in the OCI image manifest as pointing to description file of a Margo Application Package | +|``application/vnd.margo.app.licenseFile.v1+{file format}``| MUST be used to mark a layer in the OCI image manifest as pointing to the license file of a Margo Application Package| +|``application/vnd.margo.app.releaseNotes.v1+{file format}``| MUST be used to mark a layer in the OCI image manifest as pointing to the release notes file of a Margo Application Package| #### Margo-Specific Annotation Keys From 4a9fb0474095ec6db6331fe6856cfa74c4c9c10b Mon Sep 17 00:00:00 2001 From: Arne Broering Date: Wed, 10 Dec 2025 14:22:50 +0100 Subject: [PATCH 28/29] addressing more review comments from Sivanoc Signed-off-by: Arne Broering --- .../applications/application-registry.md | 24 +++++++------------ 1 file changed, 8 insertions(+), 16 deletions(-) diff --git a/system-design/specification/applications/application-registry.md b/system-design/specification/applications/application-registry.md index e1771da..78db6cd 100644 --- a/system-design/specification/applications/application-registry.md +++ b/system-design/specification/applications/application-registry.md @@ -1,6 +1,6 @@ # Application Registry -The interactions of an `Application Registry` are described [here](../../concepts/applications/application-registry.md) from a conceptual view. This section formally specifies the API of the `Application Registry` and the exchange of an [Application Package](../../concepts/applications/application-package.md), defined through an [Application Description](../../specification/applications/application-description.md) file, from an Application Developer to the [Workload Fleet Manager](../../personas-and-definitions/technical-lexicon.md#workload-fleet-manager) (WFM). The `Application Registry` is designed as an `OCI Registry`, i.e., it offers an API compliant with the [OCI Registry API (v1.1.0)](https://github.com/opencontainers/distribution-spec/blob/v1.1.0/spec.md) (called here the "OCI_spec") for digital artifact distribution. This way, the Application Registry hosts the parts of an [Application Package](../../concepts/applications/application-package.md) in the form of `blobs` and uses `image manifests` according to [OCI Image specification](https://github.com/opencontainers/image-spec/blob/v1.0.1/manifest.md) to list a set of `layers`, each pointing at a blob. +The interactions of an `Application Registry` are described [here](../../concepts/applications/application-registry.md) from a conceptual view. This section formally specifies the API of the `Application Registry` and the exchange of an [Application Package](../../concepts/applications/application-package.md), defined through an [Application Description](../../specification/applications/application-description.md) file, from an Application Developer to the [Workload Fleet Manager](../../personas-and-definitions/technical-lexicon.md#workload-fleet-manager) (WFM). The `Application Registry` is designed as an `OCI Registry`, i.e., it offers an API compliant with the [OCI Distribution Scification](https://github.com/opencontainers/distribution-spec/blob/v1.1.0/spec.md) (called here the "OCI_spec") for digital artifact distribution. This way, the Application Registry hosts the parts of an [Application Package](../../concepts/applications/application-package.md) in the form of `blobs` and uses `image manifests` according to [OCI Image specification](https://github.com/opencontainers/image-spec/blob/v1.0.1/manifest.md) to list a set of `layers`, each pointing at a blob. ## Overview of API Endpoints @@ -96,16 +96,13 @@ sequenceDiagram The interface to retrieve the list of versions of an Application Package MUST be implemented according to OCI_spec endpoint [end-8a](https://github.com/opencontainers/distribution-spec/blob/v1.1.0/spec.md#endpoints). -To get a list of available versions of an Application Package, an HTTP ``GET`` request to a resource path MUST be performed in the following format: `/v2/{name}/tags/list`. The `{name}` variable is the namespace of the Application Package repository, which was communicated by the App Developer to the WFM vendor. +The list of the available Application Package versions can be obtained as documented in the ["Listing Tags" section of the OCI_spec](https://github.com/opencontainers/distribution-spec/blob/main/spec.md#listing-tags). -The HTTP headers of the ``GET`` request MAY include ```Authorization: Bearer ``` for including the interaction with the [Authentication Service](../../concepts/applications/application-registry.md). +The API supports filtering and pagination as documented in the linked specification section. -To query a subset of tags, the following query parameters MUST be implemented by the Application Registry as defined by OCI_spec endpoint [end-8b](https://github.com/opencontainers/distribution-spec/blob/v1.1.0/spec.md#endpoints): +The `{name}` variable is the namespace of the Application Package repository, which was communicated by the App Developer to the WFM vendor. -* ``n=`` (optional, limits results to n tags) -* ``last=`` (optional, starts list of tags after ````) - -The response of the HTTP ``GET`` request according to [end-8a/end-8b](https://github.com/opencontainers/distribution-spec/blob/v1.1.0/spec.md#endpoints) is a list of tags, which comply with the versions of available Application Packages. According to OCI_spec, upon success, the response MUST be a JSON body in the following format: +The list of Application Packages versions is provided in a JSON document that MUST conform with the above mentioned OCI_spec section and therefore has following format: ```json { @@ -258,13 +255,8 @@ The following response example is a Margo-specific OCI manifest following the [O -### Get Parts of Application Package - -The interface to retrieve Application Package parts, i.e., Application Description or Application Resource (e.g., icon, license, etc.), MUST be implemented according to OCI_spec endpoint [end-2](https://github.com/opencontainers/distribution-spec/blob/v1.1.0/spec.md#endpoints) by pulling a blob. +### Retrieve Parts of Application Package -To pull such a blob, an HTTP ``GET`` request to a resource path MUST be performed in the following format: -`/v2/{name}/blobs/{digest}`. -The `{digest}` is the blob's digest as listed in the application's OCI image manifest that has been [retrieved earlier](#pull-oci-image-manifest-of-application-package). -The `{name}` variable is the namespace of the Application Package repository. +Retrieving the different files that compose an Application Package MUST be implemented according to the ["Pulling blobs" section of the OCI_spec](https://github.com/opencontainers/distribution-spec/blob/main/spec.md#pulling-blobs). -The HTTP headers of the ``GET`` request MAY include ```Authorization: Bearer ``` for including the interaction with the [Authentication Service](../../concepts/applications/application-registry.md). +Also for this purpose available tools and libraries can be used for an implementation with low complexity. \ No newline at end of file From fee8f413908f71480a0adb69fc50e9a0b7b030c5 Mon Sep 17 00:00:00 2001 From: Arne Broering Date: Wed, 10 Dec 2025 15:22:57 +0100 Subject: [PATCH 29/29] final corrections Signed-off-by: Arne Broering --- .../applications/application-package.md | 30 ++++++------ system-design/overview/applications.md | 4 +- .../technical-lexicon.md | 2 +- .../applications/application-registry.md | 46 ++++++------------- 4 files changed, 35 insertions(+), 47 deletions(-) diff --git a/system-design/concepts/applications/application-package.md b/system-design/concepts/applications/application-package.md index 737a1e2..362eeda 100644 --- a/system-design/concepts/applications/application-package.md +++ b/system-design/concepts/applications/application-package.md @@ -2,14 +2,13 @@ The Application Package, which is used to [distribute an application](../../overview/applications.md) to be deployed as [workloads](../../personas-and-definitions/technical-lexicon.md#workload) on edge devices, comprises the following elements: -- The **Application Description**: a YAML document with the element `kind` defined as `ApplicationDescription`, which is stored in a file (for example named `margo.yaml`) and contains information about the application's [metadata](../../specification/applications/application-description.md#metadata-attributes) (e.g., description, icon, release notes, license file, etc.), the application [components](../../personas-and-definitions/technical-lexicon.md#component) (e.g., Helm charts, Compose Archive), which are defined in [deployment configurations](../../specification/applications/application-description.md#deploymentprofile-attributes), and [configurable application parameters](../../specification/applications/application-description.md#defining-configurable-application-parameters). There is only one YAML file in the package root of kind `ApplicationDescription`. -- The **resources**, which are additional files associated with the application (e.g., manual, icon, release notes, license file, etc.) that may be used to provide more information about the application (e.g., in a UI such as an [application catalog](../../personas-and-definitions/technical-lexicon.md#application-catalog) of a [WFM](../../personas-and-definitions/technical-lexicon.md#workload-fleet-manager)). +- The **Application Description**: a YAML document with the element `kind` defined as `ApplicationDescription`, which is stored in a file (for example named `margo.yaml`) and contains information about the application's [metadata](../../specification/applications/application-description.md#metadata-attributes) (e.g., name, version, author, etc.), the application [components](../../personas-and-definitions/technical-lexicon.md#component) (e.g., Helm charts, Compose Archive), which are defined in [deployment configurations](../../specification/applications/application-description.md#deploymentprofile-attributes), and [configurable application parameters](../../specification/applications/application-description.md#defining-configurable-application-parameters). There is only one YAML file in the package root of kind `ApplicationDescription`. +- The **resources**, which are additional files associated with the application (human-readable description, icon, release notes, or license file) that may be used to provide more information about the application (e.g., in a UI such as an [application catalog](../../personas-and-definitions/technical-lexicon.md#application-catalog) of a [WFM](../../personas-and-definitions/technical-lexicon.md#workload-fleet-manager)). -The Application Package is distributed via an [Application Registry](./application-registry.md) and is bundled within a **repository**, according to [OCI distribution specification](https://github.com/opencontainers/distribution-spec/blob/v1.1.0/spec.md). -The Application Package is distributed via an [Application Registry](./application-registry.md) and is bundled within a **repository**, according to [OCI distribution specification](https://github.com/opencontainers/distribution-spec/blob/v1.1.0/spec.md). +The Application Package is distributed via an [Application Registry](./application-registry.md) and is bundled within a **repository** according to the [OCI distribution specification](https://github.com/opencontainers/distribution-spec/blob/v1.1.0/spec.md). All files (i.e., Application Description and resource files) belonging to the Application Package are referenced as *layers* (the equivalent term **blobs** is nowadays preferred and will be used in the rest of this document) by a **manifest** inside the repository. The blob of the Application Description file is marked with a **mediaType** value as `application/vnd.margo.app.description.v1+yaml`. -The blobs of resource files are marked with an according **mediaType** (see list [here](../../specification/applications/application-registry.md#margo-specific-media-types)) called `application/vnd.margo.app.icon.v1+jpeg`. +The blobs of resource files are marked with an according **mediaType** (see list [here](../../specification/applications/application-registry.md#margo-specific-media-types)), e.g., an icon in jpeg format is marked with the mediaTye `application/vnd.margo.app.icon.v1+jpeg`. This is illustrated in the figure below and formally defined [here](../../specification/applications/application-registry.md). @@ -38,15 +37,25 @@ direction LR ``` -An application aggregates one or more [components](../../personas-and-definitions/technical-lexicon.md#component), which each link to one or more [OCI Container Images](https://github.com/opencontainers/image-spec). -The components referenced in the [Application Description](../../specification/applications/application-description.md) are stored in a [Component Registry](../../personas-and-definitions/technical-lexicon.md#component-registry), and the linked container images are provided via a [Container Registry](../../personas-and-definitions/technical-lexicon.md#container-registry). +An application aggregates one or more [components](../../personas-and-definitions/technical-lexicon.md#component). Therefore, the [deployment profiles](../../specification/applications/application-description.md#deploymentprofile-attributes) specified in the [Application Description](../../specification/applications/application-description.md) can be defined as Helm Chart components AND/OR [Compose Archive](../../personas-and-definitions/technical-lexicon.md#compose-archive) components. + +Each component links to one or more [OCI Container Images](https://github.com/opencontainers/image-spec). +The components referenced in the [Application Description](../../specification/applications/application-description.md) are stored in a [Component Registry](../../personas-and-definitions/technical-lexicon.md#component-registry), and the linked container images are provided via a [Container Image Registry](../../personas-and-definitions/technical-lexicon.md#container-image-registry). Registries can be remote (i.e., Internet-accessible) or [local](../../concepts/applications/local-registries.md) (i.e., accessible within a local network infrastructure of the devices). -The [deployment profiles](../../specification/applications/application-description.md#deploymentprofile-attributes) specified in the [Application Description](../../specification/applications/application-description.md) are defined as Helm Chart components AND/OR [Compose Archive](../../personas-and-definitions/technical-lexicon.md#compose-archive) components. These components are being deployed as workloads on the edge devices: + The components are being deployed as workloads on the edge devices: - To target devices, which deploy workloads using Kubernetes, components need to be defined as Helm charts using [Helm (version 3)](https://helm.sh/docs/topics/charts/). - To target devices, which deploy workloads using [Compose](https://www.compose-spec.io/), components need to be packaged as [Compose Archives](../../personas-and-definitions/technical-lexicon.md#compose-archive), i.e., a tarball file containing the `compose.yaml` file and any additional artifacts referenced by the Compose file (e.g., configuration files, environment variable files, etc.). Margo recommends to digitally sign this package and to specify the location of the public key in the `ApplicationDescription` (see `keyLocation` [here](../../specification/applications/application-description.md#componentproperties-attributes)). When digitally signing the package PGP encryption MUST be used. +If either one cannot be implemented it MAY be omitted but Margo RECOMMENDS defining [deployment profiles](../../specification/applications/application-description.md#deploymentprofile-attributes) as both Helm chart **AND** Compose components to strengthen interoperability and applicability. + +> **Note** +> A device running the application will only install the application using either the Compose Archives or the Helm Charts, but not both. + + +Margo will provide more detailed discussion and specification on the following points: + > **Investigation Needed**: Question: do we need to specify the location of a SHA256 hash for the Compose Archive also (similar to the PGP key) in the ApplicationDescription? > We will also discuss how we should handle secure container registries that require a username and password. > @@ -54,11 +63,6 @@ The [deployment profiles](../../specification/applications/application-descripti > > **Investigation Needed**: Missing in the current specification are ways to define dependencies (e.g., application dependencies) as well as required infrastructure services such as storage, message queues/bus, reverse proxy, or authentication/authorization/accounting. -If either one cannot be implemented it MAY be omitted but Margo RECOMMENDS defining [deployment profiles](../../specification/applications/application-description.md#deploymentprofile-attributes) as both Helm chart **AND** Compose components to strengthen interoperability and applicability. - -> **Note** -> A device running the application will only install the application using either the Compose Archives or the Helm Charts, but not both. - ## Relevant Links Please follow the subsequent link to view the technical reference of the `ApplicationDescription` format: diff --git a/system-design/overview/applications.md b/system-design/overview/applications.md index 2ba6bc4..7413f25 100644 --- a/system-design/overview/applications.md +++ b/system-design/overview/applications.md @@ -17,8 +17,8 @@ Another advantage of Margo's [application description model](../concepts/applica ## Packaging & Distribution To distribute an application consisting of multiple components that are deployable as workloads, they are wrapped in an [application package](../concepts/applications/application-package.md) defined by the workload supplier who aims to provide it to Margo-compliant edge compute devices. -Therefore, the workload supplier creates an application description YAML document containing information about the application and references to its components. -The application package is made available in an [application registry](../concepts/applications/application-registry.md), its components (i.e., Helm Charts or Compose Archives) are stored in a remote or [local](../concepts/applications/local-registries.md) component registry, and the linked container images are provided through an container image registry. +Therefore, the workload supplier creates an [application description YAML document](../specification/applications/application-description.md) containing information about the application and references to its components. +The application package is made available in an [application registry](../concepts/applications/application-registry.md), its components (i.e., Helm Charts or Compose Archives) are stored in a remote or [local](../concepts/applications/local-registries.md) component registry, and the linked container images are provided through a container image registry. ### Example workflow diff --git a/system-design/personas-and-definitions/technical-lexicon.md b/system-design/personas-and-definitions/technical-lexicon.md index 98f2e92..4f4d41c 100644 --- a/system-design/personas-and-definitions/technical-lexicon.md +++ b/system-design/personas-and-definitions/technical-lexicon.md @@ -97,7 +97,7 @@ An Application Catalog is a visual representation of preselected, install-ready #### Component Registry A Component Registry holds [Components](#component) (e.g., Helm Charts and Compose Archives) for [Application Packages](#application-package). -When an application gets deployed through a [Workload Fleet Manager](#workload-fleet-manager), the components (linked within an [Application Description](../specification/applications/application-description.md)) are requested from the Component Registry and then deployed as [workloads](#workload). Components link to containers that are typically provided through [Container Registries](#container-registry). +When an application gets deployed through a [Workload Fleet Manager](#workload-fleet-manager), the components (linked within an [Application Description](../specification/applications/application-description.md)) are requested from the Component Registry and then deployed as [workloads](#workload). Components link to containers that are typically provided through [Container Registries](#container-image-registry). The Component Registry can be implemented, e.g., as an OCI Registry. #### Container Image Registry diff --git a/system-design/specification/applications/application-registry.md b/system-design/specification/applications/application-registry.md index 78db6cd..5042ade 100644 --- a/system-design/specification/applications/application-registry.md +++ b/system-design/specification/applications/application-registry.md @@ -1,6 +1,6 @@ # Application Registry -The interactions of an `Application Registry` are described [here](../../concepts/applications/application-registry.md) from a conceptual view. This section formally specifies the API of the `Application Registry` and the exchange of an [Application Package](../../concepts/applications/application-package.md), defined through an [Application Description](../../specification/applications/application-description.md) file, from an Application Developer to the [Workload Fleet Manager](../../personas-and-definitions/technical-lexicon.md#workload-fleet-manager) (WFM). The `Application Registry` is designed as an `OCI Registry`, i.e., it offers an API compliant with the [OCI Distribution Scification](https://github.com/opencontainers/distribution-spec/blob/v1.1.0/spec.md) (called here the "OCI_spec") for digital artifact distribution. This way, the Application Registry hosts the parts of an [Application Package](../../concepts/applications/application-package.md) in the form of `blobs` and uses `image manifests` according to [OCI Image specification](https://github.com/opencontainers/image-spec/blob/v1.0.1/manifest.md) to list a set of `layers`, each pointing at a blob. +The interactions of an `Application Registry` are described [here](../../concepts/applications/application-registry.md) from a conceptual view. This section formally specifies the API of the `Application Registry` and the exchange of an [Application Package](../../concepts/applications/application-package.md), defined through an [Application Description](../../specification/applications/application-description.md) file, from an Application Developer to the [Workload Fleet Manager](../../personas-and-definitions/technical-lexicon.md#workload-fleet-manager) (WFM). The `Application Registry` is designed as an `OCI Registry`, i.e., it offers an API compliant with the [OCI Distribution Specification](https://github.com/opencontainers/distribution-spec/blob/v1.1.0/spec.md) (called here the "OCI_spec") for digital artifact distribution. This way, the Application Registry hosts the parts of an [Application Package](../../concepts/applications/application-package.md) in the form of `blobs` and uses `image manifests` according to [OCI Image specification](https://github.com/opencontainers/image-spec/blob/v1.0.1/manifest.md) to list a set of `layers`, each pointing at a blob. ## Overview of API Endpoints @@ -35,21 +35,14 @@ Distributing the signatures alongside the Application Packages they validate can ## Uploading an Application Package This section describes the upload workflow. - However this is an application of the [standard artifact push workflow according the OCI Distribution Specification](https://github.com/opencontainers/distribution-spec/blob/main/spec.md#push) and therefore technical details are to be obtained from that specification. - There are multiple libraries (e.g., [regclient](https://pkg.go.dev/github.com/regclient/regclient) or [oras](https://pkg.go.dev/oras.land/oras-go/v2) for Go, [oras](https://pypi.org/project/oras/) for Python) and tools (e.g., [regctl](https://github.com/regclient/regclient), [skopeo](https://github.com/containers/skopeo), [oras](https://github.com/oras-project/oras), [crane](https://github.com/google/go-containerregistry/tree/main/cmd/crane)) to realize this workflow. As shown in the sequence diagram below, the Application Developer uploads the Margo-compliant `Application Package` to the Application Registry. - I.e., all parts of the Application Package MUST be pushed as blobs according the ["Pushing Blobs" section of the OCI_spec](https://github.com/opencontainers/distribution-spec/blob/main/spec.md#pushing-blobs). - Subsequently, the Application Developer creates an OCI image manifest that lists layers, each of which links to an uploaded blob. - Then the manifest MUST be pushed to the Application Registry according the ["Pushing Manifests" section of the OCI_spec](https://github.com/opencontainers/distribution-spec/blob/main/spec.md#pushing-manifests). - -The uploaded OCI image manifest MUST adhere to the Margo-specific constraints detailed [here](#oci-image-manifest-as-response-from-application-registry). - +The uploaded OCI image manifest MUST adhere to the Margo-specific constraints detailed [here](#application-package-oci-manifest). Subsequently, the App Developer uses a UI or other vendor-specific mechanism to communicate (either directly or indirectly) to the WFM the namespace of the Application Package's repository. ```mermaid @@ -66,18 +59,13 @@ sequenceDiagram ## Retrieving an Application Package This section describes the retrieval workflow. - However this is an application of the [standard artifact pull workflow according the OCI Distribution Specification](https://github.com/opencontainers/distribution-spec/blob/main/spec.md#pull) and therefore technical details are to be obtained from that specification. The WFM has received the namespace of the repository of the Application Package at the Application Registry. - Next, as shown in the sequence diagram below, the WFM uses the API endpoints defined in the OCI_spec to retrieve a list of Application Package versions (as detailed [here](#list-margo-application-package-versions)). - -Then, the WFM pulls the OCI image manifest of the selected version of the Application Package, with the identifying reference being a tag or digest (as detailed [here](#pull-oci-image-manifest-of-application-package)). - +Then, the WFM pulls the OCI image manifest of the selected version of the Application Package, with the identifying reference being a tag or digest (as detailed [here](#retrieving-oci-image-manifest-of-application-package-manifest)). If high trust requirements apply on the acquisition of the application package versions, state-of-the-art mechanisms can be applied to ensure that sophisticated attacks are not possible (for example a [TUF](https://theupdateframework.com/) implementation). - -Finally, all parts (e.g., the Application Description file, the icon, the license, etc.) of the Application Package are retrieved by pulling the respective blobs listed as layers in the image manifest (as detailed [here](#get-parts-of-application-package)). +Finally, all parts (e.g., the Application Description file, the icon, the license, etc.) of the Application Package are retrieved by pulling the respective blobs listed as layers in the image manifest (as detailed [here](#retrieve-parts-of-application-package)). ```mermaid sequenceDiagram @@ -94,12 +82,8 @@ sequenceDiagram ### List Margo Application Package Versions -The interface to retrieve the list of versions of an Application Package MUST be implemented according to OCI_spec endpoint [end-8a](https://github.com/opencontainers/distribution-spec/blob/v1.1.0/spec.md#endpoints). - The list of the available Application Package versions can be obtained as documented in the ["Listing Tags" section of the OCI_spec](https://github.com/opencontainers/distribution-spec/blob/main/spec.md#listing-tags). - The API supports filtering and pagination as documented in the linked specification section. - The `{name}` variable is the namespace of the Application Package repository, which was communicated by the App Developer to the WFM vendor. The list of Application Packages versions is provided in a JSON document that MUST conform with the above mentioned OCI_spec section and therefore has following format: @@ -115,7 +99,7 @@ The list of Application Packages versions is provided in a JSON document that MU } ``` -Thereby, a listed tag of an image manifest MUST be the same as the value of the key ``metadata.version`` as specified in the Application Description document of the associated Application Package. +Thereby, a listed tag of an image manifest MUST be the same as the value of the key ``metadata.version`` as specified in the [Application Description document](../../specification/applications/application-description.md) of the associated Application Package. #### Example A (no filtering): @@ -148,23 +132,21 @@ Response: } ``` -### Retrieving OCI Image Manifest of Application Package Manifest +### Retrieving Application Package Manifest -The Application Package OCI Manifest is a JSON document that conforms the [OCI Manifest specification](https://github.com/opencontainers/image-spec/blob/main/manifest.md) and provides metadata required for the distribution of the Application Package (from pushing to pulling) according the OCI specification. - -Therefore retrieving an Application Package OCI Manifest MUST be implemented according the ["Pulling manifests" section of the OCISpec](https://github.com/opencontainers/distribution-spec/blob/main/spec.md#pulling-manifests). +The Application Package Manifest is a JSON document that conforms to the [OCI Manifest specification](https://github.com/opencontainers/image-spec/blob/main/manifest.md) and provides metadata required for the distribution of the Application Package (from pushing to pulling) according to the OCI_spec. +Therefore retrieving an Application Package Manifest MUST be implemented according the ["Pulling manifests" section of the OCISpec](https://github.com/opencontainers/distribution-spec/blob/main/spec.md#pulling-manifests). As mentioned before, different libraries and tools do the heavylifting of implementing these workflow. - An implementation without any of those tools or libraries is possible and MUST rely on the OCI_spec to do so. -#### Application Package OCI Manifest +#### Application Package Manifest -An Application Package OCI Manifest conforms to the [OCI Image Manifest Specification](https://github.com/opencontainers/image-spec/blob/v1.1.0/manifest.md) MUST contain pointers to all parts of an Application Package within the Application Registry. -This section specifies the Margo requirements on these kind of manifests. +The Application Package Manifest is an OCI image manifest that MUST conform to the [OCI Image Manifest Specification](https://github.com/opencontainers/image-spec/blob/v1.1.0/manifest.md) and MUST contain pointers to all parts of an Application Package within the Application Registry. +This section specifies the Margo requirements on the Application Package Manifest. Please refer to the [OCI Image Manifest Specification](https://github.com/opencontainers/image-spec/blob/v1.1.0/manifest.md) for all other technical details that are not Margo specific. -Each version of an Application Package MUST have its own OCI manifest. +Each version of an Application Package MUST have its own OCI image manifest. The ``artifactType`` of the OCI image manifest must be ``application/vnd.margo.app.v1+json``. @@ -173,11 +155,13 @@ The ``config`` MUST be a so-called "empty config" and be specified in the manife Each element of the ``layers`` array contains a reference (so-called `digests`) to an artifact (so-called `blobs`) that is a part of the Application Package. Each Application Package part (file) MUST be listed as an element of the ``layers`` array: + * The [Application Description](../../specification/applications/application-description.md) of the Application Package must be referred to in one element of the ``layers`` array, where the ``mediaType`` of this blob must be ``application/vnd.margo.app.description.v1+yaml``. + * Each [application resource](../../concepts/applications/application-package.md), which is an additional file associated with the application, must be referred to as a blob listed in the ``layers`` array. The blobs of resource files must be marked with a **mediaType** specific to the kind of resource file (currently four possible resource files: ``icon``, ``releaseNotes``, ``descriptionFile``, ``licenseFile``), as listed in the [table below](../../specification/applications/application-registry.md#margo-specific-media-types)). E.g., the blob representing the icon file (e.g., in ``jpeg`` format) of an application is marked with the mediaType `application/vnd.margo.app.icon.v1+jpeg`. The [Application Description file](../../specification/applications/application-description.md) lists these resource files in the ```metadata.catalog.application`` element. -The following response example is a Margo-specific OCI manifest following the [OCI Image Manifest Specification](https://github.com/opencontainers/image-spec/blob/v1.0.1/manifest.md) and the above defined specifics: +The following response example is a Margo-specific OCI image manifest following the [OCI Image Manifest Specification](https://github.com/opencontainers/image-spec/blob/v1.0.1/manifest.md) and the above defined specifics: ```json {