shdctl release commands
Pull, generate, deploy, and uninstall shdctl release commands
Read time 12 minutesLast updated 2 days ago
Use the command group to manage the deployment lifecycle. Pull a release archive from the Unity registry, render Helm chart values from your manifest, deploy to your cluster or hand off to ArgoCD, and uninstall.
releasePull a release
Download a release from the registry. If you use a manifest file, the tool reads the version from the manifest automatically. By default, the release is extracted to .
./extracted-releaseshdctl release pull --clean-output
Parameters:
- : Directory to extract the archive to (default:
--extract-dir)./extracted-release - : Skip extracting the downloaded archive (default: extracts to
--skip-extract)./extracted-release - : Empty the extraction directory before extracting. Pass it whenever that directory already holds a release: without it, extraction stops at the first file that already exists (
--clean-output), after the archive has been savedfile already exists - : Release version to pull (optional, defaults to value from manifest)
--version - : Registry URL (default:
--registry). The manifest'succmpprivatecloud.azurecr.iois not read hereartifactSync.sourceRepository - : Output file path for the archive (default:
--outputin the working directory, kept after extraction)unity-private-cloud-shd-<version>.tar.gz
It authenticates with the credentials stored for that registry — refer to Configure registry credentials.
shdctl configureIt pulls , and falls back to , where releases up to 0.16.0 live, only when the version is not found there. A mirror you name with has to use the same repository paths.
<registry>/releases/shd-configuration:<version>releases/onprem-configuration--registryExample with manifest:
shdctl release pull --clean-output
Example without manifest, specify version:
shdctl release pull --version 2.0.0 --clean-output
Example with custom extraction directory:
shdctl release pull --extract-dir ./my-release --clean-output
Example skipping extraction:
shdctl release pull --skip-extract
Generate and deploy charts
Choose your deployment method: Helm or ArgoCD.
Whichever format you generate, values from the manifest's are merged into each chart's generated last, after every layer the release ships. Chart names there must be keys of the release's or its overlay, which the release merges; an unknown name fails the command before it writes anything, and the error lists the valid names. Refer to Per-chart Helm value overrides for the merge semantics and the caveats that come with them.
configuration.overridesvalues.yamlhelm_chartscommon/versions.yamlplatform/shd/versions.yamlGenerate Helm charts
shdctl release generate --clean-output
Parameters:
- : Empty the output directory before generating — everything in it, hidden files included, so point
--clean-outputat a directory that holds nothing else (cannot be combined with--output)--name - :
--formatadds the app-of-apps chart structure; omit it (or passargocd) for standard Helm charts. Any other value is accepted and treated ashelm, so check that a run meant for ArgoCD wrotehelmapp-of-apps-application.yaml - : Path to extracted release (defaults to
--extracted-release)./extracted-release - : Output directory (defaults to
--output)generated-charts - : Regenerate only the chart with exactly this name: its directory and the release's chart index are rewritten, and no other chart is. The output keeps describing the whole release, so
--nameandrelease deploystill see every chartrelease uninstall - : Skip shdctl version compatibility check against the release package
--skip-version-check
Example:
shdctl release generate --extracted-release ./extracted-release --output ./my-charts --clean-output
Deploy with Helm
Preview deployment (recommended):
shdctl release deploy --dry-run
The dry run prints the command for every chart, in the order the deploy runs them, and contacts nothing. Charts are grouped by wave, lowest first, and within a wave the largest generated chart comes first. Each group sits under a header naming the command that deploys that wave alone:
helm upgrade --install# Wave -3 (2 chart(s))# Deploy this wave with: shdctl release deploy --wave -3
If you're deploying Asset Manager for the first time, deploy the release in waves. Start with the lowest wave by passing the flag, for example , then validate the deployment before deploying the next wave. This ensures the release deploys in the correct order and all dependencies are satisfied.
--wave-3Execute deployment:
shdctl release deploy
Like , takes its chart list from the index writes (; a tree an earlier version generated, with , still deploys, with a warning). It refuses a directory without one, and a directory missing a chart the index lists — unless or narrows the run to charts that are present.
uninstalldeployrelease generatecharts-metadata.yamlvpctl-metadata.yaml--name--waveCommon options:
- : Show commands without executing
--dry-run - : Deployment format (
--formatorhelm; defaults toargocd)helm - : Directory containing charts (defaults to
--charts-dir)generated-charts - : Deploy only a specific wave (Helm format only). Waves deploy lowest first; in this release they run from
--waveto-3, and the dry run lists them2 - : Deploy only the chart with exactly this name
--name - : Wait for each Helm release to complete before moving on (default:
--wait; disable withtrue)--wait=false - : Timeout per Helm release when
--timeout(default:--wait=true; ignored when10m)--wait=false - : Number of additional attempts after a failed Helm command (default:
--retries). Useful for the CRD-not-yet-visible race that sometimes resolves on a second attempt.0 - : Delay between retry attempts (default:
--retry-delay; only meaningful when5s)--retries > 0 - : Update chart dependencies before deployment (default:
--dependency-update). In parallel mode (truegreater than--concurrency), the update runs as a separate1step for each chart instead of inline throughhelm dependency update --skip-refresh: refer to Parallel deployment.helm upgrade --dependency-update - : Additional Helm flags appended to every
--helm-flagscommand. The command line runs throughhelm upgrade --install, so shell quoting applies —sh -cpasses one value containing a space — and so do shell metacharacters. With Helm 4,--helm-flags "--set-string key='a b'"lets an upgrade take over fields another field manager last wrote — an earlier--helm-flags "--force-conflicts", say — instead of failing on the conflictkubectl apply - : Number of charts to deploy in parallel within a wave (default:
--concurrency, sequential; Helm format only). When you omit the flag, the manifest value1applies. Refer to Parallel deployment.deployment.helm.concurrency
Example deploying a specific wave:
shdctl release deploy --wave -3
Parallel deployment
Set (where is greater than ) to deploy the charts within the same wave in parallel. You can also set in the manifest to make it the default for your environment; the CLI flag takes precedence when both are set.
--concurrency NN1deployment.helm.concurrency- Charts within the same wave deploy concurrently through a bounded worker pool of size . Waves remain sequential: the next wave starts only after every chart in the current wave succeeds.
N - Within a wave, charts start largest first, by the size of their generated directory: the largest take the longest, and a wave lasts as long as its slowest chart.
- The per-chart calls run with
helm dependency update, and — when any Helm repositories are registered locally —--skip-refreshruns once at the start of the deployment instead. This avoids races between workers writing to the sharedhelm repo updateindex. A~/.cache/helm/repositoryprints the sequential plan, which shows neither step — and its--dry-runlines losehelm upgradetoo, so read it as a preview rather than a script to run.--dependency-update - Each chart's Helm output is buffered and printed as a single block when that chart finishes, for example , so the line ordering differs from sequential mode and there's no live progress for an in-flight chart.
==> [chart-name] done in 12.3s - A summary line at the end of every wave and at the end of the deployment reports the total, succeeded, and failed counts with the elapsed time, as in a sequential deployment: and
Wave 0 complete: 36 total, 36 succeeded, 0 failed (elapsed 4m12.318s). On failure, the error lists the failing chart names.Deploy complete: 59 total across 6 wave(s), 59 succeeded, 0 failed (elapsed 17m3.524s) - Parallel deployment applies to the Helm format only: with , any
--format argocdvalue greater than--concurrencyis rejected, because the ArgoCD path applies a single bootstrap1and does no per-chart Helm work.Application
Example deploying with four workers:
shdctl release deploy --format helm --concurrency 4
Manifest defaults for ArgoCD
You can define ArgoCD parameters in the manifest under so you don't need to pass them every time. CLI flags always take precedence over manifest values when both are provided.
deployment.argocd# manifest.yamldeployment: argocd: repoURL: "https://github.com/org/repo.git" pathPrefix: "shd/cluster1" destinationServer: "https://kubernetes.default.svc" targetRevision: "main"
When the tool reads a value from the manifest instead of a CLI flag, it prints a log message, for example, .
Using argocd-repo-url from manifest: ...Generate ArgoCD application
If you set in the manifest, you only need to pass flags you want to override:
deployment.argocdshdctl release generate --format argocd --clean-output
Or override specific values for each run:
shdctl release generate --format argocd --argocd-path-prefix <path-prefix> --argocd-target-revision <branch-or-tag> --clean-output
You can still pass all flags explicitly; they take precedence over the manifest:
shdctl release generate --format argocd --argocd-repo-url <your-git-repo-url> --argocd-destination "https://kubernetes.default.svc" --argocd-target-revision "main" --argocd-path-prefix <path-prefix> --clean-output
Parameters:
- : Generate ArgoCD format
--format argocd - : Git repository URL where charts are stored (required; can be set in manifest
--argocd-repo-url)deployment.argocd.repoURL - : Kubernetes server URL (required; can be set in manifest
--argocd-destination).deployment.argocd.destinationServerlists a default for the field, but it is not applied: generation fails when neither is setshdctl manifest schema - : Git branch or tag ArgoCD reads the charts from (default:
--argocd-target-revision; can be set in manifestmain)deployment.argocd.targetRevision - : The directory, relative to the repository root, that holds the generated charts (can be set in manifest
--argocd-path-prefix). Keep it non-empty: an empty prefix renders every child application's path asdeployment.argocd.pathPrefix, which ArgoCD rejects as absolute/<chart> - : Empty the output directory before generating (cannot be combined with
--clean-output)--name
This command creates an app-of-apps chart structure in the output directory. Before deploying, commit the output directory's contents to the repository at , on the branch: every application reads its chart and its from that path, so charts committed anywhere else leave the applications pointing at nothing.
--argocd-path-prefix--argocd-target-revisionvalues.yamlA full run writes one ArgoCD per chart your manifest enables and removes any other application file from the app-of-apps chart, so an application belonging to a chart that has left the release, or that your manifest disables, stops being part of the deployment's desired state — expect ArgoCD to delete it and its workloads on the next sync. A run regenerates that chart and rewrites the application files the same way, so the application set stays whole.
Application--name <chart>The top-level application carries no cascading-delete finalizer: deleting it leaves the child applications and their workloads running, and re-applying adopts them again. To remove a deployment, delete the top-level application first, then the child applications, whose own finalizers remove their workloads. The order matters: while the top-level application exists it syncs automatically with self-heal, so it recreates a deleted child from Git — after that child's workloads have already been removed.
asset-solutionsapp-of-apps-application.yamlkubectl -n <namespace> delete application asset-solutionskubectl -n <namespace> delete applications --all # the children, named after their charts; --all only if the namespace holds no other applications
Deploy ArgoCD application
Preview deployment (recommended):
shdctl release deploy --format argocd --dry-run
Execute deployment:
shdctl release deploy --format argocd
Common options:
- : Use ArgoCD deployment
--format argocd - : Preview kubectl command without executing
--dry-run - : Directory containing charts (defaults to
--charts-dir)generated-charts
This runs one of from into , so the kubeconfig needs , and on there, and nothing cluster-wide. and a above 1 are Helm-only and refused with this format.
kubectl applyapp-of-apps-application.yaml--charts-dirconfiguration.kubernetes.namespacegetcreatepatchapplications.argoproj.io--wave--concurrencyEvery application, the top-level one included, is created in that namespace and in ArgoCD's project, so ArgoCD must reconcile Applications there: install it in the deployment namespace, or configure it to watch that namespace (ArgoCD's "Applications in any namespace", which needs the namespace in both its setting and the project's ). An ArgoCD watching only its own namespace leaves them unsynced, with nothing reporting an error.
defaultapplication.namespacesdefaultsourceNamespacesUninstall a release
To remove a deployed release, use the uninstall command. The tool uninstalls charts in reverse wave order with the highest wave first to ensure dependencies are removed correctly.
It runs for what installed, and removes nothing else — so what Helm keeps stays: the CRDs charts ship in their directory, resources annotated , and the volumes StatefulSets claimed. An ArgoCD deployment has no Helm releases to remove — remove it through its applications instead, the top-level one first (refer to Generate ArgoCD application).
helm uninstallrelease deploy --format helmcrds/helm.sh/resource-policy: keepWhich charts are uninstalled comes from the release the directory was generated from, not from the directories present in it, so a partially generated directory is refused rather than treated as the whole release. Narrow the scope with or .
--charts-dir--name--wavePreview uninstall commands (recommended):
shdctl release uninstall --dry-run
Execute uninstall:
shdctl release uninstall
Common options:
- : Show commands without executing
--dry-run - : Directory containing charts (defaults to
--charts-dir)generated-charts - : Uninstall only charts in the specified wave (in this release, waves run from
--waveto-3)2 - : Uninstall only the chart with exactly this name
--name
A chart that fails to uninstall is logged as a warning and the command carries on with the rest, so it can exit 0 with releases still installed. Read its output, or check what is left with .
helm list -n <namespace>Example uninstalling a specific wave:
shdctl release uninstall --wave 0 --dry-run
Example uninstalling a specific chart:
shdctl release uninstall --name my-chart --dry-run
For every chart in the release, the uninstall command runs .
helm uninstall