diff options
Diffstat (limited to 'libpod/image')
-rw-r--r-- | libpod/image/docker_registry_options.go | 3 | ||||
-rw-r--r-- | libpod/image/image.go | 112 | ||||
-rw-r--r-- | libpod/image/manifests.go | 6 | ||||
-rw-r--r-- | libpod/image/prune.go | 22 | ||||
-rw-r--r-- | libpod/image/pull.go | 4 |
5 files changed, 128 insertions, 19 deletions
diff --git a/libpod/image/docker_registry_options.go b/libpod/image/docker_registry_options.go index 62a4af465..01b5558af 100644 --- a/libpod/image/docker_registry_options.go +++ b/libpod/image/docker_registry_options.go @@ -3,9 +3,9 @@ package image import ( "fmt" + "github.com/containers/buildah/pkg/parse" "github.com/containers/image/v5/docker/reference" "github.com/containers/image/v5/types" - podmanVersion "github.com/containers/libpod/version" ) @@ -41,6 +41,7 @@ func (o DockerRegistryOptions) GetSystemContext(parent *types.SystemContext, add DockerArchiveAdditionalTags: additionalDockerArchiveTags, OSChoice: o.OSChoice, ArchitectureChoice: o.ArchitectureChoice, + BigFilesTemporaryDir: parse.GetTempDir(), } if parent != nil { sc.SignaturePolicyPath = parent.SignaturePolicyPath diff --git a/libpod/image/image.go b/libpod/image/image.go index 80cc6f15a..60787b826 100644 --- a/libpod/image/image.go +++ b/libpod/image/image.go @@ -32,10 +32,10 @@ import ( "github.com/containers/libpod/pkg/registries" "github.com/containers/libpod/pkg/util" "github.com/containers/storage" - "github.com/opencontainers/go-digest" + digest "github.com/opencontainers/go-digest" imgspecv1 "github.com/opencontainers/image-spec/specs-go/v1" ociv1 "github.com/opencontainers/image-spec/specs-go/v1" - "github.com/opentracing/opentracing-go" + opentracing "github.com/opentracing/opentracing-go" "github.com/pkg/errors" "github.com/sirupsen/logrus" ) @@ -847,22 +847,97 @@ func (i *Image) Dangling() bool { return len(i.Names()) == 0 } +// Intermediate returns true if the image is cache or intermediate image. +// Cache image has parent and child. +func (i *Image) Intermediate(ctx context.Context) (bool, error) { + parent, err := i.IsParent(ctx) + if err != nil { + return false, err + } + if !parent { + return false, nil + } + img, err := i.GetParent(ctx) + if err != nil { + return false, err + } + if img != nil { + return true, nil + } + return false, nil +} + +// User returns the image's user +func (i *Image) User(ctx context.Context) (string, error) { + imgInspect, err := i.inspect(ctx, false) + if err != nil { + return "", err + } + return imgInspect.Config.User, nil +} + +// StopSignal returns the image's StopSignal +func (i *Image) StopSignal(ctx context.Context) (string, error) { + imgInspect, err := i.inspect(ctx, false) + if err != nil { + return "", err + } + return imgInspect.Config.StopSignal, nil +} + +// WorkingDir returns the image's WorkingDir +func (i *Image) WorkingDir(ctx context.Context) (string, error) { + imgInspect, err := i.inspect(ctx, false) + if err != nil { + return "", err + } + return imgInspect.Config.WorkingDir, nil +} + +// Cmd returns the image's cmd +func (i *Image) Cmd(ctx context.Context) ([]string, error) { + imgInspect, err := i.inspect(ctx, false) + if err != nil { + return nil, err + } + return imgInspect.Config.Cmd, nil +} + +// Entrypoint returns the image's entrypoint +func (i *Image) Entrypoint(ctx context.Context) ([]string, error) { + imgInspect, err := i.inspect(ctx, false) + if err != nil { + return nil, err + } + return imgInspect.Config.Entrypoint, nil +} + +// Env returns the image's env +func (i *Image) Env(ctx context.Context) ([]string, error) { + imgInspect, err := i.imageInspectInfo(ctx) + if err != nil { + return nil, err + } + return imgInspect.Env, nil +} + // Labels returns the image's labels func (i *Image) Labels(ctx context.Context) (map[string]string, error) { imgInspect, err := i.imageInspectInfo(ctx) if err != nil { - return nil, nil + return nil, err } return imgInspect.Labels, nil } // GetLabel Returns a case-insensitive match of a given label func (i *Image) GetLabel(ctx context.Context, label string) (string, error) { - imageLabels, err := i.Labels(ctx) + labels, err := i.Labels(ctx) if err != nil { return "", err } - for k, v := range imageLabels { + + for k, v := range labels { if strings.ToLower(k) == strings.ToLower(label) { return v, nil } @@ -1412,14 +1487,14 @@ func (i *Image) Save(ctx context.Context, source, format, output string, moreTag } manifestType = manifest.DockerV2Schema2MediaType case "docker-archive", "": - dst := output destImageName := imageNameForSaveDestination(i, source) - if destImageName != "" { - dst = fmt.Sprintf("%s:%s", dst, destImageName) + ref, err := dockerArchiveDstReference(destImageName) + if err != nil { + return err } - destRef, err = dockerarchive.ParseReference(dst) // FIXME? Add dockerarchive.NewReference + destRef, err = dockerarchive.NewReference(output, ref) if err != nil { - return errors.Wrapf(err, "error getting Docker archive ImageReference for %q", dst) + return errors.Wrapf(err, "error getting Docker archive ImageReference for %s:%v", output, ref) } default: return errors.Errorf("unknown format option %q", format) @@ -1439,6 +1514,23 @@ func (i *Image) Save(ctx context.Context, source, format, output string, moreTag return nil } +// dockerArchiveDestReference returns a NamedTagged reference for a tagged image and nil for untagged image. +func dockerArchiveDstReference(normalizedInput string) (reference.NamedTagged, error) { + if normalizedInput == "" { + return nil, nil + } + ref, err := reference.ParseNormalizedNamed(normalizedInput) + if err != nil { + return nil, errors.Wrapf(err, "docker-archive parsing reference %s", normalizedInput) + } + ref = reference.TagNameOnly(ref) + namedTagged, isTagged := ref.(reference.NamedTagged) + if !isTagged { + namedTagged = nil + } + return namedTagged, nil +} + // GetConfigBlob returns a schema2image. If the image is not a schema2, then // it will return an error func (i *Image) GetConfigBlob(ctx context.Context) (*manifest.Schema2Image, error) { diff --git a/libpod/image/manifests.go b/libpod/image/manifests.go index 9dbeb4cc5..7ca17f86c 100644 --- a/libpod/image/manifests.go +++ b/libpod/image/manifests.go @@ -19,6 +19,7 @@ type ManifestAddOpts struct { Arch string `json:"arch"` Features []string `json:"features"` Images []string `json:"images"` + OS string `json:"os"` OSVersion string `json:"os_version"` Variant string `json:"variant"` } @@ -86,6 +87,11 @@ func addManifestToList(ref types.ImageReference, list manifests.List, systemCont if err != nil { return nil, err } + if opts.OS != "" { + if err := list.SetOS(d, opts.OS); err != nil { + return nil, err + } + } if len(opts.OSVersion) > 0 { if err := list.SetOSVersion(d, opts.OSVersion); err != nil { return nil, err diff --git a/libpod/image/prune.go b/libpod/image/prune.go index 3afff22af..3b4ea74c4 100644 --- a/libpod/image/prune.go +++ b/libpod/image/prune.go @@ -57,7 +57,7 @@ func generatePruneFilterFuncs(filter, filterValue string) (ImageFilter, error) { } // GetPruneImages returns a slice of images that have no names/unused -func (ir *Runtime) GetPruneImages(all bool, filterFuncs []ImageFilter) ([]*Image, error) { +func (ir *Runtime) GetPruneImages(ctx context.Context, all bool, filterFuncs []ImageFilter) ([]*Image, error) { var ( pruneImages []*Image ) @@ -74,10 +74,6 @@ func (ir *Runtime) GetPruneImages(all bool, filterFuncs []ImageFilter) ([]*Image } } - if len(i.Names()) == 0 { - pruneImages = append(pruneImages, i) - continue - } if all { containers, err := i.Containers() if err != nil { @@ -85,8 +81,22 @@ func (ir *Runtime) GetPruneImages(all bool, filterFuncs []ImageFilter) ([]*Image } if len(containers) < 1 { pruneImages = append(pruneImages, i) + continue } } + + //skip the cache or intermediate images + intermediate, err := i.Intermediate(ctx) + if err != nil { + return nil, err + } + if intermediate { + continue + } + + if i.Dangling() { + pruneImages = append(pruneImages, i) + } } return pruneImages, nil } @@ -111,7 +121,7 @@ func (ir *Runtime) PruneImages(ctx context.Context, all bool, filter []string) ( filterFuncs = append(filterFuncs, generatedFunc) } - pruneImages, err := ir.GetPruneImages(all, filterFuncs) + pruneImages, err := ir.GetPruneImages(ctx, all, filterFuncs) if err != nil { return nil, errors.Wrap(err, "unable to get images to prune") } diff --git a/libpod/image/pull.go b/libpod/image/pull.go index fd359d593..6b4c40ba2 100644 --- a/libpod/image/pull.go +++ b/libpod/image/pull.go @@ -334,11 +334,11 @@ func (ir *Runtime) doPullImage(ctx context.Context, sc *types.SystemContext, goa // If the image passed in was fully-qualified, we will have 1 refpair. Bc the image is fq'd, we don't need to yap about registries. if !goal.usedSearchRegistries { if pullErrors != nil && len(pullErrors.Errors) > 0 { // this should always be true - return nil, errors.Wrap(pullErrors.Errors[0], "unable to pull image") + return nil, pullErrors.Errors[0] } return nil, errors.Errorf("unable to pull image, or you do not have pull access") } - return nil, pullErrors + return nil, errors.Cause(pullErrors) } if len(images) > 0 { ir.newImageEvent(events.Pull, images[0]) |