registry

package
v0.7.9 Latest Latest
Warning

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

Go to latest
Published: Jul 3, 2026 License: Apache-2.0 Imports: 23 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 inspected by ork push, ork pull, ork inspect, and ork patterns.

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 patterns 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 login command — use docker login.

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 push, ork pull, ork inspect, and ork patterns.

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"

	// FileSimulate is the simulate spec file for a Katalog pattern.
	FileSimulate = "simulate.yaml"

	// FileGoMod, FileGoSum, and FileMakefile are the typed operator build files.
	// Present only in typed (hooks/constructor) patterns.
	FileGoMod    = "go.mod"
	FileGoSum    = "go.sum"
	FileMakefile = "Makefile"

	// 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

	// 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"

	// HelmGitCacheDir is the local cache directory for git-sourced Helm charts.
	HelmGitCacheDir = ".orkestra/helm/git"

	// HelmRepoCacheDir is the local cache directory for remote Helm repository charts.
	HelmRepoCacheDir = ".orkestra/helm/repo"

	// FileCacheDir is the local cache directory for remote file fetches (https://).
	FileCacheDir = ".orkestra/files"
)

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) ListVersions added in v0.7.6

func (c *Client) ListVersions(ctx context.Context, ref *Ref, maxN int) ([]*VersionInfo, error)

ListVersions lists up to maxN most recent versions of a pattern by listing OCI tags and fetching metadata for each. Results are sorted newest-first by semantic version. Tags that cannot be fetched are silently skipped.

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, simulateMeta *PatternSimulate, typedMeta *PatternTyped, runtimeVersion string, 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 and simulateMeta are optional; when non-nil their fields are embedded as OCI annotations on the published artifact. typedMeta is optional; when non-nil it is written as typed-operator annotations.

func (*Client) ViewFile added in v0.7.6

func (c *Client) ViewFile(ctx context.Context, ref *Ref, f FileEntry) ([]byte, error)

ViewFile fetches the raw content of a single OCI layer blob. Use a FileEntry from PatternInfo.Files — both Digest and Size are required so the registry can validate the Content-Length on the response.

type FileEntry added in v0.7.6

type FileEntry struct {
	Name   string
	Size   int64
	Digest string // OCI layer digest — used to fetch blob content via ViewFile
}

FileEntry is one file published in an OCI artifact layer.

type HelmAndFileImports added in v0.7.9

type HelmAndFileImports struct {
	// HelmSources are all helm: entries in imports.helm.
	HelmSources []orktypes.HelmSource
	// RemoteFiles are all HTTPS URLs found in imports.files.
	RemoteFiles []string
}

HelmAndFileImports holds non-OCI remote sources that benefit from local caching: git/remote Helm sources and HTTPS file sources from a komposer spec.

func ExtractHelmAndFileImports added in v0.7.9

func ExtractHelmAndFileImports(filePath string) (*HelmAndFileImports, error)

ExtractHelmAndFileImports parses a komposer file and returns all helm sources and HTTPS file sources. Local file paths are excluded — they need no caching.

func (*HelmAndFileImports) Empty added in v0.7.9

func (h *HelmAndFileImports) Empty() bool

Empty returns true when there are no cacheable remote sources.

type LocalMotifImport added in v0.7.6

type LocalMotifImport struct {
	CRDName string
	Index   int
	Path    string
}

LocalMotifImport describes a motif import in a katalog that uses a local file path. Local imports are valid for development (ork simulate, ork template) but cannot be resolved by consumers after the katalog is published.

func ExtractLocalMotifImports added in v0.7.6

func ExtractLocalMotifImports(filePath string) ([]LocalMotifImport, error)

ExtractLocalMotifImports parses a katalog.yaml and returns any motif imports that reference local file paths. The caller should block ork push when the result is non-empty and prompt the user to replace them with OCI refs.

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 PatternDeprecated added in v0.7.6

type PatternDeprecated struct {
	MigratedTo string // full OCI ref of the replacement version
	Message    string // human-readable migration guidance
}

PatternDeprecated carries the deprecation metadata declared in the source YAML.

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"
	Assertions int    // total number of expectations run; 0 when skipped
}

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 ""
	SimulateStatus string   `json:"simulateStatus,omitempty"` // "passed", "skipped", "no-assertion", or ""
	Deprecated     bool     `json:"deprecated,omitempty"`
}

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
	Files    []FileEntry
}

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
	RuntimeVersion string             // ork version (declarative) or go.mod orkestra version (typed)
	E2E            *PatternE2E        // populated at push time from running ork e2e; nil when absent
	Simulate       *PatternSimulate   // populated at push time from running simulate gate; nil when absent
	Typed          *PatternTyped      // populated at push time from inspecting katalog CRDs; nil for motifs or non-typed katalogs
	Deprecated     *PatternDeprecated // populated from metadata.deprecation in the source YAML; 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 PatternSimulate added in v0.7.2

type PatternSimulate struct {
	Status     string // "passed", "no-assertion", "skipped"
	Duration   string // e.g. "4ms"; empty for skipped/no-assertion
	TestedAt   string // RFC3339
	Assertions int    // number of assertions declared in simulate.yaml; 0 when skipped or no-assertion
}

PatternSimulate holds simulate gate metadata embedded in OCI annotations at push time. Status values:

  • "passed" — simulate.yaml had expect: blocks and all assertions passed
  • "no-assertion" — simulate.yaml present but no expect: block; ran clean, nothing asserted
  • "skipped" — --no-simulate or --force used

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 PatternTyped added in v0.7.6

type PatternTyped struct {
	HasHooks       bool // one or more CRDs declare customHooks
	HasConstructor bool // one or more CRDs declare customConstructor
}

PatternTyped carries the typed-operator annotation flags for a katalog.

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.

type VersionInfo added in v0.7.6

type VersionInfo struct {
	Tag      string
	PushedAt time.Time
	Meta     *PatternMeta
	Digest   string
}

VersionInfo is a lightweight entry returned by ListVersions.

Jump to

Keyboard shortcuts

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