preinstall

package
v0.0.0-...-a6a35be Latest Latest
Warning

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

Go to latest
Published: Oct 15, 2026 License: AGPL-3.0 Imports: 31 Imported by: 0

Documentation

Index

Constants

View Source
const (
	// DeclareCatalogApps belongs to an upgrade. The device is already running
	// and can reach the catalog, so the apps this release expects are declared
	// whether or not any medium carried them.
	DeclareCatalogApps = CatalogPolicy("declare")
	// OmitCatalogApps belongs to a CLI install, which declares what the medium
	// carries and nothing else.
	OmitCatalogApps = CatalogPolicy("omit")
)
View Source
const (
	// DeclarationSchemaVersion is what Market accepts. The two files this
	// replaced were both "1", so refusing that value is what stops an old
	// bundle.json from being read as a declaration.
	DeclarationSchemaVersion = "2"

	MaxDeclarationBytes = 8 << 20
	MaxDeclarationApps  = 256

	// ChartSourceCatalog takes the chart from the official catalog, so the app
	// installs whatever version the catalog currently serves.
	ChartSourceCatalog = ChartSource("catalog")
	// ChartSourceLocal takes the chart from the payload beside the declaration,
	// which is what an air-gapped first install has.
	ChartSourceLocal = ChartSource("local")
)

A declaration is what this program tells Market the device should have. One file per trunk version of Olares, named for it, written once and never rewritten: a device that moves between builds of the same release is not a device that should preinstall anything again, and a device that upgrades to a new release gets a new file beside the old one rather than over it.

Both media produce the same file. An ISO declares entries whose chart travels with it; an upgrade declares entries the official catalog serves. Everything downstream of the file is one code path.

View Source
const (
	// SupportedSchemaVersion is the schema of the static bundle on the medium.
	// It is not the schema of what this program publishes: the bundle is an
	// input written by the image build, the declaration is the output Market
	// reads, and the two version independently.
	SupportedSchemaVersion = "1"
	OfficialSourceID       = "market.olares"
	BundleFileName         = "bundle.json"
	StaticRelativeDir      = "preinstall/market"
	// RuntimeRelativeDir is relative to the Olares root directory
	// (storage.OlaresRootDir), which is what the market chart renders as
	// .Values.rootPath for its read-only hostPath mount. It is not relative to
	// the installer base directory.
	RuntimeRelativeDir             = "userdata/Cache/market-preinstall"
	MaxBundleJSONBytes             = 8 << 20
	MaxBundleApps                  = 256
	MaxChartBytes            int64 = 256 << 20
	MaxTotalChartBytes             = 1 << 30
	MaxArtifactManifestBytes int64 = 64 << 20
	MaxArtifactEntries             = 1_000_000
	MaxArtifactTotalSize     int64 = 1 << 40
	ArtifactKindHFCache            = "hf-cache"
	InstallScopeShared             = InstallScope("shared")
	InstallScopePerUser            = InstallScope("per-user")
)

Variables

This section is empty.

Functions

func CheckStaticBundle

func CheckStaticBundle(dir string, opts CheckOptions) error

CheckStaticBundle validates a static market bundle directory — the directory that directly contains bundle.json (typically preinstall/market). It is read-only and does not publish runtime state or Hugging Face caches.

By default it checks the V1 JSON contract, chart presence/size/SHA-256, and artifact manifests. With opts.Full it also verifies each artifact source tree entries declared by its manifest (entry types and digests). With opts.InstallationManifest or a non-nil opts.OlaresImages it additionally renders every bundled chart and requires each image they need to appear in that list.

func DeclarationFileName

func DeclarationFileName(trunk string) string

DeclarationFileName is the contract with Market: one file per trunk, named for it, and looked for under that name and no other. The name is also the only place the trunk is written down -- the declaration does not restate it.

func Publish

func Publish(
	installerDir, rootDir, osVersion string,
	selections ProfileSelections,
	catalog CatalogPolicy,
) error

Publish writes this version's declaration, and the charts and artifact manifests it names, under rootDir/RuntimeRelativeDir. rootDir must be the Olares root directory the market chart mounts from, not the installer base directory.

An empty installerDir means no medium was brought, which is the ordinary shape of an upgrade: what that publishes is then the catalog apps of the release being installed, and nothing local.

The catalog policy decides whether those catalog apps are declared at all. A run that ends up with nothing to declare writes no file, so the runtime directory holds a declaration only for a release that expects something.

func ReadOlaresYAMLContainers

func ReadOlaresYAMLContainers(path string) ([]string, error)

ReadOlaresYAMLContainers returns output.containers[].name from a source-tree Olares.yaml. The returned slice is always non-nil so callers can distinguish "the file was read" from an unset CheckOptions.OlaresImages.

func TrunkVersion

func TrunkVersion(version string) string

TrunkVersion is the part of an Olares version that decides which declaration applies. Everything after the first hyphen is a build of the same release -- a daily, an alpha, a release candidate -- and those share one declaration.

func Validate

func Validate(bundle BundleV1) error

func ValidateDeclaration

func ValidateDeclaration(declaration *DeclarationV2) error

ValidateDeclaration mirrors what Market refuses to read. Checking it here is what turns a disagreement between the two programs into a failed install on a machine that can still say why, rather than a Market that will not start.

Types

type AppSelection

type AppSelection struct {
	SelectedGPUType string
	Envs            map[string]string
}

type ArtifactManifestEntryV1

type ArtifactManifestEntryV1 struct {
	Path   string `json:"path"`
	Type   string `json:"type"`
	Size   int64  `json:"size"`
	SHA256 string `json:"sha256,omitempty"`
	Target string `json:"target,omitempty"`
}

type ArtifactManifestV1

type ArtifactManifestV1 struct {
	SchemaVersion int                       `json:"schemaVersion"`
	Repo          string                    `json:"repo"`
	Revision      string                    `json:"revision"`
	Entries       []ArtifactManifestEntryV1 `json:"entries"`
}

func LoadArtifactManifest

func LoadArtifactManifest(root *os.Root, artifact BundleArtifactV1) (ArtifactManifestV1, error)

type BundleAppV1

type BundleAppV1 struct {
	AppID           string             `json:"appId"`
	AppName         string             `json:"appName"`
	Version         string             `json:"version"`
	InstallScope    InstallScope       `json:"installScope"`
	Chart           string             `json:"chart"`
	ChartSHA256     string             `json:"chartSha256"`
	InstallOrder    int                `json:"installOrder"`
	AllowedEnvs     []string           `json:"allowedEnvs,omitempty"`
	DefaultEnvs     map[string]string  `json:"defaultEnvs,omitempty"`
	AllowedGPUTypes []string           `json:"allowedGpuTypes,omitempty"`
	Artifacts       []BundleArtifactV1 `json:"artifacts,omitempty"`
	AppEntry        json.RawMessage    `json:"appEntry"`
}

type BundleArtifactV1

type BundleArtifactV1 struct {
	Kind           string `json:"kind"`
	Source         string `json:"source"`
	Repo           string `json:"repo"`
	Revision       string `json:"revision"`
	Manifest       string `json:"manifest"`
	ManifestSHA256 string `json:"manifestSha256"`
	TotalSize      int64  `json:"totalSize"`
}

type BundleV1

type BundleV1 struct {
	SchemaVersion string        `json:"schemaVersion"`
	SourceID      string        `json:"sourceId"`
	CatalogHash   string        `json:"catalogHash"`
	GeneratedAt   string        `json:"generatedAt"`
	Apps          []BundleAppV1 `json:"apps"`
}

func DecodeBundle

func DecodeBundle(data []byte) (BundleV1, error)

func LoadStaticBundle

func LoadStaticBundle(dir string) (BundleV1, error)

LoadStaticBundle reads and fully validates the bundle a medium carries, including every artifact manifest it names. It is the read-only half of publishing: whatever this accepts is what a declaration can be built from.

type CatalogPolicy

type CatalogPolicy string

CatalogPolicy says whether a publish declares the catalog apps of the release it publishes for. It is stated by every caller rather than defaulted: a run that declared the wrong list would still succeed, and the device would be left preinstalling apps nobody asked it to, or none of the ones it was meant to.

func (CatalogPolicy) Valid

func (p CatalogPolicy) Valid() bool

type ChartSource

type ChartSource string

ChartSource says where the chart of one declared app comes from.

func (ChartSource) Valid

func (s ChartSource) Valid() bool

type CheckOptions

type CheckOptions struct {
	// Full also verifies artifact payload trees under each artifact's
	// source directory against the corresponding manifest entries.
	Full bool

	// InstallationManifest enables the image gate. When set, every image the
	// bundled charts render must appear in it, because LoadImages and
	// PinImages both iterate the manifest and ignore anything absent from it.
	// Leaving it empty keeps the contract-only behaviour. Mutually exclusive
	// with a non-nil OlaresImages.
	InstallationManifest manifest.InstallationManifest

	// OlaresImages is output.containers[].name from a source-tree Olares.yaml.
	// A non-nil slice (including empty) enables the same chart-image gate
	// against that list, so a developer can check before packing
	// installation.manifest. Nil leaves the gate off. Mutually exclusive
	// with InstallationManifest.
	OlaresImages []string

	// ImagesDir is the directory holding the preloaded image payloads,
	// normally <baseDir>/images. When set, an image the manifest lists must
	// also have its tarball on the medium, which is the second half of what
	// prepare needs and a separate failure from a stale image list.
	ImagesDir string

	// GPUModes overrides the .Values.GPU.Type values the charts are rendered
	// under. Empty means the no-override branch plus every known family; see
	// imageRenderModes for why that, and not the bundle's allowedGpuTypes, is
	// the default.
	GPUModes []string
}

CheckOptions controls how thoroughly CheckStaticBundle inspects a static market bundle directory.

type DeclarationAppV2

type DeclarationAppV2 struct {
	AppID        string       `json:"appId"`
	AppName      string       `json:"appName"`
	InstallScope InstallScope `json:"installScope"`
	InstallOrder int          `json:"installOrder"`
	ChartSource  ChartSource  `json:"chartSource"`

	Version         string                `json:"version,omitempty"`
	Chart           string                `json:"chart,omitempty"`
	ChartSHA256     string                `json:"chartSha256,omitempty"`
	SelectedGPUType string                `json:"selectedGpuType,omitempty"`
	Envs            map[string]string     `json:"envs,omitempty"`
	Artifacts       []DeclarationArtifact `json:"artifacts,omitempty"`
	AppEntry        json.RawMessage       `json:"appEntry,omitempty"`
}

DeclarationAppV2 is one app the OS declares. The fields below ChartSource belong to a local entry alone: a catalog entry names an app and nothing else, because everything else about it is the catalog's to say.

type DeclarationArtifact

type DeclarationArtifact struct {
	Kind           string `json:"kind"`
	Source         string `json:"source"`
	Repo           string `json:"repo"`
	Revision       string `json:"revision"`
	Manifest       string `json:"manifest"`
	ManifestSHA256 string `json:"manifestSha256"`
	TotalSize      int64  `json:"totalSize"`
}

DeclarationArtifact is the same shape as BundleArtifactV1 and is kept separate so the input format on the medium can change without changing what Market reads.

type DeclarationV2

type DeclarationV2 struct {
	SchemaVersion string             `json:"schemaVersion"`
	GeneratedAt   string             `json:"generatedAt,omitempty"`
	Apps          []DeclarationAppV2 `json:"apps"`
}

func BuildDeclaration

func BuildDeclaration(
	bundle BundleV1, selections ProfileSelections, catalog []DeclarationAppV2,
) (DeclarationV2, error)

BuildDeclaration folds the medium's bundle and the installer's choices into the one file Market reads. Selections are validated against what the bundle allows here rather than published beside it: a choice the bundle never offered is a mistake in this program, and the device it would break is this one.

type HFCacheMaterializeAction

type HFCacheMaterializeAction struct {
	action.BaseAction
	// contains filtered or unexported fields
}

func (*HFCacheMaterializeAction) Execute

func (a *HFCacheMaterializeAction) Execute(runtime connector.Runtime) error

type HFCacheMaterializeModule

type HFCacheMaterializeModule struct {
	common.KubeModule
	Skip bool
}

func (*HFCacheMaterializeModule) Init

func (m *HFCacheMaterializeModule) Init()

func (*HFCacheMaterializeModule) IsSkip

func (m *HFCacheMaterializeModule) IsSkip() bool

type ImageGap

type ImageGap struct {
	AppID   string
	AppName string
	// Image is spelled the way installation.manifest and the CDN object names
	// spell it: the familiar form, without the docker.io/ prefix. Payload
	// filenames are md5 of this exact string, so a line added to images.mf in
	// any other spelling resolves to a tarball that was never uploaded.
	Image string
	Kind  ImageGapKind
}

ImageGap is one image a bundled chart needs that the installation medium will not preload.

func (ImageGap) String

func (g ImageGap) String() string

type ImageGapKind

type ImageGapKind string

ImageGapKind separates the two ways a bundled chart's image fails to be preloaded. They are reported apart because they are fixed apart: one needs a line in images.mf, the other needs the payload to actually ship.

const (
	// ImageGapUnlisted means installation.manifest never names the image.
	// LoadImages iterates the manifest, so nothing imports it and PinImages
	// never pins it; at install time the cluster falls back to pulling from a
	// registry, which an offline device cannot do.
	ImageGapUnlisted ImageGapKind = "missing from installation.manifest"
	// ImageGapUnlistedOlaresYAML means the source-tree Olares.yaml never names
	// the image in output.containers, so packing would omit it from
	// installation.manifest and the same registry fallback would happen.
	ImageGapUnlistedOlaresYAML ImageGapKind = "missing from olares.yaml"
	// ImageGapNoPayload means the manifest names the image but the medium
	// carries no tarball for it. Prepare aborts in LoadImages with
	// "image %s not found in %s".
	ImageGapNoPayload ImageGapKind = "no image payload on the medium"
)

type InstallScope

type InstallScope string

func (InstallScope) Valid

func (s InstallScope) Valid() bool

type ProfileSelections

type ProfileSelections struct {
	HardwareProfile string
	DetectedGPUType string
	Apps            map[string]AppSelection
}

ProfileSelections is what the installer decided while running: the hardware it found and anything the operator chose per app. It is folded into the published declaration rather than written beside it, because Market has no use for the choices that were available and not taken.

type PublishDeclarationAction

type PublishDeclarationAction struct {
	action.BaseAction
	InstallerDir      string
	RootDir           string
	OSVersion         string
	ProfileSelections ProfileSelections
	CatalogPolicy     CatalogPolicy
}

PublishDeclarationAction declares what this version expects a device to have.

InstallerDir is the one field whose emptiness means something: no medium was brought, which is the ordinary shape of an upgrade. The others are required -- Publish refuses an empty version and an unstated catalog policy, and an empty root would write the declaration where nothing mounts it -- so every caller states them rather than falling through to a default here, where the caller's reason for the value is no longer visible.

Both an install and an upgrade run this same action; the catalog policy is what tells the two apart.

func (*PublishDeclarationAction) Execute

type PublishDeclarationModule

type PublishDeclarationModule struct {
	common.KubeModule
	InstallerDir      string
	RootDir           string
	OSVersion         string
	ProfileSelections ProfileSelections
	CatalogPolicy     CatalogPolicy
}

func (*PublishDeclarationModule) Init

func (m *PublishDeclarationModule) Init()

Jump to

Keyboard shortcuts

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