poolmigration

package
v0.0.6 Latest Latest
Warning

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

Go to latest
Published: Jun 11, 2026 License: Apache-2.0 Imports: 17 Imported by: 0

README

poolmigration

Steady-state reconciler that keeps every legacy same-name SandboxPoolSandboxEnv pair in sync. Replaces the original one-shot adopter: drift on already-adopted Pools is fixed in the same code path as the initial wrap-into-Env, so there is no separate "backfill" loop.

Which Pools does it touch?

Two populations:

  • Legacy / orphan: created directly as a SandboxPool CR. May or may not already have an owning same-name SandboxEnv. This reconciler is authoritative for them.
  • Env-managed: created by the SandboxEnv reconciler from a member entry. Pool name differs from the owning Env's name. This reconciler exits early on these — their Member.Spec is the post-PreCreatePool frozen snapshot and must not be re-derived.

Discriminator: a Pool with any OwnerReference to a SandboxEnv whose Name differs from the Pool's own name is Env-managed.

What it does per legacy Pool

  1. Looks up the same-name SandboxEnv; creates it (with TemplateRef + autoscaling derived from the Pool) when missing.
  2. Computes the desired EnvClusterMember from the live Pool and patches env.Spec.Clusters[localClusterID].Members[me] when it differs.
  3. Stamps a controlling OwnerReference from Pool → Env.

Each step is independently idempotent so a crash between steps heals on the next pass.

Member field ownership

Member.Metadata and Member.Spec are frozen snapshots. Each field is filled exactly once — at first sync, or when the existing Member has it empty — and never overwritten afterwards. This is what keeps "Template upgrades do not auto-propagate to legacy Pools" honest.

Member.Config.ScalingGroup, InstanceType, Multiplier, and InlineResources are adopter-derived and overwritten when the derivation drifts from the stored value. User-supplied Config fields (Labels, Annotations, MaxReplicas, priorities) are preserved.

When the Pool only carries TemplateName and the existing Member.Spec.Template is empty, the reconciler fetches the referenced SandboxTemplate and copies its EmbeddedSandboxTemplate into the Member. The resolved (name, version) is then stamped onto the Pool's annotations as the version anchor — subsequent reconciles see the non-empty Member.Spec.Template and skip the fetch entirely.

Ownership signal

The authoritative "this Pool is owned by an Env" signal is the OwnerReference itself — not a label. The Pool Reconciler gates its legacy autoscaler on agentsv1alpha1.HasEnvOwner(pool) which checks only the owner refs.

This is intentionally robust against the "admin deletes the Env" scenario: the next reconcile re-creates the Env and re-stamps the ref.

Removal path

Once every legacy same-name Pool has been migrated to a Phase-2 member (Pool name distinct from Env name), this reconciler becomes a no-op and the package can be deleted. Removal checklist:

  • Delete pkg/controllers/sandboxenv/poolmigration/.
  • Drop the PoolAdoptionReconciler registration from cmd/sandbox/app/app.go.
  • The Pool Reconciler's HasEnvOwner gate keeps working unchanged because the Env-creates-Pool flow stamps the same OwnerReference.

No other code paths depend on this package.

Documentation

Overview

Package poolmigration owns the steady-state sync that keeps legacy (same-name) SandboxPool ↔ SandboxEnv pairs aligned.

Two populations of SandboxPool coexist in the cluster:

  • Legacy / orphan Pools: created directly as a SandboxPool CR (no owning SandboxEnv). This reconciler wraps each one in a same-name SandboxEnv and keeps the Env's local-cluster member entry consistent with the live Pool on every reconcile.

  • Env-managed Pools: created by the SandboxEnv reconciler from a member entry. Their owning Env has a *different* name than the Pool (Phase-2 onwards). This reconciler intentionally leaves them alone — their Member.Spec is the post-PreCreatePool frozen snapshot and must not be re-derived here.

The legacy population is identified by the absence of any OwnerReference to a different-named SandboxEnv. For each such Pool the reconciler:

  1. Looks up — or creates — the same-name SandboxEnv.
  2. Builds a desired EnvClusterMember from the live Pool (and, when the Pool only carries TemplateName, by resolving that SandboxTemplate).
  3. Patches Member.Spec / Member.Config drift into the Env. Once a Member.Spec field is non-empty it is treated as frozen ("fill once") so SandboxTemplate upgrades do not auto-propagate to legacy Pools; adopter-owned Config fields (ScalingGroup / InstanceType / Multiplier / InlineResources) are re-derived on every pass.
  4. Stamps a non-controlling OwnerReference from the Pool to the Env.

Removal path: once every legacy Pool has been migrated to a Phase-2 member, the reconciler becomes a no-op and this package can be deleted.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type PoolAdoptionReconciler

type PoolAdoptionReconciler struct {
	client.Client
	Scheme *runtime.Scheme

	// LocalClusterID identifies the cluster the Pool's member entry belongs to.
	// Defaults to "local" in SetupWithManager when empty.
	LocalClusterID string

	// InstanceTypes is the catalog used to round-trip a Pool's PodSpec
	// resources back to (InstanceType, Multiplier). A nil or Disabled provider
	// causes adoption to fall back to member.InlineResources.
	InstanceTypes instancetype.Provider
}

PoolAdoptionReconciler keeps every legacy same-name SandboxPool ↔ SandboxEnv pair in sync. It watches SandboxPool only — Env updates do not enqueue work here because the desired Member is derived from the Pool, not the Env.

func (*PoolAdoptionReconciler) Reconcile

func (r *PoolAdoptionReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error)

Reconcile owns one Pool at a time.

Steps:

  1. Early-exit when the Pool is Env-managed (an OwnerReference points at a SandboxEnv whose name differs from the Pool's name). Phase-2 Pools do not participate in legacy adoption.

  2. Look up the same-name SandboxEnv; create it when missing.

  3. Compose the desired Member from the live Pool (resolving the SandboxTemplate the first time the Member's Spec.Template is empty) and patch any drift back onto the Env.

  4. Stamp the OwnerReference from Pool → Env.

Steps (2)–(4) are independently idempotent so a Reconcile that crashes mid-way heals on the next pass.

func (*PoolAdoptionReconciler) SetupWithManager

func (r *PoolAdoptionReconciler) SetupWithManager(mgr ctrl.Manager) error

SetupWithManager wires the reconciler with a SandboxPool primary watch. No secondary watches: an Env edit (e.g. an admin tweaking the Env's autoscaling group) is not adoption-relevant.

Jump to

Keyboard shortcuts

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