+
+A collection of useful things you can do with `crane` is [here](recipes.md).
+
+## Installation
+
+### Install from Releases
+
+1. Get the [latest release](https://github.com/google/go-containerregistry/releases/latest) version.
+
+ ```sh
+ $ VERSION=$(curl -s "https://api.github.com/repos/google/go-containerregistry/releases/latest" | jq -r '.tag_name')
+ ```
+
+ or set a specific version:
+
+ ```sh
+ $ VERSION=vX.Y.Z # Version number with a leading v
+ ```
+
+1. Download the release.
+
+ ```sh
+ $ OS=Linux # or Darwin, Windows
+ $ ARCH=x86_64 # or arm64, x86_64, armv6, i386, s390x
+ $ curl -sL "https://github.com/google/go-containerregistry/releases/download/${VERSION}/go-containerregistry_${OS}_${ARCH}.tar.gz" > go-containerregistry.tar.gz
+ ```
+
+1. Verify the signature. We generate [SLSA 3 provenance](https://slsa.dev) using
+ the OpenSSF's [slsa-framework/slsa-github-generator](https://github.com/slsa-framework/slsa-github-generator).
+ To verify our release, install the verification tool from [slsa-framework/slsa-verifier#installation](https://github.com/slsa-framework/slsa-verifier#installation)
+ and verify as follows:
+
+ ```sh
+ $ curl -sL https://github.com/google/go-containerregistry/releases/download/${VERSION}/multiple.intoto.jsonl > provenance.intoto.jsonl
+ $ # NOTE: You may be using a different architecture.
+ $ slsa-verifier-linux-amd64 verify-artifact go-containerregistry.tar.gz --provenance-path provenance.intoto.jsonl --source-uri github.com/google/go-containerregistry --source-tag "${VERSION}"
+ PASSED: Verified SLSA provenance
+ ```
+
+1. Unpack it in the PATH.
+
+ ```sh
+ $ tar -zxvf go-containerregistry.tar.gz -C /usr/local/bin/ crane
+ ```
+
+### Install manually
+
+Install manually:
+
+```sh
+go install github.com/google/go-containerregistry/cmd/crane@latest
+```
+
+### Install via brew
+
+If you're macOS user and using [Homebrew](https://brew.sh/), you can install via brew command:
+
+```sh
+$ brew install crane
+```
+
+### Install on Arch Linux
+
+If you're an Arch Linux user you can install via pacman command:
+
+```sh
+$ pacman -S crane
+```
+
+### Setup on GitHub Actions
+
+You can use the [`setup-crane`](https://github.com/imjasonh/setup-crane) action
+to install `crane` and setup auth to [GitHub Container
+Registry](https://github.com/features/packages) in a GitHub Action workflow:
+
+```
+steps:
+- uses: imjasonh/setup-crane@v0.1
+```
+
+## Images
+
+You can also use crane as docker image
+
+```sh
+$ docker run --rm gcr.io/go-containerregistry/crane ls ubuntu
+10.04
+12.04.5
+12.04
+12.10
+```
+
+And it's also available with a shell, at the `:debug` tag:
+
+```sh
+docker run --rm -it --entrypoint "/busybox/sh" gcr.io/go-containerregistry/crane:debug
+```
+
+Tagged debug images are available at `gcr.io/go-containerregistry/crane/debug:[tag]`.
+
+### Using with GitLab
+
+```yaml
+# Tags an existing Docker image which was tagged with the short commit hash with the tag 'latest'
+docker-tag-latest:
+ stage: latest
+ only:
+ refs:
+ - main
+ image:
+ name: gcr.io/go-containerregistry/crane:debug
+ entrypoint: [""]
+ script:
+ - crane auth login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY
+ - crane tag $CI_REGISTRY_IMAGE:$CI_COMMIT_SHORT_SHA latest
+```
diff --git a/pkg/go-containerregistry/cmd/crane/cmd/append.go b/pkg/go-containerregistry/cmd/crane/cmd/append.go
new file mode 100644
index 00000000..79c0be23
--- /dev/null
+++ b/pkg/go-containerregistry/cmd/crane/cmd/append.go
@@ -0,0 +1,122 @@
+// Copyright 2018 Google LLC All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package cmd
+
+import (
+ "fmt"
+
+ "github.com/docker/model-runner/pkg/go-containerregistry/pkg/crane"
+ "github.com/docker/model-runner/pkg/go-containerregistry/pkg/logs"
+ "github.com/docker/model-runner/pkg/go-containerregistry/pkg/name"
+ v1 "github.com/docker/model-runner/pkg/go-containerregistry/pkg/v1"
+ "github.com/docker/model-runner/pkg/go-containerregistry/pkg/v1/empty"
+ "github.com/docker/model-runner/pkg/go-containerregistry/pkg/v1/mutate"
+ "github.com/docker/model-runner/pkg/go-containerregistry/pkg/v1/types"
+ specsv1 "github.com/opencontainers/image-spec/specs-go/v1"
+ "github.com/spf13/cobra"
+)
+
+// NewCmdAppend creates a new cobra.Command for the append subcommand.
+func NewCmdAppend(options *[]crane.Option) *cobra.Command {
+ var baseRef, newTag, outFile string
+ var newLayers []string
+ var annotate, ociEmptyBase bool
+
+ appendCmd := &cobra.Command{
+ Use: "append",
+ Short: "Append contents of a tarball to a remote image",
+ Long: `This sub-command pushes an image based on an (optional)
+base image, with appended layers containing the contents of the
+provided tarballs.
+
+If the base image is a Windows base image (i.e., its config.OS is "windows"),
+the contents of the tarballs will be modified to be suitable for a Windows
+container image.`,
+ Args: cobra.NoArgs,
+ RunE: func(cmd *cobra.Command, _ []string) error {
+ var base v1.Image
+ var err error
+
+ if baseRef == "" {
+ logs.Warn.Printf("base unspecified, using empty image")
+ base = empty.Image
+ if ociEmptyBase {
+ base = mutate.MediaType(base, types.OCIManifestSchema1)
+ base = mutate.ConfigMediaType(base, types.OCIConfigJSON)
+ }
+ } else {
+ base, err = crane.Pull(baseRef, *options...)
+ if err != nil {
+ return fmt.Errorf("pulling %s: %w", baseRef, err)
+ }
+ }
+
+ img, err := crane.Append(base, newLayers...)
+ if err != nil {
+ return fmt.Errorf("appending %v: %w", newLayers, err)
+ }
+
+ if baseRef != "" && annotate {
+ ref, err := name.ParseReference(baseRef)
+ if err != nil {
+ return fmt.Errorf("parsing ref %q: %w", baseRef, err)
+ }
+
+ baseDigest, err := base.Digest()
+ if err != nil {
+ return err
+ }
+ anns := map[string]string{
+ specsv1.AnnotationBaseImageDigest: baseDigest.String(),
+ }
+ if _, ok := ref.(name.Tag); ok {
+ anns[specsv1.AnnotationBaseImageName] = ref.Name()
+ }
+ img = mutate.Annotations(img, anns).(v1.Image)
+ }
+
+ if outFile != "" {
+ if err := crane.Save(img, newTag, outFile); err != nil {
+ return fmt.Errorf("writing output %q: %w", outFile, err)
+ }
+ } else {
+ if err := crane.Push(img, newTag, *options...); err != nil {
+ return fmt.Errorf("pushing image %s: %w", newTag, err)
+ }
+ ref, err := name.ParseReference(newTag)
+ if err != nil {
+ return fmt.Errorf("parsing reference %s: %w", newTag, err)
+ }
+ d, err := img.Digest()
+ if err != nil {
+ return fmt.Errorf("digest: %w", err)
+ }
+ fmt.Fprintln(cmd.OutOrStdout(), ref.Context().Digest(d.String()))
+ }
+ return nil
+ },
+ }
+ appendCmd.Flags().StringVarP(&baseRef, "base", "b", "", "Name of base image to append to")
+ appendCmd.Flags().StringVarP(&newTag, "new_tag", "t", "", "Tag to apply to resulting image")
+ appendCmd.Flags().StringSliceVarP(&newLayers, "new_layer", "f", []string{}, "Path to tarball to append to image")
+ appendCmd.Flags().StringVarP(&outFile, "output", "o", "", "Path to new tarball of resulting image")
+ appendCmd.Flags().BoolVar(&annotate, "set-base-image-annotations", false, "If true, annotate the resulting image as being based on the base image")
+ appendCmd.Flags().BoolVar(&ociEmptyBase, "oci-empty-base", false, "If true, empty base image will have OCI media types instead of Docker")
+
+ appendCmd.MarkFlagsMutuallyExclusive("oci-empty-base", "base")
+ appendCmd.MarkFlagRequired("new_tag")
+ appendCmd.MarkFlagRequired("new_layer")
+ return appendCmd
+}
diff --git a/pkg/go-containerregistry/cmd/crane/cmd/auth.go b/pkg/go-containerregistry/cmd/crane/cmd/auth.go
new file mode 100644
index 00000000..262a31ea
--- /dev/null
+++ b/pkg/go-containerregistry/cmd/crane/cmd/auth.go
@@ -0,0 +1,315 @@
+// Copyright 2020 Google LLC All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package cmd
+
+import (
+ "encoding/json"
+ "errors"
+ "fmt"
+ "io"
+ "log"
+ "os"
+ "strings"
+
+ "github.com/docker/cli/cli/config"
+ "github.com/docker/cli/cli/config/types"
+ "github.com/docker/model-runner/pkg/go-containerregistry/pkg/authn"
+ "github.com/docker/model-runner/pkg/go-containerregistry/pkg/crane"
+ "github.com/docker/model-runner/pkg/go-containerregistry/pkg/name"
+ "github.com/docker/model-runner/pkg/go-containerregistry/pkg/v1/remote/transport"
+ "github.com/spf13/cobra"
+)
+
+// NewCmdAuth creates a new cobra.Command for the auth subcommand.
+func NewCmdAuth(options []crane.Option, argv ...string) *cobra.Command {
+ cmd := &cobra.Command{
+ Use: "auth",
+ Short: "Log in or access credentials",
+ Args: cobra.NoArgs,
+ RunE: func(cmd *cobra.Command, _ []string) error { return cmd.Usage() },
+ }
+ cmd.AddCommand(NewCmdAuthGet(options, argv...), NewCmdAuthLogin(argv...), NewCmdAuthLogout(argv...), NewCmdAuthToken(options))
+ return cmd
+}
+
+func NewCmdAuthToken(options []crane.Option) *cobra.Command {
+ var (
+ header bool
+ push bool
+ mounts []string
+ )
+ cmd := &cobra.Command{
+ Use: "token REPO",
+ Short: "Retrieves a token for a remote repo",
+ Example: `# If you wanted to mount a blob from debian to ubuntu.
+$ curl -H "$(crane auth token -H --push --mount debian ubuntu)" ...
+
+# To get the raw list tags response
+$ curl -H "$(crane auth token -H ubuntu)" https://index.docker.io/v2/library/ubuntu/tags/list
+`,
+ Args: cobra.ExactArgs(1),
+ RunE: func(cmd *cobra.Command, args []string) error {
+ repo, err := name.NewRepository(args[0])
+ if err != nil {
+ return err
+ }
+ o := crane.GetOptions(options...)
+
+ t := transport.NewLogger(o.Transport)
+ pr, err := transport.Ping(cmd.Context(), repo.Registry, t)
+ if err != nil {
+ return err
+ }
+
+ auth, err := authn.Resolve(cmd.Context(), o.Keychain, repo)
+ if err != nil {
+ return err
+ }
+
+ scopes := []string{repo.Scope(transport.PullScope)}
+ if push {
+ scopes[0] = repo.Scope(transport.PushScope)
+ }
+
+ for _, m := range mounts {
+ mr, err := name.NewRepository(m)
+ if err != nil {
+ return err
+ }
+ scopes = append(scopes, mr.Scope(transport.PullScope))
+ }
+
+ tr, err := transport.Exchange(cmd.Context(), repo.Registry, auth, t, scopes, pr)
+ if err != nil {
+ return err
+ }
+
+ if header {
+ fmt.Fprintf(cmd.OutOrStdout(), "Authorization: Bearer %s", tr.Token)
+ return nil
+ }
+
+ if err := json.NewEncoder(os.Stdout).Encode(tr); err != nil {
+ return err
+ }
+
+ return nil
+ },
+ }
+ cmd.Flags().StringSliceVarP(&mounts, "mount", "m", []string{}, "Scopes to mount from")
+ cmd.Flags().BoolVarP(&header, "header", "H", false, "Output in header format")
+ cmd.Flags().BoolVar(&push, "push", false, "Request push scopes")
+ return cmd
+}
+
+type credentials struct {
+ Username string
+ Secret string
+}
+
+// https://github.com/docker/cli/blob/2291f610ae73533e6e0749d4ef1e360149b1e46b/cli/config/credentials/native_store.go#L100-L109
+func toCreds(config *authn.AuthConfig) credentials {
+ creds := credentials{
+ Username: config.Username,
+ Secret: config.Password,
+ }
+
+ if config.IdentityToken != "" {
+ creds.Username = "
+
+This tool implements a superset of the [`crane`](../crane/README.md) commands, with
+additional commands that are specific to [gcr.io](https://gcr.io).
+
+Note that this relies on some implementation details of GCR that are not
+consistent with the [registry spec](https://docs.docker.com/registry/spec/api/),
+so this may break in the future.
+
+## Installation
+
+Download [latest release](https://github.com/google/go-containerregistry/releases/latest).
+
+Install manually:
+
+```
+go install github.com/google/go-containerregistry/cmd/gcrane@latest
+```
+
+## Commands
+
+### ls
+
+`gcrane ls` exposes a more complex form of `ls` than `crane`, which allows for
+listing tags, manifests, and sub-repositories.
+
+### cp
+
+`gcrane cp` supports a `-r` flag that copies images recursively, which is useful
+for backing up images, georeplicating images, or renaming images en masse.
+
+### gc
+
+`gcrane gc` will calculate images that can be garbage-collected.
+By default, it will print any images that do not have tags pointing to them.
+
+This can be composed with `gcrane delete` to actually garbage collect them:
+```shell
+gcrane gc gcr.io/${PROJECT_ID}/repo | xargs -n1 gcrane delete
+```
+
+## Images
+
+You can also use gcrane as docker image
+
+```sh
+$ docker run --rm gcr.io/go-containerregistry/gcrane ls gcr.io/google-containers/busybox
+gcr.io/google-containers/busybox@sha256:4bdd623e848417d96127e16037743f0cd8b528c026e9175e22a84f639eca58ff
+gcr.io/google-containers/busybox:1.24
+gcr.io/google-containers/busybox@sha256:545e6a6310a27636260920bc07b994a299b6708a1b26910cfefd335fdfb60d2b
+gcr.io/google-containers/busybox:1.27
+gcr.io/google-containers/busybox:1.27.2
+gcr.io/google-containers/busybox@sha256:d8d3bc2c183ed2f9f10e7258f84971202325ee6011ba137112e01e30f206de67
+gcr.io/google-containers/busybox:latest
+```
+
+And it's also available with a shell, at the `:debug` tag:
+
+```sh
+docker run --rm -it --entrypoint "/busybox/sh" gcr.io/go-containerregistry/gcrane:debug
+```
+
+Tagged debug images are available at `gcr.io/go-containerregistry/gcrane/debug:[tag]`.
diff --git a/pkg/go-containerregistry/cmd/gcrane/cmd/copy.go b/pkg/go-containerregistry/cmd/gcrane/cmd/copy.go
new file mode 100644
index 00000000..022cbbc5
--- /dev/null
+++ b/pkg/go-containerregistry/cmd/gcrane/cmd/copy.go
@@ -0,0 +1,47 @@
+// Copyright 2019 Google LLC All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package cmd
+
+import (
+ "runtime"
+
+ "github.com/docker/model-runner/pkg/go-containerregistry/pkg/gcrane"
+ "github.com/spf13/cobra"
+)
+
+// NewCmdCopy creates a new cobra.Command for the copy subcommand.
+func NewCmdCopy() *cobra.Command {
+ recursive := false
+ jobs := 1
+ cmd := &cobra.Command{
+ Use: "copy SRC DST",
+ Aliases: []string{"cp"},
+ Short: "Efficiently copy a remote image from src to dst",
+ Args: cobra.ExactArgs(2),
+ RunE: func(cc *cobra.Command, args []string) error {
+ src, dst := args[0], args[1]
+ ctx := cc.Context()
+ if recursive {
+ return gcrane.CopyRepository(ctx, src, dst, gcrane.WithJobs(jobs), gcrane.WithUserAgent(userAgent()), gcrane.WithContext(ctx))
+ }
+ return gcrane.Copy(src, dst, gcrane.WithUserAgent(userAgent()), gcrane.WithContext(ctx))
+ },
+ }
+
+ cmd.Flags().BoolVarP(&recursive, "recursive", "r", false, "Whether to recurse through repos")
+ cmd.Flags().IntVarP(&jobs, "jobs", "j", runtime.GOMAXPROCS(0), "The maximum number of concurrent copies")
+
+ return cmd
+}
diff --git a/pkg/go-containerregistry/cmd/gcrane/cmd/gc.go b/pkg/go-containerregistry/cmd/gcrane/cmd/gc.go
new file mode 100644
index 00000000..545bf7c7
--- /dev/null
+++ b/pkg/go-containerregistry/cmd/gcrane/cmd/gc.go
@@ -0,0 +1,76 @@
+// Copyright 2018 Google LLC All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package cmd
+
+import (
+ "context"
+ "fmt"
+
+ "github.com/docker/model-runner/pkg/go-containerregistry/pkg/gcrane"
+ "github.com/docker/model-runner/pkg/go-containerregistry/pkg/name"
+ "github.com/docker/model-runner/pkg/go-containerregistry/pkg/v1/google"
+ "github.com/spf13/cobra"
+)
+
+// NewCmdGc creates a new cobra.Command for the gc subcommand.
+func NewCmdGc() *cobra.Command {
+ recursive := false
+ cmd := &cobra.Command{
+ Use: "gc",
+ Short: "List images that are not tagged",
+ Args: cobra.ExactArgs(1),
+ RunE: func(cc *cobra.Command, args []string) error {
+ return gc(cc.Context(), args[0], recursive)
+ },
+ }
+
+ cmd.Flags().BoolVarP(&recursive, "recursive", "r", false, "Whether to recurse through repos")
+
+ return cmd
+}
+
+func gc(ctx context.Context, root string, recursive bool) error {
+ repo, err := name.NewRepository(root)
+ if err != nil {
+ return err
+ }
+
+ opts := []google.Option{
+ google.WithAuthFromKeychain(gcrane.Keychain),
+ google.WithUserAgent(userAgent()),
+ google.WithContext(ctx),
+ }
+
+ if recursive {
+ return google.Walk(repo, printUntaggedImages, opts...)
+ }
+
+ tags, err := google.List(repo, opts...)
+ return printUntaggedImages(repo, tags, err)
+}
+
+func printUntaggedImages(repo name.Repository, tags *google.Tags, err error) error {
+ if err != nil {
+ return err
+ }
+
+ for digest, manifest := range tags.Manifests {
+ if len(manifest.Tags) == 0 {
+ fmt.Printf("%s@%s\n", repo, digest)
+ }
+ }
+
+ return nil
+}
diff --git a/pkg/go-containerregistry/cmd/gcrane/cmd/list.go b/pkg/go-containerregistry/cmd/gcrane/cmd/list.go
new file mode 100644
index 00000000..f1d749e2
--- /dev/null
+++ b/pkg/go-containerregistry/cmd/gcrane/cmd/list.go
@@ -0,0 +1,121 @@
+// Copyright 2018 Google LLC All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package cmd
+
+import (
+ "context"
+ "encoding/json"
+ "fmt"
+ "path"
+
+ "github.com/docker/model-runner/pkg/go-containerregistry/cmd/crane/cmd"
+ "github.com/docker/model-runner/pkg/go-containerregistry/pkg/gcrane"
+ "github.com/docker/model-runner/pkg/go-containerregistry/pkg/name"
+ "github.com/docker/model-runner/pkg/go-containerregistry/pkg/v1/google"
+ "github.com/spf13/cobra"
+)
+
+func userAgent() string {
+ if cmd.Version != "" {
+ return path.Join("gcrane", cmd.Version)
+ }
+
+ return "gcrane"
+}
+
+// NewCmdList creates a new cobra.Command for the ls subcommand.
+func NewCmdList() *cobra.Command {
+ recursive := false
+ json := false
+ cmd := &cobra.Command{
+ Use: "ls REPO",
+ Short: "List the contents of a repo",
+ Args: cobra.ExactArgs(1),
+ RunE: func(cc *cobra.Command, args []string) error {
+ return ls(cc.Context(), args[0], recursive, json)
+ },
+ }
+
+ cmd.Flags().BoolVarP(&recursive, "recursive", "r", false, "Whether to recurse through repos")
+ cmd.Flags().BoolVar(&json, "json", false, "Format the response from the registry as JSON, one line per repo")
+
+ return cmd
+}
+
+func ls(ctx context.Context, root string, recursive, j bool) error {
+ repo, err := name.NewRepository(root)
+ if err != nil {
+ return err
+ }
+
+ opts := []google.Option{
+ google.WithAuthFromKeychain(gcrane.Keychain),
+ google.WithUserAgent(userAgent()),
+ google.WithContext(ctx),
+ }
+
+ if recursive {
+ return google.Walk(repo, printImages(j), opts...)
+ }
+
+ tags, err := google.List(repo, opts...)
+ if err != nil {
+ return err
+ }
+
+ if !j {
+ if len(tags.Manifests) == 0 && len(tags.Children) == 0 {
+ // If we didn't see any GCR extensions, just list the tags like normal.
+ for _, tag := range tags.Tags {
+ fmt.Printf("%s:%s\n", repo, tag)
+ }
+ return nil
+ }
+
+ // Since we're not recursing, print the subdirectories too.
+ for _, child := range tags.Children {
+ fmt.Printf("%s/%s\n", repo, child)
+ }
+ }
+
+ return printImages(j)(repo, tags, err)
+}
+
+func printImages(j bool) google.WalkFunc {
+ return func(repo name.Repository, tags *google.Tags, err error) error {
+ if err != nil {
+ return err
+ }
+
+ if j {
+ b, err := json.Marshal(tags)
+ if err != nil {
+ return err
+ }
+ fmt.Printf("%s\n", b)
+ return nil
+ }
+
+ for digest, manifest := range tags.Manifests {
+ fmt.Printf("%s@%s\n", repo, digest)
+
+ for _, tag := range manifest.Tags {
+ fmt.Printf("%s:%s\n", repo, tag)
+ }
+ }
+
+ return nil
+ }
+}
diff --git a/pkg/go-containerregistry/cmd/gcrane/depcheck_test.go b/pkg/go-containerregistry/cmd/gcrane/depcheck_test.go
new file mode 100644
index 00000000..ac0744d0
--- /dev/null
+++ b/pkg/go-containerregistry/cmd/gcrane/depcheck_test.go
@@ -0,0 +1,32 @@
+// Copyright 2021 Google LLC All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package main
+
+import (
+ "testing"
+
+ "github.com/docker/model-runner/pkg/go-containerregistry/internal/depcheck"
+)
+
+func TestDeps(t *testing.T) {
+ if testing.Short() {
+ t.Skip("skipping slow depcheck")
+ }
+ depcheck.AssertNoDependency(t, map[string][]string{
+ "github.com/docker/model-runner/pkg/go-containerregistry/cmd/gcrane": {
+ "github.com/docker/model-runner/pkg/go-containerregistry/pkg/v1/daemon",
+ },
+ })
+}
diff --git a/pkg/go-containerregistry/cmd/gcrane/main.go b/pkg/go-containerregistry/cmd/gcrane/main.go
new file mode 100644
index 00000000..612d2adb
--- /dev/null
+++ b/pkg/go-containerregistry/cmd/gcrane/main.go
@@ -0,0 +1,72 @@
+// Copyright 2018 Google LLC All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package main
+
+import (
+ "context"
+ "os"
+ "os/signal"
+
+ "github.com/docker/model-runner/pkg/go-containerregistry/cmd/crane/cmd"
+ gcmd "github.com/docker/model-runner/pkg/go-containerregistry/cmd/gcrane/cmd"
+ "github.com/docker/model-runner/pkg/go-containerregistry/pkg/crane"
+ "github.com/docker/model-runner/pkg/go-containerregistry/pkg/gcrane"
+ "github.com/docker/model-runner/pkg/go-containerregistry/pkg/logs"
+ "github.com/spf13/cobra"
+)
+
+func init() {
+ logs.Warn.SetOutput(os.Stderr)
+ logs.Progress.SetOutput(os.Stderr)
+}
+
+const (
+ use = "gcrane"
+ short = "gcrane is a tool for managing container images on gcr.io and pkg.dev"
+)
+
+func main() {
+ options := []crane.Option{crane.WithAuthFromKeychain(gcrane.Keychain)}
+ // Same as crane, but override usage and keychain.
+ root := cmd.New(use, short, options)
+
+ // Add or override commands.
+ gcraneCmds := []*cobra.Command{gcmd.NewCmdList(), gcmd.NewCmdGc(), gcmd.NewCmdCopy(), cmd.NewCmdAuth(options, "gcrane", "auth")}
+
+ // Maintain a map of google-specific commands that we "override".
+ used := make(map[string]bool)
+ for _, cmd := range gcraneCmds {
+ used[cmd.Use] = true
+ }
+
+ // Remove those from crane's set of commands.
+ for _, cmd := range root.Commands() {
+ if _, ok := used[cmd.Use]; ok {
+ root.RemoveCommand(cmd)
+ }
+ }
+
+ // Add our own.
+ for _, cmd := range gcraneCmds {
+ root.AddCommand(cmd)
+ }
+
+ ctx, cancel := signal.NotifyContext(context.Background(), os.Interrupt)
+ defer cancel()
+ if err := root.ExecuteContext(ctx); err != nil {
+ cancel()
+ os.Exit(1)
+ }
+}
diff --git a/pkg/go-containerregistry/cmd/ko/README.md b/pkg/go-containerregistry/cmd/ko/README.md
new file mode 100644
index 00000000..7f3627ed
--- /dev/null
+++ b/pkg/go-containerregistry/cmd/ko/README.md
@@ -0,0 +1,3 @@
+# `ko` has moved
+
+Please find `ko` at its new home, https://github.com/google/ko
diff --git a/pkg/go-containerregistry/cmd/krane/README.md b/pkg/go-containerregistry/cmd/krane/README.md
new file mode 100644
index 00000000..2f21e004
--- /dev/null
+++ b/pkg/go-containerregistry/cmd/krane/README.md
@@ -0,0 +1,15 @@
+# `krane`
+
+
+
+This tool is a variant of the [`crane`](../crane/README.md) command, but builds in
+support for authenticating against registries using common credential helpers
+that find credentials from the environment.
+
+In particular this tool supports authenticating with common "workload identity"
+mechanisms on platforms such as GKE and EKS.
+
+This additional keychain logic only kicks in if alternative authentication
+mechanisms have NOT been configured and `crane` would otherwise perform the
+command without credentials, so **it is a drop-in replacement for `crane` that
+adds support for authenticating with cloud workload identity mechanisms**.
diff --git a/pkg/go-containerregistry/cmd/krane/go.mod b/pkg/go-containerregistry/cmd/krane/go.mod
new file mode 100644
index 00000000..9536971f
--- /dev/null
+++ b/pkg/go-containerregistry/cmd/krane/go.mod
@@ -0,0 +1,61 @@
+module github.com/google/go-containerregistry/cmd/krane
+
+go 1.24.0
+
+replace github.com/google/go-containerregistry => ../../
+
+require (
+ github.com/awslabs/amazon-ecr-credential-helper/ecr-login v0.11.0
+ github.com/chrismellard/docker-credential-acr-env v0.0.0-20230304212654-82a0ddb27589
+ github.com/google/go-containerregistry v0.20.3
+)
+
+require (
+ cloud.google.com/go/compute/metadata v0.7.0 // indirect
+ github.com/Azure/azure-sdk-for-go v68.0.0+incompatible // indirect
+ github.com/Azure/go-autorest v14.2.0+incompatible // indirect
+ github.com/Azure/go-autorest/autorest v0.11.30 // indirect
+ github.com/Azure/go-autorest/autorest/adal v0.9.24 // indirect
+ github.com/Azure/go-autorest/autorest/azure/auth v0.5.13 // indirect
+ github.com/Azure/go-autorest/autorest/azure/cli v0.4.7 // indirect
+ github.com/Azure/go-autorest/autorest/date v0.3.1 // indirect
+ github.com/Azure/go-autorest/logger v0.2.2 // indirect
+ github.com/Azure/go-autorest/tracing v0.6.1 // indirect
+ github.com/aws/aws-sdk-go-v2 v1.39.6 // indirect
+ github.com/aws/aws-sdk-go-v2/config v1.31.17 // indirect
+ github.com/aws/aws-sdk-go-v2/credentials v1.18.21 // indirect
+ github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.18.13 // indirect
+ github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.13 // indirect
+ github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.13 // indirect
+ github.com/aws/aws-sdk-go-v2/internal/ini v1.8.4 // indirect
+ github.com/aws/aws-sdk-go-v2/service/ecr v1.51.2 // indirect
+ github.com/aws/aws-sdk-go-v2/service/ecrpublic v1.38.2 // indirect
+ github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.13.3 // indirect
+ github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.13.13 // indirect
+ github.com/aws/aws-sdk-go-v2/service/sso v1.30.1 // indirect
+ github.com/aws/aws-sdk-go-v2/service/ssooidc v1.35.5 // indirect
+ github.com/aws/aws-sdk-go-v2/service/sts v1.39.1 // indirect
+ github.com/aws/smithy-go v1.23.2 // indirect
+ github.com/containerd/stargz-snapshotter/estargz v0.16.3 // indirect
+ github.com/dimchansky/utfbom v1.1.1 // indirect
+ github.com/docker/cli v28.2.2+incompatible // indirect
+ github.com/docker/distribution v2.8.3+incompatible // indirect
+ github.com/docker/docker-credential-helpers v0.9.4 // indirect
+ github.com/golang-jwt/jwt/v4 v4.5.2 // indirect
+ github.com/google/go-cmp v0.7.0 // indirect
+ github.com/inconshreveable/mousetrap v1.1.0 // indirect
+ github.com/klauspost/compress v1.18.0 // indirect
+ github.com/mitchellh/go-homedir v1.1.0 // indirect
+ github.com/opencontainers/go-digest v1.0.0 // indirect
+ github.com/opencontainers/image-spec v1.1.1 // indirect
+ github.com/pkg/errors v0.9.1 // indirect
+ github.com/sirupsen/logrus v1.9.3 // indirect
+ github.com/spf13/cobra v1.9.1 // indirect
+ github.com/spf13/pflag v1.0.6 // indirect
+ github.com/vbatts/tar-split v0.12.1 // indirect
+ golang.org/x/crypto v0.38.0 // indirect
+ golang.org/x/oauth2 v0.30.0 // indirect
+ golang.org/x/sync v0.15.0 // indirect
+ golang.org/x/sys v0.33.0 // indirect
+ gotest.tools/v3 v3.1.0 // indirect
+)
diff --git a/pkg/go-containerregistry/cmd/krane/go.sum b/pkg/go-containerregistry/cmd/krane/go.sum
new file mode 100644
index 00000000..5cbaf936
--- /dev/null
+++ b/pkg/go-containerregistry/cmd/krane/go.sum
@@ -0,0 +1,194 @@
+cloud.google.com/go/compute/metadata v0.7.0 h1:PBWF+iiAerVNe8UCHxdOt6eHLVc3ydFeOCw78U8ytSU=
+cloud.google.com/go/compute/metadata v0.7.0/go.mod h1:j5MvL9PprKL39t166CoB1uVHfQMs4tFQZZcKwksXUjo=
+github.com/Azure/azure-sdk-for-go v68.0.0+incompatible h1:fcYLmCpyNYRnvJbPerq7U0hS+6+I79yEDJBqVNcqUzU=
+github.com/Azure/azure-sdk-for-go v68.0.0+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc=
+github.com/Azure/go-autorest v14.2.0+incompatible h1:V5VMDjClD3GiElqLWO7mz2MxNAK/vTfRHdAubSIPRgs=
+github.com/Azure/go-autorest v14.2.0+incompatible/go.mod h1:r+4oMnoxhatjLLJ6zxSWATqVooLgysK6ZNox3g/xq24=
+github.com/Azure/go-autorest/autorest v0.11.28/go.mod h1:MrkzG3Y3AH668QyF9KRk5neJnGgmhQ6krbhR8Q5eMvA=
+github.com/Azure/go-autorest/autorest v0.11.30 h1:iaZ1RGz/ALZtN5eq4Nr1SOFSlf2E4pDI3Tcsl+dZPVE=
+github.com/Azure/go-autorest/autorest v0.11.30/go.mod h1:t1kpPIOpIVX7annvothKvb0stsrXa37i7b+xpmBW8Fs=
+github.com/Azure/go-autorest/autorest/adal v0.9.18/go.mod h1:XVVeme+LZwABT8K5Lc3hA4nAe8LDBVle26gTrguhhPQ=
+github.com/Azure/go-autorest/autorest/adal v0.9.22/go.mod h1:XuAbAEUv2Tta//+voMI038TrJBqjKam0me7qR+L8Cmk=
+github.com/Azure/go-autorest/autorest/adal v0.9.24 h1:BHZfgGsGwdkHDyZdtQRQk1WeUdW0m2WPAwuHZwUi5i4=
+github.com/Azure/go-autorest/autorest/adal v0.9.24/go.mod h1:7T1+g0PYFmACYW5LlG2fcoPiPlFHjClyRGL7dRlP5c8=
+github.com/Azure/go-autorest/autorest/azure/auth v0.5.13 h1:Ov8avRZi2vmrE2JcXw+tu5K/yB41r7xK9GZDiBF7NdM=
+github.com/Azure/go-autorest/autorest/azure/auth v0.5.13/go.mod h1:5BAVfWLWXihP47vYrPuBKKf4cS0bXI+KM9Qx6ETDJYo=
+github.com/Azure/go-autorest/autorest/azure/cli v0.4.6/go.mod h1:piCfgPho7BiIDdEQ1+g4VmKyD5y+p/XtSNqE6Hc4QD0=
+github.com/Azure/go-autorest/autorest/azure/cli v0.4.7 h1:Q9R3utmFg9K1B4OYtAZ7ZUUvIUdzQt7G2MN5Hi/d670=
+github.com/Azure/go-autorest/autorest/azure/cli v0.4.7/go.mod h1:bVrAueELJ0CKLBpUHDIvD516TwmHmzqwCpvONWRsw3s=
+github.com/Azure/go-autorest/autorest/date v0.3.0/go.mod h1:BI0uouVdmngYNUzGWeSYnokU+TrmwEsOqdt8Y6sso74=
+github.com/Azure/go-autorest/autorest/date v0.3.1 h1:o9Z8Jyt+VJJTCZ/UORishuHOusBwolhjokt9s5k8I4w=
+github.com/Azure/go-autorest/autorest/date v0.3.1/go.mod h1:Dz/RDmXlfiFFS/eW+b/xMUSFs1tboPVy6UjgADToWDM=
+github.com/Azure/go-autorest/autorest/mocks v0.4.1/go.mod h1:LTp+uSrOhSkaKrUy935gNZuuIPPVsHlr9DSOxSayd+k=
+github.com/Azure/go-autorest/autorest/mocks v0.4.2 h1:PGN4EDXnuQbojHbU0UWoNvmu9AGVwYHG9/fkDYhtAfw=
+github.com/Azure/go-autorest/autorest/mocks v0.4.2/go.mod h1:Vy7OitM9Kei0i1Oj+LvyAWMXJHeKH1MVlzFugfVrmyU=
+github.com/Azure/go-autorest/logger v0.2.1/go.mod h1:T9E3cAhj2VqvPOtCYAvby9aBXkZmbF5NWuPV8+WeEW8=
+github.com/Azure/go-autorest/logger v0.2.2 h1:hYqBsEBywrrOSW24kkOCXRcKfKhK76OzLTfF+MYDE2o=
+github.com/Azure/go-autorest/logger v0.2.2/go.mod h1:I5fg9K52o+iuydlWfa9T5K6WFos9XYr9dYTFzpqgibw=
+github.com/Azure/go-autorest/tracing v0.6.0/go.mod h1:+vhtPC754Xsa23ID7GlGsrdKBpUA79WCAKPPZVC2DeU=
+github.com/Azure/go-autorest/tracing v0.6.1 h1:YUMSrC/CeD1ZnnXcNYU4a/fzsO35u2Fsful9L/2nyR0=
+github.com/Azure/go-autorest/tracing v0.6.1/go.mod h1:/3EgjbsjraOqiicERAeu3m7/z0x1TzjQGAwDrJrXGkc=
+github.com/aws/aws-sdk-go-v2 v1.39.6 h1:2JrPCVgWJm7bm83BDwY5z8ietmeJUbh3O2ACnn+Xsqk=
+github.com/aws/aws-sdk-go-v2 v1.39.6/go.mod h1:c9pm7VwuW0UPxAEYGyTmyurVcNrbF6Rt/wixFqDhcjE=
+github.com/aws/aws-sdk-go-v2/config v1.31.17 h1:QFl8lL6RgakNK86vusim14P2k8BFSxjvUkcWLDjgz9Y=
+github.com/aws/aws-sdk-go-v2/config v1.31.17/go.mod h1:V8P7ILjp/Uef/aX8TjGk6OHZN6IKPM5YW6S78QnRD5c=
+github.com/aws/aws-sdk-go-v2/credentials v1.18.21 h1:56HGpsgnmD+2/KpG0ikvvR8+3v3COCwaF4r+oWwOeNA=
+github.com/aws/aws-sdk-go-v2/credentials v1.18.21/go.mod h1:3YELwedmQbw7cXNaII2Wywd+YY58AmLPwX4LzARgmmA=
+github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.18.13 h1:T1brd5dR3/fzNFAQch/iBKeX07/ffu/cLu+q+RuzEWk=
+github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.18.13/go.mod h1:Peg/GBAQ6JDt+RoBf4meB1wylmAipb7Kg2ZFakZTlwk=
+github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.13 h1:a+8/MLcWlIxo1lF9xaGt3J/u3yOZx+CdSveSNwjhD40=
+github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.13/go.mod h1:oGnKwIYZ4XttyU2JWxFrwvhF6YKiK/9/wmE3v3Iu9K8=
+github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.13 h1:HBSI2kDkMdWz4ZM7FjwE7e/pWDEZ+nR95x8Ztet1ooY=
+github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.13/go.mod h1:YE94ZoDArI7awZqJzBAZ3PDD2zSfuP7w6P2knOzIn8M=
+github.com/aws/aws-sdk-go-v2/internal/ini v1.8.4 h1:WKuaxf++XKWlHWu9ECbMlha8WOEGm0OUEZqm4K/Gcfk=
+github.com/aws/aws-sdk-go-v2/internal/ini v1.8.4/go.mod h1:ZWy7j6v1vWGmPReu0iSGvRiise4YI5SkR3OHKTZ6Wuc=
+github.com/aws/aws-sdk-go-v2/service/ecr v1.51.2 h1:aq2N/9UkbEyljIQ7OFcudEgUsJzO8MYucmfsM/k/dmc=
+github.com/aws/aws-sdk-go-v2/service/ecr v1.51.2/go.mod h1:1NVD1KuMjH2GqnPwMotPndQaT/MreKkWpjkF12d6oKU=
+github.com/aws/aws-sdk-go-v2/service/ecrpublic v1.38.2 h1:9fe6w8bydUwNAhFVmjo+SRqAJjbBMOyILL/6hTTVkyA=
+github.com/aws/aws-sdk-go-v2/service/ecrpublic v1.38.2/go.mod h1:x7gU4CAyAz4BsM9hlRkhHiYw2GIr1QCmN45uwQw9l/E=
+github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.13.3 h1:x2Ibm/Af8Fi+BH+Hsn9TXGdT+hKbDd5XOTZxTMxDk7o=
+github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.13.3/go.mod h1:IW1jwyrQgMdhisceG8fQLmQIydcT/jWY21rFhzgaKwo=
+github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.13.13 h1:kDqdFvMY4AtKoACfzIGD8A0+hbT41KTKF//gq7jITfM=
+github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.13.13/go.mod h1:lmKuogqSU3HzQCwZ9ZtcqOc5XGMqtDK7OIc2+DxiUEg=
+github.com/aws/aws-sdk-go-v2/service/sso v1.30.1 h1:0JPwLz1J+5lEOfy/g0SURC9cxhbQ1lIMHMa+AHZSzz0=
+github.com/aws/aws-sdk-go-v2/service/sso v1.30.1/go.mod h1:fKvyjJcz63iL/ftA6RaM8sRCtN4r4zl4tjL3qw5ec7k=
+github.com/aws/aws-sdk-go-v2/service/ssooidc v1.35.5 h1:OWs0/j2UYR5LOGi88sD5/lhN6TDLG6SfA7CqsQO9zF0=
+github.com/aws/aws-sdk-go-v2/service/ssooidc v1.35.5/go.mod h1:klO+ejMvYsB4QATfEOIXk8WAEwN4N0aBfJpvC+5SZBo=
+github.com/aws/aws-sdk-go-v2/service/sts v1.39.1 h1:mLlUgHn02ue8whiR4BmxxGJLR2gwU6s6ZzJ5wDamBUs=
+github.com/aws/aws-sdk-go-v2/service/sts v1.39.1/go.mod h1:E19xDjpzPZC7LS2knI9E6BaRFDK43Eul7vd6rSq2HWk=
+github.com/aws/smithy-go v1.23.2 h1:Crv0eatJUQhaManss33hS5r40CG3ZFH+21XSkqMrIUM=
+github.com/aws/smithy-go v1.23.2/go.mod h1:LEj2LM3rBRQJxPZTB4KuzZkaZYnZPnvgIhb4pu07mx0=
+github.com/awslabs/amazon-ecr-credential-helper/ecr-login v0.11.0 h1:GOPttfOAf5qAgx7r6b+zCWZrvCsfKffkL4H6mSYx1kA=
+github.com/awslabs/amazon-ecr-credential-helper/ecr-login v0.11.0/go.mod h1:a2HN6+p7k0JLDO8514sMr0l4cnrR52z4sWoZ/Uc82ho=
+github.com/chrismellard/docker-credential-acr-env v0.0.0-20230304212654-82a0ddb27589 h1:krfRl01rzPzxSxyLyrChD+U+MzsBXbm0OwYYB67uF+4=
+github.com/chrismellard/docker-credential-acr-env v0.0.0-20230304212654-82a0ddb27589/go.mod h1:OuDyvmLnMCwa2ep4Jkm6nyA0ocJuZlGyk2gGseVzERM=
+github.com/containerd/stargz-snapshotter/estargz v0.16.3 h1:7evrXtoh1mSbGj/pfRccTampEyKpjpOnS3CyiV1Ebr8=
+github.com/containerd/stargz-snapshotter/estargz v0.16.3/go.mod h1:uyr4BfYfOj3G9WBVE8cOlQmXAbPN9VEQpBBeJIuOipU=
+github.com/cpuguy83/go-md2man/v2 v2.0.6/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g=
+github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
+github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
+github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
+github.com/dimchansky/utfbom v1.1.1 h1:vV6w1AhK4VMnhBno/TPVCoK9U/LP0PkLCS9tbxHdi/U=
+github.com/dimchansky/utfbom v1.1.1/go.mod h1:SxdoEBH5qIqFocHMyGOXVAybYJdr71b1Q/j0mACtrfE=
+github.com/docker/cli v28.2.2+incompatible h1:qzx5BNUDFqlvyq4AHzdNB7gSyVTmU4cgsyN9SdInc1A=
+github.com/docker/cli v28.2.2+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8=
+github.com/docker/distribution v2.8.3+incompatible h1:AtKxIZ36LoNK51+Z6RpzLpddBirtxJnzDrHLEKxTAYk=
+github.com/docker/distribution v2.8.3+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w=
+github.com/docker/docker-credential-helpers v0.9.4 h1:76ItO69/AP/V4yT9V4uuuItG0B1N8hvt0T0c0NN/DzI=
+github.com/docker/docker-credential-helpers v0.9.4/go.mod h1:v1S+hepowrQXITkEfw6o4+BMbGot02wiKpzWhGUZK6c=
+github.com/golang-jwt/jwt/v4 v4.0.0/go.mod h1:/xlHOz8bRuivTWchD4jCa+NbatV+wEUSzwAxVc6locg=
+github.com/golang-jwt/jwt/v4 v4.2.0/go.mod h1:/xlHOz8bRuivTWchD4jCa+NbatV+wEUSzwAxVc6locg=
+github.com/golang-jwt/jwt/v4 v4.5.0/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0=
+github.com/golang-jwt/jwt/v4 v4.5.2 h1:YtQM7lnr8iZ+j5q71MGKkNw9Mn7AjHM68uc9g5fXeUI=
+github.com/golang-jwt/jwt/v4 v4.5.2/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0=
+github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
+github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
+github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=
+github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8=
+github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
+github.com/klauspost/compress v1.18.0 h1:c/Cqfb0r+Yi+JtIEq73FWXVkRonBlf0CRNYc8Zttxdo=
+github.com/klauspost/compress v1.18.0/go.mod h1:2Pp+KzxcywXVXMr50+X0Q/Lsb43OQHYWRCY2AiWywWQ=
+github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y=
+github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
+github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U=
+github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM=
+github.com/opencontainers/image-spec v1.1.1 h1:y0fUlFfIZhPF1W537XOLg0/fcx6zcHCJwooC2xJA040=
+github.com/opencontainers/image-spec v1.1.1/go.mod h1:qpqAh3Dmcf36wStyyWU+kCeDgrGnAve2nCC8+7h8Q0M=
+github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
+github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
+github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
+github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
+github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
+github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ=
+github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
+github.com/spf13/cobra v1.9.1 h1:CXSaggrXdbHK9CF+8ywj8Amf7PBRmPCOJugH954Nnlo=
+github.com/spf13/cobra v1.9.1/go.mod h1:nDyEzZ8ogv936Cinf6g1RU9MRY64Ir93oCnqb9wxYW0=
+github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
+github.com/spf13/pflag v1.0.6 h1:jFzHGLGAlb3ruxLB8MhbI6A8+AQX/2eW4qeyNZXNp2o=
+github.com/spf13/pflag v1.0.6/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
+github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
+github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
+github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
+github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
+github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
+github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
+github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
+github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U=
+github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U=
+github.com/vbatts/tar-split v0.12.1 h1:CqKoORW7BUWBe7UL/iqTVvkTBOF8UvOMKOIZykxnnbo=
+github.com/vbatts/tar-split v0.12.1/go.mod h1:eF6B6i6ftWQcDqEn3/iGFRFRo8cBIMSJVOpnNdfTMFA=
+github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
+github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
+golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
+golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
+golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
+golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
+golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
+golang.org/x/crypto v0.17.0/go.mod h1:gCAAfMLgwOJRpTjQ2zCCt2OcSfYMTeZVSRtQlPC7Nq4=
+golang.org/x/crypto v0.38.0 h1:jt+WWG8IZlBnVbomuhg2Mdq0+BBQaHbtqHEFEigjUV8=
+golang.org/x/crypto v0.38.0/go.mod h1:MvrbAqul58NNYPKnOra203SB9vpuZW0e+RRZV+Ggqjw=
+golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
+golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
+golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
+golang.org/x/mod v0.25.0 h1:n7a+ZbQKQA/Ysbyb0/6IbB1H/X41mKgbhfv7AfG/44w=
+golang.org/x/mod v0.25.0/go.mod h1:IXM97Txy2VM4PJ3gI61r1YEk/gAj6zAHN3AdZt6S9Ww=
+golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
+golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
+golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
+golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
+golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
+golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
+golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
+golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
+golang.org/x/oauth2 v0.30.0 h1:dnDm7JmhM45NNpd8FDDeLhK6FwqbOf4MLCM9zb1BOHI=
+golang.org/x/oauth2 v0.30.0/go.mod h1:B++QgG3ZKulg6sRPGD/mqlHQs5rB3Ml9erfeDY7xKlU=
+golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.15.0 h1:KWH3jNZsfyT6xfAfKiz6MRNmd46ByHDYaZ7KSkCtdW8=
+golang.org/x/sync v0.15.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA=
+golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
+golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
+golang.org/x/sys v0.33.0 h1:q3i8TbbEz+JRD9ywIRlyRAQbM0qF7hu24q3teo2hbuw=
+golang.org/x/sys v0.33.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
+golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
+golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
+golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
+golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo=
+golang.org/x/term v0.15.0/go.mod h1:BDl952bC7+uMoWR75FIrCDx79TPU9oHkTZ9yRbYOrX0=
+golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
+golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
+golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
+golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
+golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
+golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
+golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
+golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
+golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
+golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0=
+golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
+golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
+golang.org/x/tools v0.34.0 h1:qIpSLOxeCYGg9TrcJokLBG4KFA6d795g0xkBkiESGlo=
+golang.org/x/tools v0.34.0/go.mod h1:pAP9OwEaY1CAW3HOmg3hLZC5Z0CCmzjAF2UQMSqNARg=
+golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
+golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
+golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
+golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
+gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
+gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
+gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
+gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
+gotest.tools/v3 v3.1.0 h1:rVV8Tcg/8jHUkPUorwjaMTtemIMVXfIPKiOqnhEhakk=
+gotest.tools/v3 v3.1.0/go.mod h1:fHy7eyTmJFO5bQbUsEGQ1v4m2J3Jz9eWL54TP2/ZuYQ=
diff --git a/pkg/go-containerregistry/cmd/krane/main.go b/pkg/go-containerregistry/cmd/krane/main.go
new file mode 100644
index 00000000..722797b2
--- /dev/null
+++ b/pkg/go-containerregistry/cmd/krane/main.go
@@ -0,0 +1,67 @@
+// Copyright 2021 Google LLC All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package main
+
+import (
+ "context"
+ "io"
+ "os"
+ "os/signal"
+
+ ecr "github.com/awslabs/amazon-ecr-credential-helper/ecr-login"
+ "github.com/chrismellard/docker-credential-acr-env/pkg/credhelper"
+ "github.com/docker/model-runner/pkg/go-containerregistry/cmd/crane/cmd"
+ "github.com/docker/model-runner/pkg/go-containerregistry/pkg/authn"
+ "github.com/docker/model-runner/pkg/go-containerregistry/pkg/authn/github"
+ "github.com/docker/model-runner/pkg/go-containerregistry/pkg/crane"
+ "github.com/docker/model-runner/pkg/go-containerregistry/pkg/logs"
+ "github.com/docker/model-runner/pkg/go-containerregistry/pkg/v1/google"
+)
+
+var (
+ amazonKeychain authn.Keychain = authn.NewKeychainFromHelper(ecr.NewECRHelper(ecr.WithLogger(io.Discard)))
+ azureKeychain authn.Keychain = authn.NewKeychainFromHelper(credhelper.NewACRCredentialsHelper())
+)
+
+func init() {
+ logs.Warn.SetOutput(os.Stderr)
+ logs.Progress.SetOutput(os.Stderr)
+}
+
+const (
+ use = "krane"
+ short = "krane is a tool for managing container images"
+)
+
+func main() {
+ ctx, cancel := signal.NotifyContext(context.Background(), os.Interrupt)
+ defer cancel()
+
+ keychain := authn.NewMultiKeychain(
+ authn.DefaultKeychain,
+ google.Keychain,
+ github.Keychain,
+ amazonKeychain,
+ azureKeychain,
+ )
+
+ // Same as crane, but override usage and keychain.
+ root := cmd.New(use, short, []crane.Option{crane.WithAuthFromKeychain(keychain)})
+
+ if err := root.ExecuteContext(ctx); err != nil {
+ cancel()
+ os.Exit(1)
+ }
+}
diff --git a/pkg/go-containerregistry/cmd/registry/main.go b/pkg/go-containerregistry/cmd/registry/main.go
new file mode 100644
index 00000000..5e2e0549
--- /dev/null
+++ b/pkg/go-containerregistry/cmd/registry/main.go
@@ -0,0 +1,46 @@
+// Copyright 2019 Google LLC All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package main
+
+import (
+ "flag"
+ "fmt"
+ "log"
+ "net"
+ "net/http"
+ "time"
+
+ "github.com/docker/model-runner/pkg/go-containerregistry/pkg/registry"
+)
+
+var port = flag.Int("port", 1338, "port to run registry on")
+
+func main() {
+ flag.Parse()
+
+ listener, err := net.Listen("tcp", fmt.Sprintf("localhost:%d", *port))
+ if err != nil {
+ log.Fatal(err)
+ }
+ porti := listener.Addr().(*net.TCPAddr).Port
+ log.Printf("serving on port %d", porti)
+ s := &http.Server{
+ ReadHeaderTimeout: 5 * time.Second, // prevent slowloris, quiet linter
+ Handler: registry.New(
+ registry.WithWarning(.01, "Congratulations! You've won a lifetime's supply of free image pulls from this in-memory registry!"),
+ ),
+ }
+ log.Fatal(s.Serve(listener))
+}
diff --git a/pkg/go-containerregistry/cmd/registry/test.sh b/pkg/go-containerregistry/cmd/registry/test.sh
new file mode 100755
index 00000000..d0c95070
--- /dev/null
+++ b/pkg/go-containerregistry/cmd/registry/test.sh
@@ -0,0 +1,57 @@
+#!/bin/bash
+set -ex
+
+CONTAINER_OS=$(docker info -f '{{ .OSType }}')
+
+# crane can run on a Windows system, but doesn't currently support pulling Windows
+# containers, so this test can only run if Docker is in Linux container mode.
+if [[ ${CONTAINER_OS} = "windows" ]]; then
+ set +x
+ echo [TEST SKIPPED] Windows containers are not yet supported by crane
+ exit
+fi
+
+function cleanup {
+ [[ -n $PID ]] && kill $PID
+ [[ -n $CTR ]] && docker stop $CTR
+ rm -f ubuntu.tar debiand.tar debianc.tar
+ docker rmi -f \
+ localhost:1338/debianc:latest \
+ localhost:1338/debiand:latest \
+ localhost:1338/ubuntuc:foo \
+ localhost:1338/ubuntud:latest \
+ || true
+}
+trap cleanup EXIT
+
+case "$OSTYPE" in
+ # On Windows, Docker runs in a VM, so a registry running on the Windows
+ # host is not accessible via localhost for `docker pull|push`.
+ win*|msys*|cygwin*)
+ docker run -d --rm -p 1338:5000 --name test-reg registry:2
+ CTR=test-reg
+ ;;
+
+ *)
+ registry &
+ PID=$!
+ ;;
+esac
+
+go install ./cmd/registry
+go install ./cmd/crane
+
+
+crane pull debian:latest debianc.tar
+crane push debianc.tar localhost:1338/debianc:latest
+docker pull localhost:1338/debianc:latest
+docker tag localhost:1338/debianc:latest localhost:1338/debiand:latest
+docker push localhost:1338/debiand:latest
+crane pull localhost:1338/debiand:latest debiand.tar
+
+docker pull ubuntu:latest
+docker tag ubuntu:latest localhost:1338/ubuntud:latest
+docker push localhost:1338/ubuntud:latest
+crane pull localhost:1338/ubuntud:latest ubuntu.tar
+crane push ubuntu.tar localhost:1338/ubuntuc:foo
+docker pull localhost:1338/ubuntuc:foo
diff --git a/pkg/go-containerregistry/go.mod b/pkg/go-containerregistry/go.mod
new file mode 100644
index 00000000..86a2c58b
--- /dev/null
+++ b/pkg/go-containerregistry/go.mod
@@ -0,0 +1,58 @@
+module github.com/google/go-containerregistry
+
+go 1.24
+
+require (
+ github.com/containerd/stargz-snapshotter/estargz v0.16.3
+ github.com/docker/cli v28.2.2+incompatible
+ github.com/docker/distribution v2.8.3+incompatible
+ github.com/docker/docker v28.2.2+incompatible
+ github.com/google/go-cmp v0.7.0
+ github.com/klauspost/compress v1.18.0
+ github.com/mitchellh/go-homedir v1.1.0
+ github.com/moby/docker-image-spec v1.3.1
+ github.com/opencontainers/go-digest v1.0.0
+ github.com/opencontainers/image-spec v1.1.1
+ github.com/spf13/cobra v1.9.1
+ golang.org/x/oauth2 v0.30.0
+ golang.org/x/sync v0.15.0
+ golang.org/x/tools v0.34.0
+)
+
+require (
+ cloud.google.com/go/compute/metadata v0.7.0 // indirect
+ github.com/Microsoft/go-winio v0.6.2 // indirect
+ github.com/containerd/errdefs v1.0.0 // indirect
+ github.com/containerd/errdefs/pkg v0.3.0 // indirect
+ github.com/containerd/log v0.1.0 // indirect
+ github.com/cpuguy83/go-md2man/v2 v2.0.7 // indirect
+ github.com/distribution/reference v0.6.0 // indirect
+ github.com/docker/docker-credential-helpers v0.9.3 // indirect
+ github.com/docker/go-connections v0.5.0 // indirect
+ github.com/docker/go-units v0.5.0 // indirect
+ github.com/felixge/httpsnoop v1.0.4 // indirect
+ github.com/go-logr/logr v1.4.3 // indirect
+ github.com/go-logr/stdr v1.2.2 // indirect
+ github.com/gogo/protobuf v1.3.2 // indirect
+ github.com/inconshreveable/mousetrap v1.1.0 // indirect
+ github.com/moby/sys/atomicwriter v0.1.0 // indirect
+ github.com/moby/term v0.0.0-20221205130635-1aeaba878587 // indirect
+ github.com/morikuni/aec v1.0.0 // indirect
+ github.com/pkg/errors v0.9.1 // indirect
+ github.com/russross/blackfriday/v2 v2.1.0 // indirect
+ github.com/sirupsen/logrus v1.9.3 // indirect
+ github.com/spf13/pflag v1.0.6 // indirect
+ github.com/vbatts/tar-split v0.12.1 // indirect
+ go.opentelemetry.io/auto/sdk v1.1.0 // indirect
+ go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.61.0 // indirect
+ go.opentelemetry.io/otel v1.36.0 // indirect
+ go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.33.0 // indirect
+ go.opentelemetry.io/otel/metric v1.36.0 // indirect
+ go.opentelemetry.io/otel/trace v1.36.0 // indirect
+ golang.org/x/mod v0.25.0 // indirect
+ golang.org/x/sys v0.33.0 // indirect
+ golang.org/x/time v0.0.0-20210723032227-1f47c861a9ac // indirect
+ google.golang.org/protobuf v1.36.3 // indirect
+ gopkg.in/yaml.v3 v3.0.1 // indirect
+ gotest.tools/v3 v3.0.3 // indirect
+)
diff --git a/pkg/go-containerregistry/go.sum b/pkg/go-containerregistry/go.sum
new file mode 100644
index 00000000..3f195048
--- /dev/null
+++ b/pkg/go-containerregistry/go.sum
@@ -0,0 +1,182 @@
+cloud.google.com/go/compute/metadata v0.7.0 h1:PBWF+iiAerVNe8UCHxdOt6eHLVc3ydFeOCw78U8ytSU=
+cloud.google.com/go/compute/metadata v0.7.0/go.mod h1:j5MvL9PprKL39t166CoB1uVHfQMs4tFQZZcKwksXUjo=
+github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 h1:UQHMgLO+TxOElx5B5HZ4hJQsoJ/PvUvKRhJHDQXO8P8=
+github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E=
+github.com/Microsoft/go-winio v0.6.2 h1:F2VQgta7ecxGYO8k3ZZz3RS8fVIXVxONVUPlNERoyfY=
+github.com/Microsoft/go-winio v0.6.2/go.mod h1:yd8OoFMLzJbo9gZq8j5qaps8bJ9aShtEA8Ipt1oGCvU=
+github.com/cenkalti/backoff/v4 v4.3.0 h1:MyRJ/UdXutAwSAT+s3wNd7MfTIcy71VQueUuFK343L8=
+github.com/cenkalti/backoff/v4 v4.3.0/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE=
+github.com/containerd/errdefs v1.0.0 h1:tg5yIfIlQIrxYtu9ajqY42W3lpS19XqdxRQeEwYG8PI=
+github.com/containerd/errdefs v1.0.0/go.mod h1:+YBYIdtsnF4Iw6nWZhJcqGSg/dwvV7tyJ/kCkyJ2k+M=
+github.com/containerd/errdefs/pkg v0.3.0 h1:9IKJ06FvyNlexW690DXuQNx2KA2cUJXx151Xdx3ZPPE=
+github.com/containerd/errdefs/pkg v0.3.0/go.mod h1:NJw6s9HwNuRhnjJhM7pylWwMyAkmCQvQ4GpJHEqRLVk=
+github.com/containerd/log v0.1.0 h1:TCJt7ioM2cr/tfR8GPbGf9/VRAX8D2B4PjzCpfX540I=
+github.com/containerd/log v0.1.0/go.mod h1:VRRf09a7mHDIRezVKTRCrOq78v577GXq3bSa3EhrzVo=
+github.com/containerd/stargz-snapshotter/estargz v0.16.3 h1:7evrXtoh1mSbGj/pfRccTampEyKpjpOnS3CyiV1Ebr8=
+github.com/containerd/stargz-snapshotter/estargz v0.16.3/go.mod h1:uyr4BfYfOj3G9WBVE8cOlQmXAbPN9VEQpBBeJIuOipU=
+github.com/cpuguy83/go-md2man/v2 v2.0.6/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g=
+github.com/cpuguy83/go-md2man/v2 v2.0.7 h1:zbFlGlXEAKlwXpmvle3d8Oe3YnkKIK4xSRTd3sHPnBo=
+github.com/cpuguy83/go-md2man/v2 v2.0.7/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g=
+github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
+github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
+github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
+github.com/distribution/reference v0.6.0 h1:0IXCQ5g4/QMHHkarYzh5l+u8T3t73zM5QvfrDyIgxBk=
+github.com/distribution/reference v0.6.0/go.mod h1:BbU0aIcezP1/5jX/8MP0YiH4SdvB5Y4f/wlDRiLyi3E=
+github.com/docker/cli v28.2.2+incompatible h1:qzx5BNUDFqlvyq4AHzdNB7gSyVTmU4cgsyN9SdInc1A=
+github.com/docker/cli v28.2.2+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8=
+github.com/docker/distribution v2.8.3+incompatible h1:AtKxIZ36LoNK51+Z6RpzLpddBirtxJnzDrHLEKxTAYk=
+github.com/docker/distribution v2.8.3+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w=
+github.com/docker/docker v28.2.2+incompatible h1:CjwRSksz8Yo4+RmQ339Dp/D2tGO5JxwYeqtMOEe0LDw=
+github.com/docker/docker v28.2.2+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
+github.com/docker/docker-credential-helpers v0.9.3 h1:gAm/VtF9wgqJMoxzT3Gj5p4AqIjCBS4wrsOh9yRqcz8=
+github.com/docker/docker-credential-helpers v0.9.3/go.mod h1:x+4Gbw9aGmChi3qTLZj8Dfn0TD20M/fuWy0E5+WDeCo=
+github.com/docker/go-connections v0.5.0 h1:USnMq7hx7gwdVZq1L49hLXaFtUdTADjXGp+uj1Br63c=
+github.com/docker/go-connections v0.5.0/go.mod h1:ov60Kzw0kKElRwhNs9UlUHAE/F9Fe6GLaXnqyDdmEXc=
+github.com/docker/go-units v0.5.0 h1:69rxXcBk27SvSaaxTtLh/8llcHD8vYHT7WSdRZ/jvr4=
+github.com/docker/go-units v0.5.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk=
+github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg=
+github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U=
+github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
+github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI=
+github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
+github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag=
+github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE=
+github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q=
+github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
+github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
+github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
+github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=
+github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
+github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
+github.com/grpc-ecosystem/grpc-gateway/v2 v2.24.0 h1:TmHmbvxPmaegwhDubVz0lICL0J5Ka2vwTzhoePEXsGE=
+github.com/grpc-ecosystem/grpc-gateway/v2 v2.24.0/go.mod h1:qztMSjm835F2bXf+5HKAPIS5qsmQDqZna/PgVt4rWtI=
+github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8=
+github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
+github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8=
+github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
+github.com/klauspost/compress v1.18.0 h1:c/Cqfb0r+Yi+JtIEq73FWXVkRonBlf0CRNYc8Zttxdo=
+github.com/klauspost/compress v1.18.0/go.mod h1:2Pp+KzxcywXVXMr50+X0Q/Lsb43OQHYWRCY2AiWywWQ=
+github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
+github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
+github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
+github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
+github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y=
+github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
+github.com/moby/docker-image-spec v1.3.1 h1:jMKff3w6PgbfSa69GfNg+zN/XLhfXJGnEx3Nl2EsFP0=
+github.com/moby/docker-image-spec v1.3.1/go.mod h1:eKmb5VW8vQEh/BAr2yvVNvuiJuY6UIocYsFu/DxxRpo=
+github.com/moby/sys/atomicwriter v0.1.0 h1:kw5D/EqkBwsBFi0ss9v1VG3wIkVhzGvLklJ+w3A14Sw=
+github.com/moby/sys/atomicwriter v0.1.0/go.mod h1:Ul8oqv2ZMNHOceF643P6FKPXeCmYtlQMvpizfsSoaWs=
+github.com/moby/sys/sequential v0.6.0 h1:qrx7XFUd/5DxtqcoH1h438hF5TmOvzC/lspjy7zgvCU=
+github.com/moby/sys/sequential v0.6.0/go.mod h1:uyv8EUTrca5PnDsdMGXhZe6CCe8U/UiTWd+lL+7b/Ko=
+github.com/moby/term v0.0.0-20221205130635-1aeaba878587 h1:HfkjXDfhgVaN5rmueG8cL8KKeFNecRCXFhaJ2qZ5SKA=
+github.com/moby/term v0.0.0-20221205130635-1aeaba878587/go.mod h1:8FzsFHVUBGZdbDsJw/ot+X+d5HLUbvklYLJ9uGfcI3Y=
+github.com/morikuni/aec v1.0.0 h1:nP9CBfwrvYnBRgY6qfDQkygYDmYwOilePFkwzv4dU8A=
+github.com/morikuni/aec v1.0.0/go.mod h1:BbKIizmSmc5MMPqRYbxO4ZU0S0+P200+tUnFx7PXmsc=
+github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U=
+github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM=
+github.com/opencontainers/image-spec v1.1.1 h1:y0fUlFfIZhPF1W537XOLg0/fcx6zcHCJwooC2xJA040=
+github.com/opencontainers/image-spec v1.1.1/go.mod h1:qpqAh3Dmcf36wStyyWU+kCeDgrGnAve2nCC8+7h8Q0M=
+github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
+github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
+github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
+github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
+github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
+github.com/rogpeppe/go-internal v1.13.1 h1:KvO1DLK/DRN07sQ1LQKScxyZJuNnedQ5/wKSR38lUII=
+github.com/rogpeppe/go-internal v1.13.1/go.mod h1:uMEvuHeurkdAXX61udpOXGD/AzZDWNMNyH2VO9fmH0o=
+github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk=
+github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
+github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ=
+github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
+github.com/spf13/cobra v1.9.1 h1:CXSaggrXdbHK9CF+8ywj8Amf7PBRmPCOJugH954Nnlo=
+github.com/spf13/cobra v1.9.1/go.mod h1:nDyEzZ8ogv936Cinf6g1RU9MRY64Ir93oCnqb9wxYW0=
+github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
+github.com/spf13/pflag v1.0.6 h1:jFzHGLGAlb3ruxLB8MhbI6A8+AQX/2eW4qeyNZXNp2o=
+github.com/spf13/pflag v1.0.6/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
+github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
+github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
+github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
+github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
+github.com/vbatts/tar-split v0.12.1 h1:CqKoORW7BUWBe7UL/iqTVvkTBOF8UvOMKOIZykxnnbo=
+github.com/vbatts/tar-split v0.12.1/go.mod h1:eF6B6i6ftWQcDqEn3/iGFRFRo8cBIMSJVOpnNdfTMFA=
+github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
+github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
+go.opentelemetry.io/auto/sdk v1.1.0 h1:cH53jehLUN6UFLY71z+NDOiNJqDdPRaXzTel0sJySYA=
+go.opentelemetry.io/auto/sdk v1.1.0/go.mod h1:3wSPjt5PWp2RhlCcmmOial7AvC4DQqZb7a7wCow3W8A=
+go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.61.0 h1:F7Jx+6hwnZ41NSFTO5q4LYDtJRXBf2PD0rNBkeB/lus=
+go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.61.0/go.mod h1:UHB22Z8QsdRDrnAtX4PntOl36ajSxcdUMt1sF7Y6E7Q=
+go.opentelemetry.io/otel v1.36.0 h1:UumtzIklRBY6cI/lllNZlALOF5nNIzJVb16APdvgTXg=
+go.opentelemetry.io/otel v1.36.0/go.mod h1:/TcFMXYjyRNh8khOAO9ybYkqaDBb/70aVwkNML4pP8E=
+go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.33.0 h1:Vh5HayB/0HHfOQA7Ctx69E/Y/DcQSMPpKANYVMQ7fBA=
+go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.33.0/go.mod h1:cpgtDBaqD/6ok/UG0jT15/uKjAY8mRA53diogHBg3UI=
+go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.33.0 h1:wpMfgF8E1rkrT1Z6meFh1NDtownE9Ii3n3X2GJYjsaU=
+go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.33.0/go.mod h1:wAy0T/dUbs468uOlkT31xjvqQgEVXv58BRFWEgn5v/0=
+go.opentelemetry.io/otel/metric v1.36.0 h1:MoWPKVhQvJ+eeXWHFBOPoBOi20jh6Iq2CcCREuTYufE=
+go.opentelemetry.io/otel/metric v1.36.0/go.mod h1:zC7Ks+yeyJt4xig9DEw9kuUFe5C3zLbVjV2PzT6qzbs=
+go.opentelemetry.io/otel/sdk v1.36.0 h1:b6SYIuLRs88ztox4EyrvRti80uXIFy+Sqzoh9kFULbs=
+go.opentelemetry.io/otel/sdk v1.36.0/go.mod h1:+lC+mTgD+MUWfjJubi2vvXWcVxyr9rmlshZni72pXeY=
+go.opentelemetry.io/otel/sdk/metric v1.36.0 h1:r0ntwwGosWGaa0CrSt8cuNuTcccMXERFwHX4dThiPis=
+go.opentelemetry.io/otel/sdk/metric v1.36.0/go.mod h1:qTNOhFDfKRwX0yXOqJYegL5WRaW376QbB7P4Pb0qva4=
+go.opentelemetry.io/otel/trace v1.36.0 h1:ahxWNuqZjpdiFAyrIoQ4GIiAIhxAunQR6MUoKrsNd4w=
+go.opentelemetry.io/otel/trace v1.36.0/go.mod h1:gQ+OnDZzrybY4k4seLzPAWNwVBBVlF2szhehOBB/tGA=
+go.opentelemetry.io/proto/otlp v1.4.0 h1:TA9WRvW6zMwP+Ssb6fLoUIuirti1gGbP28GcKG1jgeg=
+go.opentelemetry.io/proto/otlp v1.4.0/go.mod h1:PPBWZIP98o2ElSqI35IHfu7hIhSwvc5N38Jw8pXuGFY=
+golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
+golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
+golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
+golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
+golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
+golang.org/x/mod v0.25.0 h1:n7a+ZbQKQA/Ysbyb0/6IbB1H/X41mKgbhfv7AfG/44w=
+golang.org/x/mod v0.25.0/go.mod h1:IXM97Txy2VM4PJ3gI61r1YEk/gAj6zAHN3AdZt6S9Ww=
+golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
+golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
+golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
+golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
+golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
+golang.org/x/net v0.41.0 h1:vBTly1HeNPEn3wtREYfy4GZ/NECgw2Cnl+nK6Nz3uvw=
+golang.org/x/net v0.41.0/go.mod h1:B/K4NNqkfmg07DQYrbwvSluqCJOOXwUjeb/5lOisjbA=
+golang.org/x/oauth2 v0.30.0 h1:dnDm7JmhM45NNpd8FDDeLhK6FwqbOf4MLCM9zb1BOHI=
+golang.org/x/oauth2 v0.30.0/go.mod h1:B++QgG3ZKulg6sRPGD/mqlHQs5rB3Ml9erfeDY7xKlU=
+golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.15.0 h1:KWH3jNZsfyT6xfAfKiz6MRNmd46ByHDYaZ7KSkCtdW8=
+golang.org/x/sync v0.15.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA=
+golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
+golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.33.0 h1:q3i8TbbEz+JRD9ywIRlyRAQbM0qF7hu24q3teo2hbuw=
+golang.org/x/sys v0.33.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
+golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
+golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
+golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo=
+golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ=
+golang.org/x/time v0.0.0-20210723032227-1f47c861a9ac h1:7zkz7BUtwNFFqcowJ+RIgu2MaV/MapERkDIy+mwPyjs=
+golang.org/x/time v0.0.0-20210723032227-1f47c861a9ac/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
+golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
+golang.org/x/tools v0.0.0-20190624222133-a101b041ded4/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
+golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
+golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
+golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
+golang.org/x/tools v0.34.0 h1:qIpSLOxeCYGg9TrcJokLBG4KFA6d795g0xkBkiESGlo=
+golang.org/x/tools v0.34.0/go.mod h1:pAP9OwEaY1CAW3HOmg3hLZC5Z0CCmzjAF2UQMSqNARg=
+golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
+golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
+golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
+golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
+google.golang.org/genproto/googleapis/api v0.0.0-20241209162323-e6fa225c2576 h1:CkkIfIt50+lT6NHAVoRYEyAvQGFM7xEwXUUywFvEb3Q=
+google.golang.org/genproto/googleapis/api v0.0.0-20241209162323-e6fa225c2576/go.mod h1:1R3kvZ1dtP3+4p4d3G8uJ8rFk/fWlScl38vanWACI08=
+google.golang.org/genproto/googleapis/rpc v0.0.0-20241209162323-e6fa225c2576 h1:8ZmaLZE4XWrtU3MyClkYqqtl6Oegr3235h7jxsDyqCY=
+google.golang.org/genproto/googleapis/rpc v0.0.0-20241209162323-e6fa225c2576/go.mod h1:5uTbfoYQed2U9p3KIj2/Zzm02PYhndfdmML0qC3q3FU=
+google.golang.org/grpc v1.68.1 h1:oI5oTa11+ng8r8XMMN7jAOmWfPZWbYpCFaMUTACxkM0=
+google.golang.org/grpc v1.68.1/go.mod h1:+q1XYFJjShcqn0QZHvCyeR4CXPA+llXIeUIfIe00waw=
+google.golang.org/protobuf v1.36.3 h1:82DV7MYdb8anAVi3qge1wSnMDrnKK7ebr+I0hHRN1BU=
+google.golang.org/protobuf v1.36.3/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE=
+gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
+gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
+gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
+gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
+gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
+gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
+gotest.tools/v3 v3.0.3 h1:4AuOwCGf4lLR9u3YOe2awrHygurzhO/HeQ6laiA6Sx0=
+gotest.tools/v3 v3.0.3/go.mod h1:Z7Lb0S5l+klDB31fvDQX8ss/FlKDxtlFlw3Oa8Ymbl8=
diff --git a/pkg/go-containerregistry/hack/boilerplate/boilerplate.go.txt b/pkg/go-containerregistry/hack/boilerplate/boilerplate.go.txt
new file mode 100644
index 00000000..a237f5eb
--- /dev/null
+++ b/pkg/go-containerregistry/hack/boilerplate/boilerplate.go.txt
@@ -0,0 +1,13 @@
+// Copyright 2018 Google LLC All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
diff --git a/pkg/go-containerregistry/hack/bump-deps.sh b/pkg/go-containerregistry/hack/bump-deps.sh
new file mode 100755
index 00000000..0e7325da
--- /dev/null
+++ b/pkg/go-containerregistry/hack/bump-deps.sh
@@ -0,0 +1,47 @@
+#!/bin/bash
+
+# Copyright 2022 Google LLC
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+set -o errexit
+set -o nounset
+set -o pipefail
+
+PROJECT_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
+
+pushd ${PROJECT_ROOT}
+trap popd EXIT
+
+go get -u ./...
+go mod tidy -compat=1.18
+go mod vendor
+
+cd ${PROJECT_ROOT}/pkg/authn/k8schain
+go get -u ./...
+go mod tidy -compat=1.18
+go mod download
+
+cd ${PROJECT_ROOT}/pkg/authn/kubernetes
+go get -u ./...
+go mod tidy -compat=1.18
+go mod download
+
+cd ${PROJECT_ROOT}/cmd/krane
+go get -u ./...
+go mod tidy -compat=1.18
+go mod download
+
+cd ${PROJECT_ROOT}
+
+./hack/update-deps.sh
diff --git a/pkg/go-containerregistry/hack/presubmit.sh b/pkg/go-containerregistry/hack/presubmit.sh
new file mode 100755
index 00000000..420835b8
--- /dev/null
+++ b/pkg/go-containerregistry/hack/presubmit.sh
@@ -0,0 +1,47 @@
+#!/bin/bash
+
+# Copyright 2019 Google LLC
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+set -o errexit
+set -o nounset
+set -o pipefail
+
+PROJECT_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
+
+pushd ${PROJECT_ROOT}
+trap popd EXIT
+
+# Verify that all source files are correctly formatted.
+find . -name "*.go" | grep -v vendor/ | xargs gofmt -d -e -l
+
+# Verify that generated crane docs are up-to-date.
+mkdir -p /tmp/gendoc && go run cmd/crane/help/main.go --dir /tmp/gendoc && diff -Naur /tmp/gendoc/ cmd/crane/doc/
+
+go test ./...
+./pkg/name/internal/must_test.sh
+
+./cmd/crane/rebase_test.sh
+
+pushd ${PROJECT_ROOT}/cmd/krane
+trap popd EXIT
+go build ./...
+
+pushd ${PROJECT_ROOT}/pkg/authn/k8schain
+trap popd EXIT
+go build ./...
+
+pushd ${PROJECT_ROOT}/pkg/authn/kubernetes
+trap popd EXIT
+go test ./...
diff --git a/pkg/go-containerregistry/hack/update-codegen.sh b/pkg/go-containerregistry/hack/update-codegen.sh
new file mode 100755
index 00000000..e237a506
--- /dev/null
+++ b/pkg/go-containerregistry/hack/update-codegen.sh
@@ -0,0 +1,52 @@
+#!/bin/bash
+
+# Copyright 2018 Google LLC
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+set -o errexit
+set -o nounset
+set -o pipefail
+
+PROJECT_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
+BOILER_PLATE_FILE="${PROJECT_ROOT}/hack/boilerplate/boilerplate.go.txt"
+MODULE_NAME=github.com/google/go-containerregistry
+
+pushd ${PROJECT_ROOT}
+trap popd EXIT
+
+export GOPATH=$(go env GOPATH)
+export PATH="${GOPATH}/bin:${PATH}"
+
+go mod tidy
+go mod vendor
+
+export GOBIN=$(mktemp -d)
+export PATH="$GOBIN:$PATH"
+
+go install github.com/maxbrunsfeld/counterfeiter/v6@latest
+go install k8s.io/code-generator/cmd/deepcopy-gen@v0.20.7
+
+counterfeiter -o pkg/v1/fake/index.go ${PROJECT_ROOT}/pkg/v1 ImageIndex
+counterfeiter -o pkg/v1/fake/image.go ${PROJECT_ROOT}/pkg/v1 Image
+
+DEEPCOPY_OUTPUT=$(mktemp -d)
+
+deepcopy-gen -O zz_deepcopy_generated --go-header-file $BOILER_PLATE_FILE \
+ --input-dirs "$MODULE_NAME/pkg/v1" \
+ --output-base "$DEEPCOPY_OUTPUT"
+
+# TODO - Generalize this for all directories when we need it
+cp $DEEPCOPY_OUTPUT/$MODULE_NAME/pkg/v1/*.go $PROJECT_ROOT/pkg/v1
+
+go run $PROJECT_ROOT/cmd/crane/help/main.go --dir=$PROJECT_ROOT/cmd/crane/doc/
diff --git a/pkg/go-containerregistry/hack/update-deps.sh b/pkg/go-containerregistry/hack/update-deps.sh
new file mode 100755
index 00000000..25be8103
--- /dev/null
+++ b/pkg/go-containerregistry/hack/update-deps.sh
@@ -0,0 +1,31 @@
+#!/bin/bash
+
+# Copyright 2018 Google LLC
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+set -o errexit
+set -o nounset
+set -o pipefail
+
+PROJECT_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
+
+pushd ${PROJECT_ROOT}
+trap popd EXIT
+
+go mod tidy
+go mod vendor
+
+# Delete all vendored broken symlinks.
+# From https://stackoverflow.com/questions/22097130/delete-all-broken-symbolic-links-with-a-line
+find vendor/ -type l -exec sh -c 'for x; do [ -e "$x" ] || rm "$x"; done' _ {} +
diff --git a/pkg/go-containerregistry/hack/update-dots.sh b/pkg/go-containerregistry/hack/update-dots.sh
new file mode 100755
index 00000000..570c7946
--- /dev/null
+++ b/pkg/go-containerregistry/hack/update-dots.sh
@@ -0,0 +1,30 @@
+#!/bin/bash
+
+# Copyright 2019 The original author or authors
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+set -o errexit
+set -o nounset
+set -o pipefail
+
+PROJECT_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
+
+pushd ${PROJECT_ROOT}
+trap popd EXIT
+
+dot -Tjpeg images/ociimage.gv > images/ociimage.jpeg
+
+for f in $(ls images/dot/ | grep -e '.dot$'); do
+ dot -Tsvg images/dot/$f > images/$f.svg
+done
diff --git a/pkg/go-containerregistry/images/containerd.dot.svg b/pkg/go-containerregistry/images/containerd.dot.svg
new file mode 100644
index 00000000..cb87da6e
--- /dev/null
+++ b/pkg/go-containerregistry/images/containerd.dot.svg
@@ -0,0 +1,2074 @@
+
+
+
+
+
diff --git a/pkg/go-containerregistry/images/containers.dot.svg b/pkg/go-containerregistry/images/containers.dot.svg
new file mode 100644
index 00000000..38135cf9
--- /dev/null
+++ b/pkg/go-containerregistry/images/containers.dot.svg
@@ -0,0 +1,5365 @@
+
+
+
+
+
diff --git a/pkg/go-containerregistry/images/crane.png b/pkg/go-containerregistry/images/crane.png
new file mode 100644
index 00000000..ffd95af2
Binary files /dev/null and b/pkg/go-containerregistry/images/crane.png differ
diff --git a/pkg/go-containerregistry/images/credhelper-basic.svg b/pkg/go-containerregistry/images/credhelper-basic.svg
new file mode 100644
index 00000000..44d4d0ec
--- /dev/null
+++ b/pkg/go-containerregistry/images/credhelper-basic.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/pkg/go-containerregistry/images/credhelper-oauth.svg b/pkg/go-containerregistry/images/credhelper-oauth.svg
new file mode 100644
index 00000000..a88e1b86
--- /dev/null
+++ b/pkg/go-containerregistry/images/credhelper-oauth.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/pkg/go-containerregistry/images/docker.dot.svg b/pkg/go-containerregistry/images/docker.dot.svg
new file mode 100644
index 00000000..f031ddfb
--- /dev/null
+++ b/pkg/go-containerregistry/images/docker.dot.svg
@@ -0,0 +1,2155 @@
+
+
+
+
+
diff --git a/pkg/go-containerregistry/images/dot/containerd.dot b/pkg/go-containerregistry/images/dot/containerd.dot
new file mode 100644
index 00000000..f6743960
--- /dev/null
+++ b/pkg/go-containerregistry/images/dot/containerd.dot
@@ -0,0 +1,316 @@
+digraph godep {
+nodesep=0.4
+ranksep=0.8
+node [shape="box",style="rounded,filled"]
+edge [arrowsize="0.5"]
+"bufio" [label="bufio" color="palegreen" URL="https://godoc.org/bufio" target="_blank"];
+"bytes" [label="bytes" color="palegreen" URL="https://godoc.org/bytes" target="_blank"];
+"compress/gzip" [label="compress/gzip" color="palegreen" URL="https://godoc.org/compress/gzip" target="_blank"];
+"container/list" [label="container/list" color="palegreen" URL="https://godoc.org/container/list" target="_blank"];
+"context" [label="context" color="palegreen" URL="https://godoc.org/context" target="_blank"];
+"crypto" [label="crypto" color="palegreen" URL="https://godoc.org/crypto" target="_blank"];
+"encoding" [label="encoding" color="palegreen" URL="https://godoc.org/encoding" target="_blank"];
+"encoding/base64" [label="encoding/base64" color="palegreen" URL="https://godoc.org/encoding/base64" target="_blank"];
+"encoding/json" [label="encoding/json" color="palegreen" URL="https://godoc.org/encoding/json" target="_blank"];
+"errors" [label="errors" color="palegreen" URL="https://godoc.org/errors" target="_blank"];
+"fmt" [label="fmt" color="palegreen" URL="https://godoc.org/fmt" target="_blank"];
+"github.com/containerd/containerd/archive/compression" [label="github.com/containerd/containerd/archive/compression" color="paleturquoise" URL="https://godoc.org/github.com/containerd/containerd/archive/compression" target="_blank"];
+"github.com/containerd/containerd/archive/compression" -> "bufio";
+"github.com/containerd/containerd/archive/compression" -> "bytes";
+"github.com/containerd/containerd/archive/compression" -> "compress/gzip";
+"github.com/containerd/containerd/archive/compression" -> "context";
+"github.com/containerd/containerd/archive/compression" -> "fmt";
+"github.com/containerd/containerd/archive/compression" -> "github.com/containerd/containerd/log";
+"github.com/containerd/containerd/archive/compression" -> "io";
+"github.com/containerd/containerd/archive/compression" -> "os";
+"github.com/containerd/containerd/archive/compression" -> "os/exec";
+"github.com/containerd/containerd/archive/compression" -> "strconv";
+"github.com/containerd/containerd/archive/compression" -> "sync";
+"github.com/containerd/containerd/content" [label="github.com/containerd/containerd/content" color="paleturquoise" URL="https://godoc.org/github.com/containerd/containerd/content" target="_blank"];
+"github.com/containerd/containerd/content" -> "context";
+"github.com/containerd/containerd/content" -> "github.com/containerd/containerd/errdefs";
+"github.com/containerd/containerd/content" -> "github.com/opencontainers/go-digest";
+"github.com/containerd/containerd/content" -> "github.com/opencontainers/image-spec/specs-go/v1";
+"github.com/containerd/containerd/content" -> "github.com/pkg/errors";
+"github.com/containerd/containerd/content" -> "io";
+"github.com/containerd/containerd/content" -> "io/ioutil";
+"github.com/containerd/containerd/content" -> "math/rand";
+"github.com/containerd/containerd/content" -> "sync";
+"github.com/containerd/containerd/content" -> "time";
+"github.com/containerd/containerd/errdefs" [label="github.com/containerd/containerd/errdefs" color="paleturquoise" URL="https://godoc.org/github.com/containerd/containerd/errdefs" target="_blank"];
+"github.com/containerd/containerd/errdefs" -> "context";
+"github.com/containerd/containerd/errdefs" -> "github.com/pkg/errors";
+"github.com/containerd/containerd/errdefs" -> "google.golang.org/grpc/codes";
+"github.com/containerd/containerd/errdefs" -> "google.golang.org/grpc/status";
+"github.com/containerd/containerd/errdefs" -> "strings";
+"github.com/containerd/containerd/images" [label="github.com/containerd/containerd/images" color="paleturquoise" URL="https://godoc.org/github.com/containerd/containerd/images" target="_blank"];
+"github.com/containerd/containerd/images" -> "context";
+"github.com/containerd/containerd/images" -> "encoding/json";
+"github.com/containerd/containerd/images" -> "fmt";
+"github.com/containerd/containerd/images" -> "github.com/containerd/containerd/content";
+"github.com/containerd/containerd/images" -> "github.com/containerd/containerd/errdefs";
+"github.com/containerd/containerd/images" -> "github.com/containerd/containerd/log";
+"github.com/containerd/containerd/images" -> "github.com/containerd/containerd/platforms";
+"github.com/containerd/containerd/images" -> "github.com/opencontainers/go-digest";
+"github.com/containerd/containerd/images" -> "github.com/opencontainers/image-spec/specs-go/v1";
+"github.com/containerd/containerd/images" -> "github.com/pkg/errors";
+"github.com/containerd/containerd/images" -> "golang.org/x/sync/errgroup";
+"github.com/containerd/containerd/images" -> "golang.org/x/sync/semaphore";
+"github.com/containerd/containerd/images" -> "io";
+"github.com/containerd/containerd/images" -> "sort";
+"github.com/containerd/containerd/images" -> "strings";
+"github.com/containerd/containerd/images" -> "time";
+"github.com/containerd/containerd/labels" [label="github.com/containerd/containerd/labels" color="paleturquoise" URL="https://godoc.org/github.com/containerd/containerd/labels" target="_blank"];
+"github.com/containerd/containerd/labels" -> "github.com/containerd/containerd/errdefs";
+"github.com/containerd/containerd/labels" -> "github.com/pkg/errors";
+"github.com/containerd/containerd/log" [label="github.com/containerd/containerd/log" color="paleturquoise" URL="https://godoc.org/github.com/containerd/containerd/log" target="_blank"];
+"github.com/containerd/containerd/log" -> "context";
+"github.com/containerd/containerd/log" -> "github.com/sirupsen/logrus";
+"github.com/containerd/containerd/log" -> "sync/atomic";
+"github.com/containerd/containerd/platforms" [label="github.com/containerd/containerd/platforms" color="paleturquoise" URL="https://godoc.org/github.com/containerd/containerd/platforms" target="_blank"];
+"github.com/containerd/containerd/platforms" -> "bufio";
+"github.com/containerd/containerd/platforms" -> "github.com/containerd/containerd/errdefs";
+"github.com/containerd/containerd/platforms" -> "github.com/containerd/containerd/log";
+"github.com/containerd/containerd/platforms" -> "github.com/opencontainers/image-spec/specs-go/v1";
+"github.com/containerd/containerd/platforms" -> "github.com/pkg/errors";
+"github.com/containerd/containerd/platforms" -> "os";
+"github.com/containerd/containerd/platforms" -> "regexp";
+"github.com/containerd/containerd/platforms" -> "runtime";
+"github.com/containerd/containerd/platforms" -> "strconv";
+"github.com/containerd/containerd/platforms" -> "strings";
+"github.com/containerd/containerd/reference" [label="github.com/containerd/containerd/reference" color="paleturquoise" URL="https://godoc.org/github.com/containerd/containerd/reference" target="_blank"];
+"github.com/containerd/containerd/reference" -> "errors";
+"github.com/containerd/containerd/reference" -> "fmt";
+"github.com/containerd/containerd/reference" -> "github.com/opencontainers/go-digest";
+"github.com/containerd/containerd/reference" -> "net/url";
+"github.com/containerd/containerd/reference" -> "path";
+"github.com/containerd/containerd/reference" -> "regexp";
+"github.com/containerd/containerd/reference" -> "strings";
+"github.com/containerd/containerd/remotes" [label="github.com/containerd/containerd/remotes" color="paleturquoise" URL="https://godoc.org/github.com/containerd/containerd/remotes" target="_blank"];
+"github.com/containerd/containerd/remotes" -> "context";
+"github.com/containerd/containerd/remotes" -> "fmt";
+"github.com/containerd/containerd/remotes" -> "github.com/containerd/containerd/content";
+"github.com/containerd/containerd/remotes" -> "github.com/containerd/containerd/errdefs";
+"github.com/containerd/containerd/remotes" -> "github.com/containerd/containerd/images";
+"github.com/containerd/containerd/remotes" -> "github.com/containerd/containerd/log";
+"github.com/containerd/containerd/remotes" -> "github.com/containerd/containerd/platforms";
+"github.com/containerd/containerd/remotes" -> "github.com/opencontainers/image-spec/specs-go/v1";
+"github.com/containerd/containerd/remotes" -> "github.com/pkg/errors";
+"github.com/containerd/containerd/remotes" -> "github.com/sirupsen/logrus";
+"github.com/containerd/containerd/remotes" -> "io";
+"github.com/containerd/containerd/remotes" -> "strings";
+"github.com/containerd/containerd/remotes" -> "sync";
+"github.com/containerd/containerd/remotes/docker" [label="github.com/containerd/containerd/remotes/docker" color="paleturquoise" URL="https://godoc.org/github.com/containerd/containerd/remotes/docker" target="_blank"];
+"github.com/containerd/containerd/remotes/docker" -> "bytes";
+"github.com/containerd/containerd/remotes/docker" -> "context";
+"github.com/containerd/containerd/remotes/docker" -> "encoding/base64";
+"github.com/containerd/containerd/remotes/docker" -> "encoding/json";
+"github.com/containerd/containerd/remotes/docker" -> "fmt";
+"github.com/containerd/containerd/remotes/docker" -> "github.com/containerd/containerd/content";
+"github.com/containerd/containerd/remotes/docker" -> "github.com/containerd/containerd/errdefs";
+"github.com/containerd/containerd/remotes/docker" -> "github.com/containerd/containerd/images";
+"github.com/containerd/containerd/remotes/docker" -> "github.com/containerd/containerd/labels";
+"github.com/containerd/containerd/remotes/docker" -> "github.com/containerd/containerd/log";
+"github.com/containerd/containerd/remotes/docker" -> "github.com/containerd/containerd/reference";
+"github.com/containerd/containerd/remotes/docker" -> "github.com/containerd/containerd/remotes";
+"github.com/containerd/containerd/remotes/docker" -> "github.com/containerd/containerd/remotes/docker/schema1";
+"github.com/containerd/containerd/remotes/docker" -> "github.com/containerd/containerd/version";
+"github.com/containerd/containerd/remotes/docker" -> "github.com/docker/distribution/registry/api/errcode";
+"github.com/containerd/containerd/remotes/docker" -> "github.com/opencontainers/go-digest";
+"github.com/containerd/containerd/remotes/docker" -> "github.com/opencontainers/image-spec/specs-go/v1";
+"github.com/containerd/containerd/remotes/docker" -> "github.com/pkg/errors";
+"github.com/containerd/containerd/remotes/docker" -> "github.com/sirupsen/logrus";
+"github.com/containerd/containerd/remotes/docker" -> "golang.org/x/net/context/ctxhttp";
+"github.com/containerd/containerd/remotes/docker" -> "io";
+"github.com/containerd/containerd/remotes/docker" -> "io/ioutil";
+"github.com/containerd/containerd/remotes/docker" -> "net/http";
+"github.com/containerd/containerd/remotes/docker" -> "net/url";
+"github.com/containerd/containerd/remotes/docker" -> "path";
+"github.com/containerd/containerd/remotes/docker" -> "sort";
+"github.com/containerd/containerd/remotes/docker" -> "strings";
+"github.com/containerd/containerd/remotes/docker" -> "sync";
+"github.com/containerd/containerd/remotes/docker" -> "time";
+"github.com/containerd/containerd/remotes/docker/schema1" [label="github.com/containerd/containerd/remotes/docker/schema1" color="paleturquoise" URL="https://godoc.org/github.com/containerd/containerd/remotes/docker/schema1" target="_blank"];
+"github.com/containerd/containerd/remotes/docker/schema1" -> "bytes";
+"github.com/containerd/containerd/remotes/docker/schema1" -> "context";
+"github.com/containerd/containerd/remotes/docker/schema1" -> "encoding/base64";
+"github.com/containerd/containerd/remotes/docker/schema1" -> "encoding/json";
+"github.com/containerd/containerd/remotes/docker/schema1" -> "fmt";
+"github.com/containerd/containerd/remotes/docker/schema1" -> "github.com/containerd/containerd/archive/compression";
+"github.com/containerd/containerd/remotes/docker/schema1" -> "github.com/containerd/containerd/content";
+"github.com/containerd/containerd/remotes/docker/schema1" -> "github.com/containerd/containerd/errdefs";
+"github.com/containerd/containerd/remotes/docker/schema1" -> "github.com/containerd/containerd/images";
+"github.com/containerd/containerd/remotes/docker/schema1" -> "github.com/containerd/containerd/log";
+"github.com/containerd/containerd/remotes/docker/schema1" -> "github.com/containerd/containerd/remotes";
+"github.com/containerd/containerd/remotes/docker/schema1" -> "github.com/opencontainers/go-digest";
+"github.com/containerd/containerd/remotes/docker/schema1" -> "github.com/opencontainers/image-spec/specs-go";
+"github.com/containerd/containerd/remotes/docker/schema1" -> "github.com/opencontainers/image-spec/specs-go/v1";
+"github.com/containerd/containerd/remotes/docker/schema1" -> "github.com/pkg/errors";
+"github.com/containerd/containerd/remotes/docker/schema1" -> "golang.org/x/sync/errgroup";
+"github.com/containerd/containerd/remotes/docker/schema1" -> "io";
+"github.com/containerd/containerd/remotes/docker/schema1" -> "io/ioutil";
+"github.com/containerd/containerd/remotes/docker/schema1" -> "strconv";
+"github.com/containerd/containerd/remotes/docker/schema1" -> "strings";
+"github.com/containerd/containerd/remotes/docker/schema1" -> "sync";
+"github.com/containerd/containerd/remotes/docker/schema1" -> "time";
+"github.com/containerd/containerd/version" [label="github.com/containerd/containerd/version" color="paleturquoise" URL="https://godoc.org/github.com/containerd/containerd/version" target="_blank"];
+"github.com/docker/distribution/registry/api/errcode" [label="github.com/docker/distribution/registry/api/errcode" color="palegoldenrod" URL="https://godoc.org/github.com/docker/distribution/registry/api/errcode" target="_blank"];
+"github.com/docker/distribution/registry/api/errcode" -> "encoding/json";
+"github.com/docker/distribution/registry/api/errcode" -> "fmt";
+"github.com/docker/distribution/registry/api/errcode" -> "net/http";
+"github.com/docker/distribution/registry/api/errcode" -> "sort";
+"github.com/docker/distribution/registry/api/errcode" -> "strings";
+"github.com/docker/distribution/registry/api/errcode" -> "sync";
+"github.com/golang/protobuf/proto" [label="github.com/golang/protobuf/proto" color="paleturquoise" URL="https://godoc.org/github.com/golang/protobuf/proto" target="_blank"];
+"github.com/golang/protobuf/proto" -> "bufio";
+"github.com/golang/protobuf/proto" -> "bytes";
+"github.com/golang/protobuf/proto" -> "encoding";
+"github.com/golang/protobuf/proto" -> "encoding/json";
+"github.com/golang/protobuf/proto" -> "errors";
+"github.com/golang/protobuf/proto" -> "fmt";
+"github.com/golang/protobuf/proto" -> "io";
+"github.com/golang/protobuf/proto" -> "log";
+"github.com/golang/protobuf/proto" -> "math";
+"github.com/golang/protobuf/proto" -> "os";
+"github.com/golang/protobuf/proto" -> "reflect";
+"github.com/golang/protobuf/proto" -> "sort";
+"github.com/golang/protobuf/proto" -> "strconv";
+"github.com/golang/protobuf/proto" -> "strings";
+"github.com/golang/protobuf/proto" -> "sync";
+"github.com/golang/protobuf/proto" -> "sync/atomic";
+"github.com/golang/protobuf/proto" -> "unicode/utf8";
+"github.com/golang/protobuf/proto" -> "unsafe";
+"github.com/golang/protobuf/ptypes" [label="github.com/golang/protobuf/ptypes" color="paleturquoise" URL="https://godoc.org/github.com/golang/protobuf/ptypes" target="_blank"];
+"github.com/golang/protobuf/ptypes" -> "errors";
+"github.com/golang/protobuf/ptypes" -> "fmt";
+"github.com/golang/protobuf/ptypes" -> "github.com/golang/protobuf/proto";
+"github.com/golang/protobuf/ptypes" -> "github.com/golang/protobuf/ptypes/any";
+"github.com/golang/protobuf/ptypes" -> "github.com/golang/protobuf/ptypes/duration";
+"github.com/golang/protobuf/ptypes" -> "github.com/golang/protobuf/ptypes/timestamp";
+"github.com/golang/protobuf/ptypes" -> "reflect";
+"github.com/golang/protobuf/ptypes" -> "strings";
+"github.com/golang/protobuf/ptypes" -> "time";
+"github.com/golang/protobuf/ptypes/any" [label="github.com/golang/protobuf/ptypes/any" color="paleturquoise" URL="https://godoc.org/github.com/golang/protobuf/ptypes/any" target="_blank"];
+"github.com/golang/protobuf/ptypes/any" -> "fmt";
+"github.com/golang/protobuf/ptypes/any" -> "github.com/golang/protobuf/proto";
+"github.com/golang/protobuf/ptypes/any" -> "math";
+"github.com/golang/protobuf/ptypes/duration" [label="github.com/golang/protobuf/ptypes/duration" color="paleturquoise" URL="https://godoc.org/github.com/golang/protobuf/ptypes/duration" target="_blank"];
+"github.com/golang/protobuf/ptypes/duration" -> "fmt";
+"github.com/golang/protobuf/ptypes/duration" -> "github.com/golang/protobuf/proto";
+"github.com/golang/protobuf/ptypes/duration" -> "math";
+"github.com/golang/protobuf/ptypes/timestamp" [label="github.com/golang/protobuf/ptypes/timestamp" color="paleturquoise" URL="https://godoc.org/github.com/golang/protobuf/ptypes/timestamp" target="_blank"];
+"github.com/golang/protobuf/ptypes/timestamp" -> "fmt";
+"github.com/golang/protobuf/ptypes/timestamp" -> "github.com/golang/protobuf/proto";
+"github.com/golang/protobuf/ptypes/timestamp" -> "math";
+"github.com/opencontainers/go-digest" [label="github.com/opencontainers/go-digest" color="palegoldenrod" URL="https://godoc.org/github.com/opencontainers/go-digest" target="_blank"];
+"github.com/opencontainers/go-digest" -> "crypto";
+"github.com/opencontainers/go-digest" -> "fmt";
+"github.com/opencontainers/go-digest" -> "hash";
+"github.com/opencontainers/go-digest" -> "io";
+"github.com/opencontainers/go-digest" -> "regexp";
+"github.com/opencontainers/go-digest" -> "strings";
+"github.com/opencontainers/image-spec/specs-go" [label="github.com/opencontainers/image-spec/specs-go" color="palegoldenrod" URL="https://godoc.org/github.com/opencontainers/image-spec/specs-go" target="_blank"];
+"github.com/opencontainers/image-spec/specs-go" -> "fmt";
+"github.com/opencontainers/image-spec/specs-go/v1" [label="github.com/opencontainers/image-spec/specs-go/v1" color="palegoldenrod" URL="https://godoc.org/github.com/opencontainers/image-spec/specs-go/v1" target="_blank"];
+"github.com/opencontainers/image-spec/specs-go/v1" -> "github.com/opencontainers/go-digest";
+"github.com/opencontainers/image-spec/specs-go/v1" -> "github.com/opencontainers/image-spec/specs-go";
+"github.com/opencontainers/image-spec/specs-go/v1" -> "time";
+"github.com/pkg/errors" [label="github.com/pkg/errors" color="palegoldenrod" URL="https://godoc.org/github.com/pkg/errors" target="_blank"];
+"github.com/pkg/errors" -> "fmt";
+"github.com/pkg/errors" -> "io";
+"github.com/pkg/errors" -> "path";
+"github.com/pkg/errors" -> "runtime";
+"github.com/pkg/errors" -> "strings";
+"github.com/sirupsen/logrus" [label="github.com/sirupsen/logrus" color="palegoldenrod" URL="https://godoc.org/github.com/sirupsen/logrus" target="_blank"];
+"github.com/sirupsen/logrus" -> "bufio";
+"github.com/sirupsen/logrus" -> "bytes";
+"github.com/sirupsen/logrus" -> "context";
+"github.com/sirupsen/logrus" -> "encoding/json";
+"github.com/sirupsen/logrus" -> "fmt";
+"github.com/sirupsen/logrus" -> "golang.org/x/sys/unix";
+"github.com/sirupsen/logrus" -> "io";
+"github.com/sirupsen/logrus" -> "log";
+"github.com/sirupsen/logrus" -> "os";
+"github.com/sirupsen/logrus" -> "reflect";
+"github.com/sirupsen/logrus" -> "runtime";
+"github.com/sirupsen/logrus" -> "sort";
+"github.com/sirupsen/logrus" -> "strings";
+"github.com/sirupsen/logrus" -> "sync";
+"github.com/sirupsen/logrus" -> "sync/atomic";
+"github.com/sirupsen/logrus" -> "time";
+"golang.org/x/net/context/ctxhttp" [label="golang.org/x/net/context/ctxhttp" color="palegoldenrod" URL="https://godoc.org/golang.org/x/net/context/ctxhttp" target="_blank"];
+"golang.org/x/net/context/ctxhttp" -> "context";
+"golang.org/x/net/context/ctxhttp" -> "io";
+"golang.org/x/net/context/ctxhttp" -> "net/http";
+"golang.org/x/net/context/ctxhttp" -> "net/url";
+"golang.org/x/net/context/ctxhttp" -> "strings";
+"golang.org/x/sync/errgroup" [label="golang.org/x/sync/errgroup" color="palegoldenrod" URL="https://godoc.org/golang.org/x/sync/errgroup" target="_blank"];
+"golang.org/x/sync/errgroup" -> "context";
+"golang.org/x/sync/errgroup" -> "sync";
+"golang.org/x/sync/semaphore" [label="golang.org/x/sync/semaphore" color="palegoldenrod" URL="https://godoc.org/golang.org/x/sync/semaphore" target="_blank"];
+"golang.org/x/sync/semaphore" -> "container/list";
+"golang.org/x/sync/semaphore" -> "context";
+"golang.org/x/sync/semaphore" -> "sync";
+"golang.org/x/sys/unix" [label="golang.org/x/sys/unix" color="paleturquoise" URL="https://godoc.org/golang.org/x/sys/unix" target="_blank"];
+"golang.org/x/sys/unix" -> "bytes";
+"golang.org/x/sys/unix" -> "runtime";
+"golang.org/x/sys/unix" -> "sort";
+"golang.org/x/sys/unix" -> "strings";
+"golang.org/x/sys/unix" -> "sync";
+"golang.org/x/sys/unix" -> "syscall";
+"golang.org/x/sys/unix" -> "time";
+"golang.org/x/sys/unix" -> "unsafe";
+"google.golang.org/genproto/googleapis/rpc/status" [label="google.golang.org/genproto/googleapis/rpc/status" color="paleturquoise" URL="https://godoc.org/google.golang.org/genproto/googleapis/rpc/status" target="_blank"];
+"google.golang.org/genproto/googleapis/rpc/status" -> "fmt";
+"google.golang.org/genproto/googleapis/rpc/status" -> "github.com/golang/protobuf/proto";
+"google.golang.org/genproto/googleapis/rpc/status" -> "github.com/golang/protobuf/ptypes/any";
+"google.golang.org/genproto/googleapis/rpc/status" -> "math";
+"google.golang.org/grpc/codes" [label="google.golang.org/grpc/codes" color="palegoldenrod" URL="https://godoc.org/google.golang.org/grpc/codes" target="_blank"];
+"google.golang.org/grpc/codes" -> "fmt";
+"google.golang.org/grpc/codes" -> "strconv";
+"google.golang.org/grpc/connectivity" [label="google.golang.org/grpc/connectivity" color="paleturquoise" URL="https://godoc.org/google.golang.org/grpc/connectivity" target="_blank"];
+"google.golang.org/grpc/connectivity" -> "context";
+"google.golang.org/grpc/connectivity" -> "google.golang.org/grpc/grpclog";
+"google.golang.org/grpc/grpclog" [label="google.golang.org/grpc/grpclog" color="paleturquoise" URL="https://godoc.org/google.golang.org/grpc/grpclog" target="_blank"];
+"google.golang.org/grpc/grpclog" -> "io";
+"google.golang.org/grpc/grpclog" -> "io/ioutil";
+"google.golang.org/grpc/grpclog" -> "log";
+"google.golang.org/grpc/grpclog" -> "os";
+"google.golang.org/grpc/grpclog" -> "strconv";
+"google.golang.org/grpc/internal" [label="google.golang.org/grpc/internal" color="paleturquoise" URL="https://godoc.org/google.golang.org/grpc/internal" target="_blank"];
+"google.golang.org/grpc/internal" -> "context";
+"google.golang.org/grpc/internal" -> "google.golang.org/grpc/connectivity";
+"google.golang.org/grpc/internal" -> "time";
+"google.golang.org/grpc/status" [label="google.golang.org/grpc/status" color="palegoldenrod" URL="https://godoc.org/google.golang.org/grpc/status" target="_blank"];
+"google.golang.org/grpc/status" -> "context";
+"google.golang.org/grpc/status" -> "errors";
+"google.golang.org/grpc/status" -> "fmt";
+"google.golang.org/grpc/status" -> "github.com/golang/protobuf/proto";
+"google.golang.org/grpc/status" -> "github.com/golang/protobuf/ptypes";
+"google.golang.org/grpc/status" -> "google.golang.org/genproto/googleapis/rpc/status";
+"google.golang.org/grpc/status" -> "google.golang.org/grpc/codes";
+"google.golang.org/grpc/status" -> "google.golang.org/grpc/internal";
+"hash" [label="hash" color="palegreen" URL="https://godoc.org/hash" target="_blank"];
+"io" [label="io" color="palegreen" URL="https://godoc.org/io" target="_blank"];
+"io/ioutil" [label="io/ioutil" color="palegreen" URL="https://godoc.org/io/ioutil" target="_blank"];
+"log" [label="log" color="palegreen" URL="https://godoc.org/log" target="_blank"];
+"math" [label="math" color="palegreen" URL="https://godoc.org/math" target="_blank"];
+"math/rand" [label="math/rand" color="palegreen" URL="https://godoc.org/math/rand" target="_blank"];
+"net/http" [label="net/http" color="palegreen" URL="https://godoc.org/net/http" target="_blank"];
+"net/url" [label="net/url" color="palegreen" URL="https://godoc.org/net/url" target="_blank"];
+"os" [label="os" color="palegreen" URL="https://godoc.org/os" target="_blank"];
+"os/exec" [label="os/exec" color="palegreen" URL="https://godoc.org/os/exec" target="_blank"];
+"path" [label="path" color="palegreen" URL="https://godoc.org/path" target="_blank"];
+"reflect" [label="reflect" color="palegreen" URL="https://godoc.org/reflect" target="_blank"];
+"regexp" [label="regexp" color="palegreen" URL="https://godoc.org/regexp" target="_blank"];
+"runtime" [label="runtime" color="palegreen" URL="https://godoc.org/runtime" target="_blank"];
+"sort" [label="sort" color="palegreen" URL="https://godoc.org/sort" target="_blank"];
+"strconv" [label="strconv" color="palegreen" URL="https://godoc.org/strconv" target="_blank"];
+"strings" [label="strings" color="palegreen" URL="https://godoc.org/strings" target="_blank"];
+"sync" [label="sync" color="palegreen" URL="https://godoc.org/sync" target="_blank"];
+"sync/atomic" [label="sync/atomic" color="palegreen" URL="https://godoc.org/sync/atomic" target="_blank"];
+"syscall" [label="syscall" color="palegreen" URL="https://godoc.org/syscall" target="_blank"];
+"time" [label="time" color="palegreen" URL="https://godoc.org/time" target="_blank"];
+"unicode/utf8" [label="unicode/utf8" color="palegreen" URL="https://godoc.org/unicode/utf8" target="_blank"];
+"unsafe" [label="unsafe" color="palegreen" URL="https://godoc.org/unsafe" target="_blank"];
+}
diff --git a/pkg/go-containerregistry/images/dot/containers.dot b/pkg/go-containerregistry/images/dot/containers.dot
new file mode 100644
index 00000000..3e53f846
--- /dev/null
+++ b/pkg/go-containerregistry/images/dot/containers.dot
@@ -0,0 +1,831 @@
+digraph godep {
+rankdir="LR"
+nodesep=0.4
+ranksep=0.8
+node [shape="box",style="rounded,filled"]
+edge [arrowsize="0.5"]
+"bufio" [label="bufio" color="palegreen" URL="https://godoc.org/bufio" target="_blank"];
+"bytes" [label="bytes" color="palegreen" URL="https://godoc.org/bytes" target="_blank"];
+"compress/bzip2" [label="compress/bzip2" color="palegreen" URL="https://godoc.org/compress/bzip2" target="_blank"];
+"compress/gzip" [label="compress/gzip" color="palegreen" URL="https://godoc.org/compress/gzip" target="_blank"];
+"context" [label="context" color="palegreen" URL="https://godoc.org/context" target="_blank"];
+"crypto" [label="crypto" color="palegreen" URL="https://godoc.org/crypto" target="_blank"];
+"crypto/ecdsa" [label="crypto/ecdsa" color="palegreen" URL="https://godoc.org/crypto/ecdsa" target="_blank"];
+"crypto/elliptic" [label="crypto/elliptic" color="palegreen" URL="https://godoc.org/crypto/elliptic" target="_blank"];
+"crypto/rand" [label="crypto/rand" color="palegreen" URL="https://godoc.org/crypto/rand" target="_blank"];
+"crypto/rsa" [label="crypto/rsa" color="palegreen" URL="https://godoc.org/crypto/rsa" target="_blank"];
+"crypto/sha256" [label="crypto/sha256" color="palegreen" URL="https://godoc.org/crypto/sha256" target="_blank"];
+"crypto/sha512" [label="crypto/sha512" color="palegreen" URL="https://godoc.org/crypto/sha512" target="_blank"];
+"crypto/tls" [label="crypto/tls" color="palegreen" URL="https://godoc.org/crypto/tls" target="_blank"];
+"crypto/x509" [label="crypto/x509" color="palegreen" URL="https://godoc.org/crypto/x509" target="_blank"];
+"crypto/x509/pkix" [label="crypto/x509/pkix" color="palegreen" URL="https://godoc.org/crypto/x509/pkix" target="_blank"];
+"encoding" [label="encoding" color="palegreen" URL="https://godoc.org/encoding" target="_blank"];
+"encoding/base32" [label="encoding/base32" color="palegreen" URL="https://godoc.org/encoding/base32" target="_blank"];
+"encoding/base64" [label="encoding/base64" color="palegreen" URL="https://godoc.org/encoding/base64" target="_blank"];
+"encoding/binary" [label="encoding/binary" color="palegreen" URL="https://godoc.org/encoding/binary" target="_blank"];
+"encoding/hex" [label="encoding/hex" color="palegreen" URL="https://godoc.org/encoding/hex" target="_blank"];
+"encoding/json" [label="encoding/json" color="palegreen" URL="https://godoc.org/encoding/json" target="_blank"];
+"encoding/pem" [label="encoding/pem" color="palegreen" URL="https://godoc.org/encoding/pem" target="_blank"];
+"errors" [label="errors" color="palegreen" URL="https://godoc.org/errors" target="_blank"];
+"expvar" [label="expvar" color="palegreen" URL="https://godoc.org/expvar" target="_blank"];
+"fmt" [label="fmt" color="palegreen" URL="https://godoc.org/fmt" target="_blank"];
+"github.com/BurntSushi/toml" [label="github.com/BurntSushi/toml" color="paleturquoise" URL="https://godoc.org/github.com/BurntSushi/toml" target="_blank"];
+"github.com/BurntSushi/toml" -> "bufio";
+"github.com/BurntSushi/toml" -> "encoding";
+"github.com/BurntSushi/toml" -> "errors";
+"github.com/BurntSushi/toml" -> "fmt";
+"github.com/BurntSushi/toml" -> "io";
+"github.com/BurntSushi/toml" -> "io/ioutil";
+"github.com/BurntSushi/toml" -> "math";
+"github.com/BurntSushi/toml" -> "reflect";
+"github.com/BurntSushi/toml" -> "sort";
+"github.com/BurntSushi/toml" -> "strconv";
+"github.com/BurntSushi/toml" -> "strings";
+"github.com/BurntSushi/toml" -> "sync";
+"github.com/BurntSushi/toml" -> "time";
+"github.com/BurntSushi/toml" -> "unicode";
+"github.com/BurntSushi/toml" -> "unicode/utf8";
+"github.com/beorn7/perks/quantile" [label="github.com/beorn7/perks/quantile" color="paleturquoise" URL="https://godoc.org/github.com/beorn7/perks/quantile" target="_blank"];
+"github.com/beorn7/perks/quantile" -> "math";
+"github.com/beorn7/perks/quantile" -> "sort";
+"github.com/cespare/xxhash/v2" [label="github.com/cespare/xxhash/v2" color="paleturquoise" URL="https://godoc.org/github.com/cespare/xxhash/v2" target="_blank"];
+"github.com/cespare/xxhash/v2" -> "encoding/binary";
+"github.com/cespare/xxhash/v2" -> "errors";
+"github.com/cespare/xxhash/v2" -> "math/bits";
+"github.com/cespare/xxhash/v2" -> "reflect";
+"github.com/cespare/xxhash/v2" -> "unsafe";
+"github.com/containers/image/docker" [label="github.com/containers/image/docker" color="paleturquoise" URL="https://godoc.org/github.com/containers/image/docker" target="_blank"];
+"github.com/containers/image/docker" -> "bytes";
+"github.com/containers/image/docker" -> "context";
+"github.com/containers/image/docker" -> "crypto/rand";
+"github.com/containers/image/docker" -> "crypto/tls";
+"github.com/containers/image/docker" -> "encoding/json";
+"github.com/containers/image/docker" -> "errors";
+"github.com/containers/image/docker" -> "fmt";
+"github.com/containers/image/docker" -> "github.com/containers/image/v5/docker/policyconfiguration";
+"github.com/containers/image/docker" -> "github.com/containers/image/v5/docker/reference";
+"github.com/containers/image/docker" -> "github.com/containers/image/v5/image";
+"github.com/containers/image/docker" -> "github.com/containers/image/v5/manifest";
+"github.com/containers/image/docker" -> "github.com/containers/image/v5/pkg/blobinfocache/none";
+"github.com/containers/image/docker" -> "github.com/containers/image/v5/pkg/docker/config";
+"github.com/containers/image/docker" -> "github.com/containers/image/v5/pkg/sysregistriesv2";
+"github.com/containers/image/docker" -> "github.com/containers/image/v5/pkg/tlsclientconfig";
+"github.com/containers/image/docker" -> "github.com/containers/image/v5/transports";
+"github.com/containers/image/docker" -> "github.com/containers/image/v5/types";
+"github.com/containers/image/docker" -> "github.com/docker/distribution/registry/api/errcode";
+"github.com/containers/image/docker" -> "github.com/docker/distribution/registry/api/v2";
+"github.com/containers/image/docker" -> "github.com/docker/distribution/registry/client";
+"github.com/containers/image/docker" -> "github.com/docker/go-connections/tlsconfig";
+"github.com/containers/image/docker" -> "github.com/ghodss/yaml";
+"github.com/containers/image/docker" -> "github.com/opencontainers/go-digest";
+"github.com/containers/image/docker" -> "github.com/opencontainers/image-spec/specs-go/v1";
+"github.com/containers/image/docker" -> "github.com/pkg/errors";
+"github.com/containers/image/docker" -> "github.com/sirupsen/logrus";
+"github.com/containers/image/docker" -> "io";
+"github.com/containers/image/docker" -> "io/ioutil";
+"github.com/containers/image/docker" -> "mime";
+"github.com/containers/image/docker" -> "net/http";
+"github.com/containers/image/docker" -> "net/url";
+"github.com/containers/image/docker" -> "os";
+"github.com/containers/image/docker" -> "path";
+"github.com/containers/image/docker" -> "path/filepath";
+"github.com/containers/image/docker" -> "strconv";
+"github.com/containers/image/docker" -> "strings";
+"github.com/containers/image/docker" -> "sync";
+"github.com/containers/image/docker" -> "time";
+"github.com/containers/image/v5/docker/policyconfiguration" [label="github.com/containers/image/v5/docker/policyconfiguration" color="paleturquoise" URL="https://godoc.org/github.com/containers/image/v5/docker/policyconfiguration" target="_blank"];
+"github.com/containers/image/v5/docker/policyconfiguration" -> "github.com/containers/image/v5/docker/reference";
+"github.com/containers/image/v5/docker/policyconfiguration" -> "github.com/pkg/errors";
+"github.com/containers/image/v5/docker/policyconfiguration" -> "strings";
+"github.com/containers/image/v5/docker/reference" [label="github.com/containers/image/v5/docker/reference" color="paleturquoise" URL="https://godoc.org/github.com/containers/image/v5/docker/reference" target="_blank"];
+"github.com/containers/image/v5/docker/reference" -> "errors";
+"github.com/containers/image/v5/docker/reference" -> "fmt";
+"github.com/containers/image/v5/docker/reference" -> "github.com/opencontainers/go-digest";
+"github.com/containers/image/v5/docker/reference" -> "path";
+"github.com/containers/image/v5/docker/reference" -> "regexp";
+"github.com/containers/image/v5/docker/reference" -> "strings";
+"github.com/containers/image/v5/image" [label="github.com/containers/image/v5/image" color="paleturquoise" URL="https://godoc.org/github.com/containers/image/v5/image" target="_blank"];
+"github.com/containers/image/v5/image" -> "bytes";
+"github.com/containers/image/v5/image" -> "context";
+"github.com/containers/image/v5/image" -> "crypto/sha256";
+"github.com/containers/image/v5/image" -> "encoding/hex";
+"github.com/containers/image/v5/image" -> "encoding/json";
+"github.com/containers/image/v5/image" -> "fmt";
+"github.com/containers/image/v5/image" -> "github.com/containers/image/v5/docker/reference";
+"github.com/containers/image/v5/image" -> "github.com/containers/image/v5/manifest";
+"github.com/containers/image/v5/image" -> "github.com/containers/image/v5/pkg/blobinfocache/none";
+"github.com/containers/image/v5/image" -> "github.com/containers/image/v5/types";
+"github.com/containers/image/v5/image" -> "github.com/opencontainers/go-digest";
+"github.com/containers/image/v5/image" -> "github.com/opencontainers/image-spec/specs-go/v1";
+"github.com/containers/image/v5/image" -> "github.com/pkg/errors";
+"github.com/containers/image/v5/image" -> "github.com/sirupsen/logrus";
+"github.com/containers/image/v5/image" -> "io/ioutil";
+"github.com/containers/image/v5/image" -> "strings";
+"github.com/containers/image/v5/internal/pkg/keyctl" [label="github.com/containers/image/v5/internal/pkg/keyctl" color="paleturquoise" URL="https://godoc.org/github.com/containers/image/v5/internal/pkg/keyctl" target="_blank"];
+"github.com/containers/image/v5/internal/pkg/keyctl" -> "golang.org/x/sys/unix";
+"github.com/containers/image/v5/internal/pkg/keyctl" -> "unsafe";
+"github.com/containers/image/v5/manifest" [label="github.com/containers/image/v5/manifest" color="paleturquoise" URL="https://godoc.org/github.com/containers/image/v5/manifest" target="_blank"];
+"github.com/containers/image/v5/manifest" -> "encoding/json";
+"github.com/containers/image/v5/manifest" -> "fmt";
+"github.com/containers/image/v5/manifest" -> "github.com/containers/image/v5/docker/reference";
+"github.com/containers/image/v5/manifest" -> "github.com/containers/image/v5/pkg/compression";
+"github.com/containers/image/v5/manifest" -> "github.com/containers/image/v5/pkg/strslice";
+"github.com/containers/image/v5/manifest" -> "github.com/containers/image/v5/types";
+"github.com/containers/image/v5/manifest" -> "github.com/containers/libtrust";
+"github.com/containers/image/v5/manifest" -> "github.com/containers/ocicrypt/spec";
+"github.com/containers/image/v5/manifest" -> "github.com/docker/docker/api/types/versions";
+"github.com/containers/image/v5/manifest" -> "github.com/opencontainers/go-digest";
+"github.com/containers/image/v5/manifest" -> "github.com/opencontainers/image-spec/specs-go";
+"github.com/containers/image/v5/manifest" -> "github.com/opencontainers/image-spec/specs-go/v1";
+"github.com/containers/image/v5/manifest" -> "github.com/pkg/errors";
+"github.com/containers/image/v5/manifest" -> "github.com/sirupsen/logrus";
+"github.com/containers/image/v5/manifest" -> "regexp";
+"github.com/containers/image/v5/manifest" -> "runtime";
+"github.com/containers/image/v5/manifest" -> "strings";
+"github.com/containers/image/v5/manifest" -> "time";
+"github.com/containers/image/v5/pkg/blobinfocache/none" [label="github.com/containers/image/v5/pkg/blobinfocache/none" color="paleturquoise" URL="https://godoc.org/github.com/containers/image/v5/pkg/blobinfocache/none" target="_blank"];
+"github.com/containers/image/v5/pkg/blobinfocache/none" -> "github.com/containers/image/v5/types";
+"github.com/containers/image/v5/pkg/blobinfocache/none" -> "github.com/opencontainers/go-digest";
+"github.com/containers/image/v5/pkg/compression" [label="github.com/containers/image/v5/pkg/compression" color="paleturquoise" URL="https://godoc.org/github.com/containers/image/v5/pkg/compression" target="_blank"];
+"github.com/containers/image/v5/pkg/compression" -> "bytes";
+"github.com/containers/image/v5/pkg/compression" -> "compress/bzip2";
+"github.com/containers/image/v5/pkg/compression" -> "fmt";
+"github.com/containers/image/v5/pkg/compression" -> "github.com/containers/image/v5/pkg/compression/internal";
+"github.com/containers/image/v5/pkg/compression" -> "github.com/containers/image/v5/pkg/compression/types";
+"github.com/containers/image/v5/pkg/compression" -> "github.com/klauspost/compress/zstd";
+"github.com/containers/image/v5/pkg/compression" -> "github.com/klauspost/pgzip";
+"github.com/containers/image/v5/pkg/compression" -> "github.com/pkg/errors";
+"github.com/containers/image/v5/pkg/compression" -> "github.com/sirupsen/logrus";
+"github.com/containers/image/v5/pkg/compression" -> "github.com/ulikunitz/xz";
+"github.com/containers/image/v5/pkg/compression" -> "io";
+"github.com/containers/image/v5/pkg/compression" -> "io/ioutil";
+"github.com/containers/image/v5/pkg/compression/internal" [label="github.com/containers/image/v5/pkg/compression/internal" color="paleturquoise" URL="https://godoc.org/github.com/containers/image/v5/pkg/compression/internal" target="_blank"];
+"github.com/containers/image/v5/pkg/compression/internal" -> "io";
+"github.com/containers/image/v5/pkg/compression/types" [label="github.com/containers/image/v5/pkg/compression/types" color="paleturquoise" URL="https://godoc.org/github.com/containers/image/v5/pkg/compression/types" target="_blank"];
+"github.com/containers/image/v5/pkg/compression/types" -> "github.com/containers/image/v5/pkg/compression/internal";
+"github.com/containers/image/v5/pkg/docker/config" [label="github.com/containers/image/v5/pkg/docker/config" color="paleturquoise" URL="https://godoc.org/github.com/containers/image/v5/pkg/docker/config" target="_blank"];
+"github.com/containers/image/v5/pkg/docker/config" -> "encoding/base64";
+"github.com/containers/image/v5/pkg/docker/config" -> "encoding/json";
+"github.com/containers/image/v5/pkg/docker/config" -> "fmt";
+"github.com/containers/image/v5/pkg/docker/config" -> "github.com/containers/image/v5/internal/pkg/keyctl";
+"github.com/containers/image/v5/pkg/docker/config" -> "github.com/containers/image/v5/types";
+"github.com/containers/image/v5/pkg/docker/config" -> "github.com/docker/docker-credential-helpers/client";
+"github.com/containers/image/v5/pkg/docker/config" -> "github.com/docker/docker-credential-helpers/credentials";
+"github.com/containers/image/v5/pkg/docker/config" -> "github.com/docker/docker/pkg/homedir";
+"github.com/containers/image/v5/pkg/docker/config" -> "github.com/pkg/errors";
+"github.com/containers/image/v5/pkg/docker/config" -> "github.com/sirupsen/logrus";
+"github.com/containers/image/v5/pkg/docker/config" -> "io/ioutil";
+"github.com/containers/image/v5/pkg/docker/config" -> "os";
+"github.com/containers/image/v5/pkg/docker/config" -> "path/filepath";
+"github.com/containers/image/v5/pkg/docker/config" -> "strings";
+"github.com/containers/image/v5/pkg/strslice" [label="github.com/containers/image/v5/pkg/strslice" color="paleturquoise" URL="https://godoc.org/github.com/containers/image/v5/pkg/strslice" target="_blank"];
+"github.com/containers/image/v5/pkg/strslice" -> "encoding/json";
+"github.com/containers/image/v5/pkg/sysregistriesv2" [label="github.com/containers/image/v5/pkg/sysregistriesv2" color="paleturquoise" URL="https://godoc.org/github.com/containers/image/v5/pkg/sysregistriesv2" target="_blank"];
+"github.com/containers/image/v5/pkg/sysregistriesv2" -> "fmt";
+"github.com/containers/image/v5/pkg/sysregistriesv2" -> "github.com/BurntSushi/toml";
+"github.com/containers/image/v5/pkg/sysregistriesv2" -> "github.com/containers/image/v5/docker/reference";
+"github.com/containers/image/v5/pkg/sysregistriesv2" -> "github.com/containers/image/v5/types";
+"github.com/containers/image/v5/pkg/sysregistriesv2" -> "github.com/pkg/errors";
+"github.com/containers/image/v5/pkg/sysregistriesv2" -> "github.com/sirupsen/logrus";
+"github.com/containers/image/v5/pkg/sysregistriesv2" -> "io/ioutil";
+"github.com/containers/image/v5/pkg/sysregistriesv2" -> "os";
+"github.com/containers/image/v5/pkg/sysregistriesv2" -> "path/filepath";
+"github.com/containers/image/v5/pkg/sysregistriesv2" -> "regexp";
+"github.com/containers/image/v5/pkg/sysregistriesv2" -> "strings";
+"github.com/containers/image/v5/pkg/sysregistriesv2" -> "sync";
+"github.com/containers/image/v5/pkg/tlsclientconfig" [label="github.com/containers/image/v5/pkg/tlsclientconfig" color="paleturquoise" URL="https://godoc.org/github.com/containers/image/v5/pkg/tlsclientconfig" target="_blank"];
+"github.com/containers/image/v5/pkg/tlsclientconfig" -> "crypto/tls";
+"github.com/containers/image/v5/pkg/tlsclientconfig" -> "github.com/docker/go-connections/sockets";
+"github.com/containers/image/v5/pkg/tlsclientconfig" -> "github.com/docker/go-connections/tlsconfig";
+"github.com/containers/image/v5/pkg/tlsclientconfig" -> "github.com/pkg/errors";
+"github.com/containers/image/v5/pkg/tlsclientconfig" -> "github.com/sirupsen/logrus";
+"github.com/containers/image/v5/pkg/tlsclientconfig" -> "io/ioutil";
+"github.com/containers/image/v5/pkg/tlsclientconfig" -> "net";
+"github.com/containers/image/v5/pkg/tlsclientconfig" -> "net/http";
+"github.com/containers/image/v5/pkg/tlsclientconfig" -> "os";
+"github.com/containers/image/v5/pkg/tlsclientconfig" -> "path/filepath";
+"github.com/containers/image/v5/pkg/tlsclientconfig" -> "strings";
+"github.com/containers/image/v5/pkg/tlsclientconfig" -> "time";
+"github.com/containers/image/v5/transports" [label="github.com/containers/image/v5/transports" color="paleturquoise" URL="https://godoc.org/github.com/containers/image/v5/transports" target="_blank"];
+"github.com/containers/image/v5/transports" -> "fmt";
+"github.com/containers/image/v5/transports" -> "github.com/containers/image/v5/types";
+"github.com/containers/image/v5/transports" -> "sort";
+"github.com/containers/image/v5/transports" -> "sync";
+"github.com/containers/image/v5/types" [label="github.com/containers/image/v5/types" color="paleturquoise" URL="https://godoc.org/github.com/containers/image/v5/types" target="_blank"];
+"github.com/containers/image/v5/types" -> "context";
+"github.com/containers/image/v5/types" -> "github.com/containers/image/v5/docker/reference";
+"github.com/containers/image/v5/types" -> "github.com/containers/image/v5/pkg/compression/types";
+"github.com/containers/image/v5/types" -> "github.com/opencontainers/go-digest";
+"github.com/containers/image/v5/types" -> "github.com/opencontainers/image-spec/specs-go/v1";
+"github.com/containers/image/v5/types" -> "io";
+"github.com/containers/image/v5/types" -> "time";
+"github.com/containers/libtrust" [label="github.com/containers/libtrust" color="paleturquoise" URL="https://godoc.org/github.com/containers/libtrust" target="_blank"];
+"github.com/containers/libtrust" -> "bytes";
+"github.com/containers/libtrust" -> "crypto";
+"github.com/containers/libtrust" -> "crypto/ecdsa";
+"github.com/containers/libtrust" -> "crypto/elliptic";
+"github.com/containers/libtrust" -> "crypto/rand";
+"github.com/containers/libtrust" -> "crypto/rsa";
+"github.com/containers/libtrust" -> "crypto/sha256";
+"github.com/containers/libtrust" -> "crypto/sha512";
+"github.com/containers/libtrust" -> "crypto/tls";
+"github.com/containers/libtrust" -> "crypto/x509";
+"github.com/containers/libtrust" -> "crypto/x509/pkix";
+"github.com/containers/libtrust" -> "encoding/base32";
+"github.com/containers/libtrust" -> "encoding/base64";
+"github.com/containers/libtrust" -> "encoding/binary";
+"github.com/containers/libtrust" -> "encoding/json";
+"github.com/containers/libtrust" -> "encoding/pem";
+"github.com/containers/libtrust" -> "errors";
+"github.com/containers/libtrust" -> "fmt";
+"github.com/containers/libtrust" -> "io";
+"github.com/containers/libtrust" -> "io/ioutil";
+"github.com/containers/libtrust" -> "math/big";
+"github.com/containers/libtrust" -> "net";
+"github.com/containers/libtrust" -> "net/url";
+"github.com/containers/libtrust" -> "os";
+"github.com/containers/libtrust" -> "path";
+"github.com/containers/libtrust" -> "path/filepath";
+"github.com/containers/libtrust" -> "sort";
+"github.com/containers/libtrust" -> "strings";
+"github.com/containers/libtrust" -> "sync";
+"github.com/containers/libtrust" -> "time";
+"github.com/containers/libtrust" -> "unicode";
+"github.com/containers/ocicrypt/spec" [label="github.com/containers/ocicrypt/spec" color="paleturquoise" URL="https://godoc.org/github.com/containers/ocicrypt/spec" target="_blank"];
+"github.com/docker/distribution" [label="github.com/docker/distribution" color="paleturquoise" URL="https://godoc.org/github.com/docker/distribution" target="_blank"];
+"github.com/docker/distribution" -> "context";
+"github.com/docker/distribution" -> "errors";
+"github.com/docker/distribution" -> "fmt";
+"github.com/docker/distribution" -> "github.com/docker/distribution/reference";
+"github.com/docker/distribution" -> "github.com/opencontainers/go-digest";
+"github.com/docker/distribution" -> "github.com/opencontainers/image-spec/specs-go/v1";
+"github.com/docker/distribution" -> "io";
+"github.com/docker/distribution" -> "mime";
+"github.com/docker/distribution" -> "net/http";
+"github.com/docker/distribution" -> "strings";
+"github.com/docker/distribution" -> "time";
+"github.com/docker/distribution/digestset" [label="github.com/docker/distribution/digestset" color="paleturquoise" URL="https://godoc.org/github.com/docker/distribution/digestset" target="_blank"];
+"github.com/docker/distribution/digestset" -> "errors";
+"github.com/docker/distribution/digestset" -> "github.com/opencontainers/go-digest";
+"github.com/docker/distribution/digestset" -> "sort";
+"github.com/docker/distribution/digestset" -> "strings";
+"github.com/docker/distribution/digestset" -> "sync";
+"github.com/docker/distribution/metrics" [label="github.com/docker/distribution/metrics" color="paleturquoise" URL="https://godoc.org/github.com/docker/distribution/metrics" target="_blank"];
+"github.com/docker/distribution/metrics" -> "github.com/docker/go-metrics";
+"github.com/docker/distribution/reference" [label="github.com/docker/distribution/reference" color="paleturquoise" URL="https://godoc.org/github.com/docker/distribution/reference" target="_blank"];
+"github.com/docker/distribution/reference" -> "errors";
+"github.com/docker/distribution/reference" -> "fmt";
+"github.com/docker/distribution/reference" -> "github.com/docker/distribution/digestset";
+"github.com/docker/distribution/reference" -> "github.com/opencontainers/go-digest";
+"github.com/docker/distribution/reference" -> "path";
+"github.com/docker/distribution/reference" -> "regexp";
+"github.com/docker/distribution/reference" -> "strings";
+"github.com/docker/distribution/registry/api/errcode" [label="github.com/docker/distribution/registry/api/errcode" color="paleturquoise" URL="https://godoc.org/github.com/docker/distribution/registry/api/errcode" target="_blank"];
+"github.com/docker/distribution/registry/api/errcode" -> "encoding/json";
+"github.com/docker/distribution/registry/api/errcode" -> "fmt";
+"github.com/docker/distribution/registry/api/errcode" -> "net/http";
+"github.com/docker/distribution/registry/api/errcode" -> "sort";
+"github.com/docker/distribution/registry/api/errcode" -> "strings";
+"github.com/docker/distribution/registry/api/errcode" -> "sync";
+"github.com/docker/distribution/registry/api/v2" [label="github.com/docker/distribution/registry/api/v2" color="paleturquoise" URL="https://godoc.org/github.com/docker/distribution/registry/api/v2" target="_blank"];
+"github.com/docker/distribution/registry/api/v2" -> "fmt";
+"github.com/docker/distribution/registry/api/v2" -> "github.com/docker/distribution/reference";
+"github.com/docker/distribution/registry/api/v2" -> "github.com/docker/distribution/registry/api/errcode";
+"github.com/docker/distribution/registry/api/v2" -> "github.com/gorilla/mux";
+"github.com/docker/distribution/registry/api/v2" -> "github.com/opencontainers/go-digest";
+"github.com/docker/distribution/registry/api/v2" -> "net/http";
+"github.com/docker/distribution/registry/api/v2" -> "net/url";
+"github.com/docker/distribution/registry/api/v2" -> "regexp";
+"github.com/docker/distribution/registry/api/v2" -> "strings";
+"github.com/docker/distribution/registry/api/v2" -> "unicode";
+"github.com/docker/distribution/registry/client" [label="github.com/docker/distribution/registry/client" color="paleturquoise" URL="https://godoc.org/github.com/docker/distribution/registry/client" target="_blank"];
+"github.com/docker/distribution/registry/client" -> "bytes";
+"github.com/docker/distribution/registry/client" -> "context";
+"github.com/docker/distribution/registry/client" -> "encoding/json";
+"github.com/docker/distribution/registry/client" -> "errors";
+"github.com/docker/distribution/registry/client" -> "fmt";
+"github.com/docker/distribution/registry/client" -> "github.com/docker/distribution";
+"github.com/docker/distribution/registry/client" -> "github.com/docker/distribution/reference";
+"github.com/docker/distribution/registry/client" -> "github.com/docker/distribution/registry/api/errcode";
+"github.com/docker/distribution/registry/client" -> "github.com/docker/distribution/registry/api/v2";
+"github.com/docker/distribution/registry/client" -> "github.com/docker/distribution/registry/client/auth/challenge";
+"github.com/docker/distribution/registry/client" -> "github.com/docker/distribution/registry/client/transport";
+"github.com/docker/distribution/registry/client" -> "github.com/docker/distribution/registry/storage/cache";
+"github.com/docker/distribution/registry/client" -> "github.com/docker/distribution/registry/storage/cache/memory";
+"github.com/docker/distribution/registry/client" -> "github.com/opencontainers/go-digest";
+"github.com/docker/distribution/registry/client" -> "io";
+"github.com/docker/distribution/registry/client" -> "io/ioutil";
+"github.com/docker/distribution/registry/client" -> "net/http";
+"github.com/docker/distribution/registry/client" -> "net/url";
+"github.com/docker/distribution/registry/client" -> "strconv";
+"github.com/docker/distribution/registry/client" -> "strings";
+"github.com/docker/distribution/registry/client" -> "time";
+"github.com/docker/distribution/registry/client/auth/challenge" [label="github.com/docker/distribution/registry/client/auth/challenge" color="paleturquoise" URL="https://godoc.org/github.com/docker/distribution/registry/client/auth/challenge" target="_blank"];
+"github.com/docker/distribution/registry/client/auth/challenge" -> "fmt";
+"github.com/docker/distribution/registry/client/auth/challenge" -> "net/http";
+"github.com/docker/distribution/registry/client/auth/challenge" -> "net/url";
+"github.com/docker/distribution/registry/client/auth/challenge" -> "strings";
+"github.com/docker/distribution/registry/client/auth/challenge" -> "sync";
+"github.com/docker/distribution/registry/client/transport" [label="github.com/docker/distribution/registry/client/transport" color="paleturquoise" URL="https://godoc.org/github.com/docker/distribution/registry/client/transport" target="_blank"];
+"github.com/docker/distribution/registry/client/transport" -> "errors";
+"github.com/docker/distribution/registry/client/transport" -> "fmt";
+"github.com/docker/distribution/registry/client/transport" -> "io";
+"github.com/docker/distribution/registry/client/transport" -> "net/http";
+"github.com/docker/distribution/registry/client/transport" -> "regexp";
+"github.com/docker/distribution/registry/client/transport" -> "strconv";
+"github.com/docker/distribution/registry/client/transport" -> "sync";
+"github.com/docker/distribution/registry/storage/cache" [label="github.com/docker/distribution/registry/storage/cache" color="paleturquoise" URL="https://godoc.org/github.com/docker/distribution/registry/storage/cache" target="_blank"];
+"github.com/docker/distribution/registry/storage/cache" -> "context";
+"github.com/docker/distribution/registry/storage/cache" -> "fmt";
+"github.com/docker/distribution/registry/storage/cache" -> "github.com/docker/distribution";
+"github.com/docker/distribution/registry/storage/cache" -> "github.com/docker/distribution/metrics";
+"github.com/docker/distribution/registry/storage/cache" -> "github.com/opencontainers/go-digest";
+"github.com/docker/distribution/registry/storage/cache/memory" [label="github.com/docker/distribution/registry/storage/cache/memory" color="paleturquoise" URL="https://godoc.org/github.com/docker/distribution/registry/storage/cache/memory" target="_blank"];
+"github.com/docker/distribution/registry/storage/cache/memory" -> "context";
+"github.com/docker/distribution/registry/storage/cache/memory" -> "github.com/docker/distribution";
+"github.com/docker/distribution/registry/storage/cache/memory" -> "github.com/docker/distribution/reference";
+"github.com/docker/distribution/registry/storage/cache/memory" -> "github.com/docker/distribution/registry/storage/cache";
+"github.com/docker/distribution/registry/storage/cache/memory" -> "github.com/opencontainers/go-digest";
+"github.com/docker/distribution/registry/storage/cache/memory" -> "sync";
+"github.com/docker/docker-credential-helpers/client" [label="github.com/docker/docker-credential-helpers/client" color="paleturquoise" URL="https://godoc.org/github.com/docker/docker-credential-helpers/client" target="_blank"];
+"github.com/docker/docker-credential-helpers/client" -> "bytes";
+"github.com/docker/docker-credential-helpers/client" -> "encoding/json";
+"github.com/docker/docker-credential-helpers/client" -> "fmt";
+"github.com/docker/docker-credential-helpers/client" -> "github.com/docker/docker-credential-helpers/credentials";
+"github.com/docker/docker-credential-helpers/client" -> "io";
+"github.com/docker/docker-credential-helpers/client" -> "os";
+"github.com/docker/docker-credential-helpers/client" -> "os/exec";
+"github.com/docker/docker-credential-helpers/client" -> "strings";
+"github.com/docker/docker-credential-helpers/credentials" [label="github.com/docker/docker-credential-helpers/credentials" color="paleturquoise" URL="https://godoc.org/github.com/docker/docker-credential-helpers/credentials" target="_blank"];
+"github.com/docker/docker-credential-helpers/credentials" -> "bufio";
+"github.com/docker/docker-credential-helpers/credentials" -> "bytes";
+"github.com/docker/docker-credential-helpers/credentials" -> "encoding/json";
+"github.com/docker/docker-credential-helpers/credentials" -> "fmt";
+"github.com/docker/docker-credential-helpers/credentials" -> "io";
+"github.com/docker/docker-credential-helpers/credentials" -> "os";
+"github.com/docker/docker-credential-helpers/credentials" -> "strings";
+"github.com/docker/docker/api/types/versions" [label="github.com/docker/docker/api/types/versions" color="paleturquoise" URL="https://godoc.org/github.com/docker/docker/api/types/versions" target="_blank"];
+"github.com/docker/docker/api/types/versions" -> "strconv";
+"github.com/docker/docker/api/types/versions" -> "strings";
+"github.com/docker/docker/pkg/homedir" [label="github.com/docker/docker/pkg/homedir" color="paleturquoise" URL="https://godoc.org/github.com/docker/docker/pkg/homedir" target="_blank"];
+"github.com/docker/docker/pkg/homedir" -> "github.com/docker/docker/pkg/idtools";
+"github.com/docker/docker/pkg/homedir" -> "github.com/opencontainers/runc/libcontainer/user";
+"github.com/docker/docker/pkg/homedir" -> "os";
+"github.com/docker/docker/pkg/idtools" [label="github.com/docker/docker/pkg/idtools" color="paleturquoise" URL="https://godoc.org/github.com/docker/docker/pkg/idtools" target="_blank"];
+"github.com/docker/docker/pkg/idtools" -> "bufio";
+"github.com/docker/docker/pkg/idtools" -> "bytes";
+"github.com/docker/docker/pkg/idtools" -> "fmt";
+"github.com/docker/docker/pkg/idtools" -> "github.com/docker/docker/pkg/system";
+"github.com/docker/docker/pkg/idtools" -> "github.com/opencontainers/runc/libcontainer/user";
+"github.com/docker/docker/pkg/idtools" -> "io";
+"github.com/docker/docker/pkg/idtools" -> "os";
+"github.com/docker/docker/pkg/idtools" -> "os/exec";
+"github.com/docker/docker/pkg/idtools" -> "path/filepath";
+"github.com/docker/docker/pkg/idtools" -> "regexp";
+"github.com/docker/docker/pkg/idtools" -> "sort";
+"github.com/docker/docker/pkg/idtools" -> "strconv";
+"github.com/docker/docker/pkg/idtools" -> "strings";
+"github.com/docker/docker/pkg/idtools" -> "sync";
+"github.com/docker/docker/pkg/idtools" -> "syscall";
+"github.com/docker/docker/pkg/mount" [label="github.com/docker/docker/pkg/mount" color="paleturquoise" URL="https://godoc.org/github.com/docker/docker/pkg/mount" target="_blank"];
+"github.com/docker/docker/pkg/mount" -> "bufio";
+"github.com/docker/docker/pkg/mount" -> "fmt";
+"github.com/docker/docker/pkg/mount" -> "github.com/pkg/errors";
+"github.com/docker/docker/pkg/mount" -> "github.com/sirupsen/logrus";
+"github.com/docker/docker/pkg/mount" -> "golang.org/x/sys/unix";
+"github.com/docker/docker/pkg/mount" -> "io";
+"github.com/docker/docker/pkg/mount" -> "os";
+"github.com/docker/docker/pkg/mount" -> "sort";
+"github.com/docker/docker/pkg/mount" -> "strconv";
+"github.com/docker/docker/pkg/mount" -> "strings";
+"github.com/docker/docker/pkg/system" [label="github.com/docker/docker/pkg/system" color="paleturquoise" URL="https://godoc.org/github.com/docker/docker/pkg/system" target="_blank"];
+"github.com/docker/docker/pkg/system" -> "bufio";
+"github.com/docker/docker/pkg/system" -> "errors";
+"github.com/docker/docker/pkg/system" -> "fmt";
+"github.com/docker/docker/pkg/system" -> "github.com/docker/docker/pkg/mount";
+"github.com/docker/docker/pkg/system" -> "github.com/docker/go-units";
+"github.com/docker/docker/pkg/system" -> "github.com/opencontainers/image-spec/specs-go/v1";
+"github.com/docker/docker/pkg/system" -> "github.com/pkg/errors";
+"github.com/docker/docker/pkg/system" -> "golang.org/x/sys/unix";
+"github.com/docker/docker/pkg/system" -> "io";
+"github.com/docker/docker/pkg/system" -> "io/ioutil";
+"github.com/docker/docker/pkg/system" -> "os";
+"github.com/docker/docker/pkg/system" -> "os/exec";
+"github.com/docker/docker/pkg/system" -> "path/filepath";
+"github.com/docker/docker/pkg/system" -> "runtime";
+"github.com/docker/docker/pkg/system" -> "strconv";
+"github.com/docker/docker/pkg/system" -> "strings";
+"github.com/docker/docker/pkg/system" -> "syscall";
+"github.com/docker/docker/pkg/system" -> "time";
+"github.com/docker/docker/pkg/system" -> "unsafe";
+"github.com/docker/go-connections/sockets" [label="github.com/docker/go-connections/sockets" color="paleturquoise" URL="https://godoc.org/github.com/docker/go-connections/sockets" target="_blank"];
+"github.com/docker/go-connections/sockets" -> "crypto/tls";
+"github.com/docker/go-connections/sockets" -> "errors";
+"github.com/docker/go-connections/sockets" -> "fmt";
+"github.com/docker/go-connections/sockets" -> "golang.org/x/net/proxy";
+"github.com/docker/go-connections/sockets" -> "net";
+"github.com/docker/go-connections/sockets" -> "net/http";
+"github.com/docker/go-connections/sockets" -> "net/url";
+"github.com/docker/go-connections/sockets" -> "os";
+"github.com/docker/go-connections/sockets" -> "strings";
+"github.com/docker/go-connections/sockets" -> "sync";
+"github.com/docker/go-connections/sockets" -> "syscall";
+"github.com/docker/go-connections/sockets" -> "time";
+"github.com/docker/go-connections/tlsconfig" [label="github.com/docker/go-connections/tlsconfig" color="paleturquoise" URL="https://godoc.org/github.com/docker/go-connections/tlsconfig" target="_blank"];
+"github.com/docker/go-connections/tlsconfig" -> "crypto/tls";
+"github.com/docker/go-connections/tlsconfig" -> "crypto/x509";
+"github.com/docker/go-connections/tlsconfig" -> "encoding/pem";
+"github.com/docker/go-connections/tlsconfig" -> "fmt";
+"github.com/docker/go-connections/tlsconfig" -> "github.com/pkg/errors";
+"github.com/docker/go-connections/tlsconfig" -> "io/ioutil";
+"github.com/docker/go-connections/tlsconfig" -> "os";
+"github.com/docker/go-connections/tlsconfig" -> "runtime";
+"github.com/docker/go-metrics" [label="github.com/docker/go-metrics" color="paleturquoise" URL="https://godoc.org/github.com/docker/go-metrics" target="_blank"];
+"github.com/docker/go-metrics" -> "fmt";
+"github.com/docker/go-metrics" -> "github.com/prometheus/client_golang/prometheus";
+"github.com/docker/go-metrics" -> "github.com/prometheus/client_golang/prometheus/promhttp";
+"github.com/docker/go-metrics" -> "net/http";
+"github.com/docker/go-metrics" -> "sync";
+"github.com/docker/go-metrics" -> "time";
+"github.com/docker/go-units" [label="github.com/docker/go-units" color="palegoldenrod" URL="https://godoc.org/github.com/docker/go-units" target="_blank"];
+"github.com/docker/go-units" -> "fmt";
+"github.com/docker/go-units" -> "regexp";
+"github.com/docker/go-units" -> "strconv";
+"github.com/docker/go-units" -> "strings";
+"github.com/docker/go-units" -> "time";
+"github.com/ghodss/yaml" [label="github.com/ghodss/yaml" color="paleturquoise" URL="https://godoc.org/github.com/ghodss/yaml" target="_blank"];
+"github.com/ghodss/yaml" -> "bytes";
+"github.com/ghodss/yaml" -> "encoding";
+"github.com/ghodss/yaml" -> "encoding/json";
+"github.com/ghodss/yaml" -> "fmt";
+"github.com/ghodss/yaml" -> "gopkg.in/yaml.v2";
+"github.com/ghodss/yaml" -> "reflect";
+"github.com/ghodss/yaml" -> "sort";
+"github.com/ghodss/yaml" -> "strconv";
+"github.com/ghodss/yaml" -> "strings";
+"github.com/ghodss/yaml" -> "sync";
+"github.com/ghodss/yaml" -> "unicode";
+"github.com/ghodss/yaml" -> "unicode/utf8";
+"github.com/golang/protobuf/proto" [label="github.com/golang/protobuf/proto" color="paleturquoise" URL="https://godoc.org/github.com/golang/protobuf/proto" target="_blank"];
+"github.com/golang/protobuf/proto" -> "bufio";
+"github.com/golang/protobuf/proto" -> "bytes";
+"github.com/golang/protobuf/proto" -> "encoding";
+"github.com/golang/protobuf/proto" -> "encoding/json";
+"github.com/golang/protobuf/proto" -> "errors";
+"github.com/golang/protobuf/proto" -> "fmt";
+"github.com/golang/protobuf/proto" -> "io";
+"github.com/golang/protobuf/proto" -> "log";
+"github.com/golang/protobuf/proto" -> "math";
+"github.com/golang/protobuf/proto" -> "reflect";
+"github.com/golang/protobuf/proto" -> "sort";
+"github.com/golang/protobuf/proto" -> "strconv";
+"github.com/golang/protobuf/proto" -> "strings";
+"github.com/golang/protobuf/proto" -> "sync";
+"github.com/golang/protobuf/proto" -> "sync/atomic";
+"github.com/golang/protobuf/proto" -> "unicode/utf8";
+"github.com/golang/protobuf/proto" -> "unsafe";
+"github.com/gorilla/mux" [label="github.com/gorilla/mux" color="paleturquoise" URL="https://godoc.org/github.com/gorilla/mux" target="_blank"];
+"github.com/gorilla/mux" -> "bytes";
+"github.com/gorilla/mux" -> "context";
+"github.com/gorilla/mux" -> "errors";
+"github.com/gorilla/mux" -> "fmt";
+"github.com/gorilla/mux" -> "net/http";
+"github.com/gorilla/mux" -> "net/url";
+"github.com/gorilla/mux" -> "path";
+"github.com/gorilla/mux" -> "regexp";
+"github.com/gorilla/mux" -> "strconv";
+"github.com/gorilla/mux" -> "strings";
+"github.com/klauspost/compress/flate" [label="github.com/klauspost/compress/flate" color="paleturquoise" URL="https://godoc.org/github.com/klauspost/compress/flate" target="_blank"];
+"github.com/klauspost/compress/flate" -> "bufio";
+"github.com/klauspost/compress/flate" -> "bytes";
+"github.com/klauspost/compress/flate" -> "encoding/binary";
+"github.com/klauspost/compress/flate" -> "fmt";
+"github.com/klauspost/compress/flate" -> "io";
+"github.com/klauspost/compress/flate" -> "math";
+"github.com/klauspost/compress/flate" -> "math/bits";
+"github.com/klauspost/compress/flate" -> "sort";
+"github.com/klauspost/compress/flate" -> "strconv";
+"github.com/klauspost/compress/flate" -> "sync";
+"github.com/klauspost/compress/fse" [label="github.com/klauspost/compress/fse" color="paleturquoise" URL="https://godoc.org/github.com/klauspost/compress/fse" target="_blank"];
+"github.com/klauspost/compress/fse" -> "errors";
+"github.com/klauspost/compress/fse" -> "fmt";
+"github.com/klauspost/compress/fse" -> "io";
+"github.com/klauspost/compress/fse" -> "math/bits";
+"github.com/klauspost/compress/huff0" [label="github.com/klauspost/compress/huff0" color="paleturquoise" URL="https://godoc.org/github.com/klauspost/compress/huff0" target="_blank"];
+"github.com/klauspost/compress/huff0" -> "errors";
+"github.com/klauspost/compress/huff0" -> "fmt";
+"github.com/klauspost/compress/huff0" -> "github.com/klauspost/compress/fse";
+"github.com/klauspost/compress/huff0" -> "io";
+"github.com/klauspost/compress/huff0" -> "math";
+"github.com/klauspost/compress/huff0" -> "math/bits";
+"github.com/klauspost/compress/huff0" -> "runtime";
+"github.com/klauspost/compress/huff0" -> "sync";
+"github.com/klauspost/compress/snappy" [label="github.com/klauspost/compress/snappy" color="paleturquoise" URL="https://godoc.org/github.com/klauspost/compress/snappy" target="_blank"];
+"github.com/klauspost/compress/snappy" -> "encoding/binary";
+"github.com/klauspost/compress/snappy" -> "errors";
+"github.com/klauspost/compress/snappy" -> "hash/crc32";
+"github.com/klauspost/compress/snappy" -> "io";
+"github.com/klauspost/compress/zstd" [label="github.com/klauspost/compress/zstd" color="paleturquoise" URL="https://godoc.org/github.com/klauspost/compress/zstd" target="_blank"];
+"github.com/klauspost/compress/zstd" -> "bytes";
+"github.com/klauspost/compress/zstd" -> "crypto/rand";
+"github.com/klauspost/compress/zstd" -> "encoding/binary";
+"github.com/klauspost/compress/zstd" -> "encoding/hex";
+"github.com/klauspost/compress/zstd" -> "errors";
+"github.com/klauspost/compress/zstd" -> "fmt";
+"github.com/klauspost/compress/zstd" -> "github.com/klauspost/compress/huff0";
+"github.com/klauspost/compress/zstd" -> "github.com/klauspost/compress/snappy";
+"github.com/klauspost/compress/zstd" -> "github.com/klauspost/compress/zstd/internal/xxhash";
+"github.com/klauspost/compress/zstd" -> "hash";
+"github.com/klauspost/compress/zstd" -> "hash/crc32";
+"github.com/klauspost/compress/zstd" -> "io";
+"github.com/klauspost/compress/zstd" -> "io/ioutil";
+"github.com/klauspost/compress/zstd" -> "log";
+"github.com/klauspost/compress/zstd" -> "math";
+"github.com/klauspost/compress/zstd" -> "math/bits";
+"github.com/klauspost/compress/zstd" -> "runtime";
+"github.com/klauspost/compress/zstd" -> "runtime/debug";
+"github.com/klauspost/compress/zstd" -> "strconv";
+"github.com/klauspost/compress/zstd" -> "strings";
+"github.com/klauspost/compress/zstd" -> "sync";
+"github.com/klauspost/compress/zstd/internal/xxhash" [label="github.com/klauspost/compress/zstd/internal/xxhash" color="paleturquoise" URL="https://godoc.org/github.com/klauspost/compress/zstd/internal/xxhash" target="_blank"];
+"github.com/klauspost/compress/zstd/internal/xxhash" -> "encoding/binary";
+"github.com/klauspost/compress/zstd/internal/xxhash" -> "errors";
+"github.com/klauspost/compress/zstd/internal/xxhash" -> "math/bits";
+"github.com/klauspost/pgzip" [label="github.com/klauspost/pgzip" color="paleturquoise" URL="https://godoc.org/github.com/klauspost/pgzip" target="_blank"];
+"github.com/klauspost/pgzip" -> "bufio";
+"github.com/klauspost/pgzip" -> "bytes";
+"github.com/klauspost/pgzip" -> "errors";
+"github.com/klauspost/pgzip" -> "fmt";
+"github.com/klauspost/pgzip" -> "github.com/klauspost/compress/flate";
+"github.com/klauspost/pgzip" -> "hash";
+"github.com/klauspost/pgzip" -> "hash/crc32";
+"github.com/klauspost/pgzip" -> "io";
+"github.com/klauspost/pgzip" -> "sync";
+"github.com/klauspost/pgzip" -> "time";
+"github.com/matttproud/golang_protobuf_extensions/pbutil" [label="github.com/matttproud/golang_protobuf_extensions/pbutil" color="paleturquoise" URL="https://godoc.org/github.com/matttproud/golang_protobuf_extensions/pbutil" target="_blank"];
+"github.com/matttproud/golang_protobuf_extensions/pbutil" -> "encoding/binary";
+"github.com/matttproud/golang_protobuf_extensions/pbutil" -> "errors";
+"github.com/matttproud/golang_protobuf_extensions/pbutil" -> "github.com/golang/protobuf/proto";
+"github.com/matttproud/golang_protobuf_extensions/pbutil" -> "io";
+"github.com/opencontainers/go-digest" [label="github.com/opencontainers/go-digest" color="paleturquoise" URL="https://godoc.org/github.com/opencontainers/go-digest" target="_blank"];
+"github.com/opencontainers/go-digest" -> "crypto";
+"github.com/opencontainers/go-digest" -> "fmt";
+"github.com/opencontainers/go-digest" -> "hash";
+"github.com/opencontainers/go-digest" -> "io";
+"github.com/opencontainers/go-digest" -> "regexp";
+"github.com/opencontainers/go-digest" -> "strings";
+"github.com/opencontainers/image-spec/specs-go" [label="github.com/opencontainers/image-spec/specs-go" color="paleturquoise" URL="https://godoc.org/github.com/opencontainers/image-spec/specs-go" target="_blank"];
+"github.com/opencontainers/image-spec/specs-go" -> "fmt";
+"github.com/opencontainers/image-spec/specs-go/v1" [label="github.com/opencontainers/image-spec/specs-go/v1" color="paleturquoise" URL="https://godoc.org/github.com/opencontainers/image-spec/specs-go/v1" target="_blank"];
+"github.com/opencontainers/image-spec/specs-go/v1" -> "github.com/opencontainers/go-digest";
+"github.com/opencontainers/image-spec/specs-go/v1" -> "github.com/opencontainers/image-spec/specs-go";
+"github.com/opencontainers/image-spec/specs-go/v1" -> "time";
+"github.com/opencontainers/runc/libcontainer/user" [label="github.com/opencontainers/runc/libcontainer/user" color="palegoldenrod" URL="https://godoc.org/github.com/opencontainers/runc/libcontainer/user" target="_blank"];
+"github.com/opencontainers/runc/libcontainer/user" -> "bufio";
+"github.com/opencontainers/runc/libcontainer/user" -> "errors";
+"github.com/opencontainers/runc/libcontainer/user" -> "fmt";
+"github.com/opencontainers/runc/libcontainer/user" -> "golang.org/x/sys/unix";
+"github.com/opencontainers/runc/libcontainer/user" -> "io";
+"github.com/opencontainers/runc/libcontainer/user" -> "os";
+"github.com/opencontainers/runc/libcontainer/user" -> "os/user";
+"github.com/opencontainers/runc/libcontainer/user" -> "strconv";
+"github.com/opencontainers/runc/libcontainer/user" -> "strings";
+"github.com/pkg/errors" [label="github.com/pkg/errors" color="paleturquoise" URL="https://godoc.org/github.com/pkg/errors" target="_blank"];
+"github.com/pkg/errors" -> "fmt";
+"github.com/pkg/errors" -> "io";
+"github.com/pkg/errors" -> "path";
+"github.com/pkg/errors" -> "runtime";
+"github.com/pkg/errors" -> "strings";
+"github.com/prometheus/client_golang/prometheus" [label="github.com/prometheus/client_golang/prometheus" color="paleturquoise" URL="https://godoc.org/github.com/prometheus/client_golang/prometheus" target="_blank"];
+"github.com/prometheus/client_golang/prometheus" -> "bytes";
+"github.com/prometheus/client_golang/prometheus" -> "encoding/json";
+"github.com/prometheus/client_golang/prometheus" -> "errors";
+"github.com/prometheus/client_golang/prometheus" -> "expvar";
+"github.com/prometheus/client_golang/prometheus" -> "fmt";
+"github.com/prometheus/client_golang/prometheus" -> "github.com/beorn7/perks/quantile";
+"github.com/prometheus/client_golang/prometheus" -> "github.com/cespare/xxhash/v2";
+"github.com/prometheus/client_golang/prometheus" -> "github.com/golang/protobuf/proto";
+"github.com/prometheus/client_golang/prometheus" -> "github.com/prometheus/client_golang/prometheus/internal";
+"github.com/prometheus/client_golang/prometheus" -> "github.com/prometheus/client_model/go";
+"github.com/prometheus/client_golang/prometheus" -> "github.com/prometheus/common/expfmt";
+"github.com/prometheus/client_golang/prometheus" -> "github.com/prometheus/common/model";
+"github.com/prometheus/client_golang/prometheus" -> "github.com/prometheus/procfs";
+"github.com/prometheus/client_golang/prometheus" -> "io/ioutil";
+"github.com/prometheus/client_golang/prometheus" -> "math";
+"github.com/prometheus/client_golang/prometheus" -> "os";
+"github.com/prometheus/client_golang/prometheus" -> "path/filepath";
+"github.com/prometheus/client_golang/prometheus" -> "runtime";
+"github.com/prometheus/client_golang/prometheus" -> "runtime/debug";
+"github.com/prometheus/client_golang/prometheus" -> "sort";
+"github.com/prometheus/client_golang/prometheus" -> "strings";
+"github.com/prometheus/client_golang/prometheus" -> "sync";
+"github.com/prometheus/client_golang/prometheus" -> "sync/atomic";
+"github.com/prometheus/client_golang/prometheus" -> "time";
+"github.com/prometheus/client_golang/prometheus" -> "unicode/utf8";
+"github.com/prometheus/client_golang/prometheus/internal" [label="github.com/prometheus/client_golang/prometheus/internal" color="paleturquoise" URL="https://godoc.org/github.com/prometheus/client_golang/prometheus/internal" target="_blank"];
+"github.com/prometheus/client_golang/prometheus/internal" -> "github.com/prometheus/client_model/go";
+"github.com/prometheus/client_golang/prometheus/internal" -> "sort";
+"github.com/prometheus/client_golang/prometheus/promhttp" [label="github.com/prometheus/client_golang/prometheus/promhttp" color="paleturquoise" URL="https://godoc.org/github.com/prometheus/client_golang/prometheus/promhttp" target="_blank"];
+"github.com/prometheus/client_golang/prometheus/promhttp" -> "bufio";
+"github.com/prometheus/client_golang/prometheus/promhttp" -> "compress/gzip";
+"github.com/prometheus/client_golang/prometheus/promhttp" -> "crypto/tls";
+"github.com/prometheus/client_golang/prometheus/promhttp" -> "errors";
+"github.com/prometheus/client_golang/prometheus/promhttp" -> "fmt";
+"github.com/prometheus/client_golang/prometheus/promhttp" -> "github.com/prometheus/client_golang/prometheus";
+"github.com/prometheus/client_golang/prometheus/promhttp" -> "github.com/prometheus/client_model/go";
+"github.com/prometheus/client_golang/prometheus/promhttp" -> "github.com/prometheus/common/expfmt";
+"github.com/prometheus/client_golang/prometheus/promhttp" -> "io";
+"github.com/prometheus/client_golang/prometheus/promhttp" -> "net";
+"github.com/prometheus/client_golang/prometheus/promhttp" -> "net/http";
+"github.com/prometheus/client_golang/prometheus/promhttp" -> "net/http/httptrace";
+"github.com/prometheus/client_golang/prometheus/promhttp" -> "strconv";
+"github.com/prometheus/client_golang/prometheus/promhttp" -> "strings";
+"github.com/prometheus/client_golang/prometheus/promhttp" -> "sync";
+"github.com/prometheus/client_golang/prometheus/promhttp" -> "time";
+"github.com/prometheus/client_model/go" [label="github.com/prometheus/client_model/go" color="paleturquoise" URL="https://godoc.org/github.com/prometheus/client_model/go" target="_blank"];
+"github.com/prometheus/client_model/go" -> "fmt";
+"github.com/prometheus/client_model/go" -> "github.com/golang/protobuf/proto";
+"github.com/prometheus/client_model/go" -> "math";
+"github.com/prometheus/common/expfmt" [label="github.com/prometheus/common/expfmt" color="paleturquoise" URL="https://godoc.org/github.com/prometheus/common/expfmt" target="_blank"];
+"github.com/prometheus/common/expfmt" -> "bufio";
+"github.com/prometheus/common/expfmt" -> "bytes";
+"github.com/prometheus/common/expfmt" -> "fmt";
+"github.com/prometheus/common/expfmt" -> "github.com/golang/protobuf/proto";
+"github.com/prometheus/common/expfmt" -> "github.com/matttproud/golang_protobuf_extensions/pbutil";
+"github.com/prometheus/common/expfmt" -> "github.com/prometheus/client_model/go";
+"github.com/prometheus/common/expfmt" -> "github.com/prometheus/common/internal/bitbucket.org/ww/goautoneg";
+"github.com/prometheus/common/expfmt" -> "github.com/prometheus/common/model";
+"github.com/prometheus/common/expfmt" -> "io";
+"github.com/prometheus/common/expfmt" -> "io/ioutil";
+"github.com/prometheus/common/expfmt" -> "math";
+"github.com/prometheus/common/expfmt" -> "mime";
+"github.com/prometheus/common/expfmt" -> "net/http";
+"github.com/prometheus/common/expfmt" -> "strconv";
+"github.com/prometheus/common/expfmt" -> "strings";
+"github.com/prometheus/common/expfmt" -> "sync";
+"github.com/prometheus/common/internal/bitbucket.org/ww/goautoneg" [label="github.com/prometheus/common/internal/bitbucket.org/ww/goautoneg" color="paleturquoise" URL="https://godoc.org/github.com/prometheus/common/internal/bitbucket.org/ww/goautoneg" target="_blank"];
+"github.com/prometheus/common/internal/bitbucket.org/ww/goautoneg" -> "sort";
+"github.com/prometheus/common/internal/bitbucket.org/ww/goautoneg" -> "strconv";
+"github.com/prometheus/common/internal/bitbucket.org/ww/goautoneg" -> "strings";
+"github.com/prometheus/common/model" [label="github.com/prometheus/common/model" color="paleturquoise" URL="https://godoc.org/github.com/prometheus/common/model" target="_blank"];
+"github.com/prometheus/common/model" -> "encoding/json";
+"github.com/prometheus/common/model" -> "fmt";
+"github.com/prometheus/common/model" -> "math";
+"github.com/prometheus/common/model" -> "regexp";
+"github.com/prometheus/common/model" -> "sort";
+"github.com/prometheus/common/model" -> "strconv";
+"github.com/prometheus/common/model" -> "strings";
+"github.com/prometheus/common/model" -> "time";
+"github.com/prometheus/common/model" -> "unicode/utf8";
+"github.com/prometheus/procfs" [label="github.com/prometheus/procfs" color="paleturquoise" URL="https://godoc.org/github.com/prometheus/procfs" target="_blank"];
+"github.com/prometheus/procfs" -> "bufio";
+"github.com/prometheus/procfs" -> "bytes";
+"github.com/prometheus/procfs" -> "encoding/hex";
+"github.com/prometheus/procfs" -> "errors";
+"github.com/prometheus/procfs" -> "fmt";
+"github.com/prometheus/procfs" -> "github.com/prometheus/procfs/internal/fs";
+"github.com/prometheus/procfs" -> "github.com/prometheus/procfs/internal/util";
+"github.com/prometheus/procfs" -> "io";
+"github.com/prometheus/procfs" -> "io/ioutil";
+"github.com/prometheus/procfs" -> "net";
+"github.com/prometheus/procfs" -> "os";
+"github.com/prometheus/procfs" -> "path/filepath";
+"github.com/prometheus/procfs" -> "regexp";
+"github.com/prometheus/procfs" -> "sort";
+"github.com/prometheus/procfs" -> "strconv";
+"github.com/prometheus/procfs" -> "strings";
+"github.com/prometheus/procfs" -> "time";
+"github.com/prometheus/procfs/internal/fs" [label="github.com/prometheus/procfs/internal/fs" color="paleturquoise" URL="https://godoc.org/github.com/prometheus/procfs/internal/fs" target="_blank"];
+"github.com/prometheus/procfs/internal/fs" -> "fmt";
+"github.com/prometheus/procfs/internal/fs" -> "os";
+"github.com/prometheus/procfs/internal/fs" -> "path/filepath";
+"github.com/prometheus/procfs/internal/util" [label="github.com/prometheus/procfs/internal/util" color="paleturquoise" URL="https://godoc.org/github.com/prometheus/procfs/internal/util" target="_blank"];
+"github.com/prometheus/procfs/internal/util" -> "bytes";
+"github.com/prometheus/procfs/internal/util" -> "io/ioutil";
+"github.com/prometheus/procfs/internal/util" -> "os";
+"github.com/prometheus/procfs/internal/util" -> "strconv";
+"github.com/prometheus/procfs/internal/util" -> "strings";
+"github.com/prometheus/procfs/internal/util" -> "syscall";
+"github.com/sirupsen/logrus" [label="github.com/sirupsen/logrus" color="paleturquoise" URL="https://godoc.org/github.com/sirupsen/logrus" target="_blank"];
+"github.com/sirupsen/logrus" -> "bufio";
+"github.com/sirupsen/logrus" -> "bytes";
+"github.com/sirupsen/logrus" -> "context";
+"github.com/sirupsen/logrus" -> "encoding/json";
+"github.com/sirupsen/logrus" -> "fmt";
+"github.com/sirupsen/logrus" -> "golang.org/x/sys/unix";
+"github.com/sirupsen/logrus" -> "io";
+"github.com/sirupsen/logrus" -> "log";
+"github.com/sirupsen/logrus" -> "os";
+"github.com/sirupsen/logrus" -> "reflect";
+"github.com/sirupsen/logrus" -> "runtime";
+"github.com/sirupsen/logrus" -> "sort";
+"github.com/sirupsen/logrus" -> "strings";
+"github.com/sirupsen/logrus" -> "sync";
+"github.com/sirupsen/logrus" -> "sync/atomic";
+"github.com/sirupsen/logrus" -> "time";
+"github.com/ulikunitz/xz" [label="github.com/ulikunitz/xz" color="paleturquoise" URL="https://godoc.org/github.com/ulikunitz/xz" target="_blank"];
+"github.com/ulikunitz/xz" -> "bytes";
+"github.com/ulikunitz/xz" -> "crypto/sha256";
+"github.com/ulikunitz/xz" -> "errors";
+"github.com/ulikunitz/xz" -> "fmt";
+"github.com/ulikunitz/xz" -> "github.com/ulikunitz/xz/internal/xlog";
+"github.com/ulikunitz/xz" -> "github.com/ulikunitz/xz/lzma";
+"github.com/ulikunitz/xz" -> "hash";
+"github.com/ulikunitz/xz" -> "hash/crc32";
+"github.com/ulikunitz/xz" -> "hash/crc64";
+"github.com/ulikunitz/xz" -> "io";
+"github.com/ulikunitz/xz/internal/hash" [label="github.com/ulikunitz/xz/internal/hash" color="paleturquoise" URL="https://godoc.org/github.com/ulikunitz/xz/internal/hash" target="_blank"];
+"github.com/ulikunitz/xz/internal/xlog" [label="github.com/ulikunitz/xz/internal/xlog" color="paleturquoise" URL="https://godoc.org/github.com/ulikunitz/xz/internal/xlog" target="_blank"];
+"github.com/ulikunitz/xz/internal/xlog" -> "fmt";
+"github.com/ulikunitz/xz/internal/xlog" -> "io";
+"github.com/ulikunitz/xz/internal/xlog" -> "os";
+"github.com/ulikunitz/xz/internal/xlog" -> "runtime";
+"github.com/ulikunitz/xz/internal/xlog" -> "sync";
+"github.com/ulikunitz/xz/internal/xlog" -> "time";
+"github.com/ulikunitz/xz/lzma" [label="github.com/ulikunitz/xz/lzma" color="paleturquoise" URL="https://godoc.org/github.com/ulikunitz/xz/lzma" target="_blank"];
+"github.com/ulikunitz/xz/lzma" -> "bufio";
+"github.com/ulikunitz/xz/lzma" -> "bytes";
+"github.com/ulikunitz/xz/lzma" -> "errors";
+"github.com/ulikunitz/xz/lzma" -> "fmt";
+"github.com/ulikunitz/xz/lzma" -> "github.com/ulikunitz/xz/internal/hash";
+"github.com/ulikunitz/xz/lzma" -> "github.com/ulikunitz/xz/internal/xlog";
+"github.com/ulikunitz/xz/lzma" -> "io";
+"github.com/ulikunitz/xz/lzma" -> "unicode";
+"golang.org/x/net/internal/socks" [label="golang.org/x/net/internal/socks" color="paleturquoise" URL="https://godoc.org/golang.org/x/net/internal/socks" target="_blank"];
+"golang.org/x/net/internal/socks" -> "context";
+"golang.org/x/net/internal/socks" -> "errors";
+"golang.org/x/net/internal/socks" -> "io";
+"golang.org/x/net/internal/socks" -> "net";
+"golang.org/x/net/internal/socks" -> "strconv";
+"golang.org/x/net/internal/socks" -> "time";
+"golang.org/x/net/proxy" [label="golang.org/x/net/proxy" color="paleturquoise" URL="https://godoc.org/golang.org/x/net/proxy" target="_blank"];
+"golang.org/x/net/proxy" -> "context";
+"golang.org/x/net/proxy" -> "errors";
+"golang.org/x/net/proxy" -> "golang.org/x/net/internal/socks";
+"golang.org/x/net/proxy" -> "net";
+"golang.org/x/net/proxy" -> "net/url";
+"golang.org/x/net/proxy" -> "os";
+"golang.org/x/net/proxy" -> "strings";
+"golang.org/x/net/proxy" -> "sync";
+"golang.org/x/sys/unix" [label="golang.org/x/sys/unix" color="paleturquoise" URL="https://godoc.org/golang.org/x/sys/unix" target="_blank"];
+"golang.org/x/sys/unix" -> "bytes";
+"golang.org/x/sys/unix" -> "encoding/binary";
+"golang.org/x/sys/unix" -> "net";
+"golang.org/x/sys/unix" -> "runtime";
+"golang.org/x/sys/unix" -> "sort";
+"golang.org/x/sys/unix" -> "strings";
+"golang.org/x/sys/unix" -> "sync";
+"golang.org/x/sys/unix" -> "syscall";
+"golang.org/x/sys/unix" -> "time";
+"golang.org/x/sys/unix" -> "unsafe";
+"gopkg.in/yaml.v2" [label="gopkg.in/yaml.v2" color="paleturquoise" URL="https://godoc.org/gopkg.in/yaml.v2" target="_blank"];
+"gopkg.in/yaml.v2" -> "bytes";
+"gopkg.in/yaml.v2" -> "encoding";
+"gopkg.in/yaml.v2" -> "encoding/base64";
+"gopkg.in/yaml.v2" -> "errors";
+"gopkg.in/yaml.v2" -> "fmt";
+"gopkg.in/yaml.v2" -> "io";
+"gopkg.in/yaml.v2" -> "math";
+"gopkg.in/yaml.v2" -> "reflect";
+"gopkg.in/yaml.v2" -> "regexp";
+"gopkg.in/yaml.v2" -> "sort";
+"gopkg.in/yaml.v2" -> "strconv";
+"gopkg.in/yaml.v2" -> "strings";
+"gopkg.in/yaml.v2" -> "sync";
+"gopkg.in/yaml.v2" -> "time";
+"gopkg.in/yaml.v2" -> "unicode";
+"gopkg.in/yaml.v2" -> "unicode/utf8";
+"hash" [label="hash" color="palegreen" URL="https://godoc.org/hash" target="_blank"];
+"hash/crc32" [label="hash/crc32" color="palegreen" URL="https://godoc.org/hash/crc32" target="_blank"];
+"hash/crc64" [label="hash/crc64" color="palegreen" URL="https://godoc.org/hash/crc64" target="_blank"];
+"io" [label="io" color="palegreen" URL="https://godoc.org/io" target="_blank"];
+"io/ioutil" [label="io/ioutil" color="palegreen" URL="https://godoc.org/io/ioutil" target="_blank"];
+"log" [label="log" color="palegreen" URL="https://godoc.org/log" target="_blank"];
+"math" [label="math" color="palegreen" URL="https://godoc.org/math" target="_blank"];
+"math/big" [label="math/big" color="palegreen" URL="https://godoc.org/math/big" target="_blank"];
+"math/bits" [label="math/bits" color="palegreen" URL="https://godoc.org/math/bits" target="_blank"];
+"mime" [label="mime" color="palegreen" URL="https://godoc.org/mime" target="_blank"];
+"net" [label="net" color="palegreen" URL="https://godoc.org/net" target="_blank"];
+"net/http" [label="net/http" color="palegreen" URL="https://godoc.org/net/http" target="_blank"];
+"net/http/httptrace" [label="net/http/httptrace" color="palegreen" URL="https://godoc.org/net/http/httptrace" target="_blank"];
+"net/url" [label="net/url" color="palegreen" URL="https://godoc.org/net/url" target="_blank"];
+"os" [label="os" color="palegreen" URL="https://godoc.org/os" target="_blank"];
+"os/exec" [label="os/exec" color="palegreen" URL="https://godoc.org/os/exec" target="_blank"];
+"os/user" [label="os/user" color="palegreen" URL="https://godoc.org/os/user" target="_blank"];
+"path" [label="path" color="palegreen" URL="https://godoc.org/path" target="_blank"];
+"path/filepath" [label="path/filepath" color="palegreen" URL="https://godoc.org/path/filepath" target="_blank"];
+"reflect" [label="reflect" color="palegreen" URL="https://godoc.org/reflect" target="_blank"];
+"regexp" [label="regexp" color="palegreen" URL="https://godoc.org/regexp" target="_blank"];
+"runtime" [label="runtime" color="palegreen" URL="https://godoc.org/runtime" target="_blank"];
+"runtime/debug" [label="runtime/debug" color="palegreen" URL="https://godoc.org/runtime/debug" target="_blank"];
+"sort" [label="sort" color="palegreen" URL="https://godoc.org/sort" target="_blank"];
+"strconv" [label="strconv" color="palegreen" URL="https://godoc.org/strconv" target="_blank"];
+"strings" [label="strings" color="palegreen" URL="https://godoc.org/strings" target="_blank"];
+"sync" [label="sync" color="palegreen" URL="https://godoc.org/sync" target="_blank"];
+"sync/atomic" [label="sync/atomic" color="palegreen" URL="https://godoc.org/sync/atomic" target="_blank"];
+"syscall" [label="syscall" color="palegreen" URL="https://godoc.org/syscall" target="_blank"];
+"time" [label="time" color="palegreen" URL="https://godoc.org/time" target="_blank"];
+"unicode" [label="unicode" color="palegreen" URL="https://godoc.org/unicode" target="_blank"];
+"unicode/utf8" [label="unicode/utf8" color="palegreen" URL="https://godoc.org/unicode/utf8" target="_blank"];
+"unsafe" [label="unsafe" color="palegreen" URL="https://godoc.org/unsafe" target="_blank"];
+}
diff --git a/pkg/go-containerregistry/images/dot/docker.dot b/pkg/go-containerregistry/images/dot/docker.dot
new file mode 100644
index 00000000..90dc677c
--- /dev/null
+++ b/pkg/go-containerregistry/images/dot/docker.dot
@@ -0,0 +1,327 @@
+digraph godep {
+nodesep=0.4
+ranksep=0.8
+node [shape="box",style="rounded,filled"]
+edge [arrowsize="0.5"]
+"bufio" [label="bufio" color="palegreen" URL="https://godoc.org/bufio" target="_blank"];
+"bytes" [label="bytes" color="palegreen" URL="https://godoc.org/bytes" target="_blank"];
+"compress/gzip" [label="compress/gzip" color="palegreen" URL="https://godoc.org/compress/gzip" target="_blank"];
+"context" [label="context" color="palegreen" URL="https://godoc.org/context" target="_blank"];
+"crypto" [label="crypto" color="palegreen" URL="https://godoc.org/crypto" target="_blank"];
+"crypto/tls" [label="crypto/tls" color="palegreen" URL="https://godoc.org/crypto/tls" target="_blank"];
+"encoding" [label="encoding" color="palegreen" URL="https://godoc.org/encoding" target="_blank"];
+"encoding/binary" [label="encoding/binary" color="palegreen" URL="https://godoc.org/encoding/binary" target="_blank"];
+"encoding/hex" [label="encoding/hex" color="palegreen" URL="https://godoc.org/encoding/hex" target="_blank"];
+"encoding/json" [label="encoding/json" color="palegreen" URL="https://godoc.org/encoding/json" target="_blank"];
+"errors" [label="errors" color="palegreen" URL="https://godoc.org/errors" target="_blank"];
+"expvar" [label="expvar" color="palegreen" URL="https://godoc.org/expvar" target="_blank"];
+"fmt" [label="fmt" color="palegreen" URL="https://godoc.org/fmt" target="_blank"];
+"github.com/beorn7/perks/quantile" [label="github.com/beorn7/perks/quantile" color="paleturquoise" URL="https://godoc.org/github.com/beorn7/perks/quantile" target="_blank"];
+"github.com/beorn7/perks/quantile" -> "math";
+"github.com/beorn7/perks/quantile" -> "sort";
+"github.com/cespare/xxhash/v2" [label="github.com/cespare/xxhash/v2" color="paleturquoise" URL="https://godoc.org/github.com/cespare/xxhash/v2" target="_blank"];
+"github.com/cespare/xxhash/v2" -> "encoding/binary";
+"github.com/cespare/xxhash/v2" -> "errors";
+"github.com/cespare/xxhash/v2" -> "math/bits";
+"github.com/cespare/xxhash/v2" -> "reflect";
+"github.com/cespare/xxhash/v2" -> "unsafe";
+"github.com/docker/distribution" [label="github.com/docker/distribution" color="paleturquoise" URL="https://godoc.org/github.com/docker/distribution" target="_blank"];
+"github.com/docker/distribution" -> "context";
+"github.com/docker/distribution" -> "errors";
+"github.com/docker/distribution" -> "fmt";
+"github.com/docker/distribution" -> "github.com/docker/distribution/reference";
+"github.com/docker/distribution" -> "github.com/opencontainers/go-digest";
+"github.com/docker/distribution" -> "github.com/opencontainers/image-spec/specs-go/v1";
+"github.com/docker/distribution" -> "io";
+"github.com/docker/distribution" -> "mime";
+"github.com/docker/distribution" -> "net/http";
+"github.com/docker/distribution" -> "strings";
+"github.com/docker/distribution" -> "time";
+"github.com/docker/distribution/digestset" [label="github.com/docker/distribution/digestset" color="paleturquoise" URL="https://godoc.org/github.com/docker/distribution/digestset" target="_blank"];
+"github.com/docker/distribution/digestset" -> "errors";
+"github.com/docker/distribution/digestset" -> "github.com/opencontainers/go-digest";
+"github.com/docker/distribution/digestset" -> "sort";
+"github.com/docker/distribution/digestset" -> "strings";
+"github.com/docker/distribution/digestset" -> "sync";
+"github.com/docker/distribution/metrics" [label="github.com/docker/distribution/metrics" color="paleturquoise" URL="https://godoc.org/github.com/docker/distribution/metrics" target="_blank"];
+"github.com/docker/distribution/metrics" -> "github.com/docker/go-metrics";
+"github.com/docker/distribution/reference" [label="github.com/docker/distribution/reference" color="paleturquoise" URL="https://godoc.org/github.com/docker/distribution/reference" target="_blank"];
+"github.com/docker/distribution/reference" -> "errors";
+"github.com/docker/distribution/reference" -> "fmt";
+"github.com/docker/distribution/reference" -> "github.com/docker/distribution/digestset";
+"github.com/docker/distribution/reference" -> "github.com/opencontainers/go-digest";
+"github.com/docker/distribution/reference" -> "path";
+"github.com/docker/distribution/reference" -> "regexp";
+"github.com/docker/distribution/reference" -> "strings";
+"github.com/docker/distribution/registry/api/errcode" [label="github.com/docker/distribution/registry/api/errcode" color="paleturquoise" URL="https://godoc.org/github.com/docker/distribution/registry/api/errcode" target="_blank"];
+"github.com/docker/distribution/registry/api/errcode" -> "encoding/json";
+"github.com/docker/distribution/registry/api/errcode" -> "fmt";
+"github.com/docker/distribution/registry/api/errcode" -> "net/http";
+"github.com/docker/distribution/registry/api/errcode" -> "sort";
+"github.com/docker/distribution/registry/api/errcode" -> "strings";
+"github.com/docker/distribution/registry/api/errcode" -> "sync";
+"github.com/docker/distribution/registry/api/v2" [label="github.com/docker/distribution/registry/api/v2" color="paleturquoise" URL="https://godoc.org/github.com/docker/distribution/registry/api/v2" target="_blank"];
+"github.com/docker/distribution/registry/api/v2" -> "fmt";
+"github.com/docker/distribution/registry/api/v2" -> "github.com/docker/distribution/reference";
+"github.com/docker/distribution/registry/api/v2" -> "github.com/docker/distribution/registry/api/errcode";
+"github.com/docker/distribution/registry/api/v2" -> "github.com/gorilla/mux";
+"github.com/docker/distribution/registry/api/v2" -> "github.com/opencontainers/go-digest";
+"github.com/docker/distribution/registry/api/v2" -> "net/http";
+"github.com/docker/distribution/registry/api/v2" -> "net/url";
+"github.com/docker/distribution/registry/api/v2" -> "regexp";
+"github.com/docker/distribution/registry/api/v2" -> "strings";
+"github.com/docker/distribution/registry/api/v2" -> "unicode";
+"github.com/docker/distribution/registry/client" [label="github.com/docker/distribution/registry/client" color="paleturquoise" URL="https://godoc.org/github.com/docker/distribution/registry/client" target="_blank"];
+"github.com/docker/distribution/registry/client" -> "bytes";
+"github.com/docker/distribution/registry/client" -> "context";
+"github.com/docker/distribution/registry/client" -> "encoding/json";
+"github.com/docker/distribution/registry/client" -> "errors";
+"github.com/docker/distribution/registry/client" -> "fmt";
+"github.com/docker/distribution/registry/client" -> "github.com/docker/distribution";
+"github.com/docker/distribution/registry/client" -> "github.com/docker/distribution/reference";
+"github.com/docker/distribution/registry/client" -> "github.com/docker/distribution/registry/api/errcode";
+"github.com/docker/distribution/registry/client" -> "github.com/docker/distribution/registry/api/v2";
+"github.com/docker/distribution/registry/client" -> "github.com/docker/distribution/registry/client/auth/challenge";
+"github.com/docker/distribution/registry/client" -> "github.com/docker/distribution/registry/client/transport";
+"github.com/docker/distribution/registry/client" -> "github.com/docker/distribution/registry/storage/cache";
+"github.com/docker/distribution/registry/client" -> "github.com/docker/distribution/registry/storage/cache/memory";
+"github.com/docker/distribution/registry/client" -> "github.com/opencontainers/go-digest";
+"github.com/docker/distribution/registry/client" -> "io";
+"github.com/docker/distribution/registry/client" -> "io/ioutil";
+"github.com/docker/distribution/registry/client" -> "net/http";
+"github.com/docker/distribution/registry/client" -> "net/url";
+"github.com/docker/distribution/registry/client" -> "strconv";
+"github.com/docker/distribution/registry/client" -> "strings";
+"github.com/docker/distribution/registry/client" -> "time";
+"github.com/docker/distribution/registry/client/auth" [label="github.com/docker/distribution/registry/client/auth" color="paleturquoise" URL="https://godoc.org/github.com/docker/distribution/registry/client/auth" target="_blank"];
+"github.com/docker/distribution/registry/client/auth" -> "encoding/json";
+"github.com/docker/distribution/registry/client/auth" -> "errors";
+"github.com/docker/distribution/registry/client/auth" -> "fmt";
+"github.com/docker/distribution/registry/client/auth" -> "github.com/docker/distribution/registry/client";
+"github.com/docker/distribution/registry/client/auth" -> "github.com/docker/distribution/registry/client/auth/challenge";
+"github.com/docker/distribution/registry/client/auth" -> "github.com/docker/distribution/registry/client/transport";
+"github.com/docker/distribution/registry/client/auth" -> "net/http";
+"github.com/docker/distribution/registry/client/auth" -> "net/url";
+"github.com/docker/distribution/registry/client/auth" -> "strings";
+"github.com/docker/distribution/registry/client/auth" -> "sync";
+"github.com/docker/distribution/registry/client/auth" -> "time";
+"github.com/docker/distribution/registry/client/auth/challenge" [label="github.com/docker/distribution/registry/client/auth/challenge" color="paleturquoise" URL="https://godoc.org/github.com/docker/distribution/registry/client/auth/challenge" target="_blank"];
+"github.com/docker/distribution/registry/client/auth/challenge" -> "fmt";
+"github.com/docker/distribution/registry/client/auth/challenge" -> "net/http";
+"github.com/docker/distribution/registry/client/auth/challenge" -> "net/url";
+"github.com/docker/distribution/registry/client/auth/challenge" -> "strings";
+"github.com/docker/distribution/registry/client/auth/challenge" -> "sync";
+"github.com/docker/distribution/registry/client/transport" [label="github.com/docker/distribution/registry/client/transport" color="paleturquoise" URL="https://godoc.org/github.com/docker/distribution/registry/client/transport" target="_blank"];
+"github.com/docker/distribution/registry/client/transport" -> "errors";
+"github.com/docker/distribution/registry/client/transport" -> "fmt";
+"github.com/docker/distribution/registry/client/transport" -> "io";
+"github.com/docker/distribution/registry/client/transport" -> "net/http";
+"github.com/docker/distribution/registry/client/transport" -> "regexp";
+"github.com/docker/distribution/registry/client/transport" -> "strconv";
+"github.com/docker/distribution/registry/client/transport" -> "sync";
+"github.com/docker/distribution/registry/storage/cache" [label="github.com/docker/distribution/registry/storage/cache" color="paleturquoise" URL="https://godoc.org/github.com/docker/distribution/registry/storage/cache" target="_blank"];
+"github.com/docker/distribution/registry/storage/cache" -> "context";
+"github.com/docker/distribution/registry/storage/cache" -> "fmt";
+"github.com/docker/distribution/registry/storage/cache" -> "github.com/docker/distribution";
+"github.com/docker/distribution/registry/storage/cache" -> "github.com/docker/distribution/metrics";
+"github.com/docker/distribution/registry/storage/cache" -> "github.com/opencontainers/go-digest";
+"github.com/docker/distribution/registry/storage/cache/memory" [label="github.com/docker/distribution/registry/storage/cache/memory" color="paleturquoise" URL="https://godoc.org/github.com/docker/distribution/registry/storage/cache/memory" target="_blank"];
+"github.com/docker/distribution/registry/storage/cache/memory" -> "context";
+"github.com/docker/distribution/registry/storage/cache/memory" -> "github.com/docker/distribution";
+"github.com/docker/distribution/registry/storage/cache/memory" -> "github.com/docker/distribution/reference";
+"github.com/docker/distribution/registry/storage/cache/memory" -> "github.com/docker/distribution/registry/storage/cache";
+"github.com/docker/distribution/registry/storage/cache/memory" -> "github.com/opencontainers/go-digest";
+"github.com/docker/distribution/registry/storage/cache/memory" -> "sync";
+"github.com/docker/go-metrics" [label="github.com/docker/go-metrics" color="paleturquoise" URL="https://godoc.org/github.com/docker/go-metrics" target="_blank"];
+"github.com/docker/go-metrics" -> "fmt";
+"github.com/docker/go-metrics" -> "github.com/prometheus/client_golang/prometheus";
+"github.com/docker/go-metrics" -> "github.com/prometheus/client_golang/prometheus/promhttp";
+"github.com/docker/go-metrics" -> "net/http";
+"github.com/docker/go-metrics" -> "sync";
+"github.com/docker/go-metrics" -> "time";
+"github.com/golang/protobuf/proto" [label="github.com/golang/protobuf/proto" color="paleturquoise" URL="https://godoc.org/github.com/golang/protobuf/proto" target="_blank"];
+"github.com/golang/protobuf/proto" -> "bufio";
+"github.com/golang/protobuf/proto" -> "bytes";
+"github.com/golang/protobuf/proto" -> "encoding";
+"github.com/golang/protobuf/proto" -> "encoding/json";
+"github.com/golang/protobuf/proto" -> "errors";
+"github.com/golang/protobuf/proto" -> "fmt";
+"github.com/golang/protobuf/proto" -> "io";
+"github.com/golang/protobuf/proto" -> "log";
+"github.com/golang/protobuf/proto" -> "math";
+"github.com/golang/protobuf/proto" -> "reflect";
+"github.com/golang/protobuf/proto" -> "sort";
+"github.com/golang/protobuf/proto" -> "strconv";
+"github.com/golang/protobuf/proto" -> "strings";
+"github.com/golang/protobuf/proto" -> "sync";
+"github.com/golang/protobuf/proto" -> "sync/atomic";
+"github.com/golang/protobuf/proto" -> "unicode/utf8";
+"github.com/golang/protobuf/proto" -> "unsafe";
+"github.com/gorilla/mux" [label="github.com/gorilla/mux" color="paleturquoise" URL="https://godoc.org/github.com/gorilla/mux" target="_blank"];
+"github.com/gorilla/mux" -> "bytes";
+"github.com/gorilla/mux" -> "context";
+"github.com/gorilla/mux" -> "errors";
+"github.com/gorilla/mux" -> "fmt";
+"github.com/gorilla/mux" -> "net/http";
+"github.com/gorilla/mux" -> "net/url";
+"github.com/gorilla/mux" -> "path";
+"github.com/gorilla/mux" -> "regexp";
+"github.com/gorilla/mux" -> "strconv";
+"github.com/gorilla/mux" -> "strings";
+"github.com/matttproud/golang_protobuf_extensions/pbutil" [label="github.com/matttproud/golang_protobuf_extensions/pbutil" color="paleturquoise" URL="https://godoc.org/github.com/matttproud/golang_protobuf_extensions/pbutil" target="_blank"];
+"github.com/matttproud/golang_protobuf_extensions/pbutil" -> "encoding/binary";
+"github.com/matttproud/golang_protobuf_extensions/pbutil" -> "errors";
+"github.com/matttproud/golang_protobuf_extensions/pbutil" -> "github.com/golang/protobuf/proto";
+"github.com/matttproud/golang_protobuf_extensions/pbutil" -> "io";
+"github.com/opencontainers/go-digest" [label="github.com/opencontainers/go-digest" color="paleturquoise" URL="https://godoc.org/github.com/opencontainers/go-digest" target="_blank"];
+"github.com/opencontainers/go-digest" -> "crypto";
+"github.com/opencontainers/go-digest" -> "fmt";
+"github.com/opencontainers/go-digest" -> "hash";
+"github.com/opencontainers/go-digest" -> "io";
+"github.com/opencontainers/go-digest" -> "regexp";
+"github.com/opencontainers/go-digest" -> "strings";
+"github.com/opencontainers/image-spec/specs-go" [label="github.com/opencontainers/image-spec/specs-go" color="paleturquoise" URL="https://godoc.org/github.com/opencontainers/image-spec/specs-go" target="_blank"];
+"github.com/opencontainers/image-spec/specs-go" -> "fmt";
+"github.com/opencontainers/image-spec/specs-go/v1" [label="github.com/opencontainers/image-spec/specs-go/v1" color="paleturquoise" URL="https://godoc.org/github.com/opencontainers/image-spec/specs-go/v1" target="_blank"];
+"github.com/opencontainers/image-spec/specs-go/v1" -> "github.com/opencontainers/go-digest";
+"github.com/opencontainers/image-spec/specs-go/v1" -> "github.com/opencontainers/image-spec/specs-go";
+"github.com/opencontainers/image-spec/specs-go/v1" -> "time";
+"github.com/prometheus/client_golang/prometheus" [label="github.com/prometheus/client_golang/prometheus" color="paleturquoise" URL="https://godoc.org/github.com/prometheus/client_golang/prometheus" target="_blank"];
+"github.com/prometheus/client_golang/prometheus" -> "bytes";
+"github.com/prometheus/client_golang/prometheus" -> "encoding/json";
+"github.com/prometheus/client_golang/prometheus" -> "errors";
+"github.com/prometheus/client_golang/prometheus" -> "expvar";
+"github.com/prometheus/client_golang/prometheus" -> "fmt";
+"github.com/prometheus/client_golang/prometheus" -> "github.com/beorn7/perks/quantile";
+"github.com/prometheus/client_golang/prometheus" -> "github.com/cespare/xxhash/v2";
+"github.com/prometheus/client_golang/prometheus" -> "github.com/golang/protobuf/proto";
+"github.com/prometheus/client_golang/prometheus" -> "github.com/prometheus/client_golang/prometheus/internal";
+"github.com/prometheus/client_golang/prometheus" -> "github.com/prometheus/client_model/go";
+"github.com/prometheus/client_golang/prometheus" -> "github.com/prometheus/common/expfmt";
+"github.com/prometheus/client_golang/prometheus" -> "github.com/prometheus/common/model";
+"github.com/prometheus/client_golang/prometheus" -> "github.com/prometheus/procfs";
+"github.com/prometheus/client_golang/prometheus" -> "io/ioutil";
+"github.com/prometheus/client_golang/prometheus" -> "math";
+"github.com/prometheus/client_golang/prometheus" -> "os";
+"github.com/prometheus/client_golang/prometheus" -> "path/filepath";
+"github.com/prometheus/client_golang/prometheus" -> "runtime";
+"github.com/prometheus/client_golang/prometheus" -> "runtime/debug";
+"github.com/prometheus/client_golang/prometheus" -> "sort";
+"github.com/prometheus/client_golang/prometheus" -> "strings";
+"github.com/prometheus/client_golang/prometheus" -> "sync";
+"github.com/prometheus/client_golang/prometheus" -> "sync/atomic";
+"github.com/prometheus/client_golang/prometheus" -> "time";
+"github.com/prometheus/client_golang/prometheus" -> "unicode/utf8";
+"github.com/prometheus/client_golang/prometheus/internal" [label="github.com/prometheus/client_golang/prometheus/internal" color="paleturquoise" URL="https://godoc.org/github.com/prometheus/client_golang/prometheus/internal" target="_blank"];
+"github.com/prometheus/client_golang/prometheus/internal" -> "github.com/prometheus/client_model/go";
+"github.com/prometheus/client_golang/prometheus/internal" -> "sort";
+"github.com/prometheus/client_golang/prometheus/promhttp" [label="github.com/prometheus/client_golang/prometheus/promhttp" color="paleturquoise" URL="https://godoc.org/github.com/prometheus/client_golang/prometheus/promhttp" target="_blank"];
+"github.com/prometheus/client_golang/prometheus/promhttp" -> "bufio";
+"github.com/prometheus/client_golang/prometheus/promhttp" -> "compress/gzip";
+"github.com/prometheus/client_golang/prometheus/promhttp" -> "crypto/tls";
+"github.com/prometheus/client_golang/prometheus/promhttp" -> "errors";
+"github.com/prometheus/client_golang/prometheus/promhttp" -> "fmt";
+"github.com/prometheus/client_golang/prometheus/promhttp" -> "github.com/prometheus/client_golang/prometheus";
+"github.com/prometheus/client_golang/prometheus/promhttp" -> "github.com/prometheus/client_model/go";
+"github.com/prometheus/client_golang/prometheus/promhttp" -> "github.com/prometheus/common/expfmt";
+"github.com/prometheus/client_golang/prometheus/promhttp" -> "io";
+"github.com/prometheus/client_golang/prometheus/promhttp" -> "net";
+"github.com/prometheus/client_golang/prometheus/promhttp" -> "net/http";
+"github.com/prometheus/client_golang/prometheus/promhttp" -> "net/http/httptrace";
+"github.com/prometheus/client_golang/prometheus/promhttp" -> "strconv";
+"github.com/prometheus/client_golang/prometheus/promhttp" -> "strings";
+"github.com/prometheus/client_golang/prometheus/promhttp" -> "sync";
+"github.com/prometheus/client_golang/prometheus/promhttp" -> "time";
+"github.com/prometheus/client_model/go" [label="github.com/prometheus/client_model/go" color="paleturquoise" URL="https://godoc.org/github.com/prometheus/client_model/go" target="_blank"];
+"github.com/prometheus/client_model/go" -> "fmt";
+"github.com/prometheus/client_model/go" -> "github.com/golang/protobuf/proto";
+"github.com/prometheus/client_model/go" -> "math";
+"github.com/prometheus/common/expfmt" [label="github.com/prometheus/common/expfmt" color="paleturquoise" URL="https://godoc.org/github.com/prometheus/common/expfmt" target="_blank"];
+"github.com/prometheus/common/expfmt" -> "bufio";
+"github.com/prometheus/common/expfmt" -> "bytes";
+"github.com/prometheus/common/expfmt" -> "fmt";
+"github.com/prometheus/common/expfmt" -> "github.com/golang/protobuf/proto";
+"github.com/prometheus/common/expfmt" -> "github.com/matttproud/golang_protobuf_extensions/pbutil";
+"github.com/prometheus/common/expfmt" -> "github.com/prometheus/client_model/go";
+"github.com/prometheus/common/expfmt" -> "github.com/prometheus/common/internal/bitbucket.org/ww/goautoneg";
+"github.com/prometheus/common/expfmt" -> "github.com/prometheus/common/model";
+"github.com/prometheus/common/expfmt" -> "io";
+"github.com/prometheus/common/expfmt" -> "io/ioutil";
+"github.com/prometheus/common/expfmt" -> "math";
+"github.com/prometheus/common/expfmt" -> "mime";
+"github.com/prometheus/common/expfmt" -> "net/http";
+"github.com/prometheus/common/expfmt" -> "strconv";
+"github.com/prometheus/common/expfmt" -> "strings";
+"github.com/prometheus/common/expfmt" -> "sync";
+"github.com/prometheus/common/internal/bitbucket.org/ww/goautoneg" [label="github.com/prometheus/common/internal/bitbucket.org/ww/goautoneg" color="paleturquoise" URL="https://godoc.org/github.com/prometheus/common/internal/bitbucket.org/ww/goautoneg" target="_blank"];
+"github.com/prometheus/common/internal/bitbucket.org/ww/goautoneg" -> "sort";
+"github.com/prometheus/common/internal/bitbucket.org/ww/goautoneg" -> "strconv";
+"github.com/prometheus/common/internal/bitbucket.org/ww/goautoneg" -> "strings";
+"github.com/prometheus/common/model" [label="github.com/prometheus/common/model" color="paleturquoise" URL="https://godoc.org/github.com/prometheus/common/model" target="_blank"];
+"github.com/prometheus/common/model" -> "encoding/json";
+"github.com/prometheus/common/model" -> "fmt";
+"github.com/prometheus/common/model" -> "math";
+"github.com/prometheus/common/model" -> "regexp";
+"github.com/prometheus/common/model" -> "sort";
+"github.com/prometheus/common/model" -> "strconv";
+"github.com/prometheus/common/model" -> "strings";
+"github.com/prometheus/common/model" -> "time";
+"github.com/prometheus/common/model" -> "unicode/utf8";
+"github.com/prometheus/procfs" [label="github.com/prometheus/procfs" color="paleturquoise" URL="https://godoc.org/github.com/prometheus/procfs" target="_blank"];
+"github.com/prometheus/procfs" -> "bufio";
+"github.com/prometheus/procfs" -> "bytes";
+"github.com/prometheus/procfs" -> "encoding/hex";
+"github.com/prometheus/procfs" -> "errors";
+"github.com/prometheus/procfs" -> "fmt";
+"github.com/prometheus/procfs" -> "github.com/prometheus/procfs/internal/fs";
+"github.com/prometheus/procfs" -> "github.com/prometheus/procfs/internal/util";
+"github.com/prometheus/procfs" -> "io";
+"github.com/prometheus/procfs" -> "io/ioutil";
+"github.com/prometheus/procfs" -> "net";
+"github.com/prometheus/procfs" -> "os";
+"github.com/prometheus/procfs" -> "path/filepath";
+"github.com/prometheus/procfs" -> "regexp";
+"github.com/prometheus/procfs" -> "sort";
+"github.com/prometheus/procfs" -> "strconv";
+"github.com/prometheus/procfs" -> "strings";
+"github.com/prometheus/procfs" -> "time";
+"github.com/prometheus/procfs/internal/fs" [label="github.com/prometheus/procfs/internal/fs" color="paleturquoise" URL="https://godoc.org/github.com/prometheus/procfs/internal/fs" target="_blank"];
+"github.com/prometheus/procfs/internal/fs" -> "fmt";
+"github.com/prometheus/procfs/internal/fs" -> "os";
+"github.com/prometheus/procfs/internal/fs" -> "path/filepath";
+"github.com/prometheus/procfs/internal/util" [label="github.com/prometheus/procfs/internal/util" color="paleturquoise" URL="https://godoc.org/github.com/prometheus/procfs/internal/util" target="_blank"];
+"github.com/prometheus/procfs/internal/util" -> "bytes";
+"github.com/prometheus/procfs/internal/util" -> "io/ioutil";
+"github.com/prometheus/procfs/internal/util" -> "os";
+"github.com/prometheus/procfs/internal/util" -> "strconv";
+"github.com/prometheus/procfs/internal/util" -> "strings";
+"github.com/prometheus/procfs/internal/util" -> "syscall";
+"hash" [label="hash" color="palegreen" URL="https://godoc.org/hash" target="_blank"];
+"io" [label="io" color="palegreen" URL="https://godoc.org/io" target="_blank"];
+"io/ioutil" [label="io/ioutil" color="palegreen" URL="https://godoc.org/io/ioutil" target="_blank"];
+"log" [label="log" color="palegreen" URL="https://godoc.org/log" target="_blank"];
+"math" [label="math" color="palegreen" URL="https://godoc.org/math" target="_blank"];
+"math/bits" [label="math/bits" color="palegreen" URL="https://godoc.org/math/bits" target="_blank"];
+"mime" [label="mime" color="palegreen" URL="https://godoc.org/mime" target="_blank"];
+"net" [label="net" color="palegreen" URL="https://godoc.org/net" target="_blank"];
+"net/http" [label="net/http" color="palegreen" URL="https://godoc.org/net/http" target="_blank"];
+"net/http/httptrace" [label="net/http/httptrace" color="palegreen" URL="https://godoc.org/net/http/httptrace" target="_blank"];
+"net/url" [label="net/url" color="palegreen" URL="https://godoc.org/net/url" target="_blank"];
+"os" [label="os" color="palegreen" URL="https://godoc.org/os" target="_blank"];
+"path" [label="path" color="palegreen" URL="https://godoc.org/path" target="_blank"];
+"path/filepath" [label="path/filepath" color="palegreen" URL="https://godoc.org/path/filepath" target="_blank"];
+"reflect" [label="reflect" color="palegreen" URL="https://godoc.org/reflect" target="_blank"];
+"regexp" [label="regexp" color="palegreen" URL="https://godoc.org/regexp" target="_blank"];
+"runtime" [label="runtime" color="palegreen" URL="https://godoc.org/runtime" target="_blank"];
+"runtime/debug" [label="runtime/debug" color="palegreen" URL="https://godoc.org/runtime/debug" target="_blank"];
+"sort" [label="sort" color="palegreen" URL="https://godoc.org/sort" target="_blank"];
+"strconv" [label="strconv" color="palegreen" URL="https://godoc.org/strconv" target="_blank"];
+"strings" [label="strings" color="palegreen" URL="https://godoc.org/strings" target="_blank"];
+"sync" [label="sync" color="palegreen" URL="https://godoc.org/sync" target="_blank"];
+"sync/atomic" [label="sync/atomic" color="palegreen" URL="https://godoc.org/sync/atomic" target="_blank"];
+"syscall" [label="syscall" color="palegreen" URL="https://godoc.org/syscall" target="_blank"];
+"time" [label="time" color="palegreen" URL="https://godoc.org/time" target="_blank"];
+"unicode" [label="unicode" color="palegreen" URL="https://godoc.org/unicode" target="_blank"];
+"unicode/utf8" [label="unicode/utf8" color="palegreen" URL="https://godoc.org/unicode/utf8" target="_blank"];
+"unsafe" [label="unsafe" color="palegreen" URL="https://godoc.org/unsafe" target="_blank"];
+}
diff --git a/pkg/go-containerregistry/images/dot/ggcr.dot b/pkg/go-containerregistry/images/dot/ggcr.dot
new file mode 100644
index 00000000..459ba6d2
--- /dev/null
+++ b/pkg/go-containerregistry/images/dot/ggcr.dot
@@ -0,0 +1,130 @@
+digraph godep {
+nodesep=0.4
+ranksep=0.8
+node [shape="box",style="rounded,filled"]
+edge [arrowsize="0.5"]
+"bufio" [label="bufio" color="palegreen" URL="https://godoc.org/bufio" target="_blank"];
+"bytes" [label="bytes" color="palegreen" URL="https://godoc.org/bytes" target="_blank"];
+"context" [label="context" color="palegreen" URL="https://godoc.org/context" target="_blank"];
+"encoding/base64" [label="encoding/base64" color="palegreen" URL="https://godoc.org/encoding/base64" target="_blank"];
+"encoding/json" [label="encoding/json" color="palegreen" URL="https://godoc.org/encoding/json" target="_blank"];
+"errors" [label="errors" color="palegreen" URL="https://godoc.org/errors" target="_blank"];
+"fmt" [label="fmt" color="palegreen" URL="https://godoc.org/fmt" target="_blank"];
+"github.com/docker/cli/cli/config" [label="github.com/docker/cli/cli/config" color="paleturquoise" URL="https://godoc.org/github.com/docker/cli/cli/config" target="_blank"];
+"github.com/docker/cli/cli/config" -> "fmt";
+"github.com/docker/cli/cli/config" -> "github.com/docker/cli/cli/config/configfile";
+"github.com/docker/cli/cli/config" -> "github.com/docker/cli/cli/config/credentials";
+"github.com/docker/cli/cli/config" -> "github.com/docker/cli/cli/config/types";
+"github.com/docker/cli/cli/config" -> "github.com/docker/docker/pkg/homedir";
+"github.com/docker/cli/cli/config" -> "github.com/pkg/errors";
+"github.com/docker/cli/cli/config" -> "io";
+"github.com/docker/cli/cli/config" -> "os";
+"github.com/docker/cli/cli/config" -> "path/filepath";
+"github.com/docker/cli/cli/config" -> "strings";
+"github.com/docker/cli/cli/config/configfile" [label="github.com/docker/cli/cli/config/configfile" color="paleturquoise" URL="https://godoc.org/github.com/docker/cli/cli/config/configfile" target="_blank"];
+"github.com/docker/cli/cli/config/configfile" -> "encoding/base64";
+"github.com/docker/cli/cli/config/configfile" -> "encoding/json";
+"github.com/docker/cli/cli/config/configfile" -> "fmt";
+"github.com/docker/cli/cli/config/configfile" -> "github.com/docker/cli/cli/config/credentials";
+"github.com/docker/cli/cli/config/configfile" -> "github.com/docker/cli/cli/config/types";
+"github.com/docker/cli/cli/config/configfile" -> "github.com/pkg/errors";
+"github.com/docker/cli/cli/config/configfile" -> "io";
+"github.com/docker/cli/cli/config/configfile" -> "io/ioutil";
+"github.com/docker/cli/cli/config/configfile" -> "os";
+"github.com/docker/cli/cli/config/configfile" -> "path/filepath";
+"github.com/docker/cli/cli/config/configfile" -> "strings";
+"github.com/docker/cli/cli/config/credentials" [label="github.com/docker/cli/cli/config/credentials" color="paleturquoise" URL="https://godoc.org/github.com/docker/cli/cli/config/credentials" target="_blank"];
+"github.com/docker/cli/cli/config/credentials" -> "github.com/docker/cli/cli/config/types";
+"github.com/docker/cli/cli/config/credentials" -> "github.com/docker/docker-credential-helpers/client";
+"github.com/docker/cli/cli/config/credentials" -> "github.com/docker/docker-credential-helpers/credentials";
+"github.com/docker/cli/cli/config/credentials" -> "os/exec";
+"github.com/docker/cli/cli/config/credentials" -> "strings";
+"github.com/docker/cli/cli/config/types" [label="github.com/docker/cli/cli/config/types" color="paleturquoise" URL="https://godoc.org/github.com/docker/cli/cli/config/types" target="_blank"];
+"github.com/docker/docker-credential-helpers/client" [label="github.com/docker/docker-credential-helpers/client" color="palegoldenrod" URL="https://godoc.org/github.com/docker/docker-credential-helpers/client" target="_blank"];
+"github.com/docker/docker-credential-helpers/client" -> "bytes";
+"github.com/docker/docker-credential-helpers/client" -> "encoding/json";
+"github.com/docker/docker-credential-helpers/client" -> "fmt";
+"github.com/docker/docker-credential-helpers/client" -> "github.com/docker/docker-credential-helpers/credentials";
+"github.com/docker/docker-credential-helpers/client" -> "io";
+"github.com/docker/docker-credential-helpers/client" -> "os";
+"github.com/docker/docker-credential-helpers/client" -> "os/exec";
+"github.com/docker/docker-credential-helpers/client" -> "strings";
+"github.com/docker/docker-credential-helpers/credentials" [label="github.com/docker/docker-credential-helpers/credentials" color="palegoldenrod" URL="https://godoc.org/github.com/docker/docker-credential-helpers/credentials" target="_blank"];
+"github.com/docker/docker-credential-helpers/credentials" -> "bufio";
+"github.com/docker/docker-credential-helpers/credentials" -> "bytes";
+"github.com/docker/docker-credential-helpers/credentials" -> "encoding/json";
+"github.com/docker/docker-credential-helpers/credentials" -> "fmt";
+"github.com/docker/docker-credential-helpers/credentials" -> "io";
+"github.com/docker/docker-credential-helpers/credentials" -> "os";
+"github.com/docker/docker-credential-helpers/credentials" -> "strings";
+"github.com/docker/docker/pkg/homedir" [label="github.com/docker/docker/pkg/homedir" color="paleturquoise" URL="https://godoc.org/github.com/docker/docker/pkg/homedir" target="_blank"];
+"github.com/docker/docker/pkg/homedir" -> "errors";
+"github.com/docker/docker/pkg/homedir" -> "os";
+"github.com/docker/docker/pkg/homedir" -> "os/user";
+"github.com/docker/docker/pkg/homedir" -> "path/filepath";
+"github.com/docker/docker/pkg/homedir" -> "strings";
+"github.com/google/go-containerregistry/pkg/authn" [label="github.com/google/go-containerregistry/pkg/authn" color="paleturquoise" URL="https://godoc.org/github.com/google/go-containerregistry/pkg/authn" target="_blank"];
+"github.com/google/go-containerregistry/pkg/authn" -> "encoding/json";
+"github.com/google/go-containerregistry/pkg/authn" -> "github.com/docker/cli/cli/config";
+"github.com/google/go-containerregistry/pkg/authn" -> "github.com/docker/cli/cli/config/types";
+"github.com/google/go-containerregistry/pkg/authn" -> "github.com/google/go-containerregistry/pkg/logs";
+"github.com/google/go-containerregistry/pkg/authn" -> "github.com/google/go-containerregistry/pkg/name";
+"github.com/google/go-containerregistry/pkg/authn" -> "os";
+"github.com/google/go-containerregistry/pkg/internal/retry" [label="github.com/google/go-containerregistry/pkg/internal/retry" color="paleturquoise" URL="https://godoc.org/github.com/google/go-containerregistry/pkg/internal/retry" target="_blank"];
+"github.com/google/go-containerregistry/pkg/internal/retry" -> "context";
+"github.com/google/go-containerregistry/pkg/internal/retry" -> "fmt";
+"github.com/google/go-containerregistry/pkg/internal/retry" -> "github.com/google/go-containerregistry/pkg/internal/retry/wait";
+"github.com/google/go-containerregistry/pkg/internal/retry/wait" [label="github.com/google/go-containerregistry/pkg/internal/retry/wait" color="paleturquoise" URL="https://godoc.org/github.com/google/go-containerregistry/pkg/internal/retry/wait" target="_blank"];
+"github.com/google/go-containerregistry/pkg/internal/retry/wait" -> "errors";
+"github.com/google/go-containerregistry/pkg/internal/retry/wait" -> "math/rand";
+"github.com/google/go-containerregistry/pkg/internal/retry/wait" -> "time";
+"github.com/google/go-containerregistry/pkg/logs" [label="github.com/google/go-containerregistry/pkg/logs" color="paleturquoise" URL="https://godoc.org/github.com/google/go-containerregistry/pkg/logs" target="_blank"];
+"github.com/google/go-containerregistry/pkg/logs" -> "io/ioutil";
+"github.com/google/go-containerregistry/pkg/logs" -> "log";
+"github.com/google/go-containerregistry/pkg/name" [label="github.com/google/go-containerregistry/pkg/name" color="paleturquoise" URL="https://godoc.org/github.com/google/go-containerregistry/pkg/name" target="_blank"];
+"github.com/google/go-containerregistry/pkg/name" -> "fmt";
+"github.com/google/go-containerregistry/pkg/name" -> "net";
+"github.com/google/go-containerregistry/pkg/name" -> "net/url";
+"github.com/google/go-containerregistry/pkg/name" -> "regexp";
+"github.com/google/go-containerregistry/pkg/name" -> "strings";
+"github.com/google/go-containerregistry/pkg/name" -> "unicode/utf8";
+"github.com/google/go-containerregistry/pkg/v1/remote/transport" [label="github.com/google/go-containerregistry/pkg/v1/remote/transport" color="paleturquoise" URL="https://godoc.org/github.com/google/go-containerregistry/pkg/v1/remote/transport" target="_blank"];
+"github.com/google/go-containerregistry/pkg/v1/remote/transport" -> "encoding/base64";
+"github.com/google/go-containerregistry/pkg/v1/remote/transport" -> "encoding/json";
+"github.com/google/go-containerregistry/pkg/v1/remote/transport" -> "fmt";
+"github.com/google/go-containerregistry/pkg/v1/remote/transport" -> "github.com/google/go-containerregistry/pkg/authn";
+"github.com/google/go-containerregistry/pkg/v1/remote/transport" -> "github.com/google/go-containerregistry/pkg/internal/retry";
+"github.com/google/go-containerregistry/pkg/v1/remote/transport" -> "github.com/google/go-containerregistry/pkg/logs";
+"github.com/google/go-containerregistry/pkg/v1/remote/transport" -> "github.com/google/go-containerregistry/pkg/name";
+"github.com/google/go-containerregistry/pkg/v1/remote/transport" -> "io/ioutil";
+"github.com/google/go-containerregistry/pkg/v1/remote/transport" -> "net";
+"github.com/google/go-containerregistry/pkg/v1/remote/transport" -> "net/http";
+"github.com/google/go-containerregistry/pkg/v1/remote/transport" -> "net/http/httputil";
+"github.com/google/go-containerregistry/pkg/v1/remote/transport" -> "net/url";
+"github.com/google/go-containerregistry/pkg/v1/remote/transport" -> "strings";
+"github.com/google/go-containerregistry/pkg/v1/remote/transport" -> "time";
+"github.com/pkg/errors" [label="github.com/pkg/errors" color="palegoldenrod" URL="https://godoc.org/github.com/pkg/errors" target="_blank"];
+"github.com/pkg/errors" -> "fmt";
+"github.com/pkg/errors" -> "io";
+"github.com/pkg/errors" -> "path";
+"github.com/pkg/errors" -> "runtime";
+"github.com/pkg/errors" -> "strings";
+"io" [label="io" color="palegreen" URL="https://godoc.org/io" target="_blank"];
+"io/ioutil" [label="io/ioutil" color="palegreen" URL="https://godoc.org/io/ioutil" target="_blank"];
+"log" [label="log" color="palegreen" URL="https://godoc.org/log" target="_blank"];
+"math/rand" [label="math/rand" color="palegreen" URL="https://godoc.org/math/rand" target="_blank"];
+"net" [label="net" color="palegreen" URL="https://godoc.org/net" target="_blank"];
+"net/http" [label="net/http" color="palegreen" URL="https://godoc.org/net/http" target="_blank"];
+"net/http/httputil" [label="net/http/httputil" color="palegreen" URL="https://godoc.org/net/http/httputil" target="_blank"];
+"net/url" [label="net/url" color="palegreen" URL="https://godoc.org/net/url" target="_blank"];
+"os" [label="os" color="palegreen" URL="https://godoc.org/os" target="_blank"];
+"os/exec" [label="os/exec" color="palegreen" URL="https://godoc.org/os/exec" target="_blank"];
+"os/user" [label="os/user" color="palegreen" URL="https://godoc.org/os/user" target="_blank"];
+"path" [label="path" color="palegreen" URL="https://godoc.org/path" target="_blank"];
+"path/filepath" [label="path/filepath" color="palegreen" URL="https://godoc.org/path/filepath" target="_blank"];
+"regexp" [label="regexp" color="palegreen" URL="https://godoc.org/regexp" target="_blank"];
+"runtime" [label="runtime" color="palegreen" URL="https://godoc.org/runtime" target="_blank"];
+"strings" [label="strings" color="palegreen" URL="https://godoc.org/strings" target="_blank"];
+"time" [label="time" color="palegreen" URL="https://godoc.org/time" target="_blank"];
+"unicode/utf8" [label="unicode/utf8" color="palegreen" URL="https://godoc.org/unicode/utf8" target="_blank"];
+}
diff --git a/pkg/go-containerregistry/images/dot/image-anatomy.dot b/pkg/go-containerregistry/images/dot/image-anatomy.dot
new file mode 100644
index 00000000..179e3112
--- /dev/null
+++ b/pkg/go-containerregistry/images/dot/image-anatomy.dot
@@ -0,0 +1,26 @@
+digraph {
+ compound=true;
+ rankdir="LR";
+
+ tag [label="", shape="circle", width=0.1, style="filled", color="black"];
+ manifest [shape="note"];
+ config [shape="note"];
+
+ tag -> manifest [label="digest", taillabel="tag", tailport=head, labeldistance=2.1, labelangle=108];
+ manifest -> config [label="(image id)"];
+ config -> l1 [label="diffid"];
+ config -> l2 [label="diffid"];
+ manifest -> l1 [lhead=cluster_layer1, label="layer digest"];
+ manifest -> l2 [lhead=cluster_layer2, label="layer digest"];
+
+ subgraph cluster_layer1 {
+ label = "layer.tar.gz";
+ margin = 20.0;
+ l1 [label="layer.tar", shape="folder"];
+ }
+ subgraph cluster_layer2 {
+ label = "layer.tar.gz";
+ margin = 20.0;
+ l2 [label="layer.tar", shape="folder"];
+ }
+}
diff --git a/pkg/go-containerregistry/images/dot/index-anatomy-strange.dot b/pkg/go-containerregistry/images/dot/index-anatomy-strange.dot
new file mode 100644
index 00000000..2bccba3e
--- /dev/null
+++ b/pkg/go-containerregistry/images/dot/index-anatomy-strange.dot
@@ -0,0 +1,24 @@
+digraph {
+ ordering = out;
+ compound=true;
+ rankdir="LR";
+
+ tag [label="", shape="circle", width=0.1, style="filled", color="black"];
+ tag2 [label="", shape="circle", width=0.1, style="filled", color="black"];
+ tag3 [label="", shape="circle", width=0.1, style="filled", color="black"];
+ index [shape="note"];
+ index2 [label="index", shape="note"];
+ image [shape="note"];
+ image2 [label="image", shape="note"];
+ image3 [label="image", shape="note"];
+ xml;
+
+ tag -> index [taillabel="r124356", tailport=head, labeldistance=2.1, labelangle=108];
+ tag2 -> index2 [taillabel="stable-release", tailport=head, labeldistance=2.1, labelangle=108];
+ tag3 -> image [taillabel="v1.0", tailport=head, labeldistance=2.1, labelangle=108];
+ index -> image;
+ index -> xml;
+ index -> index2;
+ index2 -> image2;
+ index2 -> image3;
+}
diff --git a/pkg/go-containerregistry/images/dot/index-anatomy.dot b/pkg/go-containerregistry/images/dot/index-anatomy.dot
new file mode 100644
index 00000000..9155af02
--- /dev/null
+++ b/pkg/go-containerregistry/images/dot/index-anatomy.dot
@@ -0,0 +1,18 @@
+digraph {
+ ordering = out;
+ compound=true;
+ rankdir="LR";
+
+ tag [label="", shape="circle", width=0.1, style="filled", color="black"];
+ tag2 [label="", shape="circle", width=0.1, style="filled", color="black"];
+ tag3 [label="", shape="circle", width=0.1, style="filled", color="black"];
+ index [shape="note"];
+ image [shape="note"];
+ image2 [label="image", shape="note"];
+
+ tag -> index [taillabel="latest", tailport=head, labeldistance=2.1, labelangle=108];
+ tag2 -> image [taillabel="amd64", tailport=head, labeldistance=2.1, labelangle=108];
+ tag3 -> image2 [taillabel="ppc64le", tailport=head, labeldistance=2.1, labelangle=252];
+ index -> image;
+ index -> image2;
+}
diff --git a/pkg/go-containerregistry/images/dot/mutate.dot b/pkg/go-containerregistry/images/dot/mutate.dot
new file mode 100644
index 00000000..228f8b63
--- /dev/null
+++ b/pkg/go-containerregistry/images/dot/mutate.dot
@@ -0,0 +1,59 @@
+digraph {
+ input [label="v1.Image", shape=box];
+ output [label="v1.Image", shape=box];
+
+ ordering = "out";
+
+ subgraph cluster_source {
+ label = "Sources";
+ "remotesource" [label="remote"];
+ "tarballsource" [label="tarball"];
+ "randomsource" [label="random"];
+ "layoutsource" [label="layout"];
+ "daemonsource" [label="daemon"];
+ }
+
+ subgraph cluster_mutate {
+ label = "mutate";
+ "mutateconfig" [label="Config"];
+ "mutatetime" [label="Time"];
+ "mutatemediatype" [label="MediaType"];
+ "mutateappend" [label="Append"];
+ "mutaterebase" [label="Rebase"];
+ }
+
+ subgraph cluster_sinks {
+ label = "Sinks";
+ labelloc = "b";
+
+ "remotesink" [label="remote"];
+ "tarballsink" [label="tarball"];
+ "legacy/tarballsink" [label="legacy/tarball"];
+ "layoutsink" [label="layout"];
+ "daemonsink" [label="daemon"];
+ }
+
+ "randomsource" -> input;
+ "layoutsource" -> input;
+ "daemonsource" -> input;
+ "tarballsource" -> input;
+ "remotesource" -> input;
+
+ input -> "mutateconfig";
+ input -> "mutatetime";
+ input -> "mutatemediatype";
+ input -> "mutateappend";
+ input -> "mutaterebase";
+
+ "mutateconfig" -> output;
+ "mutatetime" -> output;
+ "mutatemediatype" -> output;
+ "mutateappend" -> output;
+ "mutaterebase" -> output;
+
+ output -> "legacy/tarballsink";
+ output -> "layoutsink";
+ output -> "daemonsink";
+ output -> "tarballsink";
+ output -> "remotesink";
+}
diff --git a/pkg/go-containerregistry/images/dot/remote.dot b/pkg/go-containerregistry/images/dot/remote.dot
new file mode 100644
index 00000000..9b5e08c1
--- /dev/null
+++ b/pkg/go-containerregistry/images/dot/remote.dot
@@ -0,0 +1,66 @@
+digraph {
+ compound=true;
+ rankdir="LR";
+ ordering = in;
+
+ subgraph cluster_registry {
+ label = "registry";
+
+ subgraph cluster_tags {
+ label = "/v2/.../tags/list";
+
+ tag [label="tag", shape="rect"];
+ tag2 [label="tag", shape="rect"];
+ }
+
+ subgraph cluster_manifests {
+ label = "/v2/.../manifests/";
+
+ subgraph cluster_manifest {
+ label = "manifest";
+
+ mconfig [label="config", shape="rect"];
+ layers [label="layers", shape="rect"];
+ }
+
+ subgraph cluster_manifest2 {
+ label = "manifest";
+
+ mconfig2 [label="config", shape="rect"];
+ layers2 [label="layers", shape="rect"];
+ }
+
+ subgraph cluster_index {
+ label = "index";
+
+ imanifest [label="manifests", shape="rect"];
+ }
+
+ imanifest -> mconfig [lhead=cluster_manifest];
+ imanifest -> mconfig2 [lhead=cluster_manifest2];
+ }
+
+ subgraph cluster_blobs {
+ label = "/v2/.../blobs/| image manifest (platform A) |
| - schema version |
| - media type |
| - config : descriptor |
| - layers : array of descriptors |
| - (annotations) |
| image index |
| - schema version |
| - media type |
| - manifests : array of descriptors |
| - (annotations) |
| configuration |
| - rootfs/diff_ids : array of layer ids |
| - container config |
| - history |
| layer |
| file system additions, overwrites, and deletions |
| image reference |
| - hostname |
| - path |
| - (tag) |
| - (SHA-256 digest of compressed content) |
| descriptor |
| targets content with the following properties: |
| - media type |
| - SHA-256 digest of compressed content |
| - size |
| - (urls) |
| - (annotations) |
| id |
| - SHA-256 digest of uncompressed content |
+
+
+
+
+
+
+
+