| 
									
										
										
										
											2017-02-11 00:48:15 +08:00
										 |  |  | package buildah | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | import ( | 
					
						
							| 
									
										
										
										
											2018-04-12 22:20:36 +08:00
										 |  |  | 	"context" | 
					
						
							| 
									
										
										
										
											2019-01-07 15:06:36 +08:00
										 |  |  | 	"fmt" | 
					
						
							| 
									
										
										
										
											2018-08-09 04:38:53 +08:00
										 |  |  | 	"io" | 
					
						
							| 
									
										
										
										
											2019-03-14 04:03:13 +08:00
										 |  |  | 	"path/filepath" | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-07-29 05:29:37 +08:00
										 |  |  | 	"strings" | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-10-18 06:06:16 +08:00
										 |  |  | 	"github.com/containers/buildah/pkg/blobcache" | 
					
						
							| 
									
										
										
										
											2018-09-18 03:20:16 +08:00
										 |  |  | 	"github.com/containers/buildah/util" | 
					
						
							| 
									
										
										
										
											2017-06-05 21:42:30 +08:00
										 |  |  | 	cp "github.com/containers/image/copy" | 
					
						
							| 
									
										
										
										
											2019-02-02 20:29:05 +08:00
										 |  |  | 	"github.com/containers/image/directory" | 
					
						
							| 
									
										
										
										
											2019-01-07 15:06:36 +08:00
										 |  |  | 	"github.com/containers/image/docker" | 
					
						
							| 
									
										
										
										
											2019-02-02 20:29:05 +08:00
										 |  |  | 	dockerarchive "github.com/containers/image/docker/archive" | 
					
						
							| 
									
										
										
										
											2017-02-14 00:44:47 +08:00
										 |  |  | 	"github.com/containers/image/docker/reference" | 
					
						
							| 
									
										
										
										
											2018-03-19 10:16:47 +08:00
										 |  |  | 	tarfile "github.com/containers/image/docker/tarfile" | 
					
						
							|  |  |  | 	ociarchive "github.com/containers/image/oci/archive" | 
					
						
							| 
									
										
										
										
											2019-02-20 05:59:59 +08:00
										 |  |  | 	oci "github.com/containers/image/oci/layout" | 
					
						
							| 
									
										
										
										
											2017-02-11 00:48:15 +08:00
										 |  |  | 	"github.com/containers/image/signature" | 
					
						
							|  |  |  | 	is "github.com/containers/image/storage" | 
					
						
							| 
									
										
										
										
											2017-07-29 05:29:37 +08:00
										 |  |  | 	"github.com/containers/image/transports" | 
					
						
							| 
									
										
										
										
											2017-02-11 00:48:15 +08:00
										 |  |  | 	"github.com/containers/image/types" | 
					
						
							| 
									
										
										
										
											2017-05-17 23:53:28 +08:00
										 |  |  | 	"github.com/containers/storage" | 
					
						
							| 
									
										
										
										
											2019-02-22 06:35:51 +08:00
										 |  |  | 	multierror "github.com/hashicorp/go-multierror" | 
					
						
							| 
									
										
										
										
											2017-06-02 03:23:02 +08:00
										 |  |  | 	"github.com/pkg/errors" | 
					
						
							| 
									
										
										
										
											2017-10-10 03:05:56 +08:00
										 |  |  | 	"github.com/sirupsen/logrus" | 
					
						
							| 
									
										
										
										
											2017-02-11 00:48:15 +08:00
										 |  |  | ) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-08-09 04:38:53 +08:00
										 |  |  | // PullOptions can be used to alter how an image is copied in from somewhere.
 | 
					
						
							|  |  |  | type PullOptions struct { | 
					
						
							|  |  |  | 	// SignaturePolicyPath specifies an override location for the signature
 | 
					
						
							|  |  |  | 	// policy which should be used for verifying the new image as it is
 | 
					
						
							|  |  |  | 	// being written.  Except in specific circumstances, no value should be
 | 
					
						
							|  |  |  | 	// specified, indicating that the shared, system-wide default policy
 | 
					
						
							|  |  |  | 	// should be used.
 | 
					
						
							|  |  |  | 	SignaturePolicyPath string | 
					
						
							|  |  |  | 	// ReportWriter is an io.Writer which will be used to log the writing
 | 
					
						
							|  |  |  | 	// of the new image.
 | 
					
						
							|  |  |  | 	ReportWriter io.Writer | 
					
						
							|  |  |  | 	// Store is the local storage store which holds the source image.
 | 
					
						
							|  |  |  | 	Store storage.Store | 
					
						
							|  |  |  | 	// github.com/containers/image/types SystemContext to hold credentials
 | 
					
						
							|  |  |  | 	// and other authentication/authorization information.
 | 
					
						
							|  |  |  | 	SystemContext *types.SystemContext | 
					
						
							| 
									
										
										
										
											2018-10-18 06:06:16 +08:00
										 |  |  | 	// BlobDirectory is the name of a directory in which we'll attempt to
 | 
					
						
							|  |  |  | 	// store copies of layer blobs that we pull down, if any.  It should
 | 
					
						
							|  |  |  | 	// already exist.
 | 
					
						
							|  |  |  | 	BlobDirectory string | 
					
						
							| 
									
										
										
										
											2019-01-07 15:06:36 +08:00
										 |  |  | 	// AllTags is a boolean value that determines if all tagged images
 | 
					
						
							|  |  |  | 	// will be downloaded from the repository. The default is false.
 | 
					
						
							|  |  |  | 	AllTags bool | 
					
						
							| 
									
										
										
										
											2018-08-09 04:38:53 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-02-22 07:01:08 +08:00
										 |  |  | func localImageNameForReference(ctx context.Context, store storage.Store, srcRef types.ImageReference) (string, error) { | 
					
						
							| 
									
										
										
										
											2017-07-29 05:29:37 +08:00
										 |  |  | 	if srcRef == nil { | 
					
						
							|  |  |  | 		return "", errors.Errorf("reference to image is empty") | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2018-03-19 10:16:47 +08:00
										 |  |  | 	var name string | 
					
						
							|  |  |  | 	switch srcRef.Transport().Name() { | 
					
						
							| 
									
										
										
										
											2019-02-02 20:29:05 +08:00
										 |  |  | 	case dockerarchive.Transport.Name(): | 
					
						
							| 
									
										
										
										
											2019-02-22 07:01:08 +08:00
										 |  |  | 		file := srcRef.StringWithinTransport() | 
					
						
							| 
									
										
										
										
											2018-03-19 10:16:47 +08:00
										 |  |  | 		tarSource, err := tarfile.NewSourceFromFile(file) | 
					
						
							|  |  |  | 		if err != nil { | 
					
						
							| 
									
										
										
										
											2018-10-03 22:05:46 +08:00
										 |  |  | 			return "", errors.Wrapf(err, "error opening tarfile %q as a source image", file) | 
					
						
							| 
									
										
										
										
											2017-07-29 05:29:37 +08:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2018-03-19 10:16:47 +08:00
										 |  |  | 		manifest, err := tarSource.LoadTarManifest() | 
					
						
							|  |  |  | 		if err != nil { | 
					
						
							| 
									
										
										
										
											2018-10-03 22:05:46 +08:00
										 |  |  | 			return "", errors.Errorf("error retrieving manifest.json from tarfile %q: %v", file, err) | 
					
						
							| 
									
										
										
										
											2018-03-19 10:16:47 +08:00
										 |  |  | 		} | 
					
						
							|  |  |  | 		// to pull the first image stored in the tar file
 | 
					
						
							|  |  |  | 		if len(manifest) == 0 { | 
					
						
							|  |  |  | 			// use the hex of the digest if no manifest is found
 | 
					
						
							| 
									
										
										
										
											2018-04-12 22:20:36 +08:00
										 |  |  | 			name, err = getImageDigest(ctx, srcRef, nil) | 
					
						
							| 
									
										
										
										
											2018-03-19 10:16:47 +08:00
										 |  |  | 			if err != nil { | 
					
						
							|  |  |  | 				return "", err | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} else { | 
					
						
							|  |  |  | 			if len(manifest[0].RepoTags) > 0 { | 
					
						
							|  |  |  | 				name = manifest[0].RepoTags[0] | 
					
						
							|  |  |  | 			} else { | 
					
						
							|  |  |  | 				// If the input image has no repotags, we need to feed it a dest anyways
 | 
					
						
							| 
									
										
										
										
											2018-04-12 22:20:36 +08:00
										 |  |  | 				name, err = getImageDigest(ctx, srcRef, nil) | 
					
						
							| 
									
										
										
										
											2018-03-19 10:16:47 +08:00
										 |  |  | 				if err != nil { | 
					
						
							|  |  |  | 					return "", err | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2019-02-02 20:29:05 +08:00
										 |  |  | 	case ociarchive.Transport.Name(): | 
					
						
							| 
									
										
										
										
											2018-03-19 10:16:47 +08:00
										 |  |  | 		// retrieve the manifest from index.json to access the image name
 | 
					
						
							|  |  |  | 		manifest, err := ociarchive.LoadManifestDescriptor(srcRef) | 
					
						
							|  |  |  | 		if err != nil { | 
					
						
							| 
									
										
										
										
											2018-10-03 22:05:46 +08:00
										 |  |  | 			return "", errors.Wrapf(err, "error loading manifest for %q", transports.ImageName(srcRef)) | 
					
						
							| 
									
										
										
										
											2018-03-19 10:16:47 +08:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2018-05-17 00:38:11 +08:00
										 |  |  | 		// if index.json has no reference name, compute the image digest instead
 | 
					
						
							| 
									
										
										
										
											2018-03-19 10:16:47 +08:00
										 |  |  | 		if manifest.Annotations == nil || manifest.Annotations["org.opencontainers.image.ref.name"] == "" { | 
					
						
							| 
									
										
										
										
											2018-05-17 00:38:11 +08:00
										 |  |  | 			name, err = getImageDigest(ctx, srcRef, nil) | 
					
						
							|  |  |  | 			if err != nil { | 
					
						
							|  |  |  | 				return "", err | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} else { | 
					
						
							|  |  |  | 			name = manifest.Annotations["org.opencontainers.image.ref.name"] | 
					
						
							| 
									
										
										
										
											2018-03-19 10:16:47 +08:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2019-02-02 20:29:05 +08:00
										 |  |  | 	case directory.Transport.Name(): | 
					
						
							| 
									
										
										
										
											2018-03-19 10:16:47 +08:00
										 |  |  | 		// supports pull from a directory
 | 
					
						
							| 
									
										
										
										
											2019-02-22 07:01:08 +08:00
										 |  |  | 		name = srcRef.StringWithinTransport() | 
					
						
							| 
									
										
										
										
											2018-03-19 10:16:47 +08:00
										 |  |  | 		// remove leading "/"
 | 
					
						
							|  |  |  | 		if name[:1] == "/" { | 
					
						
							|  |  |  | 			name = name[1:] | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2019-02-20 05:59:59 +08:00
										 |  |  | 	case oci.Transport.Name(): | 
					
						
							|  |  |  | 		// supports pull from a directory
 | 
					
						
							| 
									
										
										
										
											2019-02-22 07:01:08 +08:00
										 |  |  | 		split := strings.SplitN(srcRef.StringWithinTransport(), ":", 2) | 
					
						
							|  |  |  | 		name = split[0] | 
					
						
							| 
									
										
										
										
											2019-02-20 05:59:59 +08:00
										 |  |  | 		// remove leading "/"
 | 
					
						
							|  |  |  | 		if name[:1] == "/" { | 
					
						
							|  |  |  | 			name = name[1:] | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2018-03-19 10:16:47 +08:00
										 |  |  | 	default: | 
					
						
							|  |  |  | 		ref := srcRef.DockerReference() | 
					
						
							|  |  |  | 		if ref == nil { | 
					
						
							| 
									
										
										
										
											2018-04-19 16:52:24 +08:00
										 |  |  | 			name = srcRef.StringWithinTransport() | 
					
						
							| 
									
										
										
										
											2018-03-19 10:16:47 +08:00
										 |  |  | 			_, err := is.Transport.ParseStoreReference(store, name) | 
					
						
							| 
									
										
										
										
											2017-07-29 05:29:37 +08:00
										 |  |  | 			if err == nil { | 
					
						
							|  |  |  | 				return name, nil | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2018-10-03 22:05:46 +08:00
										 |  |  | 			logrus.Debugf("error parsing local storage reference %q: %v", name, err) | 
					
						
							| 
									
										
										
										
											2018-03-19 10:16:47 +08:00
										 |  |  | 			if strings.LastIndex(name, "/") != -1 { | 
					
						
							|  |  |  | 				name = name[strings.LastIndex(name, "/")+1:] | 
					
						
							|  |  |  | 				_, err = is.Transport.ParseStoreReference(store, name) | 
					
						
							|  |  |  | 				if err == nil { | 
					
						
							| 
									
										
										
										
											2018-10-03 22:05:46 +08:00
										 |  |  | 					return name, errors.Wrapf(err, "error parsing local storage reference %q", name) | 
					
						
							| 
									
										
										
										
											2018-03-19 10:16:47 +08:00
										 |  |  | 				} | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			return "", errors.Errorf("reference to image %q is not a named reference", transports.ImageName(srcRef)) | 
					
						
							| 
									
										
										
										
											2017-07-29 05:29:37 +08:00
										 |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-03-19 10:16:47 +08:00
										 |  |  | 		if named, ok := ref.(reference.Named); ok { | 
					
						
							|  |  |  | 			name = named.Name() | 
					
						
							|  |  |  | 			if namedTagged, ok := ref.(reference.NamedTagged); ok { | 
					
						
							|  |  |  | 				name = name + ":" + namedTagged.Tag() | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			if canonical, ok := ref.(reference.Canonical); ok { | 
					
						
							|  |  |  | 				name = name + "@" + canonical.Digest().String() | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2017-07-29 05:29:37 +08:00
										 |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if _, err := is.Transport.ParseStoreReference(store, name); err != nil { | 
					
						
							|  |  |  | 		return "", errors.Wrapf(err, "error parsing computed local image name %q", name) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return name, nil | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-10-03 04:44:12 +08:00
										 |  |  | // Pull copies the contents of the image from somewhere else to local storage.
 | 
					
						
							| 
									
										
										
										
											2019-01-07 15:06:36 +08:00
										 |  |  | func Pull(ctx context.Context, imageName string, options PullOptions) error { | 
					
						
							| 
									
										
										
										
											2019-03-14 04:03:13 +08:00
										 |  |  | 	systemContext := getSystemContext(options.Store, options.SystemContext, options.SignaturePolicyPath) | 
					
						
							| 
									
										
										
										
											2019-02-02 20:29:05 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	boptions := BuilderOptions{ | 
					
						
							|  |  |  | 		FromImage:           imageName, | 
					
						
							|  |  |  | 		SignaturePolicyPath: options.SignaturePolicyPath, | 
					
						
							|  |  |  | 		SystemContext:       systemContext, | 
					
						
							| 
									
										
										
										
											2019-03-14 04:03:13 +08:00
										 |  |  | 		BlobDirectory:       options.BlobDirectory, | 
					
						
							| 
									
										
										
										
											2019-02-02 20:29:05 +08:00
										 |  |  | 		ReportWriter:        options.ReportWriter, | 
					
						
							| 
									
										
										
										
											2019-01-07 15:06:36 +08:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2019-03-14 04:03:13 +08:00
										 |  |  | 	if options.BlobDirectory != "" { | 
					
						
							|  |  |  | 		systemContext.BlobInfoCacheDir = options.BlobDirectory | 
					
						
							|  |  |  | 	} else { | 
					
						
							|  |  |  | 		if systemContext.BlobInfoCacheDir != "" { | 
					
						
							|  |  |  | 			systemContext.BlobInfoCacheDir = filepath.Join(options.Store.GraphRoot(), "cache") | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2019-02-02 20:29:05 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	storageRef, transport, img, err := resolveImage(ctx, systemContext, options.Store, boptions) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		return err | 
					
						
							| 
									
										
										
										
											2019-01-24 02:33:09 +08:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2019-02-02 20:29:05 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	var errs *multierror.Error | 
					
						
							| 
									
										
										
										
											2019-01-07 15:06:36 +08:00
										 |  |  | 	if options.AllTags { | 
					
						
							| 
									
										
										
										
											2019-02-02 20:29:05 +08:00
										 |  |  | 		if transport != util.DefaultTransport { | 
					
						
							|  |  |  | 			return errors.New("Non-docker transport is not supported, for --all-tags pulling") | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-02-22 06:45:30 +08:00
										 |  |  | 		repo := reference.TrimNamed(storageRef.DockerReference()) | 
					
						
							| 
									
										
										
										
											2019-02-22 07:25:13 +08:00
										 |  |  | 		dockerRef, err := docker.NewReference(reference.TagNameOnly(storageRef.DockerReference())) | 
					
						
							| 
									
										
										
										
											2019-02-02 20:29:05 +08:00
										 |  |  | 		if err != nil { | 
					
						
							| 
									
										
										
										
											2019-02-22 07:25:13 +08:00
										 |  |  | 			return errors.Wrapf(err, "internal error creating docker.Transport reference for %s", storageRef.DockerReference().String()) | 
					
						
							| 
									
										
										
										
											2019-01-07 15:06:36 +08:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2019-02-22 06:35:51 +08:00
										 |  |  | 		tags, err := docker.GetRepositoryTags(ctx, systemContext, dockerRef) | 
					
						
							| 
									
										
										
										
											2019-01-07 15:06:36 +08:00
										 |  |  | 		if err != nil { | 
					
						
							|  |  |  | 			return errors.Wrapf(err, "error getting repository tags") | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		for _, tag := range tags { | 
					
						
							| 
									
										
										
										
											2019-02-22 06:45:30 +08:00
										 |  |  | 			tagged, err := reference.WithTag(repo, tag) | 
					
						
							|  |  |  | 			if err != nil { | 
					
						
							|  |  |  | 				errs = multierror.Append(errs, err) | 
					
						
							|  |  |  | 				continue | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2019-02-22 07:20:36 +08:00
										 |  |  | 			taggedRef, err := docker.NewReference(tagged) | 
					
						
							|  |  |  | 			if err != nil { | 
					
						
							|  |  |  | 				return errors.Wrapf(err, "internal error creating docker.Transport reference for %s", tagged.String()) | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2019-02-02 20:29:05 +08:00
										 |  |  | 			if options.ReportWriter != nil { | 
					
						
							| 
									
										
										
										
											2019-02-22 06:45:30 +08:00
										 |  |  | 				options.ReportWriter.Write([]byte("Pulling " + tagged.String() + "\n")) | 
					
						
							| 
									
										
										
										
											2019-02-02 20:29:05 +08:00
										 |  |  | 			} | 
					
						
							| 
									
										
										
										
											2019-02-22 07:20:36 +08:00
										 |  |  | 			ref, err := pullImage(ctx, options.Store, taggedRef, options, systemContext) | 
					
						
							| 
									
										
										
										
											2019-02-02 20:29:05 +08:00
										 |  |  | 			if err != nil { | 
					
						
							|  |  |  | 				errs = multierror.Append(errs, err) | 
					
						
							|  |  |  | 				continue | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2019-02-23 10:08:09 +08:00
										 |  |  | 			taggedImg, err := is.Transport.GetStoreImage(options.Store, ref) | 
					
						
							| 
									
										
										
										
											2019-02-02 20:29:05 +08:00
										 |  |  | 			if err != nil { | 
					
						
							|  |  |  | 				errs = multierror.Append(errs, err) | 
					
						
							|  |  |  | 				continue | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2019-02-23 10:08:09 +08:00
										 |  |  | 			fmt.Printf("%s\n", taggedImg.ID) | 
					
						
							| 
									
										
										
										
											2019-01-07 15:06:36 +08:00
										 |  |  | 		} | 
					
						
							|  |  |  | 	} else { | 
					
						
							|  |  |  | 		fmt.Printf("%s\n", img.ID) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return errs.ErrorOrNil() | 
					
						
							| 
									
										
										
										
											2018-08-09 04:38:53 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-02-22 07:20:36 +08:00
										 |  |  | func pullImage(ctx context.Context, store storage.Store, srcRef types.ImageReference, options PullOptions, sc *types.SystemContext) (types.ImageReference, error) { | 
					
						
							| 
									
										
										
										
											2018-10-03 02:48:11 +08:00
										 |  |  | 	blocked, err := isReferenceBlocked(srcRef, sc) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		return nil, errors.Wrapf(err, "error checking if pulling from registry for %q is blocked", transports.ImageName(srcRef)) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	if blocked { | 
					
						
							|  |  |  | 		return nil, errors.Errorf("pull access to registry for %q is blocked by configuration", transports.ImageName(srcRef)) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-02-22 07:01:08 +08:00
										 |  |  | 	destName, err := localImageNameForReference(ctx, store, srcRef) | 
					
						
							| 
									
										
										
										
											2017-07-29 05:29:37 +08:00
										 |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		return nil, errors.Wrapf(err, "error computing local image name for %q", transports.ImageName(srcRef)) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	if destName == "" { | 
					
						
							|  |  |  | 		return nil, errors.Errorf("error computing local image name for %q", transports.ImageName(srcRef)) | 
					
						
							| 
									
										
										
										
											2017-02-11 00:48:15 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-07-29 05:29:37 +08:00
										 |  |  | 	destRef, err := is.Transport.ParseStoreReference(store, destName) | 
					
						
							| 
									
										
										
										
											2017-02-11 00:48:15 +08:00
										 |  |  | 	if err != nil { | 
					
						
							| 
									
										
										
										
											2017-07-29 05:29:37 +08:00
										 |  |  | 		return nil, errors.Wrapf(err, "error parsing image name %q", destName) | 
					
						
							| 
									
										
										
										
											2017-02-11 00:48:15 +08:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2018-10-18 06:06:16 +08:00
										 |  |  | 	var maybeCachedDestRef types.ImageReference = destRef | 
					
						
							|  |  |  | 	if options.BlobDirectory != "" { | 
					
						
							|  |  |  | 		cachedRef, err := blobcache.NewBlobCache(destRef, options.BlobDirectory, types.PreserveOriginal) | 
					
						
							|  |  |  | 		if err != nil { | 
					
						
							|  |  |  | 			return nil, errors.Wrapf(err, "error wrapping image reference %q in blob cache at %q", transports.ImageName(destRef), options.BlobDirectory) | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		maybeCachedDestRef = cachedRef | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2017-02-11 00:48:15 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	policy, err := signature.DefaultPolicy(sc) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							| 
									
										
										
										
											2017-07-29 05:29:37 +08:00
										 |  |  | 		return nil, errors.Wrapf(err, "error obtaining default signature policy") | 
					
						
							| 
									
										
										
										
											2017-02-11 00:48:15 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	policyContext, err := signature.NewPolicyContext(policy) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							| 
									
										
										
										
											2017-07-29 05:29:37 +08:00
										 |  |  | 		return nil, errors.Wrapf(err, "error creating new signature policy context") | 
					
						
							| 
									
										
										
										
											2017-02-11 00:48:15 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-07-29 00:58:29 +08:00
										 |  |  | 	defer func() { | 
					
						
							|  |  |  | 		if err2 := policyContext.Destroy(); err2 != nil { | 
					
						
							| 
									
										
										
										
											2017-06-29 05:07:58 +08:00
										 |  |  | 			logrus.Debugf("error destroying signature policy context: %v", err2) | 
					
						
							| 
									
										
										
										
											2017-07-29 00:58:29 +08:00
										 |  |  | 		} | 
					
						
							|  |  |  | 	}() | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-02-22 07:20:36 +08:00
										 |  |  | 	logrus.Debugf("copying %q to %q", transports.ImageName(srcRef), destName) | 
					
						
							| 
									
										
										
										
											2019-03-14 04:03:13 +08:00
										 |  |  | 	if _, err := cp.Image(ctx, policyContext, maybeCachedDestRef, srcRef, getCopyOptions(store, options.ReportWriter, srcRef, sc, maybeCachedDestRef, nil, "")); err != nil { | 
					
						
							| 
									
										
										
										
											2019-02-22 07:20:36 +08:00
										 |  |  | 		logrus.Debugf("error copying src image [%q] to dest image [%q] err: %v", transports.ImageName(srcRef), destName, err) | 
					
						
							| 
									
										
										
										
											2018-08-04 09:29:16 +08:00
										 |  |  | 		return nil, err | 
					
						
							| 
									
										
										
										
											2017-06-29 05:07:58 +08:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2018-08-04 09:29:16 +08:00
										 |  |  | 	return destRef, nil | 
					
						
							| 
									
										
										
										
											2017-02-11 00:48:15 +08:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2018-03-19 10:16:47 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | // getImageDigest creates an image object and uses the hex value of the digest as the image ID
 | 
					
						
							|  |  |  | // for parsing the store reference
 | 
					
						
							| 
									
										
										
										
											2018-04-12 22:20:36 +08:00
										 |  |  | func getImageDigest(ctx context.Context, src types.ImageReference, sc *types.SystemContext) (string, error) { | 
					
						
							|  |  |  | 	newImg, err := src.NewImage(ctx, sc) | 
					
						
							| 
									
										
										
										
											2018-03-19 10:16:47 +08:00
										 |  |  | 	if err != nil { | 
					
						
							| 
									
										
										
										
											2018-10-03 22:05:46 +08:00
										 |  |  | 		return "", errors.Wrapf(err, "error opening image %q for reading", transports.ImageName(src)) | 
					
						
							| 
									
										
										
										
											2018-03-19 10:16:47 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 	defer newImg.Close() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	digest := newImg.ConfigInfo().Digest | 
					
						
							|  |  |  | 	if err = digest.Validate(); err != nil { | 
					
						
							| 
									
										
										
										
											2018-10-03 22:05:46 +08:00
										 |  |  | 		return "", errors.Wrapf(err, "error getting config info from image %q", transports.ImageName(src)) | 
					
						
							| 
									
										
										
										
											2018-03-19 10:16:47 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 	return "@" + digest.Hex(), nil | 
					
						
							|  |  |  | } |