# vpctl artifact command

> Mirror Docker images, ORAS artifacts, and OCI Helm charts between registries.

Before you deploy, sync artifacts from the source registry (`artifactSync.sourceRepository`) to the target registry (`configuration.kubernetes.docker.repository`). Use one of these subcommands for the artifact type:

* `vpctl artifact sync images` — Docker container images (uses `docker pull`/`tag`/`push`)
* `vpctl artifact sync oras` — ORAS artifacts (registry-to-registry copy via `oras-go`)
* `vpctl artifact sync charts` — OCI Helm charts (registry-to-registry copy via `oras-go`; runs only when `deployment.helmChartMode: "remote"` is set in the manifest)

The manifest's `docker.namespace` is used to prefix image paths on the target registry when set.

## Preflight

Verify your Docker and ORAS credentials are working before you run a full sync:

```sh
vpctl artifact sync preflight
```

The command picks one Docker image, one ORAS artifact, and one Helm chart (when `helmChartMode: "remote"`) from the release and attempts to sync them. A successful run confirms pull/push credentials. On failure, the command prints troubleshooting hints, such as expired tokens or a missing `docker login`.

## Sync Docker images

1. Authenticate to both source and target registries before you sync:

   ```sh
   docker login <source-registry>
   docker login <target-registry>
   ```

2. Preview the commands that would be executed:

   ```sh
   vpctl artifact sync images --dry-run
   ```

3. Run the sync:

   ```sh
   vpctl artifact sync images
   ```

**Options:**

* `--dry-run`: Show commands without executing (default: false)
* `--target-registry`: Target registry URL (defaults to manifest value)
* `--extracted-release`: Path to extracted release (defaults to `./extracted-release`)
* `--name`: Filter to sync only images that match a name pattern
* `--cleanup`: Remove local images (`docker rmi`) after each push (default: false)
* `--skip-existing`: Skip images already present on the target registry (default: false)
* `--concurrency`: Set how many images sync in parallel. CLI flag default: `1` (sequential). If omitted, the manifest value `artifactSync.concurrency` applies. Manifest default: `5`.

Example for CI: skip existing, cleanup disk.

```sh
vpctl artifact sync images --skip-existing --cleanup
```

## Sync ORAS artifacts

ORAS artifact sync reads authentication from Docker's credential store (`~/.docker/config.json`) automatically. Run `docker login` for both source and target registries before you sync.

```sh
vpctl artifact sync oras --dry-run
```

This shows the `oras copy` commands that would be executed.

```sh
vpctl artifact sync oras
```

**Options:**

* `--dry-run`: Show commands without executing (default: false)
* `--target-registry`: Target registry URL (defaults to manifest value)
* `--extracted-release`: Path to extracted release (defaults to `./extracted-release`)
* `--name`: Filter to sync only ORAS artifacts matching a name pattern
* `--concurrency`: Number of artifacts to sync in parallel. CLI flag default: `1` (sequential). When the flag is omitted, the manifest value `artifactSync.concurrency` applies (manifest default: `5`).

## Sync OCI Helm charts

OCI Helm chart sync mirrors only the charts marked `type: "remote"` in `versions.yaml`. It runs only when the manifest sets `deployment.helmChartMode: "remote"`; if the mode is `"local"` (the default), the command exits without syncing anything. Authentication is read from Docker's credential store (`~/.docker/config.json`), so run `docker login` for both source and target registries before you sync.

```sh
vpctl artifact sync charts --dry-run
```

This shows the `oras copy` commands that would be executed.

```sh
vpctl artifact sync charts
```

**Options:**

* `--dry-run`: Show commands without executing (default: false)
* `--target-registry`: Target registry URL (defaults to manifest value)
* `--extracted-release`: Path to extracted release (defaults to `./extracted-release`)
* `--name`: Filter to sync only Helm charts matching a name pattern
* `--concurrency`: Number of charts to sync in parallel (default: `1`, sequential)

## Full sync example with ECR

```sh
# Authenticate to both registries (Docker prompts for the password)
aws ecr get-login-password --region us-east-1 | docker login --username AWS --password-stdin <account>.dkr.ecr.us-east-1.amazonaws.com
docker login -u <user> uccmpprivatecloud.azurecr.io

# Preflight: verify authentication works
vpctl artifact sync preflight

# Sync Docker images
vpctl artifact sync images --skip-existing --cleanup

# Sync ORAS artifacts (reads Docker credential store automatically)
vpctl artifact sync oras
```

In automated environments, pipe the password from a secret store with `--password-stdin` instead of passing `-p <password>` on the command line. The `-p` flag writes the password to your shell history and to the process list (visible to `ps aux`), and Docker prints `WARNING! Using --password via the CLI is insecure` when you use it.
