Skip to content

*: use a Go binary for image mirroring#257

Open
stevekuznetsov wants to merge 1 commit into
Azure:mainfrom
stevekuznetsov:skuznets/image-mirror-go
Open

*: use a Go binary for image mirroring#257
stevekuznetsov wants to merge 1 commit into
Azure:mainfrom
stevekuznetsov:skuznets/image-mirror-go

Conversation

@stevekuznetsov

Copy link
Copy Markdown
Contributor

No description provided.

Copilot AI review requested due to automatic review settings June 24, 2026 16:23

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR introduces a new Go-based imagemirror tool (with subcommands to mirror images from a registry or from an OCI layout tar) and updates pipeline step resolution/schema to optionally use a native imagemirror binary instead of the existing on-demand shell script approach.

Changes:

  • Added a new tools/imagemirror Go module implementing from-registry and from-oci-layout mirroring flows (including ACR token exchange and optional Key Vault pull-secret auth).
  • Extended pipelines/types.ImageMirrorStep and the pipeline schema to support useNativeMirror, and added resolution logic to emit a direct imagemirror ... command.
  • Updated tests/fixtures and workspace configuration (go.work, sums) to include the new tool and validate the resolved native commands.

Reviewed changes

Copilot reviewed 13 out of 14 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
tools/imagemirror/go.mod New module definition and direct dependencies for the imagemirror tool.
tools/imagemirror/go.sum New module dependency checksums.
tools/imagemirror/command.go Defines the root cobra command and wires subcommands.
tools/imagemirror/fromregistry.go Implements mirroring from a source registry (supports anonymous, docker config, or KV pull-secret auth).
tools/imagemirror/fromocilayout.go Implements mirroring from a local OCI-layout tar using metadata-provided tags.
tools/imagemirror/acr.go Implements ARM→ACR token exchange with retry and minimal JWT expiry parsing.
pipelines/types/pipeline.schema.v1.json Adds useNativeMirror to the ImageMirror step schema.
pipelines/types/imagemirror.go Adds UseNativeMirror flag and resolves native vs script-based ShellStep commands.
pipelines/types/imagemirror_test.go Extends test cases to cover native mirroring resolution.
pipelines/types/testdata/zz_fixture_*.yaml New golden fixtures for native mirroring command resolution.
go.work Adds ./tools/imagemirror to the workspace.
go.work.sum Updates workspace sums for new dependencies.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread pipelines/types/imagemirror.go
Comment thread tools/imagemirror/acr.go
Comment thread tools/imagemirror/fromregistry.go
@stevekuznetsov stevekuznetsov force-pushed the skuznets/image-mirror-go branch 2 times, most recently from 4f9cc7a to 7f1061e Compare June 24, 2026 16:54
Copilot AI review requested due to automatic review settings June 24, 2026 16:54

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 13 out of 14 changed files in this pull request and generated 3 comments.

Comment on lines +156 to +172
case "oci-layout":
variables = []Variable{
namedVariable("TARGET_ACR", input.TargetACR),
namedVariable("REPOSITORY", input.Repository),
namedVariable("IMAGE_TAR", input.ImageTarFileName),
namedVariable("IMAGE_METADATA", input.ImageMetadataFileName),
}
parts := []string{
opts.ImageMirrorBinary, "from-oci-layout",
"--target-acr", "${TARGET_ACR}",
"--acr-suffix", opts.ACRSuffix,
"--repository", "${REPOSITORY}",
"--image-tar", "${IMAGE_TAR}",
"--image-metadata", "${IMAGE_METADATA}",
"--cloud", opts.Cloud,
}
command = strings.Join(parts, " ")
Comment on lines +316 to +319
vaultURI := fmt.Sprintf("https://%s.vault.azure.net", vaultName)
client, err := azsecrets.NewClient(vaultURI, cred, &azsecrets.ClientOptions{
ClientOptions: azcore.ClientOptions{Cloud: cloudConfig},
})
Comment on lines +352 to +375
var config dockerConfig
if err := json.Unmarshal(configData, &config); err != nil {
return fmt.Errorf("failed to unmarshal Docker auth config: %w", err)
}

for registry, entry := range config.Auths {
decoded, err := base64.StdEncoding.DecodeString(entry.Auth)
if err != nil {
return fmt.Errorf("failed to decode auth for registry %s: %w", registry, err)
}

parts := strings.SplitN(string(decoded), ":", 2)
if len(parts) != 2 {
return fmt.Errorf("invalid auth format for registry %s", registry)
}

cred := auth.Credential{
Username: parts[0],
Password: parts[1],
}
if err := store.Put(ctx, registry, cred); err != nil {
return fmt.Errorf("failed to store credential for registry %s: %w", registry, err)
}
}
@stevekuznetsov stevekuznetsov force-pushed the skuznets/image-mirror-go branch from 7f1061e to 7b2d60f Compare June 24, 2026 18:34
Signed-off-by: Steve Kuznetsov <stekuznetsov@microsoft.com>
Copilot AI review requested due to automatic review settings June 24, 2026 22:43
@stevekuznetsov stevekuznetsov force-pushed the skuznets/image-mirror-go branch from 7b2d60f to 9587d97 Compare June 24, 2026 22:43

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 13 out of 14 changed files in this pull request and generated 2 comments.

Comment on lines +155 to +173
switch input.CopyFrom {
case "oci-layout":
variables = []Variable{
namedVariable("TARGET_ACR", input.TargetACR),
namedVariable("REPOSITORY", input.Repository),
namedVariable("IMAGE_TAR", input.ImageTarFileName),
namedVariable("IMAGE_METADATA", input.ImageMetadataFileName),
}
parts := []string{
opts.ImageMirrorBinary, "from-oci-layout",
"--target-acr", "${TARGET_ACR}",
"--acr-suffix", opts.ACRSuffix,
"--repository", "${REPOSITORY}",
"--image-tar", "${IMAGE_TAR}",
"--image-metadata", "${IMAGE_METADATA}",
"--cloud", opts.Cloud,
}
command = strings.Join(parts, " ")
default:
Comment on lines +314 to +319
// fetchPullSecretFromKeyVault fetches a pull secret from Azure Key Vault and base64-decodes it.
func fetchPullSecretFromKeyVault(ctx context.Context, cred azcore.TokenCredential, cloudConfig cloud.Configuration, vaultName, secretName string) ([]byte, error) {
vaultURI := fmt.Sprintf("https://%s.vault.azure.net", vaultName)
client, err := azsecrets.NewClient(vaultURI, cred, &azsecrets.ClientOptions{
ClientOptions: azcore.ClientOptions{Cloud: cloudConfig},
})
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants