Allow rootless users to use the cache directory in homedir
Currently rootless podman attempts to write to /var/lib/containers/cache and fails. This causes us to repeatedly push images that have already been pushed. This cache directory should be relative to the location of containers/storage and not always stored in the same directory. Signed-off-by: Daniel J Walsh <dwalsh@redhat.com> Closes: #1411 Approved by: TomSweeneyRedHat
This commit is contained in:
		
							parent
							
								
									26bc8fb769
								
							
						
					
					
						commit
						939de6f4d9
					
				|  | @ -336,10 +336,10 @@ type BuilderOptions struct { | |||
| 	// needs to be pulled and the image name alone can not be resolved to a
 | ||||
| 	// reference to a source image.  No separator is implicitly added.
 | ||||
| 	Registry string | ||||
| 	// PullBlobDirectory is the name of a directory in which we'll attempt
 | ||||
| 	// 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.
 | ||||
| 	PullBlobDirectory string | ||||
| 	BlobDirectory string | ||||
| 	// Mount signals to NewBuilder() that the container should be mounted
 | ||||
| 	// immediately.
 | ||||
| 	Mount bool | ||||
|  |  | |||
|  | @ -183,6 +183,11 @@ func budCmd(c *cobra.Command, inputArgs []string, iopts budResults) error { | |||
| 	if err != nil { | ||||
| 		return errors.Wrapf(err, "error building system context") | ||||
| 	} | ||||
| 	if iopts.BlobCache != "" { | ||||
| 		systemContext.BlobInfoCacheDir = iopts.BlobCache | ||||
| 	} else { | ||||
| 		systemContext.BlobInfoCacheDir = filepath.Join(store.GraphRoot(), "cache") | ||||
| 	} | ||||
| 
 | ||||
| 	isolation, err := parse.IsolationOption(c) | ||||
| 	if err != nil { | ||||
|  |  | |||
|  | @ -156,6 +156,7 @@ func commitCmd(c *cobra.Command, args []string, iopts commitInputOptions) error | |||
| 		Squash:                iopts.squash, | ||||
| 		BlobDirectory:         iopts.blobCache, | ||||
| 		OmitTimestamp:         iopts.omitTimestamp, | ||||
| 		Store:                 store, | ||||
| 	} | ||||
| 	if !iopts.quiet { | ||||
| 		options.ReportWriter = os.Stderr | ||||
|  |  | |||
|  | @ -226,7 +226,7 @@ func fromCmd(c *cobra.Command, args []string, iopts fromReply) error { | |||
| 		DropCapabilities:      iopts.CapDrop, | ||||
| 		CommonBuildOpts:       commonOpts, | ||||
| 		Format:                format, | ||||
| 		PullBlobDirectory:     iopts.BlobCache, | ||||
| 		BlobDirectory:         iopts.BlobCache, | ||||
| 	} | ||||
| 
 | ||||
| 	if !iopts.quiet { | ||||
|  |  | |||
							
								
								
									
										12
									
								
								commit.go
								
								
								
								
							
							
						
						
									
										12
									
								
								commit.go
								
								
								
								
							|  | @ -71,6 +71,9 @@ type CommitOptions struct { | |||
| 	// OmitTimestamp forces epoch 0 as created timestamp to allow for
 | ||||
| 	// deterministic, content-addressable builds.
 | ||||
| 	OmitTimestamp bool | ||||
| 
 | ||||
| 	// Store is the local storage store which holds the source image.
 | ||||
| 	Store storage.Store | ||||
| } | ||||
| 
 | ||||
| // PushOptions can be used to alter how an image is copied somewhere.
 | ||||
|  | @ -114,7 +117,7 @@ type PushOptions struct { | |||
| func (b *Builder) Commit(ctx context.Context, dest types.ImageReference, options CommitOptions) (string, reference.Canonical, digest.Digest, error) { | ||||
| 	var imgID string | ||||
| 
 | ||||
| 	systemContext := getSystemContext(options.SystemContext, options.SignaturePolicyPath) | ||||
| 	systemContext := getSystemContext(options.Store, options.SystemContext, options.SignaturePolicyPath) | ||||
| 
 | ||||
| 	blocked, err := isReferenceBlocked(dest, systemContext) | ||||
| 	if err != nil { | ||||
|  | @ -178,7 +181,7 @@ func (b *Builder) Commit(ctx context.Context, dest types.ImageReference, options | |||
| 		systemContext.DirForceCompress = true | ||||
| 	} | ||||
| 	var manifestBytes []byte | ||||
| 	if manifestBytes, err = cp.Image(ctx, policyContext, maybeCachedDest, maybeCachedSrc, getCopyOptions(options.ReportWriter, maybeCachedSrc, nil, maybeCachedDest, systemContext, "")); err != nil { | ||||
| 	if manifestBytes, err = cp.Image(ctx, policyContext, maybeCachedDest, maybeCachedSrc, getCopyOptions(options.Store, options.ReportWriter, maybeCachedSrc, nil, maybeCachedDest, systemContext, "")); err != nil { | ||||
| 		return imgID, nil, "", errors.Wrapf(err, "error copying layers and metadata for container %q", b.ContainerID) | ||||
| 	} | ||||
| 	if len(options.AdditionalTags) > 0 { | ||||
|  | @ -230,7 +233,7 @@ func (b *Builder) Commit(ctx context.Context, dest types.ImageReference, options | |||
| 
 | ||||
| // Push copies the contents of the image to a new location.
 | ||||
| func Push(ctx context.Context, image string, dest types.ImageReference, options PushOptions) (reference.Canonical, digest.Digest, error) { | ||||
| 	systemContext := getSystemContext(options.SystemContext, options.SignaturePolicyPath) | ||||
| 	systemContext := getSystemContext(options.Store, options.SystemContext, options.SignaturePolicyPath) | ||||
| 
 | ||||
| 	if options.Quiet { | ||||
| 		options.ReportWriter = nil // Turns off logging output
 | ||||
|  | @ -266,6 +269,7 @@ func Push(ctx context.Context, image string, dest types.ImageReference, options | |||
| 		if err != nil { | ||||
| 			return nil, "", errors.Wrapf(err, "error wrapping image reference %q in blob cache at %q", transports.ImageName(src), options.BlobDirectory) | ||||
| 		} | ||||
| 		systemContext.BlobInfoCacheDir = options.BlobDirectory | ||||
| 		maybeCachedSrc = cache | ||||
| 	} | ||||
| 	// Copy everything.
 | ||||
|  | @ -276,7 +280,7 @@ func Push(ctx context.Context, image string, dest types.ImageReference, options | |||
| 		systemContext.DirForceCompress = true | ||||
| 	} | ||||
| 	var manifestBytes []byte | ||||
| 	if manifestBytes, err = cp.Image(ctx, policyContext, dest, maybeCachedSrc, getCopyOptions(options.ReportWriter, maybeCachedSrc, nil, dest, systemContext, options.ManifestType)); err != nil { | ||||
| 	if manifestBytes, err = cp.Image(ctx, policyContext, dest, maybeCachedSrc, getCopyOptions(options.Store, options.ReportWriter, maybeCachedSrc, nil, dest, systemContext, options.ManifestType)); err != nil { | ||||
| 		return nil, "", errors.Wrapf(err, "error copying layers and metadata from %q to %q", transports.ImageName(maybeCachedSrc), transports.ImageName(dest)) | ||||
| 	} | ||||
| 	if options.ReportWriter != nil { | ||||
|  |  | |||
							
								
								
									
										32
									
								
								common.go
								
								
								
								
							
							
						
						
									
										32
									
								
								common.go
								
								
								
								
							|  | @ -8,6 +8,7 @@ import ( | |||
| 	cp "github.com/containers/image/copy" | ||||
| 	"github.com/containers/image/types" | ||||
| 	"github.com/containers/libpod/pkg/rootless" | ||||
| 	"github.com/containers/storage" | ||||
| ) | ||||
| 
 | ||||
| const ( | ||||
|  | @ -17,31 +18,15 @@ const ( | |||
| 	DOCKER = "docker" | ||||
| ) | ||||
| 
 | ||||
| // userRegistriesFile is the path to the per user registry configuration file.
 | ||||
| var userRegistriesFile = filepath.Join(os.Getenv("HOME"), ".config/containers/registries.conf") | ||||
| 
 | ||||
| func getCopyOptions(reportWriter io.Writer, sourceReference types.ImageReference, sourceSystemContext *types.SystemContext, destinationReference types.ImageReference, destinationSystemContext *types.SystemContext, manifestType string) *cp.Options { | ||||
| 	sourceCtx := &types.SystemContext{} | ||||
| func getCopyOptions(store storage.Store, reportWriter io.Writer, sourceReference types.ImageReference, sourceSystemContext *types.SystemContext, destinationReference types.ImageReference, destinationSystemContext *types.SystemContext, manifestType string) *cp.Options { | ||||
| 	sourceCtx := getSystemContext(store, nil, "") | ||||
| 	if sourceSystemContext != nil { | ||||
| 		*sourceCtx = *sourceSystemContext | ||||
| 	} else { | ||||
| 		if rootless.IsRootless() { | ||||
| 			if _, err := os.Stat(userRegistriesFile); err == nil { | ||||
| 				sourceCtx.SystemRegistriesConfPath = userRegistriesFile | ||||
| 	} | ||||
| 
 | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	destinationCtx := &types.SystemContext{} | ||||
| 	destinationCtx := getSystemContext(store, nil, "") | ||||
| 	if destinationSystemContext != nil { | ||||
| 		*destinationCtx = *destinationSystemContext | ||||
| 	} else { | ||||
| 		if rootless.IsRootless() { | ||||
| 			if _, err := os.Stat(userRegistriesFile); err == nil { | ||||
| 				destinationCtx.SystemRegistriesConfPath = userRegistriesFile | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	return &cp.Options{ | ||||
|  | @ -52,7 +37,7 @@ func getCopyOptions(reportWriter io.Writer, sourceReference types.ImageReference | |||
| 	} | ||||
| } | ||||
| 
 | ||||
| func getSystemContext(defaults *types.SystemContext, signaturePolicyPath string) *types.SystemContext { | ||||
| func getSystemContext(store storage.Store, defaults *types.SystemContext, signaturePolicyPath string) *types.SystemContext { | ||||
| 	sc := &types.SystemContext{} | ||||
| 	if defaults != nil { | ||||
| 		*sc = *defaults | ||||
|  | @ -60,11 +45,16 @@ func getSystemContext(defaults *types.SystemContext, signaturePolicyPath string) | |||
| 	if signaturePolicyPath != "" { | ||||
| 		sc.SignaturePolicyPath = signaturePolicyPath | ||||
| 	} | ||||
| 	if store != nil { | ||||
| 		if sc.BlobInfoCacheDir == "" { | ||||
| 			sc.BlobInfoCacheDir = filepath.Join(store.GraphRoot(), "cache") | ||||
| 		} | ||||
| 		if sc.SystemRegistriesConfPath == "" && rootless.IsRootless() { | ||||
| 			userRegistriesFile := filepath.Join(store.GraphRoot(), "registries.conf") | ||||
| 			if _, err := os.Stat(userRegistriesFile); err == nil { | ||||
| 				sc.SystemRegistriesConfPath = userRegistriesFile | ||||
| 			} | ||||
| 
 | ||||
| 		} | ||||
| 	} | ||||
| 	return sc | ||||
| } | ||||
|  |  | |||
|  | @ -666,7 +666,7 @@ func (b *Executor) Prepare(ctx context.Context, stage imagebuilder.Stage, from s | |||
| 		FromImage:             from, | ||||
| 		PullPolicy:            b.pullPolicy, | ||||
| 		Registry:              b.registry, | ||||
| 		PullBlobDirectory:     b.blobDirectory, | ||||
| 		BlobDirectory:         b.blobDirectory, | ||||
| 		SignaturePolicyPath:   b.signaturePolicyPath, | ||||
| 		ReportWriter:          b.reportWriter, | ||||
| 		SystemContext:         b.systemContext, | ||||
|  |  | |||
|  | @ -83,7 +83,7 @@ func importBuilder(ctx context.Context, store storage.Store, options ImportOptio | |||
| 		return nil, err | ||||
| 	} | ||||
| 
 | ||||
| 	systemContext := getSystemContext(&types.SystemContext{}, options.SignaturePolicyPath) | ||||
| 	systemContext := getSystemContext(store, &types.SystemContext{}, options.SignaturePolicyPath) | ||||
| 
 | ||||
| 	builder, err := importBuilderDataFromImage(ctx, store, systemContext, c.ImageID, options.Container, c.ID) | ||||
| 	if err != nil { | ||||
|  | @ -115,7 +115,7 @@ func importBuilderFromImage(ctx context.Context, store storage.Store, options Im | |||
| 		return nil, errors.Errorf("image name must be specified") | ||||
| 	} | ||||
| 
 | ||||
| 	systemContext := getSystemContext(options.SystemContext, options.SignaturePolicyPath) | ||||
| 	systemContext := getSystemContext(store, options.SystemContext, options.SignaturePolicyPath) | ||||
| 
 | ||||
| 	_, img, err := util.FindImage(store, "", systemContext, options.Image) | ||||
| 	if err != nil { | ||||
|  |  | |||
							
								
								
									
										10
									
								
								new.go
								
								
								
								
							
							
						
						
									
										10
									
								
								new.go
								
								
								
								
							|  | @ -4,6 +4,7 @@ import ( | |||
| 	"context" | ||||
| 	"fmt" | ||||
| 	"math/rand" | ||||
| 	"path/filepath" | ||||
| 	"strings" | ||||
| 
 | ||||
| 	"github.com/containers/buildah/util" | ||||
|  | @ -29,7 +30,7 @@ func pullAndFindImage(ctx context.Context, store storage.Store, srcRef types.Ima | |||
| 		ReportWriter:  options.ReportWriter, | ||||
| 		Store:         store, | ||||
| 		SystemContext: options.SystemContext, | ||||
| 		BlobDirectory: options.PullBlobDirectory, | ||||
| 		BlobDirectory: options.BlobDirectory, | ||||
| 	} | ||||
| 	ref, err := pullImage(ctx, store, srcRef, pullOptions, sc) | ||||
| 	if err != nil { | ||||
|  | @ -244,7 +245,12 @@ func newBuilder(ctx context.Context, store storage.Store, options BuilderOptions | |||
| 		options.FromImage = "" | ||||
| 	} | ||||
| 
 | ||||
| 	systemContext := getSystemContext(options.SystemContext, options.SignaturePolicyPath) | ||||
| 	systemContext := getSystemContext(store, options.SystemContext, options.SignaturePolicyPath) | ||||
| 	if options.BlobDirectory != "" { | ||||
| 		systemContext.BlobInfoCacheDir = options.BlobDirectory | ||||
| 	} else { | ||||
| 		systemContext.BlobInfoCacheDir = filepath.Join(store.GraphRoot(), "cache") | ||||
| 	} | ||||
| 
 | ||||
| 	if options.FromImage != "" && options.FromImage != "scratch" { | ||||
| 		ref, _, img, err = resolveImage(ctx, systemContext, store, options) | ||||
|  |  | |||
							
								
								
									
										15
									
								
								pull.go
								
								
								
								
							
							
						
						
									
										15
									
								
								pull.go
								
								
								
								
							|  | @ -4,6 +4,8 @@ import ( | |||
| 	"context" | ||||
| 	"fmt" | ||||
| 	"io" | ||||
| 	"path/filepath" | ||||
| 
 | ||||
| 	"strings" | ||||
| 
 | ||||
| 	"github.com/containers/buildah/pkg/blobcache" | ||||
|  | @ -153,15 +155,22 @@ func localImageNameForReference(ctx context.Context, store storage.Store, srcRef | |||
| 
 | ||||
| // Pull copies the contents of the image from somewhere else to local storage.
 | ||||
| func Pull(ctx context.Context, imageName string, options PullOptions) error { | ||||
| 	systemContext := getSystemContext(options.SystemContext, options.SignaturePolicyPath) | ||||
| 	systemContext := getSystemContext(options.Store, options.SystemContext, options.SignaturePolicyPath) | ||||
| 
 | ||||
| 	boptions := BuilderOptions{ | ||||
| 		FromImage:           imageName, | ||||
| 		SignaturePolicyPath: options.SignaturePolicyPath, | ||||
| 		SystemContext:       systemContext, | ||||
| 		PullBlobDirectory:   options.BlobDirectory, | ||||
| 		BlobDirectory:       options.BlobDirectory, | ||||
| 		ReportWriter:        options.ReportWriter, | ||||
| 	} | ||||
| 	if options.BlobDirectory != "" { | ||||
| 		systemContext.BlobInfoCacheDir = options.BlobDirectory | ||||
| 	} else { | ||||
| 		if systemContext.BlobInfoCacheDir != "" { | ||||
| 			systemContext.BlobInfoCacheDir = filepath.Join(options.Store.GraphRoot(), "cache") | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	storageRef, transport, img, err := resolveImage(ctx, systemContext, options.Store, boptions) | ||||
| 	if err != nil { | ||||
|  | @ -262,7 +271,7 @@ func pullImage(ctx context.Context, store storage.Store, srcRef types.ImageRefer | |||
| 	}() | ||||
| 
 | ||||
| 	logrus.Debugf("copying %q to %q", transports.ImageName(srcRef), destName) | ||||
| 	if _, err := cp.Image(ctx, policyContext, maybeCachedDestRef, srcRef, getCopyOptions(options.ReportWriter, srcRef, sc, maybeCachedDestRef, nil, "")); err != nil { | ||||
| 	if _, err := cp.Image(ctx, policyContext, maybeCachedDestRef, srcRef, getCopyOptions(store, options.ReportWriter, srcRef, sc, maybeCachedDestRef, nil, "")); err != nil { | ||||
| 		logrus.Debugf("error copying src image [%q] to dest image [%q] err: %v", transports.ImageName(srcRef), destName, err) | ||||
| 		return nil, err | ||||
| 	} | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue