diff --git a/.github/workflows/publish-site.yaml b/.github/workflows/publish-site.yaml index 9e39d2e1..6f930c94 100644 --- a/.github/workflows/publish-site.yaml +++ b/.github/workflows/publish-site.yaml @@ -42,11 +42,10 @@ jobs: run: | python3 -m pip install json-schema-for-humans generate-schema-doc --config-file generate-schema.yaml static/schemas/component-descriptor-v2 schema-v2.html - generate-schema-doc --config-file generate-schema.yaml static/schemas/component-descriptor-v3alpha1 schema-v3alpha1.html - name: Copy Schema run: | - cp schema-v2.html schema-v3alpha1.html schema_doc.css schema_doc.min.js public/docs/overview/specification + cp schema-v2.html schema_doc.css schema_doc.min.js public/docs/overview/specification - name: Publish as GitHub Pages uses: peaceiris/actions-gh-pages@v4 diff --git a/content/docs/component-descriptors/version-2.md b/content/docs/component-descriptors/version-2.md index 11f488a7..ecbbee4b 100644 --- a/content/docs/component-descriptors/version-2.md +++ b/content/docs/component-descriptors/version-2.md @@ -10,9 +10,9 @@ weight: 1 toc: true --- -The following is an example of a public-key-based signed component descriptor containing a resource, source and one component reference. It uses the `v2` schema (which is the default). There are no differences in the semantics between version v2 and v3. `meta.schemaVersion` is used as kind of moniker for different serializing/deserializing formats (`v3` has the format of Kubernetes resources). +The following is an example of a public-key-based signed component descriptor containing a resource, source and one component reference. It uses the default `v2` schema. -This component is publicly available and can be inspected using the following command: +The component is publicly available in the GitHub package repository and can be inspected using the following command: ```shell ocm componentversion get --repo ghcr.io/phoban01/ocm github.com/weaveworks/weave-gitops -oyaml @@ -20,52 +20,90 @@ ocm componentversion get --repo ghcr.io/phoban01/ocm github.com/weaveworks/weave ```yaml meta: - schemaVersion: v2 # component schema version + # component schema version + schemaVersion: v2 component: - name: github.com/weaveworks/weave-gitops # name of the component - version: v1.0.0 # version of the component - provider: weaveworks # component provider information - repositoryContexts: # list of repository context the component version "lived" in, with the current one at the top + # name of the component. Must start with URL-prefix that should be controlled + # by the owner of the component to avoid collisions + # regex: ^[a-z][-a-z0-9]*([.][a-z][-a-z0-9]*)*[.][a-z]{2,}(/[a-z][-a-z0-9_]*([.][a-z][-a-z0-9_]*)*)+$ + name: github.com/weaveworks/weave-gitops + # version of the component. Must adhere to “relaxed SemVer” + # major, minor (+ optional patch level) - optional v-prefix + # regex: ^[v]?(0|[1-9]\\d*)(?:\\.(0|[1-9]\\d*))?(?:\\.(0|[1-9]\\d*))?(?:-((?:0|[1-9]\\d*|\\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\\.(?:0|[1-9]\\d*|\\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\\+([0-9a-zA-Z-]+(?:\\.[0-9a-zA-Z-]+)*))?$ + + version: v1.0.0 + # component provider + provider: weaveworks + # list of labels that can contain arbitrary metadata in form of K/V pairs + # labels can be added on component root, resource, source and reference level + labels: + - name: link-to-documentation + value: https://github.com/weaveworks/weave-gitops + # list of repository context the component version "lived" in, + # with the current one at the top + repositoryContexts: - baseUrl: ghcr.io componentNameMapping: urlPath subPath: phoban01/ocm type: OCIRegistry - resources: # list of resources modelled by the component - - name: image # resource name - relation: external # resource location (external repository or internal to this repository) - type: ociImage # resource type - version: v0.14.1 # resource version - access: # metadata describing how to access the resource - type: ociArtifact # type of access information + # list of resources that describe the payload of the component + resources: + # resource name + - name: image + # resource location (external repository or internal to this repository) + relation: external + # resource type + type: ociImage + # resource version. Must also adhere to “relaxed SemVer” (see `component.versio` above`) + version: v0.14.1 + # metadata describing how to access the resource + access: + # type of access information + type: ociArtifact imageReference: ghcr.io/weaveworks/wego-app:v0.14.1 - digest: # signing metadata for the resource + # signing metadata for the resource (if component has been signed) + digest: hashAlgorithm: SHA-256 normalisationAlgorithm: ociArtifactDigest/v1 value: efa2b9980ca2de65dc5a0c8cc05638b1a4b4ce8f6972dc08d0e805e5563ba5bb - sources: # list of sources relevant to this component - - name: weave-gitops # source name - type: git # source type - version: v0.14.1 # source version - access: # metadata describing how to access the source + # list of sources that describe the input for creating the resources + sources: + # source name + - name: weave-gitops + # source type + type: git + # source version. Must also adhere to “relaxed SemVer” (see `component.versio` above`) + version: v0.14.1 + # metadata describing how to access the source + access: commit: 727513969553bfcc603e1c0ae1a75d79e4132b58 ref: refs/tags/v0.14.1 repoUrl: github.com/weaveworks/weave-gitops type: gitHub - componentReferences: # list of references to other components - - name: prometheus # reference name - version: v1.0.0 # reference version - componentName: cncf.io/prometheus # referenced component name - digest: # signing metadata for the referenced resource + # list of references to other components + componentReferences: + # reference name + - name: prometheus + # reference version + version: v1.0.0 + # referenced component name + componentName: cncf.io/prometheus + # signing metadata for the referenced resource (if component has been signed) + digest: hashAlgorithm: SHA-256 normalisationAlgorithm: jsonNormalisation/v1 value: 04eb20b6fd942860325caf7f4415d1acf287a1aabd9e4827719328ba25d6f801 -signatures: # list of signatures used for signing and verification -- name: ww-dev # name of the signature - digest: # digest of the signature including the algorithm used +# list of signatures used for signing and verification +signatures: + # name of the signature +- name: ww-dev + # digest of the signature including the algorithm used + digest: hashAlgorithm: SHA-256 normalisationAlgorithm: jsonNormalisation/v1 value: 4faff7822616305ecd09284d7c3e74a64f2269dcc524a9cdf0db4b592b8cee6a - signature: # signature including the algorithm used + # signature including the algorithm used + signature: algorithm: RSASSA-PSS mediaType: application/vnd.ocm.signature.rsa value: 26468587671bdbd2166cf5f69829f090c10768511b15e804294fcb26e552654316c8f4851ed396f279ec99335e5f4b11cb043feb97f1f9a42115f4fda2d31ae8b481b7303b9a913d3a4b92d446fbee9ed487c93b09e513f3f68355040ec08454675e1f407422062abbd2681f70dd5488ad29020b30cfa7e001455c550458da96166bc3243c8426977d73352aface5323fb2b5a374e9c31b272a59c160b85631231c9fc2f23c032401b80fef937029a39111cee34470c61ae86cd4942553466411a5a116159fdcc10e50fe9360c5184028e72d1fe9c7315f26e15d7b4849f62d197501b8cc6b6f1b1391ecc2fc2fc0c1290d2554594505b25fa8f9bfb28c8df24 diff --git a/content/docs/component-descriptors/version-3.md b/content/docs/component-descriptors/version-3.md deleted file mode 100644 index 0784e390..00000000 --- a/content/docs/component-descriptors/version-3.md +++ /dev/null @@ -1,76 +0,0 @@ ---- -title: "Version 3" -description: "" -lead: "" -date: 2023-01-17T10:22:23Z -lastmod: 2023-01-17T10:22:23Z -draft: false -images: [] -weight: 2 -toc: true ---- - -The following is an example of a public-key-based signed component descriptor containing a resource, source and one component reference. It uses the `v3alpha1` schema. There are no differences in the semantics between version v2 and v3. `apiVersion` is used as kind of moniker for different serializing/deserializing formats (`v3` has the format of Kubernetes resources). - -This component is publicly available and can be inspected using the following command: - -```shell -ocm componentversion get --repo ghcr.io/phoban01/ocm github.com/weaveworks/weave-gitops --scheme v3alpha1 -oyaml -``` - -## Component Descriptor - -```yaml -apiVersion: ocm.software/v3alpha1 # component schema version -kind: ComponentVersion -metadata: - name: github.com/weaveworks/weave-gitops # name of the component - provider: # component provider information - name: weaveworks - version: v1.0.0 # version of the component -repositoryContexts: # list of repository context the component version "lived" in, with the current one at the top -- baseUrl: ghcr.io - componentNameMapping: urlPath - subPath: phoban01/ocm - type: OCIRegistry -spec: - resources: # list of resources modelled by the component - - name: image # resource name - relation: external # resource location (external repository or internal to this repository) - type: ociImage # resource type - version: v0.14.1 # resource version - access: # metadata describing how to access the resource - type: ociArtifact # type of accesss information - imageReference: ghcr.io/weaveworks/wego-app:v0.14.1 # oci image url - digest: # signing metadata for the resource - hashAlgorithm: SHA-256 - normalisationAlgorithm: ociArtifactDigest/v1 - value: efa2b9980ca2de65dc5a0c8cc05638b1a4b4ce8f6972dc08d0e805e5563ba5bb # the digest itself - sources: # list of sources relevant to this component - - name: weave-gitops # source name - type: git # source type - version: v0.14.1 # source version - access: # metadata describing how to access the source - type: gitHub # - ref: refs/tags/v0.14.1 - repoUrl: github.com/weaveworks/weave-gitops - commit: 727513969553bfcc603e1c0ae1a75d79e4132b58 - references: # list of references to other components - - name: prometheus # reference name - version: v1.0.0 # reference version - componentName: cncf.io/prometheus # referenced component name - digest: # signing metadata for the referenced resource - hashAlgorithm: SHA-256 - normalisationAlgorithm: jsonNormalisation/v1 - value: 04eb20b6fd942860325caf7f4415d1acf287a1aabd9e4827719328ba25d6f801 -signatures: # list of signatures used for signing and verification -- name: ww-dev # name of the signature - digest: # digest of the signature including the algorithm used - hashAlgorithm: SHA-256 - normalisationAlgorithm: jsonNormalisation/v1 - value: 4faff7822616305ecd09284d7c3e74a64f2269dcc524a9cdf0db4b592b8cee6a - signature: # signature including the algorithm used - algorithm: RSASSA-PSS - mediaType: application/vnd.ocm.signature.rsa - value: 26468587671bdbd2166cf5f69829f090c10768511b15e804294fcb26e552654316c8f4851ed396f279ec99335e5f4b11cb043feb97f1f9a42115f4fda2d31ae8b481b7303b9a913d3a4b92d446fbee9ed487c93b09e513f3f68355040ec08454675e1f407422062abbd2681f70dd5488ad29020b30cfa7e001455c550458da96166bc3243c8426977d73352aface5323fb2b5a374e9c31b272a59c160b85631231c9fc2f23c032401b80fef937029a39111cee34470c61ae86cd4942553466411a5a116159fdcc10e50fe9360c5184028e72d1fe9c7315f26e15d7b4849f62d197501b8cc6b6f1b1391ecc2fc2fc0c1290d2554594505b25fa8f9bfb28c8df24 -``` diff --git a/content/docs/getting-started/getting-started-with-ocm/create-component-version.md b/content/docs/getting-started/getting-started-with-ocm/create-component-version.md index c3315745..0f4dd22b 100644 --- a/content/docs/getting-started/getting-started-with-ocm/create-component-version.md +++ b/content/docs/getting-started/getting-started-with-ocm/create-component-version.md @@ -12,14 +12,14 @@ toc: true ## Creating and Storing Component Versions -Component Versions are created using a `component-constructor.yaml` file, which is a description file that contains one or multiple components. The file describes the components and their artifacts, resources and sources, metadata in form of labels and references to other components. +Component Versions are created using a `component-constructor.yaml` file, which is a description file that contains one or multiple components. The file describes the components and their artifacts - resources and sources, metadata in form of labels and references to other components. -Component Versions are locally stored in archives using the Common Transfer Format ([CTF](https://github.com/open-component-model/ocm-spec/blob/main/doc/04-extensions/03-storage-backends/ctf.md)). A CTF archive is also the entity used to transfer components between component repositories. A CTF archive may contain any number of component versions. It may also be pushed to an OCM repository. +Component Versions are locally stored in archives using the [Common Transfer Format (CTF)](https://github.com/open-component-model/ocm-spec/blob/main/doc/04-extensions/03-storage-backends/ctf.md). A CTF archive may contain any number of component versions and is used to transfer components to and between component repositories. -Note that a CTF archive itself is also an OCM repository, so it can be used as source or target for component transfer operations. +Note that a CTF archive itself is also an OCM repository, so it can be used as source or target for component transfer operations using the OCM CLI. The command [`ocm add componentversions`](https://github.com/open-component-model/ocm/blob/main/docs/reference/ocm_add_componentversions.md) -directly creates a component version from a `component-constructor.yaml` file and stores it in a CTF archive. +directly creates a component version from a `component-constructor.yaml` file and stores it in a local CTF archive. ### Create a Component Version @@ -27,25 +27,30 @@ In this examle we will use the The `ocm` CLI tool to create a very basic compone We start by creating a test folder where we execute all required steps for this example and navigating into it: -```bash +```shell mkdir /tmp/helloworld cd /tmp/helloworld ``` Now we download the `podinfo` Helm Chart that we want to use as local resource and extract it: -```bash +```shell helm repo add podinfo https://stefanprodan.github.io/podinfo helm pull --untar podinfo/podinfo ``` -Create a file `component-constructor.yaml`, which describes all elements of the component. You can use our public configuration schema to validate the configuration. The schema is available at `https://ocm.software/schemas/configuration-schema.yaml` and can be used in your editor to validate the configuration (e.g., in Visual Studio Code). As mentioned before our example component should contain a Helm Chart and a Docker image: +Create a file `component-constructor.yaml`, which describes all elements of the component. You can use our public configuration schema to validate the configuration. The schema is available at `https://ocm.software/schemas/configuration-schema.yaml` and can be used in your editor to validate the configuration (e.g., in Visual Studio Code). + +Component versions need to have at least a `name`, `version` and `provider` attribute. All other attributes are optional. Check out an [example component descriptor](https://ocm.software/docs/component-descriptors/version-2) or the [OCM Specification](https://github.com/open-component-model/ocm-spec/blob/main/README.md) to see all available attributes. + +As mentioned before our example component will just contain a Helm Chart and a Docker image as resources: ```yaml # specify a schema to validate the configuration and get auto-completion in your editor # yaml-language-server: $schema=https://ocm.software/schemas/configuration-schema.yaml components: - name: github.com/acme.org/helloworld + # version needs to follow "relaxed" SemVer version: 1.0.0 provider: name: acme.org @@ -80,13 +85,14 @@ For more complex scenarios, the description files might use variable substitutio ### Add Component Version to CTF archive -To store our component version and to make it transportable, we now add it to a CTF archive using the following command. The option `--create` is used to create a new CTF archive if it does not exist: +To store our component version locally and to make it transportable, we now add it to a CTF archive +using the following command. The option `--create` is used to create a new CTF archive if it does not exist: -```bash +```shell ocm add componentversions --create --file ctf-hello-world component-constructor.yaml ``` -```bash +```shell processing component-constructor.yaml... processing document 1... processing index 1 @@ -101,7 +107,7 @@ ocm add componentversions --create --file ctf-hello-world component-constructor. The command creates the CTF archive (option `--create`) and adds the listed components with the described resources. -```bash +```shell ctf-hello-world/ ├── artifact-index.json └── blobs @@ -114,7 +120,7 @@ with the described resources. The transport archive's contents can be found in `artifact-index.json`. This file contains the list of component version artifacts to be transported. -```bash +```shell jq . ${CTF_ARCHIVE}/artifact-index.json ``` @@ -135,7 +141,7 @@ The content of the transport archive is stored as OCI artifacts. Notice that the The component version is described as an OCI manifest: -```bash +```shell jq . ${CTF_ARCHIVE}/blobs/sha256.d3cf4858f5387eaea194b7e40b7f6eb23460a658ad4005c5745361978897e043 ``` @@ -165,7 +171,7 @@ jq . ${CTF_ARCHIVE}/blobs/sha256.d3cf4858f5387eaea194b7e40b7f6eb23460a658ad4005c Notice that the output of the component version above contains the component descriptor as one of the `layers`. It can be identified by its content type, which is `application/vnd.ocm.software.component-descriptor.v2+yaml+tar`. In this case, the component descriptor can be displayed with the following command: -```bash +```shell tar xvf ${CTF_ARCHIVE}/blobs/sha256.4ab29c8acb0c8b002a5037e6d9edf2d657222da76fee2a10f38d65ecd981d0c6 -O - component-descriptor.yaml ``` @@ -205,3 +211,4 @@ component: The other elements listed as `layers` describe the blobs for the local resources stored along with the component version. The digests can be seen in the `localReference` attributes of the component descriptor. + diff --git a/content/docs/getting-started/getting-started-with-ocm/display-examine-component-versions.md b/content/docs/getting-started/getting-started-with-ocm/display-examine-component-versions.md index 980db838..c00e9a0f 100644 --- a/content/docs/getting-started/getting-started-with-ocm/display-examine-component-versions.md +++ b/content/docs/getting-started/getting-started-with-ocm/display-examine-component-versions.md @@ -14,18 +14,18 @@ toc: true To show a component stored in an OCM repository or CTF archive (which itself is an OCM repository), the [`ocm get componentversion`](https://github.com/open-component-model/ocm/blob/main/docs/reference/ocm_get_componentversions.md) command can be used: -```bash +```shell ocm get componentversion ghcr.io/open-component-model/ocm//ocm.software/toi/demo/helmdemo:0.12.0 ``` -```bash +```shell COMPONENT VERSION PROVIDER ocm.software/toi/demo/helmdemo 0.12.0 ocm.software ``` To see the component descriptor of the displayed component version, use the output format option `-o yaml`: -```bash +```shell ocm get cv ghcr.io/open-component-model/ocm//ocm.software/toi/demo/helmdemo:0.12.0 -o yaml ``` @@ -77,11 +77,11 @@ Optionally, a specific version can be appended, separated by a colon (`:`). If n With the option `--recursive`, it is possible to show the complete component version, including the component versions it references. -```bash +```shell ocm get cv ghcr.io/open-component-model/ocm//ocm.software/toi/demo/helmdemo:0.12.0 --recursive ``` -```bash +```shell REFERENCEPATH COMPONENT VERSION PROVIDER IDENTITY ocm.software/toi/demo/helmdemo 0.12.0 ocm.software ocm.software/toi/demo/helmdemo:0.12.0 ocm.software/toi/installers/helminstaller 0.12.0 ocm.software "name"="installer" @@ -89,11 +89,11 @@ ocm get cv ghcr.io/open-component-model/ocm//ocm.software/toi/demo/helmdemo:0.12 To get a tree view, add the option `-o tree`: -```bash +```shell ocm get cv ghcr.io/open-component-model/ocm//ocm.software/toi/demo/helmdemo:0.12.0 --recursive -o tree ``` -```bash +```shell NESTING COMPONENT VERSION PROVIDER IDENTITY └─ ⊗ ocm.software/toi/demo/helmdemo 0.12.0 ocm.software └─ ocm.software/toi/installers/helminstaller 0.12.0 ocm.software "name"="installer" @@ -101,11 +101,11 @@ ocm get cv ghcr.io/open-component-model/ocm//ocm.software/toi/demo/helmdemo:0.12 As mentioned before a CTF archive itself is an OCM repository, so we can execute the same commands on a CTF archive. So, let's get the information about the component `github.com/acme.org/helloworld` we created in the previous step and that we stored in the CTF archive `/tmp/helloworld/ctf-hello-world`: -```bash +```shell ocm get cv /tmp/helloworld/ctf-hello-world//github.com/acme.org/helloworld:1.0.0 ``` -```bash +```shell COMPONENT VERSION PROVIDER github.com/acme.org/helloworld 0.1.0 ocm.software ``` @@ -114,7 +114,7 @@ ocm get cv /tmp/helloworld/ctf-hello-world//github.com/acme.org/helloworld:1.0.0 To list the resources found in a component version tree, the command [`ocm get resources`](https://github.com/open-component-model/ocm/blob/main/docs/reference/ocm_get_resources.md) can be used: -```bash +```shell ocm get resources ghcr.io/open-component-model/ocm//ocm.software/toi/demo/helmdemo:0.12.0 --recursive -o tree ``` ``` @@ -134,7 +134,7 @@ ocm get resources ghcr.io/open-component-model/ocm//ocm.software/toi/demo/helmde Use the [`ocm download`](https://github.com/open-component-model/ocm/blob/main/docs/reference/ocm_download_resources.md) command to download resources such as component versions, individual resources or artifacts: -```bash +```shell ocm download resource ghcr.io/open-component-model/ocm//ocm.software/toi/demo/helmdemo:0.12.0 chart -O helmchart.tgz ``` ``` @@ -147,7 +147,7 @@ Because it is stored as OCI artifact in an OCI registry, the filesystem format u The file `helmchart.tgz` was downloaded. -```bash +```shell tar xvf helmchart.tgz ``` ``` @@ -159,7 +159,7 @@ tar xvf helmchart.tgz x blobs/sha256.ea8e5b44cd1aff1f3d9377d169ad795be20fbfcd58475a62341ed8fb74d4788c ``` -```bash +```shell $ jq . index.json ``` ```json @@ -194,7 +194,7 @@ If a download handler is available for the artifact type and the blob media type used to store the blob in the OCM repository, it will convert the blob format into a more suitable format: -```bash +```shell ocm download resource -d ghcr.io/open-component-model/ocm//ocm.software/toi/demo/helmdemo:0.12.0 chart -O helmchart.tgz ``` ``` @@ -205,7 +205,7 @@ ocm download resource -d ghcr.io/open-component-model/ocm//ocm.software/toi/demo The downloaded archive is now a regular Helm Chart archive: -```bash +```shell tar tvf helmchart.tgz ``` ``` @@ -228,7 +228,7 @@ tar tvf helmchart.tgz For example, for OCI images, the OCI format is more suitable: -```bash +```shell ocm download resource ghcr.io/open-component-model/ocm//ocm.software/toi/demo/helmdemo:0.12.0 image -O image.tgz ``` ``` @@ -239,7 +239,7 @@ ocm download resource ghcr.io/open-component-model/ocm//ocm.software/toi/demo/he The file `image.tgz` was downloaded. -```bash +```shell tar xvf image.tgz ``` ``` @@ -260,7 +260,7 @@ tar xvf image.tgz x blobs/sha256.e0962580d8254d0b1ef35006d7e2319eb4870e63dc1f9573d2406c7c47d442d2 ``` -```bash +```shell jq . index.json ``` ```json @@ -294,7 +294,7 @@ version. Example: -```bash +```shell ocm get componentversion ghcr.io/open-component-model/ocm//ocm.software/ocmcli:0.1.0-dev -o yaml ``` ```yaml @@ -330,7 +330,7 @@ component version complies to this convention, executables can directly be downl platform with the use of the `-x` option. If only one executable is contained in the component version, the resource name can be omitted. Example: -```bash +```shell ocm download resource -x --latest ghcr.io/open-component-model/ocm//ocm.software/ocmcli ``` ``` @@ -339,7 +339,7 @@ ocm download resource -x --latest ghcr.io/open-component-model/ocm//ocm.software
What happened? -```bash +```shell file ocm ``` ``` @@ -360,7 +360,7 @@ files. Additionally, it filters all matching resources for executables and the c Download entire component versions using the [`ocm download componentversion`](https://github.com/open-component-model/ocm/blob/main/docs/reference/ocm_download_componentversions.md) command: -```bash +```shell ocm download componentversions ghcr.io/open-component-model/ocm//ocm.software/toi/demo/helmdemo:0.12.0 -O helloworld ``` ``` @@ -373,7 +373,7 @@ The result is a CTF archive. This can then be modified using the `ocm add ...` c The component version was downloaded. -```bash +```shell tree helloworld ``` ``` @@ -390,7 +390,7 @@ tree helloworld Download OCI artifacts from an OCI registry, such as OCI images, with the [`ocm download artifacts`](https://github.com/open-component-model/ocm/blob/main/docs/reference/ocm_download_artifacts.md) command: -```bash +```shell ocm download artifact ghcr.io/open-component-model/ocm-controller:v0.24.0 -O ocm-controller ``` ``` @@ -401,7 +401,7 @@ ocm download artifact ghcr.io/open-component-model/ocm-controller:v0.24.0 -O ocm The OCI image `echoserver` was downloaded. -```bash +```shell tree echoserver ``` ```