*: use a Go binary for image mirroring#257
Open
stevekuznetsov wants to merge 1 commit into
Open
Conversation
There was a problem hiding this comment.
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/imagemirrorGo module implementingfrom-registryandfrom-oci-layoutmirroring flows (including ACR token exchange and optional Key Vault pull-secret auth). - Extended
pipelines/types.ImageMirrorStepand the pipeline schema to supportuseNativeMirror, and added resolution logic to emit a directimagemirror ...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.
4f9cc7a to
7f1061e
Compare
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) | ||
| } | ||
| } |
7f1061e to
7b2d60f
Compare
Signed-off-by: Steve Kuznetsov <stekuznetsov@microsoft.com>
7b2d60f to
9587d97
Compare
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}, | ||
| }) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
No description provided.