Creating Packages
Create, push content to, render, and publish a package using the CRD-based architecture.
Before enabling the CRD-based architecture, ensure you have:
Packagerevisions reconciler):9447) for container-based KRM functionsFUNCTION_RUNNER_ADDRESS if you also want cached-binary execPorch supports a controller-based architecture where PackageRevisions are managed as native Kubernetes CRDs (API version porch.kpt.dev/v1alpha2). This replaces the synchronous aggregated API model with an asynchronous controller that reconciles desired state against Git in the background.
For now, this is an opt-in feature. You enable it by adding the Packagerevisions reconciler to the controllers deployment. The aggregated API and CRD-based architectures can coexist in the same cluster.
kubectl describe show exactly what is happening.The PackageRevision CRD (porch.kpt.dev/v1alpha2) must be installed in the cluster. If you deployed Porch using the standard manifests, the CRD is included. Verify it exists:
kubectl get crd packagerevisions.porch.kpt.dev
Expected output:
NAME CREATED AT
packagerevisions.porch.kpt.dev 2025-01-15T10:00:00Z
Add packagerevisions to the --reconcilers flag on the controllers deployment. If you are already running the repository controller, the flag becomes:
--reconcilers=repositories,packagerevisions
You can patch an existing deployment:
kubectl -n porch-system patch deployment porch-controllers \
--type='json' \
-p='[{"op": "replace", "path": "/spec/template/spec/containers/0/args", "value": ["--reconcilers=repositories,packagerevisions"]}]'
Repositories must be annotated to opt into CRD-based management. Without this annotation, the repository controller will not create v1alpha2 PackageRevision CRDs, and the API server will continue to handle the repository via the v1alpha1 path.
Add the annotation to each repository you want managed by the PR Controller:
kubectl annotate repository my-repo porch.kpt.dev/v1alpha2-migration=true
Or include it in the Repository manifest:
apiVersion: config.porch.kpt.dev/v1alpha1
kind: Repository
metadata:
name: my-repo
namespace: default
annotations:
porch.kpt.dev/v1alpha2-migration: "true"
spec:
type: git
git:
repo: https://github.com/example/my-repo.git
branch: main
Once annotated:
Check that the controllers pod restarted and the PR Controller is active:
kubectl -n porch-system logs deployment/porch-controllers | grep "packagerevisions"
You should see log lines indicating the reconciler has started:
"Starting workers" controller="packagerevisions" worker count=50
If you plan to use container-based KRM functions, confirm POD_EVALUATOR_ADDRESS is set on porch-controllers and WRAPPER_SERVER_IMAGE is set on porch-server. Function Runner is optional (exec fast path) and is not set on default controller manifests.
kubectl -n porch-system get deploy porch-controllers -o jsonpath='{.spec.template.spec.containers[0].env}' | grep -o 'POD_EVALUATOR_ADDRESS[^}]*'
kubectl -n porch-system get deploy porch-server -o jsonpath='{.spec.template.spec.containers[0].env}' | grep -o 'WRAPPER_SERVER_IMAGE[^}]*'
kubectl -n porch-system get pods -l app=function-runner
When you enable v1alpha2 migration on a repository, the repository controller discovers published, draft, and proposed packages:
Drafts and proposed packages are migrated only if their workspace names comply with Kubernetes DNS-1123 rules (lowercase alphanumeric + hyphens):
dev, prod-v1, staging-2, qa, reviewmy_workspace (underscore), MY-WS (uppercase), ws.env (dot)Invalid packages are skipped with informational logging. Important: Packages with invalid workspace names will not be migrated and will become unavailable in both v1alpha1 and v1alpha2 APIs once the migration annotation is enabled. To recover:
porchctl clone with a new workspace or manually creating a new revision)DeletionProposed is a lifecycle state for published packages marked for deletion (not a separate package discovery case). During migration, published packages retain their full lifecycle state. If a package was marked for deletion before migration, its DeletionProposed status is preserved and can be managed via v1alpha2 lifecycle transitions.
To roll back to v1alpha1 serving, remove the migration annotation:
kubectl annotate repository my-repo porch.kpt.dev/v1alpha2-migration- --overwrite
Or via kubectl patch:
kubectl patch repository my-repo --type merge -p '{"metadata":{"annotations":{"porch.kpt.dev/v1alpha2-migration":null}}}'
Orphaned v1alpha2 CRDs remain in etcd and can be cleaned up by deleting the repository (via ownerReference cascading).
Watch v1alpha2 CRD creation:
# List migrated PackageRevisions
kubectl get packagerevisions -l porch.kpt.dev/repository=my-repo -o wide
# Check for errors
kubectl logs -l app=porch-controller -c repository-controller --since=5m | grep -i "migration\|error"
# Check repository sync status
kubectl describe repository my-repo
Create, push content to, render, and publish a package using the CRD-based architecture.
What changes for users when moving from the aggregated API to the CRD-based architecture.
How Porch blocks deletion of a v1alpha2 PackageRevision that other packages depend on