Selection Examples

The following examples are executed as tests (TestUploaderExamples in bindings/go/transfer/internal), so each outcome below is what the transfer does. They all transfer the component ocm.software/demo:1.0.0 and, unless stated otherwise, target the OCI registry ghcr.io/target-org/ocm (baseUrl: ghcr.io/target-org/ocm, subPath: ""). The component has these resources:

NameAccess
appociArtifact/v1 imageReference: ghcr.io/acme/app:1.0.0; label {name: ocm.software/transfer, value: oci}
nginxociArtifact/v1 imageReference: docker.io/library/nginx:1.25
charthelm/v1 helmRepository: https://charts.acme.io/stable, helmChart: app, version: 1.0.0
bundleLocalBlob/v1 mediaType: application/vnd.oci.image.manifest.v1+json, referenceName: acme/bundle:1.0.0
notesLocalBlob/v1 mediaType: text/plain
docsWget/v1 url: https://docs.acme.io/guide.tar

Outcomes:

  • oci <ref>: pushed as a separate OCI artifact to <ref>.
  • local blob: embedded in the target as a local blob.
  • by reference: not copied; the access is unchanged in the target.

The baseline applies to resources no uploader selects: local blobs are copied as local blobs and all other resources stay by reference. A catch-all localblob.uploader… entry copies every supported resource.

E1 — default OCI uploader (replaces –upload-as ociArtifact)

type: generic.config.ocm.software/v1
configurations:
  - type: oci.uploader.transfer.config.ocm.software/v1alpha1
ResourceOutcome
appoci ghcr.io/target-org/ocm/acme/app:1.0.0
nginxoci ghcr.io/target-org/ocm/library/nginx:1.25
chartoci ghcr.io/target-org/ocm/stable/app:1.0.0
bundleoci ghcr.io/target-org/ocm/acme/bundle:1.0.0
noteslocal blob (the default match does not select it: not an OCI manifest)
docsby reference (the default match does not select Wget)

E2 — the same as one entry per access type

One entry per access type, each with the default imageReference for its access type spelled out, gives the same outcome as E1. This is the starting point for changing the reference of one access type only.

type: generic.config.ocm.software/v1
configurations:
  - type: oci.uploader.transfer.config.ocm.software/v1alpha1
    match: target.type == "OCIRepository" && resource.access.isType("OCIImage")
    imageReference: |-
      ${target.baseUrl + (target.subPath == "" ? "" : "/" + target.subPath) + "/"
        + resource.access.toOCI().repository
        + (resource.access.toOCI().tag == "" ? "" : ":" + resource.access.toOCI().tag)}
  - type: oci.uploader.transfer.config.ocm.software/v1alpha1
    match: target.type == "OCIRepository" && resource.access.isType("Helm")
    # imageReference omitted: the Helm default applies
  - type: oci.uploader.transfer.config.ocm.software/v1alpha1
    match: >-
      target.type == "OCIRepository"
      && resource.access.isType("LocalBlob")
      && has(resource.access.mediaType) && isOCIManifest(resource.access.mediaType)
      && has(resource.access.referenceName)
    imageReference: '${target.baseUrl + (target.subPath == "" ? "" : "/" + target.subPath) + "/" + resource.access.referenceName}'

E3 — Helm charts only

An explicit match replaces the default entirely, so it must repeat the target check.

type: generic.config.ocm.software/v1
configurations:
  - type: oci.uploader.transfer.config.ocm.software/v1alpha1
    match: target.type == "OCIRepository" && resource.access.isType("Helm")
ResourceOutcome
chartoci ghcr.io/target-org/ocm/stable/app:1.0.0
app, nginx, docsby reference
bundle, noteslocal blob

E4 — OCI-manifest local blobs only

type: generic.config.ocm.software/v1
configurations:
  - type: oci.uploader.transfer.config.ocm.software/v1alpha1
    match: >-
      target.type == "OCIRepository"
      && resource.access.isType("LocalBlob")
      && has(resource.access.mediaType) && isOCIManifest(resource.access.mediaType)
      && has(resource.access.referenceName)
ResourceOutcome
bundleoci ghcr.io/target-org/ocm/acme/bundle:1.0.0
noteslocal blob
app, nginx, chart, docsby reference

E5 — only images from Docker Hub

type: generic.config.ocm.software/v1
configurations:
  - type: oci.uploader.transfer.config.ocm.software/v1alpha1
    match: >-
      target.type == "OCIRepository"
      && resource.access.isType("OCIImage")
      && (resource.access.toOCI().host == "docker.io"
        || resource.access.toOCI().host.endsWith(".docker.io"))
ResourceOutcome
nginxoci ghcr.io/target-org/ocm/library/nginx:1.25
app, chart, docsby reference
bundle, noteslocal blob

toOCI() normalizes Docker Hub references to the host registry-1.docker.io, hence endsWith. toOCI() is only called for OCIImage accesses: && short-circuits, so the Helm and local blob resources never reach it.

E6 — select by label

type: generic.config.ocm.software/v1
configurations:
  - type: oci.uploader.transfer.config.ocm.software/v1alpha1
    match: >-
      target.type == "OCIRepository"
      && resource.access.isType("OCIImage")
      && has(resource.labels)
      && resource.labels.exists(l, l.name == "ocm.software/transfer" && l.value == "oci")
ResourceOutcome
appoci ghcr.io/target-org/ocm/acme/app:1.0.0
nginx, chart, docsby reference
bundle, noteslocal blob

has(resource.labels) is required because labels is omitted from a resource that has none.

E7 — CTF target, images mirrored to a registry

Target ctf::./archive. The template does not use target, so it evaluates for a CTF target.

type: generic.config.ocm.software/v1
configurations:
  - type: oci.uploader.transfer.config.ocm.software/v1alpha1
    match: resource.access.isType("OCIImage")
    imageReference: '${"registry.example.com/mirror/" + resource.access.toOCI().repository + ":" + resource.access.toOCI().tag}'
ResourceOutcome
appoci registry.example.com/mirror/acme/app:1.0.0
nginxoci registry.example.com/mirror/library/nginx:1.25
chart, docsby reference
bundle, noteslocal blob

E8 — relocate one resource, default for the rest

type: generic.config.ocm.software/v1
configurations:
  - type: oci.uploader.transfer.config.ocm.software/v1alpha1
    match: resource.name == "app"
    imageReference: ghcr.io/target-org/special/app:1.0.0
  - type: oci.uploader.transfer.config.ocm.software/v1alpha1
ResourceOutcome
appoci ghcr.io/target-org/special/app:1.0.0 (first entry: match selects by name, default match of second entry would also select but first wins)
nginx, chart, bundle, notes, docsas in E1 (second entry)

E9 — errors instead of silent skipping

Each case transfers a component with only the named resource.

Config entryResource / targetError contains
OCI, match: resource.access.isType("Wget")docsoci uploader cannot upload access type Wget/v1
OCI, match: resource.access.isType("LocalBlob")notesnot an OCI manifest
OCI, match: resource.access.isType(appinvalid match
OCI, match: '"yes"'appmust evaluate to a bool
OCI, match: resource.access.isType("OCIImage"), default imageReferenceapp, target ctf::./archiveimageReference does not evaluate (the default template reads target.baseUrl, which a CTF target does not have)

E10 — copy everything as local blobs (replaces –copy-resources)

type: generic.config.ocm.software/v1
configurations:
  - type: localblob.uploader.transfer.config.ocm.software/v1alpha1
ResourceOutcome
applocal blob
nginxlocal blob
chartlocal blob
bundlelocal blob
noteslocal blob
docslocal blob

chart goes through GetHelmChart → ConvertHelmToOCI → OCIAddLocalResource; docs through DownloadWgetResource → OCIAddLocalResource. A config with only a localblob.uploader… entry (no other uploaders) produces the same graph.

E11 — OCI artifacts plus everything else copied

type: generic.config.ocm.software/v1
configurations:
  - type: oci.uploader.transfer.config.ocm.software/v1alpha1
  - type: localblob.uploader.transfer.config.ocm.software/v1alpha1
ResourceOutcome
appoci ghcr.io/target-org/ocm/acme/app:1.0.0
nginxoci ghcr.io/target-org/ocm/library/nginx:1.25
chartoci ghcr.io/target-org/ocm/stable/app:1.0.0
bundleoci ghcr.io/target-org/ocm/acme/bundle:1.0.0
noteslocal blob
docslocal blob

E12 — exclude one resource from a catch-all

type: generic.config.ocm.software/v1
configurations:
  - type: reference.uploader.transfer.config.ocm.software/v1alpha1
    match: resource.name == "nginx"
  - type: oci.uploader.transfer.config.ocm.software/v1alpha1
  - type: localblob.uploader.transfer.config.ocm.software/v1alpha1
ResourceOutcome
nginxby reference
appoci ghcr.io/target-org/ocm/acme/app:1.0.0
chartoci ghcr.io/target-org/ocm/stable/app:1.0.0
bundleoci ghcr.io/target-org/ocm/acme/bundle:1.0.0
noteslocal blob
docslocal blob

E13 — keep Docker Hub images by reference, copy the rest

type: generic.config.ocm.software/v1
configurations:
  - type: reference.uploader.transfer.config.ocm.software/v1alpha1
    match: resource.access.isType("OCIImage") && (resource.access.toOCI().host == "docker.io" || resource.access.toOCI().host.endsWith(".docker.io"))
  - type: localblob.uploader.transfer.config.ocm.software/v1alpha1
ResourceOutcome
nginxby reference
applocal blob
chartlocal blob
bundlelocal blob
noteslocal blob
docslocal blob

E14 — copy only wget downloads

type: generic.config.ocm.software/v1
configurations:
  - type: localblob.uploader.transfer.config.ocm.software/v1alpha1
    match: resource.access.isType("Wget")
ResourceOutcome
docslocal blob
app, nginx, chartby reference
bundle, noteslocal blob (baseline)

E15 — errors

Each case transfers a component with only the named resource.

Config entryResourceError contains
reference, match: "true"bundlelocal blobs cannot be kept by reference
localblob, match: "true"custom with access {"type": "Custom/v1"}local blob uploader cannot copy access type Custom/v1

The Complete Example on the overview page is executed as E16.