Files
podman/pkg/domain/infra/abi/images_list.go
Jan Kaluza a98154a978 Switch common, storage and image to monorepo.
Signed-off-by: Jan Kaluza <jkaluza@redhat.com>
2025-09-01 12:33:04 +02:00

109 lines
3.1 KiB
Go

//go:build !remote
package abi
import (
"context"
"fmt"
"slices"
"github.com/containers/podman/v5/libpod/define"
"github.com/containers/podman/v5/pkg/domain/entities"
"go.podman.io/common/libimage"
)
func (ir *ImageEngine) List(ctx context.Context, opts entities.ImageListOptions) ([]*entities.ImageSummary, error) {
listImagesOptions := &libimage.ListImagesOptions{
Filters: opts.Filter,
SetListData: true,
}
if !opts.All && !slices.Contains(listImagesOptions.Filters, "intermediate=true") {
// Filter intermediate images unless we want to list *all*.
// NOTE: it's a positive filter, so `intermediate=false` means
// to display non-intermediate images.
listImagesOptions.Filters = append(listImagesOptions.Filters, "intermediate=false")
}
images, err := ir.Libpod.LibimageRuntime().ListImages(ctx, listImagesOptions)
if err != nil {
return nil, err
}
summaries := []*entities.ImageSummary{}
for _, img := range images {
summary, err := func() (*entities.ImageSummary, error) {
repoDigests, err := img.RepoDigests()
if err != nil {
return nil, fmt.Errorf("getting repoDigests from image %q: %w", img.ID(), err)
}
if img.ListData.IsDangling == nil { // Sanity check
return nil, fmt.Errorf("%w: ListData.IsDangling is nil but should not be", define.ErrInternal)
}
isDangling := *img.ListData.IsDangling
parentID := ""
if img.ListData.Parent != nil {
parentID = img.ListData.Parent.ID()
}
s := &entities.ImageSummary{
ID: img.ID(),
Created: img.Created().Unix(),
Dangling: isDangling,
Digest: string(img.Digest()),
RepoDigests: repoDigests,
History: img.NamesHistory(),
Names: img.Names(),
ReadOnly: img.IsReadOnly(),
SharedSize: 0,
RepoTags: img.Names(), // may include tags and digests
ParentId: parentID,
}
if opts.ExtendedAttributes {
iml, err := img.IsManifestList(ctx)
if err != nil {
return nil, err
}
s.IsManifestList = &iml
if !iml {
imgData, err := img.Inspect(ctx, nil)
if err != nil {
return nil, err
}
s.Arch = imgData.Architecture
s.Os = imgData.Os
}
}
s.Labels, err = img.Labels(ctx)
if err != nil {
return nil, fmt.Errorf("retrieving label for image %q: you may need to remove the image to resolve the error: %w", img.ID(), err)
}
ctnrs, err := img.Containers()
if err != nil {
return nil, fmt.Errorf("retrieving containers for image %q: you may need to remove the image to resolve the error: %w", img.ID(), err)
}
s.Containers = len(ctnrs)
sz, err := img.Size()
if err != nil {
return nil, fmt.Errorf("retrieving size of image %q: you may need to remove the image to resolve the error: %w", img.ID(), err)
}
s.Size = sz
// This is good enough for now, but has to be
// replaced later with correct calculation logic
s.VirtualSize = sz
return s, nil
}()
if err != nil {
if libimage.ErrorIsImageUnknown(err) {
// The image may have been (partially) removed in the meantime
continue
}
return nil, err
}
summaries = append(summaries, summary)
}
return summaries, nil
}