registry

package
v0.5.3 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: May 24, 2026 License: Apache-2.0 Imports: 20 Imported by: 0

README

pkg/registry

The registry package implements the Orkestra artifact registry — an OCI-based store for patterns (Katalog-based operators) and motifs (reusable resource primitives) that can be pushed, pulled, and listed by the ork registry CLI commands.

Artifact kind is detected automatically from the primary YAML file (kind: Katalog → pattern, kind: Motif → motif). No separate code path per kind is needed — adding a new artifact kind is a one-line entry in artifactSpecs in artifact.go.

What this package provides

What Where in code
Generic artifact kind detection and validation artifact.goDetectKind, ValidateArtifactDirectory, LoadArtifactMeta
Push/pull/info/list over OCI client.goClient
Reference resolution (bare name → full OCI ref) resolve.goResolve, ResolveForKind, Ref
Pattern directory validation (legacy) pattern.goPatternMeta, PatternIndex
Index management (auto-updated on push) client.goupdateIndex, fetchIndex, pushIndex
Local cache at ~/.orkestra/registry/ resolve.goCachePath, IsCached
File and media-type constants constant.go

Artifact kinds

Pattern (kind: Katalog)

A Katalog-based operator pattern. Required files: katalog.yaml, crd.yaml.

my-operator/
  katalog.yaml   application/vnd.orkestra.katalog.v1+yaml       (required)
  crd.yaml       application/vnd.kubernetes.crd.v1+yaml         (required)
  README.md      text/markdown                                   (optional)
  cr.yaml        application/vnd.kubernetes.cr.v1+yaml          (optional)

Manifest media type: application/vnd.orkestra.pattern.v1+tar+gzip
Default registry: ghcr.io/orkspace/orkestra-registry/patterns
Override: ORK_REGISTRY

Motif (kind: Motif)

A reusable resource primitive (stateful service, shared infrastructure). Required file: motif.yaml.

my-motif/
  motif.yaml     application/vnd.orkestra.motif.v1+yaml         (required)
  README.md      text/markdown                                   (optional)
  example/       (directory)                                     (optional)

Manifest media type: application/vnd.orkestra.motif.v1+tar+gzip
Default registry: ghcr.io/orkspace/orkestra-motifs
Override: ORK_MOTIFS_REGISTRY

Push flow

ValidateArtifactDirectory(dir)   — detect kind, check required files, list all files
LoadArtifactMeta(dir, spec)      — read name/version/description from primary YAML
    ↓
client.Push(ctx, ref, dir)
    → read each file into memory store (nothing written back to dir)
    → oras.Pack  — manifest with kind-specific media type and artifact annotations
    → store.Tag  — register manifest under ref.Tag
    → oras.Copy  — push all blobs + manifest to remote
    → updateIndex — upsert entry into index:latest (best-effort)

Additional validation layers run in the CLI before client.Push is called (see docs/04-patterns.md).

Annotations

Every manifest carries standard OCI annotations derived from the artifact's primary YAML:

Annotation Source
org.opencontainers.image.title ArtifactMeta.Name
org.opencontainers.image.version ArtifactMeta.Version
org.opencontainers.image.description ArtifactMeta.Description
org.opencontainers.image.authors ArtifactMeta.Author
org.opencontainers.image.created time of push
io.orkestra.artifact.kind ArtifactMeta.Kind (Katalog or Motif)
io.orkestra.artifact.name ArtifactMeta.Name
io.orkestra.artifact.version ArtifactMeta.Version
io.orkestra.artifact.author ArtifactMeta.Author
io.orkestra.artifact.license ArtifactMeta.License
io.orkestra.artifact.tags comma-separated ArtifactMeta.Tags

Info reads these annotations to reconstruct metadata without downloading any files. The legacy io.orkestra.pattern.* keys are still read for backward compatibility with artifacts pushed before the generic artifact layer.

Index artifact

ork registry list reads a single index:latest artifact from the registry namespace root. Each registry has its own index:

  • Patterns: ghcr.io/orkspace/orkestra-registry/patterns/index:latest
  • Motifs: ghcr.io/orkspace/orkestra-motifs/index:latest

Push automatically updates the index after every successful push. If the index push fails it is logged as a warning — the artifact push is not rolled back.

Reference resolution

Resolve routes bare names to the pattern registry (for backward compatibility). ResolveForKind picks the correct registry based on detected kind:

// Pattern
ref, err := registry.ResolveForKind("postgres:v1", registry.KatalogKind)
// → ghcr.io/orkspace/orkestra-registry/patterns/postgres:v1

// Motif
ref, err := registry.ResolveForKind("redis:v7", registry.MotifKind)
// → ghcr.io/orkspace/orkestra-motifs/redis:v7

// Full OCI ref — used as-is regardless of kind
ref, err := registry.ResolveForKind("oci://ghcr.io/myorg/motifs/redis:v7", registry.MotifKind)
// → ghcr.io/myorg/motifs/redis:v7

Authentication

Reads ~/.docker/config.json via credentials.NewStoreFromDocker. Run docker login ghcr.io before pushing. No separate ork registry login command.

Developer documentation

I want to… Go to
Understand push and pull end-to-end docs/01-push-pull.md
Understand the index and how list works docs/02-index.md
Understand reference resolution and the cache docs/03-resolve-cache.md
Publish a pattern or motif / extend the artifact format docs/04-artifacts.md

Documentation

Overview

pkg/registry/client.go

ORAS-based OCI client for pushing and pulling Orkestra artifacts.

Authentication uses ~/.docker/config.json via oras.land/oras-go/v2. No separate login step — docker login ghcr.io is sufficient.

Push: validates the directory, reads each file, pushes as OCI layers. Pull: fetches the manifest, extracts layers to the cache directory. Info: fetches the manifest only, reads annotations. List: fetches the index pattern from the registry root.

pkg/registry/imports.go

Extracts OCI references from a katalog or komposer file so they can be pre-pulled before running validate, generate, or run commands.

pkg/registry/pattern.go

Generic pattern layer for the Orkestra registry.

Every Orkestra pattern file carries a kind: field. This package reads that field to determine the pattern's media type, required/optional files, and which registry to push to — without a separate code path per kind.

To add a new pattern kind: add one entry to patternSpecs. Nothing else changes.

pkg/registry/resolve.go

Reference resolution for ork registry commands.

A bare reference like "postgres:v14" is resolved to a full OCI reference using the following priority:

  1. Full OCI reference (starts with "oci://") — used as-is
  2. ORK_REGISTRY env var + "/name:version"
  3. Default: ghcr.io/orkspace/orkestra-registry/patterns/katalogs/name:version

The "oci://" prefix is stripped before passing to ORAS — it is a user-facing convention to signal "this is an OCI reference", not part of the actual URL.

CachedDir provides the local cache lookup used by pkg/merger pull helpers. Cache layout: ~/.orkestra/registry/<host>/<repo>/<version>/ A hit is declared when katalog.yaml or motif.yaml exists in that directory.

Index

Constants

View Source
const (
	KatalogKind PatternKind = "Katalog" // Katalog-based operator pattern
	MotifKind   PatternKind = "Motif"   // Reusable resource primitive
	UnknownKind PatternKind = ""

	// MediaType is the OCI pattern media type for Orkestra patterns.
	MediaType = "application/vnd.orkestra.pattern.v1+tar+gzip"

	// FileKatalog is the required operator declaration file.
	FileKatalog = "katalog.yaml"

	// FileMotif is the required motif declaration file.
	FileMotif = "motif.yaml"

	// FileCRD is the required CRD schema file.
	FileCRD = "crd.yaml"

	// FileReadme is the human documentation file.
	FileReadme = "README.md"

	// FileCR is the example CR file.
	FileCR = "cr.yaml"

	// FileE2E is the E2E test definition file for a Katalog pattern.
	FileE2E = "e2e.yaml"

	// DefaultKatalogRegistry is the official OCI path for Katalog patterns.
	DefaultKatalogRegistry = "ghcr.io/orkspace/orkestra-registry/patterns/katalogs"

	// DefaultMotifRegistry is the official OCI path for Motif patterns.
	DefaultMotifRegistry = "ghcr.io/orkspace/orkestra-registry/patterns/motifs"

	// DefaultPatternRegistry is an alias for DefaultKatalogRegistry.
	DefaultPatternRegistry = DefaultKatalogRegistry

	// DefaultRegistry is an alias for DefaultKatalogRegistry.
	DefaultRegistry = DefaultKatalogRegistry

	// EnvPatternRegistry overrides the default katalog registry path.
	EnvPatternRegistry = "ORK_REGISTRY"

	// EnvMotifRegistry overrides the default motif registry path.
	EnvMotifRegistry = "ORK_MOTIFS_REGISTRY"

	// EnvRegistry is an alias for EnvPatternRegistry.
	EnvRegistry = EnvPatternRegistry

	// CacheDir is the local cache directory for pulled artifacts.
	// Resolved relative to the user's home directory.
	CacheDir = ".orkestra/registry"
)

Variables

This section is empty.

Functions

func CachedDir added in v0.4.8

func CachedDir(ociURL, version string) (string, bool)

CachedDir returns the local cache directory for an OCI artifact if it has been pulled previously. A hit requires katalog.yaml or motif.yaml to be present — whichever sentinel file is found first counts as a complete pull.

ociURL must be the bare host+path without the oci:// prefix or tag, e.g. "ghcr.io/orkspace/orkestra-registry/patterns/motifs/postgres". Returns ("", false) when not cached or on any error.

func DetectKind added in v0.4.3

func DetectKind(dir string) (PatternKind, *PatternSpec, error)

DetectKind reads the primary YAML file in dir and returns the pattern kind. Tries katalog.yaml first, then motif.yaml.

func ExtractTagVersion added in v0.4.3

func ExtractTagVersion(ref string) string

ExtractTagVersion extracts the tag portion from a reference like:

"name:version" -> "version"
"ghcr.io/org/repo/name:version" -> "version"
"oci://ghcr.io/org/repo/name:version" -> "version"

If no tag is present (e.g., "name" or "ghcr.io/org/repo/name@sha256:..."), returns "".

func PersistMetadataVersion added in v0.4.3

func PersistMetadataVersion(dir, primaryFile, newVersion string) error

helper to persist metadata.version into the primary file dir: directory containing the primary file primaryFile: filename (e.g., "motif.yaml" or "katalog.yaml") newVersion: version string to write into metadata.version uses WriteFileAndFormat so the file is formatted after the change.

func ValidatePatternDirectory added in v0.4.3

func ValidatePatternDirectory(dir string) (PatternKind, *PatternSpec, []string, error)

ValidatePatternDirectory validates that dir contains a well-formed pattern of the auto-detected kind. Returns the kind, spec, and the list of files to include.

Types

type Client

type Client struct {
	// contains filtered or unexported fields
}

Client wraps ORAS for Orkestra pattern operations.

func NewClient

func NewClient() (*Client, error)

NewClient returns a Client with credentials loaded from the Docker config.

func (*Client) Info

func (c *Client) Info(ctx context.Context, ref *Ref) (*PatternInfo, error)

Info fetches manifest metadata without downloading the pattern files.

func (*Client) List

func (c *Client) List(ctx context.Context, registryURL string) (*PatternIndex, error)

List fetches the pattern index from the given registry URL. Returns an empty index (not an error) when no artifacts have been pushed yet.

func (*Client) Pull

func (c *Client) Pull(ctx context.Context, ref *Ref, refresh bool) (string, error)

Pull fetches an pattern from the registry into the local cache. Returns the cache directory path.

func (*Client) Push

func (c *Client) Push(ctx context.Context, ref *Ref, dir string, e2eMeta *PatternE2E, progress func(file string, size int64)) (string, error)

Push validates the directory, auto-detects the pattern kind, and pushes all files to the registry. Returns the manifest digest on success. e2eMeta is optional; when non-nil its fields are embedded as io.orkestra.e2e.* OCI annotations on the published artifact.

type OCIImports added in v0.4.8

type OCIImports struct {
	MotifImports    []orktypes.MotifImport
	RegistrySources []orktypes.RegistrySource
}

OCIImports holds all OCI references found in a katalog or komposer file.

func ExtractOCIImports added in v0.4.8

func ExtractOCIImports(filePath string) (*OCIImports, error)

ExtractOCIImports parses a katalog or komposer file and returns all OCI references that must be pre-pulled before validate/generate/run.

For Katalog files: spec.crds[*].imports[*].motif refs that resolve to OCI. For Komposer files: imports.registry[*] sources where oci: true or the URL has an oci:// prefix.

Motif shorthands (bare names like "postgres" or "postgres:v0.1.0") are treated as OCI — they resolve against the default motif registry, same as the LoadImport resolution order.

func (*OCIImports) Empty added in v0.4.8

func (o *OCIImports) Empty() bool

Empty returns true when there are no OCI refs to pull.

type PatternE2E added in v0.4.8

type PatternE2E struct {
	Status   string // "passed", "skipped"
	Duration string // e.g. "45s"
	TestedAt string // RFC3339
	Runner   string // "local" or "github-actions"
}

PatternE2E holds E2E verification metadata embedded in OCI annotations at push time.

type PatternEntry

type PatternEntry struct {
	Name          string   `json:"name"`
	LatestVersion string   `json:"latestVersion"`
	Description   string   `json:"description"`
	Tags          []string `json:"tags"`
	Author        string   `json:"author,omitempty"`
	Kind          string   `json:"kind,omitempty"`      // "Katalog" or "Motif"
	E2EStatus     string   `json:"e2eStatus,omitempty"` // "passed", "skipped", or ""
}

PatternEntry is one row in the pattern index.

type PatternIndex

type PatternIndex struct {
	UpdatedAt string         `json:"updatedAt"`
	Entries   []PatternEntry `json:"entries"`
}

PatternIndex is the top-level index stored at registry/index:latest.

type PatternInfo

type PatternInfo struct {
	Ref      *Ref
	Digest   string
	Size     int64
	PushedAt time.Time
	Meta     *PatternMeta
}

PatternInfo holds the metadata returned by Info.

type PatternKind added in v0.4.3

type PatternKind string

PatternKind is the Orkestra pattern type, read from the kind: field.

func (PatternKind) String added in v0.4.3

func (k PatternKind) String() string

String implements fmt.Stringer so PatternKind prints nicely with fmt.

func (PatternKind) ToString added in v0.4.3

func (k PatternKind) ToString() string

ToString returns the underlying string value.

type PatternMeta

type PatternMeta struct {
	Kind        PatternKind
	Name        string
	Version     string
	Description string
	Author      string
	License     string
	Tags        []string
	E2E         *PatternE2E // populated at push time from running ork e2e; nil when absent
}

PatternMeta holds metadata for an pattern — read from its primary YAML on push, and reconstructed from OCI annotations on info/list.

func LoadPatternMeta

func LoadPatternMeta(dir string, spec *PatternSpec) (*PatternMeta, error)

LoadPatternMeta reads name/version/description from the primary file. Works for both Katalog (katalog.yaml) and Motif (motif.yaml).

type PatternSpec added in v0.4.3

type PatternSpec struct {
	Kind          PatternKind
	MediaType     string
	PrimaryFile   string
	RequiredFiles []string
	OptionalFiles []string
}

PatternSpec describes the conventions for one pattern kind.

func SpecFor added in v0.4.3

func SpecFor(kind PatternKind) (*PatternSpec, error)

SpecFor returns the PatternSpec for a given kind.

type Ref

type Ref struct {
	// Registry is the hostname (e.g. "ghcr.io").
	Registry string
	// Repository is the full repository path without the registry
	// (e.g. "orkspace/orkestra-registry/postgres").
	Repository string
	// Tag is the version tag (e.g. "v14").
	Tag string
	// Full is the complete reference without the oci:// prefix.
	Full string
}

Ref holds a resolved OCI reference.

func Resolve

func Resolve(input string) (*Ref, error)

Resolve converts a user-supplied reference to a fully qualified OCI Ref.

"postgres:v14"                                           → ghcr.io/orkspace/orkestra-registry/patterns/katalogs/postgres:v14
"oci://ghcr.io/myorg/patterns/katalogs/redis:v7"        → ghcr.io/myorg/patterns/katalogs/redis:v7
"myorg/redis:v7" (with ORK_REGISTRY set)           → resolved against env

func ResolveForKind added in v0.4.3

func ResolveForKind(input string, k PatternKind) (*Ref, error)

ResolveForKind resolves a reference against the correct default registry for the given pattern kind. A full OCI reference (contains a dot in the host) or an oci:// prefix is used as-is regardless of kind.

func (*Ref) CachePath

func (r *Ref) CachePath() (string, error)

CachePath returns the local filesystem path for this ref. Structure: ~/.orkestra/registry/<registry>/<repository>/<tag>/

func (*Ref) IsCached

func (r *Ref) IsCached() bool

IsCached returns true when the pattern is already in the local cache. Checks for either katalog.yaml (pattern) or motif.yaml (motif).

func (*Ref) ShortName

func (r *Ref) ShortName() string

ShortName returns the name:tag portion for display.

func (*Ref) String

func (r *Ref) String() string

String returns the full reference with oci:// prefix for display.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL