catalog

package
v0.9.2 Latest Latest
Warning

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

Go to latest
Published: Nov 6, 2026 License: Apache-2.0 Imports: 16 Imported by: 0

Documentation

Overview

Package catalog holds Levelrail's own curated set of one-click service templates (ADR 015). Every Template's name, slogan, and Compose body here is written fresh for this platform: none of it is copied or lightly-rewritten from any other project's own dataset. Image tags are real, versioned tags for each well-known open-source project; where a specific tag's exact string couldn't be verified against a live registry in this environment, that entry says so in its own comment.

Index

Constants

View Source
const (
	TrustListed         = "listed"
	TrustVerified       = "verified"
	TrustVerifiedSigned = "verified_signed"
)

Trust levels. Every entry is at least listed.

View Source
const (
	ListingMaintainers = "maintainers"
	ListingCommunity   = "community"
	ListingVendor      = "vendor"
)

Who stands behind a catalog entry.

View Source
const (
	ClassPermissive      = "permissive"
	ClassCopyleft        = "copyleft"
	ClassNetworkCopyleft = "network-copyleft"
	ClassSourceAvailable = "source-available"
	ClassProprietary     = "proprietary"
)

License classes shown on the marketplace. The site prints the class label, never a judgment.

View Source
const (
	SourceUpstream  = "upstream"
	SourceOfficial  = "official"
	SourceRebuilder = "rebuilder"
	SourceCommunity = "community"
)

Image source classes: who owns the registry namespace an image comes from.

View Source
const (
	StatusActive     = "active"
	StatusDeprecated = "deprecated"
	StatusYanked     = "yanked"
)

Entry lifecycle states.

View Source
const (
	SeverityInfo     = "info"
	SeverityReview   = "review"
	SeverityElevated = "elevated"
)

Finding severities, ordered info < review < elevated.

View Source
const (
	FindingPrivileged       = "privileged"
	FindingDockerSocket     = "docker_socket"
	FindingHostNetwork      = "host_network"
	FindingHostNamespace    = "host_namespace"
	FindingCapAdd           = "cap_add"
	FindingDevices          = "devices"
	FindingSecurityOpt      = "security_opt"
	FindingHostMount        = "host_mount"
	FindingUnpinnedImage    = "unpinned_image"
	FindingPublishedPorts   = "published_ports"
	FindingGeneratedSecrets = "generated_secrets"
	FindingRequiredSecrets  = "required_secrets"
	FindingNoHealthcheck    = "no_healthcheck"
	FindingPersistentData   = "persistent_data"
	FindingGPU              = "gpu"
	FindingUnparsed         = "unparsed"
)

Finding codes, stable identifiers the dashboard maps to translated copy.

View Source
const (
	ProtectionIngress  = "https_ingress"
	ProtectionMasking  = "secret_masking"
	ProtectionBackups  = "volume_backups"
	ProtectionHealth   = "health_gated_deploy"
	ProtectionRollback = "rollback"
	ProtectionExposure = "exposure_report"
	ProtectionFirewall = "firewall"
)

Protection codes for what Levelrail adds around a template.

View Source
const StatusPageURL = "https://github.com/glincker/levelrail/blob/main/docs/templates-status.md"

StatusPageURL records smoke passes that predate CI run links.

Variables

View Source
var Templates = concat(
	starterKitsTemplates,
	automationTemplates,
	monitoringTemplates,
	storageTemplates,
	analyticsTemplates,
	infrastructureTemplates,
	securityTemplates,
	productivity1Templates,
	productivity2Templates,
	productivity3Templates,
	applicationsTemplates,
	devtools1Templates,
	devtools2Templates,
	dashboardTemplates,
	financeTemplates,
	media1Templates,
	media2Templates,
	communicationTemplates,
	databasesTemplates,
	iotTemplates,
	aiml1Templates,
	aiml2Templates,
	selfhosted1Templates,
	selfhosted2Templates,
	selfhosted3Templates,
	selfhosted4Templates,
	aiTemplates,
	devtoolsBatchTemplates,
	productivityBatchTemplates,
	automationBatchTemplates,
	catalogBatch2Templates,
	catalogBatch3Templates,
	catalogBatch4Templates,
	catalogBatch5Templates,
	catalogBatch6Templates,
	catalogRustDeskTemplates,
	catalogGamesTemplates,
	mailTemplates,
	catalogDevtoolsInfraTemplates,
	contribTemplates,
	manifestTemplates,
)

Templates is the full catalog, served by GET /api/v1/service-templates and GET /api/v1/service-templates/{id}. contribTemplates (contrib.go) are contributor-submitted YAML entries, merged in last so they're indistinguishable from the hand-written Go ones to every consumer.

Functions

func ComposeImages

func ComposeImages(compose string) (images []string, ok bool)

ComposeImages returns the distinct image references of a compose body. ok is false when any service has no literal image (build only or a ${VAR} reference), so callers must treat the template as unknown.

func ImageSourceClass

func ImageSourceClass(ref, sourceRepo string) string

ImageSourceClass says who owns the namespace of an image ref relative to the source repo.

func IsVerified

func IsVerified(id string) bool

IsVerified reports whether the catalog template id has a smoke record that still matches its pinned images.

func LegacyManifestIDs

func LegacyManifestIDs() map[string]bool

LegacyManifestIDs are manifests that predate the marketplace rules. The list only shrinks: bringing one up to the rules means deleting its line.

func PinnedImages

func PinnedImages(t Template) (refs []string, ok bool)

PinnedImages returns the template's distinct image refs, sorted. ok is false when any ref is unpinned (no tag, latest, digest or a variable).

func PrimaryTag

func PrimaryTag(t Template) string

PrimaryTag is the tag of the template's main image: the service its healthcheck names, else the first ref in sorted order.

func RecordVerified

func RecordVerified(path string, t Template, run VerifiedRun) error

RecordVerified merges one passed run for t into the file at path. Arches already recorded for the same pinned images are kept.

func SplitImageRef

func SplitImageRef(ref string) (image, tag string)

SplitImageRef splits repo and tag. A digest-pinned ref keeps the whole string as the image and an empty tag.

func ValidateCompose added in v0.2.0

func ValidateCompose(body []byte) (map[string]bool, error)

ValidateCompose runs a compose body through the same parse, magic-var and translation steps a real deploy uses, with stand-in secrets, and returns the declared service keys. A later catalog import batch runs this over every candidate file (scripts/validate-templates).

func ValidateSubmissions

func ValidateSubmissions(fsys fs.FS, dir string, legacy map[string]bool, only map[string]bool) error

ValidateSubmissions loads every manifest under dir and applies ValidateSubmission to those whose id is not in the legacy exemption list.

func VerifiedData

func VerifiedData() map[string]VerifiedRecord

VerifiedData returns the committed smoke records, keyed by template id.

Types

type Admission

type Admission struct {
	KEVHit         bool   `json:"kev_hit"`
	SecretsAllowed int    `json:"secrets_allowed"`
	RunURL         string `json:"run_url"`
}

Admission is the result of the admission checks for one template.

type DomainPrompt added in v0.2.0

type DomainPrompt struct {
	Service     string `yaml:"service" json:"service"`
	Port        int    `yaml:"port" json:"port"`
	Description string `yaml:"description" json:"description,omitempty"`
}

DomainPrompt is a service the installer offers to put behind a domain.

type EnvPrompt added in v0.2.0

type EnvPrompt struct {
	Key         string `yaml:"key" json:"key"`
	Label       string `yaml:"label" json:"label,omitempty"`
	Description string `yaml:"description" json:"description,omitempty"`
	Default     string `yaml:"default" json:"default,omitempty"`
	Generate    string `yaml:"generate" json:"generate,omitempty"`
	Length      int    `yaml:"length" json:"length,omitempty"`
	Required    bool   `yaml:"required" json:"required,omitempty"`
	Secret      bool   `yaml:"secret" json:"secret,omitempty"`
}

EnvPrompt is one ${KEY} placeholder the installer asks for.

type Finding

type Finding struct {
	Code     string   `json:"code"`
	Severity string   `json:"severity"`
	Services []string `json:"services,omitempty"`
	Detail   string   `json:"detail,omitempty"`
	Message  string   `json:"message"`
}

Finding is one thing a template asks of the host or the operator.

type ImageFact

type ImageFact struct {
	Service     string    `json:"service"`
	Image       string    `json:"image"`
	Tag         string    `json:"tag"`
	Digest      string    `json:"digest,omitempty"`
	SourceClass string    `json:"source_class"`
	Platforms   []string  `json:"platforms,omitempty"`
	Signed      *SignedBy `json:"signed"`
	Provenance  bool      `json:"provenance"`
	SBOM        bool      `json:"sbom"`
	NonRoot     bool      `json:"non_root"`
}

ImageFact is one service image with the facts tied to its pinned tag.

type ImagePlatforms

type ImagePlatforms struct {
	Image     string   `json:"image"`
	Tag       string   `json:"tag"`
	Platforms []string `json:"platforms"`
	CheckedAt string   `json:"checked_at"`
	Error     string   `json:"error,omitempty"`
}

ImagePlatforms is one scanned image reference and the platforms its registry manifest lists. An empty list with an Error means unknown.

func (ImagePlatforms) Ref

func (p ImagePlatforms) Ref() string

Ref returns the pullable reference the scan inspected.

type InstallInput added in v0.2.0

type InstallInput struct {
	Env     map[string]string
	Domains map[string]string
}

InstallInput is what an operator supplies when installing a manifest.

type License

type License struct {
	SPDX  string `json:"spdx"`
	Class string `json:"class"`
	URL   string `json:"url,omitempty"`
}

License is the stated license and its class.

type Listing

type Listing struct {
	By        string
	VendorOrg string
	Proof     string
}

Listing is who stands behind a catalog entry.

func ListingFor

func ListingFor(t Template) Listing

ListingFor returns the entry's listing. A manifest may set it; contrib YAML files are community entries; everything else is maintainer curated.

type LockFile

type LockFile struct {
	Images    map[string]LockedImage `json:"images"`
	Admission map[string]Admission   `json:"admission"`
}

LockFile is images.lock.json: digests and signals per ref, admission per template.

func Lock

func Lock() LockFile

Lock returns the committed image lock.

type LockedImage

type LockedImage struct {
	Digest     string    `json:"digest"`
	Signed     *SignedBy `json:"signed"`
	Provenance bool      `json:"provenance"`
	SBOM       bool      `json:"sbom"`
	NonRoot    bool      `json:"non_root"`
}

LockedImage is what CI resolved for one pinned ref. It is generated, never hand-written.

type Manifest added in v0.2.0

type Manifest struct {
	ID               string `yaml:"id" json:"id"`
	Name             string `yaml:"name" json:"name"`
	Description      string `yaml:"description" json:"description"`
	Icon             string `yaml:"icon" json:"icon,omitempty"`
	Category         string `yaml:"category" json:"category"`
	DocumentationURL string `yaml:"documentation_url" json:"documentation_url"`
	// Marketplace listing fields. All optional for entries that predate the
	// marketplace; ValidateSubmission requires them for new manifests.
	SourceRepo             string               `yaml:"source_repo" json:"source_repo,omitempty"`
	License                string               `yaml:"license" json:"license,omitempty"`
	LicenseClass           string               `yaml:"license_class" json:"license_class,omitempty"`
	LicenseURL             string               `yaml:"license_url" json:"license_url,omitempty"`
	HostedUse              string               `yaml:"hosted_use" json:"hosted_use,omitempty"`
	Listing                *ManifestListing     `yaml:"listing" json:"listing,omitempty"`
	Status                 string               `yaml:"status" json:"status,omitempty"`
	StatusReason           string               `yaml:"status_reason" json:"status_reason,omitempty"`
	ReplacedBy             string               `yaml:"replaced_by" json:"replaced_by,omitempty"`
	Aliases                []string             `yaml:"aliases" json:"aliases,omitempty"`
	FirstRun               []string             `yaml:"first_run" json:"first_run,omitempty"`
	ComposeFile            string               `yaml:"compose_file" json:"-"`
	RecommendedMemoryBytes int64                `yaml:"recommended_memory_bytes" json:"recommended_memory_bytes,omitempty"`
	Env                    []EnvPrompt          `yaml:"env" json:"env,omitempty"`
	Domains                []DomainPrompt       `yaml:"domains" json:"domains,omitempty"`
	Healthcheck            *ManifestHealthcheck `yaml:"healthcheck" json:"healthcheck,omitempty"`
	// ConsoleCommand is the argv "apps console" runs in the container. It must read any secret from the container env, never carry one.
	ConsoleCommand []string `yaml:"console_command" json:"console_command,omitempty"`
	Compose        string   `yaml:"-" json:"-"`
}

Manifest is one template directory: template.yaml plus the compose file it names.

func LoadManifest added in v0.2.0

func LoadManifest(fsys fs.FS, dir string) (Manifest, error)

LoadManifest reads and validates one template directory.

func LoadManifests added in v0.2.0

func LoadManifests(fsys fs.FS, dir string) ([]Manifest, error)

LoadManifests reads every <dir>/<id>/template.yaml in fsys, sorted by id, and validates each one. All problems are reported, not just the first.

func (Manifest) Render added in v0.2.0

func (m Manifest) Render(in InstallInput, allowMissing bool) (string, error)

Render returns the manifest's compose file with every prompt filled in. Values are substituted into parsed YAML scalars, never into raw text, so an operator value cannot change the document's structure. With allowMissing, a required prompt with no value becomes an unresolved magic var, which the deploy path reports as "needs configuration".

func (Manifest) Template added in v0.2.0

func (m Manifest) Template() (Template, error)

Template converts the manifest into a catalog entry; its Compose is the default render, so the generic one-click path keeps working.

func (Manifest) Validate added in v0.2.0

func (m Manifest) Validate() error

Validate checks the manifest's fields, that its prompts and placeholders match one to one, and that a sample render deploys through the compose path.

func (Manifest) ValidateSubmission

func (m Manifest) ValidateSubmission() error

ValidateSubmission applies the stricter marketplace rules to a manifest. Entries that predate the marketplace are exempt (legacy_manifests.txt).

type ManifestHealthcheck added in v0.2.0

type ManifestHealthcheck struct {
	Service string `yaml:"service" json:"service"`
	Port    int    `yaml:"port" json:"port"`
	Path    string `yaml:"path" json:"path"`
	// Expect is the status the path answers when it is not 200 to 399 (401 or 403 behind a login).
	Expect int `yaml:"expect" json:"expect,omitempty"`
	// Kind is http (default) or tcp for services with no HTTP surface.
	Kind string `yaml:"kind" json:"kind,omitempty"`
}

ManifestHealthcheck is the HTTP check that proves an install actually serves.

type ManifestListing

type ManifestListing struct {
	By        string `yaml:"by" json:"by"`
	VendorOrg string `yaml:"vendor_org" json:"vendor_org,omitempty"`
	Proof     string `yaml:"proof" json:"proof,omitempty"`
}

ManifestListing says who stands behind the entry.

type Marketplace

type Marketplace struct {
	SourceRepo   string
	License      *License
	Status       string
	StatusReason string
	ReplacedBy   string
	// HostedUse feeds the public index only; the product API never exposes it.
	HostedUse    string
	Aliases      []string
	Listing      Listing
	Trust        Trust
	Arch         map[string]string
	Verification *Verification
	Admission    *Admission
	Images       []ImageFact
}

Marketplace is every derived marketplace fact for one template. The site index and the product API both read it, so the two never disagree.

func MarketplaceByID

func MarketplaceByID(id string) (Marketplace, bool)

MarketplaceByID is the cached form for request paths: the catalog is static, so facts are derived once.

func MarketplaceFor

func MarketplaceFor(t Template) Marketplace

MarketplaceFor derives the marketplace facts of one template. A compose body that fails to parse yields the facts without images, never an error.

type PlatformsFile

type PlatformsFile struct {
	ScannedAt string              `json:"scanned_at"`
	Images    []ImagePlatforms    `json:"images"`
	Templates map[string][]string `json:"templates"`
}

PlatformsFile is the checked-in output of scripts/scan-catalog-platforms.

func PlatformsData

func PlatformsData() PlatformsFile

PlatformsData returns the committed scan result.

type Protection

type Protection struct {
	Code  string `json:"code"`
	Label string `json:"label"`
}

Protection is one Levelrail safeguard that applies to a template.

type Requirements

type Requirements struct {
	Level       RequirementsLevel `json:"level"`
	Findings    []Finding         `json:"findings"`
	Protections []Protection      `json:"protections"`
}

Requirements is the computed "what this needs, what Levelrail adds" card.

func ComputeRequirements

func ComputeRequirements(composeBody string) Requirements

ComputeRequirements derives the requirements card from a template's Compose body alone. A body that fails to parse is reported as review.

type RequirementsLevel

type RequirementsLevel string

RequirementsLevel summarizes how much trust a template asks of the host.

const (
	LevelStandard RequirementsLevel = "standard"
	LevelReview   RequirementsLevel = "review"
	LevelElevated RequirementsLevel = "elevated"
)

Requirements levels, ordered standard < review < elevated.

type SignedBy

type SignedBy struct {
	Method   string `json:"method"`
	Identity string `json:"identity"`
}

SignedBy is a verified keyless signature identity.

type Template

type Template struct {
	ID     string
	Name   string
	Slogan string
	// Description is optional operator setup notes (ports, firewall, required env, licence), plain text.
	Description      string
	Category         string
	DocumentationURL string
	Compose          string
	// RecommendedMemoryBytes is a static, pre-deploy RAM advisory (zero
	// means none). Informational only, not checked against any node's
	// real available memory.
	RecommendedMemoryBytes int64
	// RequiresGPU marks entries that reserve an NVIDIA GPU through
	// deploy.resources.reservations.devices in their Compose body.
	RequiresGPU bool
	// Platforms lists os/arch pairs verified in the registry manifest of every
	// image (platforms.json). Empty means not checked, never a claim.
	Platforms []string
	// Manifest is set for entries loaded from manifests/ (env prompts, domains, healthcheck).
	Manifest *Manifest
}

Template is one deployable entry in the catalog. Compose is a full compose.yaml body, valid against internal/compose's supported subset (see catalog_test.go, which parses and validates every one).

func TemplateByID added in v0.2.0

func TemplateByID(id string) (Template, bool)

TemplateByID returns the Templates entry with this ID, or false if none matches.

type TemplateMeta

type TemplateMeta struct {
	SourceRepo   string `json:"source_repo,omitempty"`
	License      string `json:"license,omitempty"`
	LicenseClass string `json:"license_class,omitempty"`
	LicenseURL   string `json:"license_url,omitempty"`
	Description  string `json:"description,omitempty"`
	// Status stays empty for active entries; deprecated ones carry a plain-fact reason.
	Status       string `json:"status,omitempty"`
	StatusReason string `json:"status_reason,omitempty"`
	ReplacedBy   string `json:"replaced_by,omitempty"`
}

TemplateMeta is marketplace metadata for templates compiled from Go literals, which have no template.yaml to carry it.

func MetaFor

func MetaFor(id string) (TemplateMeta, bool)

MetaFor returns the marketplace metadata recorded for a template id.

type TombstoneEntry

type TombstoneEntry struct {
	ID         string `json:"id"`
	ReplacedBy string `json:"replaced_by,omitempty"`
	Reason     string `json:"reason"`
	RemovedIn  string `json:"removed_in"`
}

TombstoneEntry is a removed id that must never be reused.

func Tombstones

func Tombstones() []TombstoneEntry

Tombstones returns removed ids that must not be reused.

type Trust

type Trust struct {
	Level       string `json:"level"`
	EvidenceURL string `json:"evidence_url,omitempty"`
}

Trust is the composite level and the CI run that backs it.

type Verification

type Verification struct {
	Tag        string   `json:"tag"`
	Digest     string   `json:"digest,omitempty"`
	HTTPStatus int      `json:"http_status,omitempty"`
	Arches     []string `json:"arches"`
	RunURL     string   `json:"run_url,omitempty"`
}

Verification is the smoke record, bound to a tag and digest, with no dates.

type VerifiedRecord

type VerifiedRecord struct {
	Tag    string   `json:"tag"`
	Images []string `json:"images"`
	// Digest is the primary image digest the run pulled; empty for historical local runs.
	Digest     string   `json:"digest,omitempty"`
	Arches     []string `json:"arches"`
	HTTPStatus int      `json:"http_status,omitempty"`
	// RunURL links the CI run that produced the record; empty for historical local runs.
	RunURL string `json:"run_url,omitempty"`
}

VerifiedRecord is one passed smoke run. Images lists every pinned ref the run used, so a record stops counting the moment any of them changes.

func VerifiedFor

func VerifiedFor(t Template) (VerifiedRecord, bool)

VerifiedFor returns the record only while it still matches the template's current pinned images. Verified is a fact about those tags, never a date.

type VerifiedRun

type VerifiedRun struct {
	Arch       string
	Digest     string
	HTTPStatus int
	RunURL     string
}

VerifiedRun is one passed smoke run to fold into verified.json.

Jump to

Keyboard shortcuts

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