aboutsummaryrefslogtreecommitdiff
path: root/vendor/github.com/containers/image/docker/docker_image_src.go
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/github.com/containers/image/docker/docker_image_src.go')
-rw-r--r--vendor/github.com/containers/image/docker/docker_image_src.go98
1 files changed, 88 insertions, 10 deletions
diff --git a/vendor/github.com/containers/image/docker/docker_image_src.go b/vendor/github.com/containers/image/docker/docker_image_src.go
index 8367792bf..c8fdb407c 100644
--- a/vendor/github.com/containers/image/docker/docker_image_src.go
+++ b/vendor/github.com/containers/image/docker/docker_image_src.go
@@ -13,9 +13,10 @@ import (
"github.com/containers/image/docker/reference"
"github.com/containers/image/manifest"
+ "github.com/containers/image/pkg/sysregistriesv2"
"github.com/containers/image/types"
"github.com/docker/distribution/registry/client"
- "github.com/opencontainers/go-digest"
+ digest "github.com/opencontainers/go-digest"
"github.com/pkg/errors"
"github.com/sirupsen/logrus"
)
@@ -28,17 +29,94 @@ type dockerImageSource struct {
cachedManifestMIMEType string // Only valid if cachedManifest != nil
}
-// newImageSource creates a new ImageSource for the specified image reference.
-// The caller must call .Close() on the returned ImageSource.
-func newImageSource(sys *types.SystemContext, ref dockerReference) (*dockerImageSource, error) {
- c, err := newDockerClientFromRef(sys, ref, false, "pull")
+// newImageSource creates a new `ImageSource` for the specified image reference
+// `ref`.
+//
+// The following steps will be done during the instance creation:
+//
+// - Lookup the registry within the configured location in
+// `sys.SystemRegistriesConfPath`. If there is no configured registry available,
+// we fallback to the provided docker reference `ref`.
+//
+// - References which contain a configured prefix will be automatically rewritten
+// to the correct target reference. For example, if the configured
+// `prefix = "example.com/foo"`, `location = "example.com"` and the image will be
+// pulled from the ref `example.com/foo/image`, then the resulting pull will
+// effectively point to `example.com/image`.
+//
+// - If the rewritten reference succeeds, it will be used as the `dockerRef`
+// in the client. If the rewrite fails, the function immediately returns an error.
+//
+// - Each mirror will be used (in the configured order) to test the
+// availability of the image manifest on the remote location. For example,
+// if the manifest is not reachable due to connectivity issues, then the next
+// mirror will be tested instead. If no mirror is configured or contains the
+// target manifest, then the initial `ref` will be tested as fallback. The
+// creation of the new `dockerImageSource` only succeeds if a remote
+// location with the available manifest was found.
+//
+// A cleanup call to `.Close()` is needed if the caller is done using the returned
+// `ImageSource`.
+func newImageSource(ctx context.Context, sys *types.SystemContext, ref dockerReference) (*dockerImageSource, error) {
+ registry, err := sysregistriesv2.FindRegistry(sys, ref.ref.Name())
if err != nil {
- return nil, err
+ return nil, errors.Wrapf(err, "error loading registries configuration")
+ }
+
+ if registry == nil {
+ // No configuration was found for the provided reference, so we create
+ // a fallback registry by hand to make the client creation below work
+ // as intended.
+ registry = &sysregistriesv2.Registry{
+ Endpoint: sysregistriesv2.Endpoint{
+ Location: ref.ref.String(),
+ },
+ Prefix: ref.ref.String(),
+ }
+ }
+
+ primaryDomain := reference.Domain(ref.ref)
+ // Found the registry within the sysregistriesv2 configuration. Now we test
+ // all endpoints for the manifest availability. If a working image source
+ // was found, it will be used for all future pull actions.
+ manifestLoadErr := errors.New("Internal error: newImageSource returned without trying any endpoint")
+ for _, endpoint := range append(registry.Mirrors, registry.Endpoint) {
+ logrus.Debugf("Trying to pull %q from endpoint %q", ref.ref, endpoint.Location)
+
+ newRef, err := endpoint.RewriteReference(ref.ref, registry.Prefix)
+ if err != nil {
+ return nil, err
+ }
+ dockerRef, err := newReference(newRef)
+ if err != nil {
+ return nil, err
+ }
+
+ endpointSys := sys
+ // sys.DockerAuthConfig does not explicitly specify a registry; we must not blindly send the credentials intended for the primary endpoint to mirrors.
+ if endpointSys != nil && endpointSys.DockerAuthConfig != nil && reference.Domain(dockerRef.ref) != primaryDomain {
+ copy := *endpointSys
+ copy.DockerAuthConfig = nil
+ endpointSys = &copy
+ }
+
+ client, err := newDockerClientFromRef(endpointSys, dockerRef, false, "pull")
+ if err != nil {
+ return nil, err
+ }
+ client.tlsClientConfig.InsecureSkipVerify = endpoint.Insecure
+
+ testImageSource := &dockerImageSource{
+ ref: dockerRef,
+ c: client,
+ }
+
+ manifestLoadErr = testImageSource.ensureManifestIsLoaded(ctx)
+ if manifestLoadErr == nil {
+ return testImageSource, nil
+ }
}
- return &dockerImageSource{
- ref: ref,
- c: c,
- }, nil
+ return nil, manifestLoadErr
}
// Reference returns the reference used to set up this source, _as specified by the user_