hostedimage

package
v1.0.1 Latest Latest
Warning

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

Go to latest
Published: Oct 29, 2026 License: Apache-2.0 Imports: 7 Imported by: 0

Documentation

Overview

Package hostedimage holds the ONE vocabulary for "can the control plane pull this hosted image": the push-base resolution rule, the off-base finding, and its wording.

It exists as its own package because the rule has three consumers that cannot import each other:

  • internal/cli's build, which resolves a bare hosted image to the push base and refuses one it cannot resolve;
  • internal/cli's `env render`, which refuses a host-bearing image it can prove is off-base;
  • internal/cli/lint, which reports the same thing as a finding and must not import internal/cli.

Without a shared package the third consumer would restate the message, and a restated message is one that drifts — which matters here because the message IS the product: an author who misreads it declares the wrong registry and discovers it at publish time, which is the defect ADR-0003 F1 closes.

Everything here is pure and offline. No consumer of this package may make a call: a render that needed a credential would stop being the reproducible projection every other surface diffs against.

Index

Constants

View Source
const DefaultRegistryHost = "registry.reliantapi.com"

DefaultRegistryHost is Reliant's hosted container registry — what `forge.ControlPlane {}` means when it names no registry_host.

One fact, twice: kcl/schema.k's RELIANT_REGISTRY_HOST is the KCL copy, which is what a render actually reads. This is the Go copy, for the surfaces that have no KCL in front of them. A test renders the schema and fails if the two disagree (TestRegistryDefault_KCLMatchesGo).

It is a HOST, with no scheme and no trailing slash, because it is joined into an image reference.

Variables

This section is empty.

Functions

func DeniedHint

func DeniedHint(reference string) string

DeniedHint is the sentence to append to a refused push.

The registry's realm scopes a credential to its OWN organization's subtree, and forge composes the push address from that same organization (it asks the control plane which one the token acts for). So a denial here is never a mis-declared org: it is a credential that has expired, or one that holds deploy:read but not the deploy:write a push needs.

func HasRegistryHost

func HasRegistryHost(reference string) bool

HasRegistryHost reports whether a reference's first path component is a registry host — the same rule kcl/lib/images.k and v1alpha1.ValidateImage apply, so forge's three layers agree about what "bare" means.

func IsDenied

func IsDenied(err error, output string) bool

IsDenied reports whether err is a registry refusal to let this credential write here — as opposed to a network fault, a missing credential store, or a bad reference.

Both transports forge pushes over are covered, because both reach the same registry and the author cannot be expected to care which one carried their image:

  • oras (bundles, static-site releases) returns a typed *errcode.ErrorResponse, so the status is read rather than matched.
  • `docker push` is a subprocess whose exit status is just "failed", so the only signal is the daemon's own message on the pipe. Matched on the OCI distribution error CODE (`denied`, `UNAUTHORIZED`), which is part of the spec rather than of docker's phrasing.

func Name

func Name(repository string) string

Name is a repository's last path segment — the artifact name (`ghcr.io/acme/shop` → `shop`).

func NormalizeBase

func NormalizeBase(base string) string

NormalizeBase trims the one difference that is not a difference: a trailing slash. Every join below is explicit.

func PushBase

func PushBase(registryHost, organization, project string) string

PushBase composes `<registryHost>/<organization>/<project>`.

It returns "" when any segment is missing, and that is deliberately not an error here: this function has no env to name and no opinion about whether the caller can proceed. The callers decide, and they decide differently — a build refuses a bare image it cannot resolve, a render reports what it could not compare.

registryHost defaults to DefaultRegistryHost when empty, so a control plane that names no registry resolves to Reliant's — the overwhelmingly common case.

func Repository

func Repository(image string) string

Repository strips any `:tag` / `@digest`, keeping the registry host.

func ResolveBase

func ResolveBase(base, image string) string

ResolveBase is the resolution rule (ADR-0003 F1): a BARE image on a hosted item becomes `<base>/<image>`; a host-bearing one is returned verbatim.

base "" returns the image unchanged. That is deliberately not an error here — this function has no env to name and no opinion about whether the caller can proceed. The caller decides: a build refuses (it has nowhere to push), a render warns (it has nothing to compare).

func UnderBase

func UnderBase(base, image string) bool

UnderBase reports whether a reference sits inside the subtree base names. An image already under it is correct, merely redundant — the author wrote the platform's own registry out in full.

Types

type Finding

type Finding struct {
	Owner string
	Image string
	// Base is the subtree the platform admits, or "" when forge could not
	// learn it. This is the field that decides how much the finding claims.
	Base string
}

Finding is one host-bearing image on a hosted item.

func OffBase

func OffBase(items []Item, base string) []Finding

OffBase is every host-bearing image among items, judged against base when base is known.

A BARE image is never a finding: that is the resolved, correct shape. The caller that must refuse an unresolvable bare image does so separately (internal/cli: checkHostedImagesResolve), because the remedy differs — there the declaration cannot be shipped at all, here it can be shipped somewhere the platform will not pull from.

func Verified

func Verified(findings []Finding) []Finding

Verified narrows findings to the ones forge proved.

func (Finding) FixHint

func (f Finding) FixHint() string

FixHint is the remediation, separated for the structured reporters.

func (Finding) Message

func (f Finding) Message() string

Message is the one sentence a reader acts on. The unverified wording claims strictly less, for the reason Verified documents.

func (Finding) Verified

func (f Finding) Verified() bool

Verified reports whether forge actually COMPARED this image against a known base, as opposed to merely noticing that a host was declared.

The distinction is load-bearing, not cosmetic. A verified finding is a fact — forge holds the admitted subtree and this image is not in it, so the publish will be refused. An unverified one is an observation: a hosted author does not need to declare a host, and forge could not check the one they declared. Acting on the second as though it were the first means failing a render over an assertion forge never made, and on a project whose registry IS the platform's that assertion would be false.

type Item

type Item struct {
	Owner string
	Image string
}

Item is one hosted thing that carries an image: a workload or a frontend. Owner is what the message names, because a project may declare several and only one of them is wrong.

func ScanTree

func ScanTree(dir string) []Item

ScanTree returns every hosted item it can see in the deploy KCL tree at dir, as (owner, image) pairs ready for OffBase.

It joins two facts that are frequently declared in different files: an image on a workload in `workloads.k`, and that workload's runtime binding in `deploy/kcl/<env>/main.k`. Reporting only same-literal declarations would miss the shape most real projects use.

A missing or unreadable tree yields no items and no error: a project without a deploy tree has nothing to judge, and a lint must not fail over a file it merely hoped to find.

Jump to

Keyboard shortcuts

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