Skip to main content

Authoring

Extension seams

Bring your own content without forking the repo.

docs/authoring/extensions.md
On this page

SnowOps Labs keeps a small, documented seam so custom or private builds can plug in behaviour without forking the engine. Everything in the open repository behaves identically whether or not anything is injected — no business logic ever enters the open engine.

This package is part of the public SDK and is CODEOWNERS-locked:

  • pkg/extension — where content comes from (resolvers) and what happens around lifecycle phases (hooks).

The entitlement seam and the OCI/pack resolver that used to live here were removed in v2 — see ADR-0001 and ADR-0008. Content distribution is now plain directories plus SNOWOPS_CONTENT_PATH.

Resolvers — where content comes from

type Resolver interface {
    CanResolve(ref string) bool
    Resolve(ctx context.Context, ref, destDir string) error
}

A Chain tries each resolver in order and uses the first that reports CanResolve. The built-in open resolvers are:

Resolver Handles
GitResolver https://…, git+https://…@ref, ssh URLs — clones a shallow content snapshot and drops .git
LocalResolver file://… and existing local directories — copies the tree

DefaultResolver() returns Chain{GitResolver{}, LocalResolver{}}.

To add a source, implement the interface and put it ahead of the chain:

chain := append(extension.Chain{myResolver{}}, extension.DefaultResolver()...)

GitResolver takes a GitRunner so tests can inject a stub instead of shelling out to real git.

Hooks — around lifecycle phases

type Hooks interface {
    PreStage(ctx context.Context, ev Event) error
    PostStage(ctx context.Context, ev Event) error
}

DefaultHooks() is a no-op. A Pre* hook returning an error aborts the phase, so a custom build can enforce policy without the engine knowing the policy exists. Hooks receive an Event naming the scenario and stage.

Rules for anything built on these seams

  • The open engine must behave identically with the default implementations.
  • Custom logic lives in a separate repository and is injected at construction — never merged into the open engine.
  • Changes to these interfaces follow the SDK & Schema Stability Policy.

The incident field notes

One real Kubernetes failure a week — the symptom, the commands that found it, and the fix. Written from actual lab runs, not from memory.

You'll get the Kubernetes Incident Response Field Guide, plus occasional emails about new scenarios, posts and paid offerings such as courses and workshops. Unsubscribe any time.