Tutorial Overview#
You will learn how to:
- Find a PackageRevision to clone
- Clone a PackageRevision to a different repository
- Modify the cloned PackageRevision
- Propose and approve the new revision
{{% alert title="Note" color="primary" %}}
Please note the tutorial assumes repositories are initialized with the "blueprints" and "deployments" names.
We recommended to use these for simpler copy pasting of commands otherwise replace these values with your repository names in the below commands.
{{% /alert %}}
Understanding Clone Operations#
Cloning creates a new PackageRevision based on an existing one and works across different repositories. The cloned PackageRevision maintains an upstream reference to its source, allowing it to receive updates.
When to Use Clone#
Use porchctl rpkg clone when:
- You need to import a package from a different repository (cross-repository operation)
- You want to maintain an upstream relationship for future updates
- You're importing blueprints from a central repository to deployment repositories
- You need to pull packages from external Git or OCI repositories
- You want to keep deployment packages synchronized with their upstream sources
- You're following the blueprint → deployment pattern
Do NOT use clone when:
- Source and target are in the same repository - use
porchctl rpkg copyinstead - You want a completely independent copy with no upstream link - use
porchctl rpkg copyinstead - You're just creating a new version within the same repository - use
porchctl rpkg copyinstead
{{% alert title="Note" color="primary" %}}
For same-repository operations without upstream relationships, see [Copying Package Revisions Guide]({{% relref "/docs/4_tutorials_and_how-tos/working_with_package_revisions/copying-packages.md" %}}).
{{% /alert %}}
Step 1: Find a PackageRevision to Clone#
First, list available PackageRevisions to find one to clone:
porchctl rpkg get --namespace default
Example output:
NAME PACKAGE WORKSPACENAME REVISION LATEST LIFECYCLE REPOSITORY
blueprints.nginx.main nginx main 5 true Published blueprints
blueprints.wordpress.v1 wordpress v1 3 true Published blueprints
deployments.my-app.v1 my-app v1 1 true Published deployments
What to look for:
- Published PackageRevisions from blueprint repositories are good candidates for cloning
- Note the full NAME (e.g.,
blueprints.nginx.main) - Check the REPOSITORY column to identify the source repository
Step 2: Clone the PackageRevision#
Clone an existing PackageRevision to a different repository:
porchctl rpkg clone \
blueprints.nginx.main \
my-nginx \
--namespace default \
--repository deployments \
--workspace v1
What this does:
- Creates a new PackageRevision based on
blueprints.nginx.main - Names the new PackageRevision
my-nginx(package name) - Places it in the
deploymentsrepository (different from source) - Uses
v1as the workspace name - Starts in
Draftlifecycle state - Maintains an upstream reference to
blueprints.nginx.main
Verify the clone was created:
porchctl rpkg get --namespace default --name my-nginx
Example output:
NAME PACKAGE WORKSPACENAME REVISION LATEST LIFECYCLE REPOSITORY
deployments.my-nginx.v1 my-nginx v1 0 false Draft deployments
Step 3: Modify the Cloned PackageRevision#
After cloning, you can modify the new PackageRevision. Pull it locally:
porchctl rpkg pull deployments.my-nginx.v1 ./my-nginx --namespace default
Make your changes:
vim ./my-nginx/Kptfile
For example, customize the namespace:
apiVersion: kpt.dev/v1
kind: Kptfile
metadata:
name: my-nginx
annotations:
config.kubernetes.io/local-config: "true"
info:
description: Nginx deployment for production
upstream:
type: git
git:
repo: blueprints
directory: nginx
ref: main
pipeline:
mutators:
- image: gcr.io/kpt-fn/set-namespace:v0.4.1
configMap:
namespace: production
Push the changes back:
porchctl rpkg push deployments.my-nginx.v1 ./my-nginx --namespace default
Step 4: Propose and Approve#
Once you're satisfied with the changes, propose the PackageRevision:
porchctl rpkg propose deployments.my-nginx.v1 --namespace default
Verify the state change:
porchctl rpkg get deployments.my-nginx.v1 --namespace default
Example output:
NAME PACKAGE WORKSPACENAME REVISION LATEST LIFECYCLE REPOSITORY
deployments.my-nginx.v1 my-nginx v1 0 false Proposed deployments
Approve to publish:
porchctl rpkg approve deployments.my-nginx.v1 --namespace default
Verify publication:
porchctl rpkg get deployments.my-nginx.v1 --namespace default
Example output:
NAME PACKAGE WORKSPACENAME REVISION LATEST LIFECYCLE REPOSITORY
deployments.my-nginx.v1 my-nginx v1 1 true Published deployments
{{% alert title="Note" color="primary" %}}
For complete details on the porchctl rpkg clone command options and flags, see the [Porch CLI Guide]({{% relref "/docs/7_cli_api/porchctl.md" %}}).
{{% /alert %}}
Common Use Cases#
Here are practical scenarios where cloning PackageRevisions is useful.
Importing from Blueprint Repository#
Clone a blueprint package to your deployment repository:
# Clone from blueprints to deployments
porchctl rpkg clone \
blueprints.base-app.main \
my-app \
--namespace default \
--repository deployments \
--workspace v1
# Customize and publish
porchctl rpkg pull deployments.my-app.v1 ./my-app --namespace default
# ... customize ...
porchctl rpkg push deployments.my-app.v1 ./my-app --namespace default
porchctl rpkg propose deployments.my-app.v1 --namespace default
porchctl rpkg approve deployments.my-app.v1 --namespace default
Cloning from External Git Repository#
Clone directly from a Git repository URL:
# Clone from external Git repo
porchctl rpkg clone \
https://github.com/example/blueprints.git \
external-app \
--namespace default \
--repository deployments \
--workspace v1 \
--ref main \
--directory packages/app
# Publish
porchctl rpkg propose deployments.external-app.v1 --namespace default
porchctl rpkg approve deployments.external-app.v1 --namespace default
Troubleshooting#
Common issues when cloning PackageRevisions and how to resolve them.
Clone fails with "repository not found"?
- Verify the target repository exists:
porchctl repo get --namespace default - Check the repository name is correct
- Ensure you have permission to write to the target repository
Clone fails with "source not found"?
- Verify the source PackageRevision exists:
porchctl rpkg get --namespace default - Check the exact name including repository, package, and workspace
- Ensure you have permission to read the source PackageRevision
Clone fails with "upstream revision may not be the placeholder package revision":
- Using the upstream package's placeholder PackageRevision as the upstream PackageRevision is not supported
- See [Core Concepts]({{% relref "/docs/2_concepts#core-concepts" %}}) for the rules which identify a placeholder PackageRevision
- Choose a different PackageRevision from the same package to use as the upstream PackageRevision
Clone fails with "workspace already exists"?
- The workspace name must be unique within the package in the target repository
- Choose a different workspace name:
--workspace v2or--workspace prod - List existing workspaces:
porchctl rpkg get --namespace default --name <package>
Cloned PackageRevision has unexpected content?
- The clone includes all resources from the source at the time of cloning
- Pull and inspect:
porchctl rpkg pull <name> ./dir --namespace default - Make corrections and push back
Need to clone within the same repository?
- Use
porchctl rpkg copyinstead ofclonefor same-repository operations - The
copycommand is simpler and doesn't maintain upstream references - See [Copying Package Revisions Guide]({{% relref "/docs/4_tutorials_and_how-tos/working_with_package_revisions/copying-packages.md" %}})
Key Concepts#
- Clone: Creates a new PackageRevision that can be in a different repository
- Upstream Reference: Cloned packages maintain a link to their source for updates
- Cross-repository: Clone works across different repositories, unlike copy
- Source Types: Can clone from Porch packages, Git URLs, or OCI repositories
- Workspace: Must be unique within the package in the target repository
- Blueprint Pattern: Common pattern is blueprints repository → deployment repositories