Package Variants and Package Variant Sets
What are PackageVariants?
A PackageVariant is a Kubernetes custom resource that automates the creation and maintenance of downstream package revisions based on an upstream package. It establishes a relationship between an upstream (source) package and one or more downstream (target) packages, automatically keeping them synchronized.
PackageVariants enable:
- Automatic cloning of package revisions from upstream to downstream repositories
- Continuous tracking of package revisions of the upstream package
- Automated creation of new downstream revisions when a new revision of the upstream is published
- Customization of downstream package revisions through injectors, functions, and package context
How PackageVariants Work
Porch’s PackageVariant controller watches for changes to:
- The PackageVariant resource itself
- The upstream PackageRevision it references
- The downstream PackageRevisions it owns
When changes occur, the controller:
- Creates a new downstream PackageRevision if none exists (via clone task)
- Updates existing downstream PackageRevisions when upstream changes (via upgrade task)
- Applies customizations specified in the PackageVariant spec (functions, injectors, labels, annotations)
- Manages the lifecycle of downstream PackageRevisions (draft → published)
PackageVariant Spec
A PackageVariant defines:
Upstream: The source PackageRevision to track
upstream:
repo: blueprints
package: my-app
revision: v1 # optional: tracks latest if omitted
Downstream: The target PackageRevision to create/maintain
downstream:
repo: deployments
package: prod-my-app
Customizations: How to modify the downstream PackageRevision
pipeline: Additional KRM functions (mutators/validators) to inject into the Kptfileinjectors: References to cluster objects whose data should be injected into the PackageRevisionpackageContext: Key-value data to add/remove from the package-context.yaml ConfigMaplabelsandannotations: Metadata to apply to the downstream PackageRevision
Policies:
adoptionPolicy: Whether to adopt existing PackageRevisions (adoptNoneoradoptExisting)deletionPolicy: Whether to delete or orphan downstream PackageRevisions when the PackageVariant is deleted (deleteororphan)
PackageVariant Lifecycle
The PackageVariant controller manages downstream PackageRevisions through their lifecycle:
- Initial creation: Creates a Draft PackageRevision with a clone task
- Customization: Applies functions, injectors, and package context modifications
- Upstream updates: When upstream changes, creates a new Draft with an upgrade task
- Downstream modifications: When customizations change, creates a new Draft with an edit task
- Cleanup: When PackageVariant is deleted, deletes or orphans downstream PackageRevisions based on deletionPolicy
What are PackageVariantSets?
PackageVariantSet is a higher-level resource that creates multiple PackageVariants from a single upstream package to multiple downstream targets. It’s essentially a template for generating PackageVariants.
PackageVariantSets enable:
- One-to-many package distribution (one upstream → many downstreams)
- Dynamic target selection via label selectors
- Templated downstream package naming and customization
- Centralized management of multiple PackageVariants
PackageVariantSet Spec
A PackageVariantSet defines:
Upstream: The source PackageRevision (same as PackageVariant)
Targets: How to select downstream repositories
repositories: Explicit list of Repository resourcesrepositorySelector: Label selector to dynamically select repositoriesobjectSelector: Selector against arbitrary cluster objects
Template: How to generate each PackageVariant
- Defines the spec for generated PackageVariants
- Supports CEL expressions for dynamic values (e.g.,
packageExpr,repoExpr) - Can customize labels, annotations, pipeline, injectors per target
PackageVariantSet Behavior
The PackageVariantSet controller:
- Evaluates target selectors to determine downstream repositories
- Creates a PackageVariant resource for each target
- Applies the template to customize each PackageVariant
- Manages the lifecycle of generated PackageVariants
- Updates PackageVariants when the PackageVariantSet changes
Key Points
- PackageVariant automates the upstream → downstream relationship between package revisions
- The controller creates and updates downstream PackageRevisions automatically
- Customizations (functions, injectors, context) are applied to downstream PackageRevisions
- PackageVariantSet creates multiple PackageVariants from a single definition
- Both resources use Kubernetes controller patterns for reconciliation
- Adoption and deletion policies control how existing PackageRevisions are handled on PackageVariant creation and deletion