Skip to content

Latest commit

 

History

History
167 lines (130 loc) · 6.48 KB

README.md

File metadata and controls

167 lines (130 loc) · 6.48 KB

How to work with the library

The complete library is arranged around area specific Context objects, which bundle all the settings and supported extensions of the Open Component Model. Extension points are implemented by handlers that can be registered at dedicated context objects or at the default runtime environment. The context then provides all the methods required to access elements managed in the dedicated area.

The examples shown here provide an overview of the library. A more detailed annotated tour through various aspects of the library with ready-to work examples can be for here.

In the comparison scenario there is an example for an end-to-end scenario, from providing a component version by a software provider, over its publishing up to the consumption in an air-gapped environment, and the final deployment in this environment. Especially the deployment part just wants to illustrate the basic workflow using a Helm chart based example. It is not intended to be used as productive environment.

Working with OCM repositories

For working with OCM repositories an appropriate context, which can be used to retrieve OCM repositories, can be accessed with:

import "ocm.software/ocm/api/ocm"


func MyFirstOCMApplication() {
   octx := ocm.DefaultContext()

   ...
}

If a decoupled environment with dedicated special settings is required, the builder methods of the ocm package (With...) can be used to compose a context.

With ocm.New() a fresh ocm context is created using the default settings. It is possible to create any number of such contexts.

The context can then be used to gain access to (OCM) repositories, which provide access to hosted components and component versions.

To access a repository, a repository specification is required. Every repository type extension supported by this library uses its own package under ocm.software/ocm/api/ocm/extensions/repositories. To access an OCM repository based on an OCI registry the package ocm.software/ocm/api/ocm/extensions/repositories/ocireg contains the appropriate language binding for the OCI registry mappings.

Those packages typically have the method NewRepositorySpec to create an appropriate specification object for a concrete instance.

  repoSpec := ocireg.NewRepositorySpec("ghcr.io/mandelsoft/ocm", nil)

  repo, err := octx.RepositoryForSpec(repoSpec)
  if err != nil {
          return err
  }
  defer repo.Close()

Once a repository object is available it can be used to access component versions.

  compvers, err := repo.LookupComponentVersion(componentName, componentVersion)
  if err != nil {
          return err
  }
  defer compvers.Close()

The component version now provides access to the described content, the component descriptor, resources, sources, component references, and signatures.

The component descriptor is accessible by a standardized Go representation, which is independent of the actually used serialization format. If can be encoded again in the original or any other supported scheme versions.

  cd := compvers.GetDescriptor()
  data, err := compdesc.Encode(cd)
  if err != nil {
          return err
  }

Any resource (or source) can be accessed by getting the appropriate resource object by its resource identity in the context of the component version.

  res, err := compvers.GetResource(metav1.NewIdentity(resourceName))
  if err != nil {
          return err
  }

  fmt.Printf("resource %s:\n  type: %s\n", resourceName, res.Meta().Type)

The content of a described resource can be accessed using the appropriate access method described as part of the resource specification (another extension point of the model). It is described by an access specification. Supported methods can be directly be requested using the resource object.

  meth, err := res.AccessMethod()
  if err != nil {
          return err
  }
  defer meth.Close()

  fmt.Printf("  mime: %s\n", meth.MimeType())

The access method then provides access to the technical blob content. Here a stream access or a byte array access is possible.

  data, err = meth.Get()
  if err != nil {
          return err
  }

  fmt.Printf("  content:\n%s\n", utils.IndentLines(string(data), "    ",))

Besides this simple example, there are more usage scenarios, which typically require more configuration:

End-to-end Scenario

In folder comparison-scenario there is an example for an end-to-end scenario, from building a component version to publishing, consuming and deploying it in a separate environment. It shows the usage of the OCM library to implement all the required process steps.

It builds a component version for the podinfo helm chart. There are two scenarios:

  • provisioning
    • building a component version with a helm based deployment description
    • signing it and
    • publishing it
  • consumption in a separate repository environment
    • transferring the component version into a separate repository environment.
    • using the deployment description to localize the helm chart value - preparing values to refer to the podinfo OCI image available in the local environment.
    • finally deploying it with helm.