aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--cmd/podman/images.go89
-rw-r--r--libpod/image/image.go26
-rw-r--r--libpod/image/utils.go20
-rw-r--r--libpod/runtime_img.go146
4 files changed, 111 insertions, 170 deletions
diff --git a/cmd/podman/images.go b/cmd/podman/images.go
index 846f00c98..67f7920f2 100644
--- a/cmd/podman/images.go
+++ b/cmd/podman/images.go
@@ -10,7 +10,7 @@ import (
"github.com/pkg/errors"
"github.com/projectatomic/libpod/cmd/podman/formats"
"github.com/projectatomic/libpod/libpod"
- "github.com/projectatomic/libpod/pkg/inspect"
+ "github.com/projectatomic/libpod/libpod/image"
"github.com/urfave/cli"
)
@@ -81,6 +81,10 @@ var (
)
func imagesCmd(c *cli.Context) error {
+ var (
+ filterFuncs []libpod.ImageResultFilter
+ newImage *image.Image
+ )
if err := validateFlags(c, imagesFlags); err != nil {
return err
}
@@ -90,18 +94,19 @@ func imagesCmd(c *cli.Context) error {
return errors.Wrapf(err, "Could not get runtime")
}
defer runtime.Shutdown(false)
- var filterFuncs []libpod.ImageResultFilter
- var imageInput string
if len(c.Args()) == 1 {
- imageInput = c.Args().Get(0)
+ newImage, err = runtime.ImageRuntime().NewFromLocal(c.Args().Get(0))
+ if err != nil {
+ return err
+ }
}
if len(c.Args()) > 1 {
return errors.New("'podman images' requires at most 1 argument")
}
- if len(c.StringSlice("filter")) > 0 || len(strings.TrimSpace(imageInput)) != 0 {
- filterFuncs, err = CreateFilterFuncs(runtime, c, imageInput)
+ if len(c.StringSlice("filter")) > 0 || newImage != nil {
+ filterFuncs, err = CreateFilterFuncs(runtime, c, newImage)
if err != nil {
return err
}
@@ -123,14 +128,14 @@ func imagesCmd(c *cli.Context) error {
children to the image once built. until buildah supports caching builds,
it will not generate these intermediate images.
*/
- images, err := runtime.GetImageResults()
+ images, err := runtime.ImageRuntime().GetImages()
if err != nil {
return errors.Wrapf(err, "unable to get images")
}
- var filteredImages []inspect.ImageResult
+ var filteredImages []*image.Image
// filter the images
- if len(c.StringSlice("filter")) > 0 || len(strings.TrimSpace(imageInput)) != 0 {
+ if len(c.StringSlice("filter")) > 0 || newImage != nil {
filteredImages = libpod.FilterImages(images, filterFuncs)
} else {
filteredImages = images
@@ -174,24 +179,28 @@ func imagesToGeneric(templParams []imagesTemplateParams, JSONParams []imagesJSON
}
// getImagesTemplateOutput returns the images information to be printed in human readable format
-func getImagesTemplateOutput(runtime *libpod.Runtime, images []inspect.ImageResult, opts imagesOptions) (imagesOutput []imagesTemplateParams) {
+func getImagesTemplateOutput(runtime *libpod.Runtime, images []*image.Image, opts imagesOptions) (imagesOutput []imagesTemplateParams) {
for _, img := range images {
- createdTime := img.Created
+ createdTime := img.Created()
- imageID := "sha256:" + img.ID
+ imageID := "sha256:" + img.ID()
if !opts.noTrunc {
- imageID = shortID(img.ID)
+ imageID = shortID(img.ID())
}
// get all specified repo:tag pairs and print them separately
- for repo, tags := range libpod.ReposToMap(img.RepoTags) {
+ for repo, tags := range image.ReposToMap(img.Names()) {
for _, tag := range tags {
+ size, err := img.Size()
+ if err != nil {
+ size = nil
+ }
params := imagesTemplateParams{
Repository: repo,
Tag: tag,
ID: imageID,
- Digest: img.Digest,
+ Digest: img.Digest(),
Created: units.HumanDuration(time.Since((createdTime))) + " ago",
- Size: units.HumanSizeWithPrecision(float64(*img.Size), 3),
+ Size: units.HumanSizeWithPrecision(float64(*size), 3),
}
imagesOutput = append(imagesOutput, params)
}
@@ -201,14 +210,18 @@ func getImagesTemplateOutput(runtime *libpod.Runtime, images []inspect.ImageResu
}
// getImagesJSONOutput returns the images information in its raw form
-func getImagesJSONOutput(runtime *libpod.Runtime, images []inspect.ImageResult) (imagesOutput []imagesJSONParams) {
+func getImagesJSONOutput(runtime *libpod.Runtime, images []*image.Image) (imagesOutput []imagesJSONParams) {
for _, img := range images {
+ size, err := img.Size()
+ if err != nil {
+ size = nil
+ }
params := imagesJSONParams{
- ID: img.ID,
- Name: img.RepoTags,
- Digest: img.Digest,
- Created: img.Created,
- Size: img.Size,
+ ID: img.ID(),
+ Name: img.Names(),
+ Digest: img.Digest(),
+ Created: img.Created(),
+ Size: size,
}
imagesOutput = append(imagesOutput, params)
}
@@ -217,7 +230,7 @@ func getImagesJSONOutput(runtime *libpod.Runtime, images []inspect.ImageResult)
// generateImagesOutput generates the images based on the format provided
-func generateImagesOutput(runtime *libpod.Runtime, images []inspect.ImageResult, opts imagesOptions) error {
+func generateImagesOutput(runtime *libpod.Runtime, images []*image.Image, opts imagesOptions) error {
if len(images) == 0 {
return nil
}
@@ -253,35 +266,23 @@ func (i *imagesTemplateParams) HeaderMap() map[string]string {
// CreateFilterFuncs returns an array of filter functions based on the user inputs
// and is later used to filter images for output
-func CreateFilterFuncs(r *libpod.Runtime, c *cli.Context, userInput string) ([]libpod.ImageResultFilter, error) {
+func CreateFilterFuncs(r *libpod.Runtime, c *cli.Context, image *image.Image) ([]libpod.ImageResultFilter, error) {
var filterFuncs []libpod.ImageResultFilter
for _, filter := range c.StringSlice("filter") {
splitFilter := strings.Split(filter, "=")
switch splitFilter[0] {
case "before":
- before := r.NewImage(splitFilter[1])
- _, beforeID, _ := before.GetLocalImageName()
-
- if before.LocalName == "" {
- return nil, errors.Errorf("unable to find image % in local stores", splitFilter[1])
- }
- img, err := r.GetImage(beforeID)
+ before, err := r.ImageRuntime().NewFromLocal(splitFilter[1])
if err != nil {
- return nil, err
+ return nil, errors.Wrapf(err, "unable to find image % in local stores", splitFilter[1])
}
- filterFuncs = append(filterFuncs, libpod.ImageCreatedBefore(img.Created))
+ filterFuncs = append(filterFuncs, libpod.ImageCreatedBefore(before.Created()))
case "after":
- after := r.NewImage(splitFilter[1])
- _, afterID, _ := after.GetLocalImageName()
-
- if after.LocalName == "" {
- return nil, errors.Errorf("unable to find image % in local stores", splitFilter[1])
- }
- img, err := r.GetImage(afterID)
+ after, err := r.ImageRuntime().NewFromLocal(splitFilter[1])
if err != nil {
- return nil, err
+ return nil, errors.Wrapf(err, "unable to find image % in local stores", splitFilter[1])
}
- filterFuncs = append(filterFuncs, libpod.ImageCreatedAfter(img.Created))
+ filterFuncs = append(filterFuncs, libpod.ImageCreatedAfter(after.Created()))
case "dangling":
filterFuncs = append(filterFuncs, libpod.ImageDangling())
case "label":
@@ -291,8 +292,8 @@ func CreateFilterFuncs(r *libpod.Runtime, c *cli.Context, userInput string) ([]l
return nil, errors.Errorf("invalid filter %s ", splitFilter[0])
}
}
- if len(strings.TrimSpace(userInput)) != 0 {
- filterFuncs = append(filterFuncs, libpod.OutputImageFilter(userInput))
+ if image != nil {
+ filterFuncs = append(filterFuncs, libpod.OutputImageFilter(image))
}
return filterFuncs, nil
}
diff --git a/libpod/image/image.go b/libpod/image/image.go
index 5e69a0a98..15fc5174c 100644
--- a/libpod/image/image.go
+++ b/libpod/image/image.go
@@ -29,12 +29,16 @@ import (
// Image is the primary struct for dealing with images
// It is still very much a work in progress
type Image struct {
+ // Adding these two structs for now but will cull when we near
+ // completion of this library.
inspect.ImageData
+ inspect.ImageResult
InputName string
Local bool
//runtime *libpod.Runtime
image *storage.Image
imageruntime *Runtime
+ repotagsMap map[string][]string
}
// Runtime contains the store
@@ -496,6 +500,28 @@ func (i *Image) History() ([]ociv1.History, []types.BlobInfo, error) {
return oci.History, img.LayerInfos(), nil
}
+// Dangling returns a bool if the image is "dangling"
+func (i *Image) Dangling() bool {
+ return len(i.Names()) == 0
+}
+
+// Labels returns the image's labels
+func (i *Image) Labels() (map[string]string, error) {
+ sr, err := i.toStorageReference()
+ if err != nil {
+ return nil, err
+ }
+ ic, err := sr.NewImage(&types.SystemContext{})
+ if err != nil {
+ return nil, err
+ }
+ imgInspect, err := ic.Inspect()
+ if err != nil {
+ return nil, err
+ }
+ return imgInspect.Labels, nil
+}
+
// Import imports and image into the store and returns an image
func Import(path, reference string, writer io.Writer, signingOptions SigningOptions, imageConfig ociv1.Image, runtime *Runtime) (*Image, error) {
file := TarballTransport + ":" + path
diff --git a/libpod/image/utils.go b/libpod/image/utils.go
index 76ec349f9..c1b2aacde 100644
--- a/libpod/image/utils.go
+++ b/libpod/image/utils.go
@@ -90,3 +90,23 @@ func getPolicyContext(ctx *types.SystemContext) (*signature.PolicyContext, error
func hasTransport(image string) bool {
return strings.Contains(image, "://")
}
+
+// ReposToMap parses the specified repotags and returns a map with repositories
+// as keys and the corresponding arrays of tags as values.
+func ReposToMap(repotags []string) map[string][]string {
+ // map format is repo -> tag
+ repos := make(map[string][]string)
+ for _, repo := range repotags {
+ var repository, tag string
+ if len(repo) > 0 {
+ li := strings.LastIndex(repo, ":")
+ repository = repo[0:li]
+ tag = repo[li+1:]
+ }
+ repos[repository] = append(repos[repository], tag)
+ }
+ if len(repos) == 0 {
+ repos["<none>"] = []string{"<none>"}
+ }
+ return repos
+}
diff --git a/libpod/runtime_img.go b/libpod/runtime_img.go
index a58626855..e3cb4e2c3 100644
--- a/libpod/runtime_img.go
+++ b/libpod/runtime_img.go
@@ -110,7 +110,7 @@ type imageDecomposeStruct struct {
}
// ImageResultFilter is a mock function for image filtering
-type ImageResultFilter func(inspect.ImageResult) bool
+type ImageResultFilter func(*image.Image) bool
func (k *Image) assembleFqName() string {
return fmt.Sprintf("%s/%s:%s", k.Registry, k.ImageName, k.Tag)
@@ -983,8 +983,6 @@ func (r *Runtime) GetImages(params *ImageFilterParams, filters ...ImageFilter) (
if include {
newImage := img
- // TODO I dont think this is needed. Will verify along the way
- //newImage.Names = []string{name}
imagesFiltered = append(imagesFiltered, newImage)
}
}
@@ -1184,98 +1182,11 @@ func getPolicyContext(ctx *types.SystemContext) (*signature.PolicyContext, error
return policyContext, nil
}
-// sizer knows its size.
-type sizer interface {
- Size() (int64, error)
-}
-
-func imageSize(img types.ImageSource) *uint64 {
- if s, ok := img.(sizer); ok {
- if sum, err := s.Size(); err == nil {
- usum := uint64(sum)
- return &usum
- }
- }
- return nil
-}
-
-// ReposToMap parses the specified repotags and returns a map with repositories
-// as keys and the corresponding arrays of tags as values.
-func ReposToMap(repotags []string) map[string][]string {
- // map format is repo -> tag
- repos := make(map[string][]string)
- for _, repo := range repotags {
- var repository, tag string
- if len(repo) > 0 {
- li := strings.LastIndex(repo, ":")
- repository = repo[0:li]
- tag = repo[li+1:]
- }
- repos[repository] = append(repos[repository], tag)
- }
- if len(repos) == 0 {
- repos["<none>"] = []string{"<none>"}
- }
- return repos
-}
-
-// GetImageResults gets the images for podman images and returns them as
-// an array of ImageResults
-func (r *Runtime) GetImageResults() ([]inspect.ImageResult, error) {
- var results []inspect.ImageResult
-
- images, err := r.store.Images()
- if err != nil {
- return nil, err
- }
- for _, image := range images {
- storeRef, err := is.Transport.ParseStoreReference(r.store, image.ID)
- if err != nil {
- return nil, err
- }
- systemContext := &types.SystemContext{}
- img, err := storeRef.NewImageSource(systemContext)
- if err != nil {
- return nil, err
- }
- ic, err := storeRef.NewImage(&types.SystemContext{})
- if err != nil {
- return nil, err
- }
- imgInspect, err := ic.Inspect()
- if err != nil {
- return nil, err
- }
- dangling := false
- if len(image.Names) == 0 {
- dangling = true
- }
-
- for repo, tags := range ReposToMap(image.Names) {
- // use the first pair as the image's default repo and tag
- results = append(results, inspect.ImageResult{
- ID: image.ID,
- Repository: repo,
- RepoTags: image.Names,
- Tag: tags[0],
- Size: imageSize(img),
- Digest: image.Digest,
- Created: image.Created,
- Labels: imgInspect.Labels,
- Dangling: dangling,
- })
- break
- }
-
- }
- return results, nil
-}
-
// ImageCreatedBefore allows you to filter on images created before
// the given time.Time
func ImageCreatedBefore(createTime time.Time) ImageResultFilter {
- return func(i inspect.ImageResult) bool {
- if i.Created.Before(createTime) {
+ return func(i *image.Image) bool {
+ if i.Created().Before(createTime) {
return true
}
return false
@@ -1285,8 +1196,8 @@ func ImageCreatedBefore(createTime time.Time) ImageResultFilter {
// ImageCreatedAfter allows you to filter on images created after
// the given time.Time
func ImageCreatedAfter(createTime time.Time) ImageResultFilter {
- return func(i inspect.ImageResult) bool {
- if i.Created.After(createTime) {
+ return func(i *image.Image) bool {
+ if i.Created().After(createTime) {
return true
}
return false
@@ -1295,8 +1206,8 @@ func ImageCreatedAfter(createTime time.Time) ImageResultFilter {
// ImageDangling allows you to filter images for dangling images
func ImageDangling() ImageResultFilter {
- return func(i inspect.ImageResult) bool {
- if i.Dangling {
+ return func(i *image.Image) bool {
+ if i.Dangling() {
return true
}
return false
@@ -1306,51 +1217,34 @@ func ImageDangling() ImageResultFilter {
// ImageLabel allows you to filter by images labels key and/or value
func ImageLabel(labelfilter string) ImageResultFilter {
// We need to handle both label=key and label=key=value
- return func(i inspect.ImageResult) bool {
+ return func(i *image.Image) bool {
var value string
splitFilter := strings.Split(labelfilter, "=")
key := splitFilter[0]
if len(splitFilter) > 1 {
value = splitFilter[1]
}
- for labelKey, labelValue := range i.Labels {
- // handles label=key
- if key == labelKey && len(strings.TrimSpace(value)) == 0 {
- return true
- }
- //handles label=key=value
- if key == labelKey && value == labelValue {
- return true
- }
+ labels, err := i.Labels()
+ if err != nil {
+ return false
}
- return false
+ if len(strings.TrimSpace(labels[key])) > 0 && len(strings.TrimSpace(value)) == 0 {
+ return true
+ }
+ return labels[key] == value
}
}
// OutputImageFilter allows you to filter by an a specific image name
-func OutputImageFilter(name string) ImageResultFilter {
- return func(i inspect.ImageResult) bool {
- li := strings.LastIndex(name, ":")
- var repository, tag string
- if li < 0 {
- repository = name
- } else {
- repository = name[0:li]
- tag = name[li+1:]
- }
- if repository == i.Repository && len(strings.TrimSpace(tag)) == 0 {
- return true
- }
- if repository == i.Repository && tag == i.Tag {
- return true
- }
- return false
+func OutputImageFilter(userImage *image.Image) ImageResultFilter {
+ return func(i *image.Image) bool {
+ return userImage.ID() == i.ID()
}
}
// FilterImages filters images using a set of predefined fitler funcs
-func FilterImages(images []inspect.ImageResult, filters []ImageResultFilter) []inspect.ImageResult {
- var filteredImages []inspect.ImageResult
+func FilterImages(images []*image.Image, filters []ImageResultFilter) []*image.Image {
+ var filteredImages []*image.Image
for _, image := range images {
include := true
for _, filter := range filters {