migrate

package
v1.11.2 Latest Latest
Warning

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

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

Documentation

Overview

Package migrate is the `agent-manager migrate` command: the expand–contract migration of an installation's agents from one Generic chart major to the next. Two hops exist, and the target range (Options.TargetSemver) picks one, because a cluster serves one kagent line at a time and a namespace's releases share one chart source:

  • 0.x -> 1.x: kagent.dev/v1alpha2 Agent to kagent.dev/v1alpha3 AgentTemplate; removed keys dropped, muster.toolNames renamed, skills pinned to commits and digests; the five kagent.dev CRDs the 1.x line no longer ships are deleted last.
  • 1.x -> 2.x: kagent.dev/v1alpha3 AgentTemplate to api.kagent.dev/v1alpha3 Agent; sub-agent bindings (extraTools[], extraAgentSpec.tools[]) move from `agent` to `subAgent`, the 1.x Harness admission label becomes agent.harness. The old kagent.dev CRDs are the platform's to remove.

A release deployed from a chart older than the hop's source major is reported, never rewritten. The command runs once per installation as a Job of the connectivity chart and by hand with a kubeconfig; every phase is idempotent and gated on the previous one, so re-running is always safe:

  • expand: every Generic-chart release rendering into a managed namespace gets the target major's values, validated against the target chart's schema; the releases of a chart source are written only when every one of them validates. A GitOps-owned or external release is never written — its rewrite is emitted as a diff for a pull request. The namespace's agent-chart OCIRepository moves to the target range last, only when every release it serves is on target values and the registry has a version in that range.
  • wait: the contract runs only when every release is deployed from a chart in the target range, every object the target chart renders is Ready and no object of the old line is still rendered by a release Flux has yet to upgrade; until then the report names what is pending.
  • contract: the leftover agent objects of the old line in the managed namespaces are deleted, then (0.x -> 1.x only) the removed CRDs.

Every run records a report per managed namespace (ConfigMap agent-manager-migrate-report); --dry-run prints it and writes nothing.

Index

Constants

View Source
const (
	ReportKeyPhase   = "phase"
	ReportKeySummary = "summary"
	ReportKeyReport  = "report.yaml"
)

Report ConfigMap data keys.

View Source
const (
	// PhaseExpand: a Generic-chart release still carries the old major's
	// values (pending, failed, or GitOps-owned with its diff not merged), or a
	// chart source is not on the target range yet.
	PhaseExpand = "expand"
	// PhaseWait: every release is on the target major's values and every
	// writable source on the target range; Flux and kagent have not finished
	// (a release still on the old chart, a rendered object not Ready, the
	// target line's resource not served yet).
	PhaseWait = "wait"
	// PhaseContract: the gate passed; the old line's leftover agent objects
	// of the namespace were deleted (0.x -> 1.x: the CRDs too when every
	// namespace passed).
	PhaseContract = "contract"
	// PhaseComplete: nothing of the old line is left that this command
	// handles.
	PhaseComplete = "complete"
)

The phases a namespace can be in.

View Source
const (
	ActionRewritten = "rewritten"
	ActionUnchanged = "unchanged"
	ActionDiff      = "diff"
	ActionPending   = "pending"
	ActionFailed    = "failed"
)

Actions on a release.

View Source
const (
	SourceMoved    = "moved"
	SourceNotMoved = "not-moved"
)

Actions on a chart source.

View Source
const (
	AgentAwaitingUpgrade = "awaiting-upgrade"
	AgentNotMigratable   = "not-migratable"
	AgentDeleted         = "deleted"
)

Actions on an agent object of the old line.

View Source
const (
	OwnershipHelmRelease = agents.ManagedHelmRelease
	OwnershipGitOps      = agents.ManagedGitOps
	// OwnershipExternal: the object lives outside the managed namespaces
	// (reached through provenance labels); read-only for this command.
	OwnershipExternal = "external"
)

Ownership of a release or source.

View Source
const (
	CRDDeleted = "deleted"
	CRDAbsent  = "absent"
	CRDKept    = "kept"
)

Actions on a CRD in the contract phase.

View Source
const DefaultReportConfigMap = "agent-manager-migrate-report"

DefaultReportConfigMap is the report's ConfigMap name.

View Source
const HarnessAdmissionLabel = "agent-platform.giantswarm.io/harness"

HarnessAdmissionLabel is the 1.x label a Harness admitted templates by.

Variables

View Source
var RemovedCRDs = []string{"agents.kagent.dev", "sandboxagents.kagent.dev", "agentharnesses.kagent.dev", "memories.kagent.dev", "toolservers.kagent.dev"}

RemovedCRDs are the kagent.dev CRDs the API v2 chart no longer ships and Helm never deletes (helm.sh/resource-policy: keep); the contract phase of the 0.x -> 1.x hop does.

Functions

func TargetMajor added in v1.10.0

func TargetMajor(constraint string) (uint64, error)

TargetMajor is the one chart major the range admits; the migration path follows from it (1: 0.x to 1.x, 2: 1.x to 2.x). A range that admits no version or versions of two majors is refused.

Types

type AgentReport

type AgentReport struct {
	Name      string `json:"name"`
	Namespace string `json:"namespace"`
	// Kind is the object's API and kind, such as kagent.dev/v1alpha2 Agent.
	Kind string `json:"kind"`
	// Owner is the HelmRelease the provenance labels name (namespace/name).
	Owner  string `json:"owner,omitempty"`
	Action string `json:"action"`
	Reason string `json:"reason,omitempty"`
}

AgentReport is one agent object of the old line.

type CRDReport

type CRDReport struct {
	Name   string `json:"name"`
	Action string `json:"action"`
	Reason string `json:"reason,omitempty"`
}

CRDReport is one removed CRD.

type ChartInfo

type ChartInfo struct {
	OCIURL string `json:"ociUrl"`
	// TargetSemver is the range every source moves to.
	TargetSemver string `json:"targetSemver"`
	// TargetSemverFilter is the tag filter every source moves to; absent
	// when each source keeps its own.
	TargetSemverFilter *string `json:"targetSemverFilter,omitempty"`
	// LatestVersion is the newest published version in that range, "" when
	// none exists (no source is moved then).
	LatestVersion string `json:"latestVersion,omitempty"`
	// SchemaVersion / SchemaSource say which values.schema.json judged the
	// rewrites.
	SchemaVersion string `json:"schemaVersion"`
	SchemaSource  string `json:"schemaSource"`
}

ChartInfo is the target chart as the run saw it.

type ContractReport

type ContractReport struct {
	// AgentsDeleted are the old line's agent objects removed from the
	// namespace.
	AgentsDeleted []string `json:"agentsDeleted"`
	// CRDs is the fate of the five CRDs the 0.x -> 1.x hop removes
	// (cluster-scoped, so the same in every namespace's report); absent on
	// 1.x -> 2.x, where the platform removes the kagent.dev CRDs.
	CRDs []CRDReport `json:"crds,omitempty"`
}

ContractReport is what the contract phase did.

type Options

type Options struct {
	// Namespaces are the managed namespaces (the default one first): the
	// releases rendering into them are migrated, their reports written there.
	Namespaces []string
	// GitOpsNamespaces are searched for Generic-chart HelmReleases with a
	// targetNamespace in Namespaces, next to what the provenance labels name.
	GitOpsNamespaces []string
	// HarnessName is the platform Harness every agent runs on; composed as
	// agent.harness when it is not the chart default.
	HarnessName string
	// ChartOCIURL identifies the agent chart's sources; TargetSemver is the
	// range they move to, and its major picks the hop (1.x or 2.x).
	ChartOCIURL  string
	TargetSemver string
	// TargetSemverFilter is the ref.semverFilter the sources move to with
	// the range; empty removes one, nil leaves each source's as it is.
	TargetSemverFilter *string
	// ReportConfigMap names the report per namespace.
	ReportConfigMap string
	// DryRun prints the report and writes nothing.
	DryRun bool
	// KagentAPIVersion is the served version of the kagent API the target
	// chart renders into: kagent.dev for 1.x, api.kagent.dev for 2.x.
	KagentAPIVersion string
	// HelmReleaseAPIVersion / OCIRepositoryAPIVersion are the served Flux APIs.
	HelmReleaseAPIVersion   string
	OCIRepositoryAPIVersion string
	// Version is the agent-manager version recorded in the report.
	Version string
}

Options configures a run.

type ReleaseReport

type ReleaseReport struct {
	Name      string `json:"name"`
	Namespace string `json:"namespace"`
	// TargetNamespace is where the release renders when it is not its own.
	TargetNamespace string `json:"targetNamespace,omitempty"`
	Ownership       string `json:"ownership"`
	Action          string `json:"action"`
	Reason          string `json:"reason,omitempty"`
	// ChartVersion is the deployed chart version (status.history), else the
	// last attempted revision.
	ChartVersion string        `json:"chartVersion,omitempty"`
	Changes      *ValueChanges `json:"changes,omitempty"`
	// Diff is the rewrite as a unified diff of the manifest (GitOps-owned and
	// external releases; never written).
	Diff string `json:"diff,omitempty"`
	// Warnings are what the rewrite cannot settle and the write does not
	// wait for (a sub-agent binding to a template that does not exist).
	Warnings []string `json:"warnings,omitempty"`
	// Template is the object the release renders on the target line (a
	// kagent.dev AgentTemplate on 1.x, an api.kagent.dev Agent on 2.x), as
	// the wait phase saw it.
	Template *TemplateReport `json:"template,omitempty"`
}

ReleaseReport is one Generic-chart release.

type Report

type Report struct {
	Namespace string  `json:"namespace"`
	Phase     string  `json:"phase"`
	Summary   string  `json:"summary"`
	Run       RunInfo `json:"run"`
	// Changed is true when this run wrote something in the namespace.
	Changed bool `json:"changed"`
	// Releases are the Generic-chart releases rendering into the namespace.
	Releases []ReleaseReport `json:"releases"`
	// Sources are the OCIRepositories of the agent chart those releases use.
	Sources []SourceReport `json:"sources"`
	// Agents are the old line's agent objects found in the namespace:
	// kagent.dev/v1alpha2 Agents (0.x -> 1.x) or kagent.dev/v1alpha3
	// AgentTemplates (1.x -> 2.x).
	Agents []AgentReport `json:"agents"`
	// Pending names what gates the next phase.
	Pending []string `json:"pending,omitempty"`
	// Warnings are what the wait phase found when nothing gates on it any
	// more (an object not Ready in a namespace that has nothing left to
	// contract).
	Warnings []string `json:"warnings,omitempty"`
	// Contract is what the contract phase did, when it ran.
	Contract *ContractReport `json:"contract,omitempty"`
}

Report is one namespace's migration state.

func (*Report) String

func (r *Report) String() string

String is the report with a header line, for stdout.

func (*Report) YAML

func (r *Report) YAML() string

YAML renders the report.

type Result

type Result struct {
	Reports []*Report
}

Result is one run: a report per managed namespace.

type RunInfo

type RunInfo struct {
	At      string `json:"at"`
	DryRun  bool   `json:"dryRun"`
	Version string `json:"version"`
	Harness string `json:"harness"`
	// Path is the hop the target range picks: "0.x -> 1.x" or "1.x -> 2.x".
	Path  string    `json:"path"`
	Chart ChartInfo `json:"chart"`
}

RunInfo says which run wrote the report.

type Runner

type Runner struct {
	// contains filtered or unexported fields
}

Runner runs the migration.

func New

func New(client kube.Client, c agents.ChartSource, p agents.SkillPinner, st StatusReader, opts Options, log *slog.Logger) (*Runner, error)

New builds a runner; the target range must admit exactly one major with a migration path to it.

func (*Runner) Run

func (r *Runner) Run(ctx context.Context) (*Result, error)

Run performs the phases the cluster's state admits and writes the reports. The error is for what needs an operator (API failures, a write refused); everything the migration itself decides is in the reports.

type SkillPin

type SkillPin struct {
	Name string `json:"name"`
	// Source is the reference as the 0.x values carried it (repository@ref
	// with its path, or the OCI reference).
	Source string `json:"source"`
	// Pinned is the commit id or the digest reference written.
	Pinned string `json:"pinned"`
}

SkillPin is one skill reference and the pin it was written as.

type SourceReport

type SourceReport struct {
	Name      string `json:"name"`
	Namespace string `json:"namespace"`
	Ownership string `json:"ownership"`
	Action    string `json:"action"`
	From      string `json:"from,omitempty"`
	To        string `json:"to,omitempty"`
	// FromSemverFilter and ToSemverFilter are the source's ref.semverFilter
	// before and after, beside the range.
	FromSemverFilter string `json:"fromSemverFilter,omitempty"`
	ToSemverFilter   string `json:"toSemverFilter,omitempty"`
	Reason           string `json:"reason,omitempty"`
	Diff             string `json:"diff,omitempty"`
}

SourceReport is one OCIRepository of the agent chart.

type StatusReader

type StatusReader interface {
	Status(ctx context.Context, loc agents.Location, name string) (*agents.Status, error)
}

StatusReader is the verdict on the object a release on the target chart renders: the service's get_agent_status for an api.kagent.dev Agent, the TemplateStatus for a kagent.dev AgentTemplate.

type TemplateReport

type TemplateReport struct {
	Name    string `json:"name"`
	Exists  bool   `json:"exists"`
	Verdict string `json:"verdict,omitempty"`
	Summary string `json:"summary,omitempty"`
}

TemplateReport is the verdict on the object a release renders.

type TemplateStatus added in v1.10.0

type TemplateStatus struct {
	Client     dynamic.Interface
	APIVersion string
	Harness    string
}

TemplateStatus is the wait phase's verdict on a kagent.dev AgentTemplate, what Generic chart 1.x renders: Ready when the Harness's entry in status.harnesses[] is Ready with the desired revision its latest successful one, failed when a condition of that entry is False for another reason than the pending golden snapshot, progressing otherwise. The service reads api.kagent.dev Agents only, so the 0.x -> 1.x hop reads its templates here.

func (TemplateStatus) Status added in v1.10.0

func (s TemplateStatus) Status(ctx context.Context, loc agents.Location, name string) (*agents.Status, error)

Status implements StatusReader.

type ValueChanges

type ValueChanges struct {
	// Removed are the 0.x keys dropped (dotted paths).
	Removed []string `json:"removed,omitempty"`
	// Renamed are the keys moved, as "old -> new".
	Renamed []string `json:"renamed,omitempty"`
	// Set are the keys the platform adds, as "key=value".
	Set []string `json:"set,omitempty"`
	// Skills are the skill references pinned, one per entry whose written
	// form changed.
	Skills []SkillPin `json:"skills,omitempty"`
	// DriftIgnoreRemoved are the v1alpha2 driftDetection.ignore paths dropped
	// from the HelmRelease.
	DriftIgnoreRemoved []string `json:"driftIgnoreRemoved,omitempty"`
}

ValueChanges records what a rewrite did to one release's values.

func (*ValueChanges) Empty

func (c *ValueChanges) Empty() bool

Empty is true when the rewrite changed nothing.

Jump to

Keyboard shortcuts

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