Documentation
¶
Overview ¶
Package stackspecmigration contains the bounded compatibility seam for the one-minor StackSpec v1 -> v2 migration described by ADR-0029.
The package deliberately stops at architecture normalization. It does not compile a ResolvedPlan and it does not claim that a normalized architecture is a complete, CUE-valid StackSpec v2. The future compiler must combine this result with explicit topology, capability, provider, access, and inventory inputs before any generator or runtime can consume it.
Index ¶
- Constants
- func MigrateDocument(document Document, options Options) (NormalizedArchitecture, Report, error)
- func MigrateV1(spec *models.StackSpec, options Options) (NormalizedArchitecture, Report, error)
- type Blocker
- type Decision
- type Document
- type KitProfile
- type ManualAction
- type MigrationError
- type MigrationStatus
- type NodeDefaults
- type NormalizedArchitecture
- type Options
- type ReadError
- type Report
- type SiteKind
- type SiteTarget
- type SourceVersion
- type V2Identity
- type Warning
Constants ¶
const ( APIVersionV1 = "stackkit/v1" APIVersionV2Alpha1 = "stackkit/v2alpha1" APIVersionV2Alpha2 = "stackkit/v2alpha2" APIVersionMigrationProjection = "stackkit.migration/v1" KindStackSpec = "StackSpec" KindMigrationProjection = "StackSpecMigrationProjection" )
Variables ¶
This section is empty.
Functions ¶
func MigrateDocument ¶
func MigrateDocument(document Document, options Options) (NormalizedArchitecture, Report, error)
MigrateDocument is the safe entry for file/API migration. In contrast to MigrateV1 it has access to the lossless reader metadata and therefore blocks unknown legacy fields before a caller could write a lossy projection.
Types ¶
type Blocker ¶
type Blocker struct {
Code string `json:"code" yaml:"code"`
Field string `json:"field" yaml:"field"`
Message string `json:"message" yaml:"message"`
RequiredInputs []string `json:"requiredInputs" yaml:"requiredInputs"`
SuggestedKitProfiles []KitProfile `json:"suggestedKitProfiles,omitempty" yaml:"suggestedKitProfiles,omitempty"`
}
Blocker describes missing or contradictory intent that ADR-0029 forbids the migration from guessing.
type Decision ¶
type Decision struct {
Code string `json:"code" yaml:"code"`
Field string `json:"field" yaml:"field"`
From string `json:"from,omitempty" yaml:"from,omitempty"`
To string `json:"to" yaml:"to"`
Reason string `json:"reason" yaml:"reason"`
}
Decision makes every deterministic normalization or explicit operator choice auditable.
type Document ¶
type Document struct {
Version SourceVersion
Raw []byte
Legacy *models.StackSpec
UnknownV1Fields []string
V2 *V2Identity
}
Document preserves the original bytes so dual-read cannot silently discard fields. Legacy is populated only for v1. V2 contains only dispatch identity; the complete document must still be validated by the CUE v2 contract.
type KitProfile ¶
type KitProfile string
KitProfile is the canonical v2 product identity. Context never selects it.
const ( KitProfileBasement KitProfile = "basement-kit" KitProfileCloud KitProfile = "cloud-kit" KitProfileModern KitProfile = "modern-homelab" // LegacyHAKitSlug is recognized only by the bounded v1 migration seam. It // is never a canonical KitProfile or an active product/discovery value. LegacyHAKitSlug = "ha-kit" )
type ManualAction ¶
type ManualAction struct {
Code string `json:"code" yaml:"code"`
Fields []string `json:"fields" yaml:"fields"`
Message string `json:"message" yaml:"message"`
Required bool `json:"required" yaml:"required"`
}
ManualAction records information that cannot be transferred into a complete StackSpecV2 without an operator or a later shadow-resolution stage. It must never be silently dropped by a write-mode migration command.
type MigrationError ¶
type MigrationError struct {
Blockers []Blocker
}
MigrationError is returned with the same blockers contained in Report. errors.As can be used to present machine-actionable guidance.
func (*MigrationError) Error ¶
func (e *MigrationError) Error() string
type MigrationStatus ¶
type MigrationStatus string
MigrationStatus communicates whether the normalization is usable by the next migration stage or requires additional operator intent.
const ( MigrationStatusReady MigrationStatus = "ready-for-shadow-resolution" MigrationStatusCompleted MigrationStatus = "completed-v2" MigrationStatusBlocked MigrationStatus = "blocked" )
type NodeDefaults ¶
type NodeDefaults struct {
SiteRef string `json:"siteRef" yaml:"siteRef"`
HardwareProfile string `json:"hardwareProfile,omitempty" yaml:"hardwareProfile,omitempty"`
ApplyToAllLegacyNodes bool `json:"applyToAllLegacyNodes" yaml:"applyToAllLegacyNodes"`
}
NodeDefaults records how the deprecated stack-level context is projected to legacy nodes. HardwareProfile is populated only for context=pi; local/cloud never invent a hardware class.
type NormalizedArchitecture ¶
type NormalizedArchitecture struct {
APIVersion string `json:"apiVersion" yaml:"apiVersion"`
Kind string `json:"kind" yaml:"kind"`
KitProfile KitProfile `json:"kitProfile" yaml:"kitProfile"`
PrimarySite SiteTarget `json:"primarySite" yaml:"primarySite"`
AuthoritySiteRef string `json:"authoritySiteRef" yaml:"authoritySiteRef"`
NodeDefaults NodeDefaults `json:"nodeDefaults" yaml:"nodeDefaults"`
}
NormalizedArchitecture is the architecture-only output of v1 normalization. It is intentionally not named StackSpecV2: topology and security contracts still have to be supplied and CUE-validated by the compiler.
type Options ¶
type Options struct {
TargetKitProfile KitProfile `json:"targetKitProfile,omitempty" yaml:"targetKitProfile,omitempty"`
}
Options contains explicit operator decisions. TargetKitProfile is never inferred from context. It is only needed when the legacy product identity is missing or when the operator explicitly accepts a supported reclassification.
type Report ¶
type Report struct {
SourceVersion string `json:"sourceVersion" yaml:"sourceVersion"`
TargetVersion string `json:"targetVersion" yaml:"targetVersion"`
Status MigrationStatus `json:"status" yaml:"status"`
RequiresExplicitAcceptance bool `json:"requiresExplicitAcceptance" yaml:"requiresExplicitAcceptance"`
Decisions []Decision `json:"decisions" yaml:"decisions"`
Warnings []Warning `json:"warnings" yaml:"warnings"`
ManualActions []ManualAction `json:"manualActions" yaml:"manualActions"`
Blockers []Blocker `json:"blockers" yaml:"blockers"`
}
Report is emitted for successful and blocked migrations. Callers must show it to the operator before explicit acceptance; it is not optional telemetry.
type SiteTarget ¶
SiteTarget is the single-site target that can be derived from a non-Modern v1 spec without inventing a hybrid topology.
type SourceVersion ¶
type SourceVersion string
SourceVersion identifies which side of the one-minor dual-read seam a document belongs to.
const ( SourceVersionV1 SourceVersion = "v1" SourceVersionV2Alpha1 SourceVersion = "v2alpha1" SourceVersionV2Alpha2 SourceVersion = "v2alpha2" )
func (SourceVersion) IsV2 ¶
func (v SourceVersion) IsV2() bool
IsV2 identifies the CUE-owned architecture family without collapsing the explicit v2alpha1 compatibility adapter into native v2alpha2 intent.
type V2Identity ¶
type V2Identity struct {
APIVersion string
Kind string
KitProfile KitProfile
}
V2Identity is the minimum safe dispatch header for a canonical v2 document.
type Warning ¶
type Warning struct {
Code string `json:"code" yaml:"code"`
Field string `json:"field" yaml:"field"`
Message string `json:"message" yaml:"message"`
RequiredAction string `json:"requiredAction,omitempty" yaml:"requiredAction,omitempty"`
}
Warning describes a non-blocking compatibility concern.