diff --git a/cmd/podman/images/list.go b/cmd/podman/images/list.go index 9bddf1cff1..10a2a4f873 100644 --- a/cmd/podman/images/list.go +++ b/cmd/podman/images/list.go @@ -87,6 +87,7 @@ func imageListFlagSet(cmd *cobra.Command) { flags := cmd.Flags() flags.BoolVarP(&listOptions.All, "all", "a", false, "Show all images (default hides intermediate images)") + flags.BoolVarP(&listOptions.Size, "size", "", true, "Compute the size of each image") filterFlagName := "filter" flags.StringSliceVarP(&listOptions.Filter, filterFlagName, "f", []string{}, "Filter output based on conditions provided (default [])") @@ -320,7 +321,10 @@ func lsFormatFromFlags(flags listFlagType) string { row = append(row, "{{.Digest}}") } - row = append(row, "{{.ID}}", "{{.Created}}", "{{.Size}}") + row = append(row, "{{.ID}}", "{{.Created}}") + if listOptions.Size { + row = append(row, "{{.Size}}") + } if flags.history { row = append(row, "{{if .History}}{{.History}}{{else}}{{end}}") diff --git a/docs/source/markdown/podman-images.1.md b/docs/source/markdown/podman-images.1.md index e28df840de..bdd187348e 100644 --- a/docs/source/markdown/podman-images.1.md +++ b/docs/source/markdown/podman-images.1.md @@ -100,6 +100,10 @@ Omit the table headings from the listing of images. Lists only the image IDs. +#### **--size** + +Compute and display the size of each image. The default is true. Computing the size of images can be costly. If listing images is critical to performance, consider turning off size-computation via `--size=false`. + #### **--sort**=*sort*=*created* Sort by created, id, repository, size or tag (default: created) diff --git a/pkg/api/handlers/compat/images.go b/pkg/api/handlers/compat/images.go index edefce0105..ea2df4a732 100644 --- a/pkg/api/handlers/compat/images.go +++ b/pkg/api/handlers/compat/images.go @@ -415,8 +415,9 @@ func GetImages(w http.ResponseWriter, r *http.Request) { All bool Digests bool Filter string // Docker 1.24 compatibility + Size bool }{ - // This is where you can override the golang default value for one of fields + Size: true, } if err := decoder.Decode(&query, r.URL.Query()); err != nil { @@ -443,7 +444,7 @@ func GetImages(w http.ResponseWriter, r *http.Request) { imageEngine := abi.ImageEngine{Libpod: runtime} - listOptions := entities.ImageListOptions{All: query.All, Filter: filterList} + listOptions := entities.ImageListOptions{All: query.All, Filter: filterList, Size: query.Size} summaries, err := imageEngine.List(r.Context(), listOptions) if err != nil { utils.Error(w, http.StatusInternalServerError, err) diff --git a/pkg/api/server/register_images.go b/pkg/api/server/register_images.go index 89f808e7d4..2ed7aa054a 100644 --- a/pkg/api/server/register_images.go +++ b/pkg/api/server/register_images.go @@ -840,6 +840,11 @@ func (s *APIServer) registerImagesHandlers(r *mux.Router) error { // - `id`=(``) // - `since`=(`[:]`, `` or ``) // type: string + // - name: size + // in: query + // description: Compute the size of each image + // type: boolean + // default: true // produces: // - application/json // responses: diff --git a/pkg/bindings/images/types.go b/pkg/bindings/images/types.go index 75cb38a0ad..87ec28dc2f 100644 --- a/pkg/bindings/images/types.go +++ b/pkg/bindings/images/types.go @@ -31,6 +31,8 @@ type ListOptions struct { All *bool // filters that can be used to get a more specific list of images Filters map[string][]string + // Compute the size of each image + Size *bool } //go:generate go run ../generator/generator.go GetOptions diff --git a/pkg/bindings/images/types_list_options.go b/pkg/bindings/images/types_list_options.go index f47cd9c757..7f479630fb 100644 --- a/pkg/bindings/images/types_list_options.go +++ b/pkg/bindings/images/types_list_options.go @@ -46,3 +46,18 @@ func (o *ListOptions) GetFilters() map[string][]string { } return o.Filters } + +// WithSize set field Size to given value +func (o *ListOptions) WithSize(value bool) *ListOptions { + o.Size = &value + return o +} + +// GetSize returns value of field Size +func (o *ListOptions) GetSize() bool { + if o.Size == nil { + var z bool + return z + } + return *o.Size +} diff --git a/pkg/domain/entities/images.go b/pkg/domain/entities/images.go index 7081c5d25a..56126f46c9 100644 --- a/pkg/domain/entities/images.go +++ b/pkg/domain/entities/images.go @@ -251,6 +251,7 @@ type ImageSearchReport struct { type ImageListOptions struct { All bool `json:"all" schema:"all"` Filter []string `json:"Filter,omitempty"` + Size bool `json:"size" schema:"size"` } type ImagePruneOptions struct { diff --git a/pkg/domain/infra/abi/images_list.go b/pkg/domain/infra/abi/images_list.go index 9a0aaaf3ae..8825f1ac65 100644 --- a/pkg/domain/infra/abi/images_list.go +++ b/pkg/domain/infra/abi/images_list.go @@ -60,14 +60,16 @@ func (ir *ImageEngine) List(ctx context.Context, opts entities.ImageListOptions) } e.Containers = len(ctnrs) - sz, err := img.Size() - if err != nil { - return nil, errors.Wrapf(err, "error retrieving size of image %q: you may need to remove the image to resolve the error", img.ID()) + if opts.Size { + sz, err := img.Size() + if err != nil { + return nil, errors.Wrapf(err, "error retrieving size of image %q: you may need to remove the image to resolve the error", img.ID()) + } + e.Size = sz + // This is good enough for now, but has to be + // replaced later with correct calculation logic + e.VirtualSize = sz } - e.Size = sz - // This is good enough for now, but has to be - // replaced later with correct calculation logic - e.VirtualSize = sz parent, err := img.Parent(ctx) if err != nil { diff --git a/pkg/domain/infra/tunnel/images.go b/pkg/domain/infra/tunnel/images.go index 18e10e8dd6..4694189e37 100644 --- a/pkg/domain/infra/tunnel/images.go +++ b/pkg/domain/infra/tunnel/images.go @@ -38,7 +38,7 @@ func (ir *ImageEngine) List(ctx context.Context, opts entities.ImageListOptions) f := strings.Split(filter, "=") filters[f[0]] = f[1:] } - options := new(images.ListOptions).WithAll(opts.All).WithFilters(filters) + options := new(images.ListOptions).WithAll(opts.All).WithFilters(filters).WithSize(opts.Size) psImages, err := images.List(ir.ClientCtx, options) if err != nil { return nil, err diff --git a/test/system/010-images.bats b/test/system/010-images.bats index 2575084185..352c3aa957 100644 --- a/test/system/010-images.bats +++ b/test/system/010-images.bats @@ -312,4 +312,15 @@ Deleted: $pauseID" is "$output" "" } +@test "podman images --size" { + run_podman images + is "${lines[0]}" "REPOSITORY.*TAG.*IMAGE ID.*CREATED.*SIZE" + run_podman images --noheading --format "{{.Size}}" + is "$output" ".* MB" + run_podman images --size=false + is "${lines[0]}" "REPOSITORY.*TAG.*IMAGE ID.*CREATED" + run_podman images --noheading --format "{{.Size}}" --size=false + is "$output" "0 B" +} + # vim: filetype=sh