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
- Variables
- func TargetMajor(constraint string) (uint64, error)
- type AgentReport
- type CRDReport
- type ChartInfo
- type ContractReport
- type Options
- type ReleaseReport
- type Report
- type Result
- type RunInfo
- type Runner
- type SkillPin
- type SourceReport
- type StatusReader
- type TemplateReport
- type TemplateStatus
- type ValueChanges
Constants ¶
const ( ReportKeyPhase = "phase" ReportKeySummary = "summary" ReportKeyReport = "report.yaml" )
Report ConfigMap data keys.
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.
const ( ActionRewritten = "rewritten" ActionUnchanged = "unchanged" ActionDiff = "diff" ActionPending = "pending" ActionFailed = "failed" )
Actions on a release.
const ( SourceMoved = "moved" SourceNotMoved = "not-moved" )
Actions on a chart source.
const ( AgentAwaitingUpgrade = "awaiting-upgrade" AgentNotMigratable = "not-migratable" AgentDeleted = "deleted" )
Actions on an agent object of the old line.
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.
const ( CRDDeleted = "deleted" CRDAbsent = "absent" CRDKept = "kept" )
Actions on a CRD in the contract phase.
const DefaultReportConfigMap = "agent-manager-migrate-report"
DefaultReportConfigMap is the report's ConfigMap name.
const HarnessAdmissionLabel = "agent-platform.giantswarm.io/harness"
HarnessAdmissionLabel is the 1.x label a Harness admitted templates by.
Variables ¶
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
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.
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.
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
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.
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.