|
@@ -21,7 +21,6 @@ import (
|
|
timetypes "github.com/docker/docker/api/types/time"
|
|
timetypes "github.com/docker/docker/api/types/time"
|
|
"github.com/docker/docker/container"
|
|
"github.com/docker/docker/container"
|
|
"github.com/docker/docker/errdefs"
|
|
"github.com/docker/docker/errdefs"
|
|
- "github.com/docker/docker/image"
|
|
|
|
dockerspec "github.com/moby/docker-image-spec/specs-go/v1"
|
|
dockerspec "github.com/moby/docker-image-spec/specs-go/v1"
|
|
"github.com/opencontainers/go-digest"
|
|
"github.com/opencontainers/go-digest"
|
|
"github.com/opencontainers/image-spec/identity"
|
|
"github.com/opencontainers/image-spec/identity"
|
|
@@ -93,10 +92,9 @@ func (i *ImageService) Images(ctx context.Context, opts imagetypes.ListOptions)
|
|
}
|
|
}
|
|
|
|
|
|
var (
|
|
var (
|
|
- allContainers []*container.Container
|
|
|
|
- summaries = make([]*imagetypes.Summary, 0, len(imgs))
|
|
|
|
- root []*[]digest.Digest
|
|
|
|
- layers map[digest.Digest]int
|
|
|
|
|
|
+ summaries = make([]*imagetypes.Summary, 0, len(imgs))
|
|
|
|
+ root []*[]digest.Digest
|
|
|
|
+ layers map[digest.Digest]int
|
|
)
|
|
)
|
|
if opts.SharedSize {
|
|
if opts.SharedSize {
|
|
root = make([]*[]digest.Digest, 0, len(imgs))
|
|
root = make([]*[]digest.Digest, 0, len(imgs))
|
|
@@ -155,10 +153,6 @@ func (i *ImageService) Images(ctx context.Context, opts imagetypes.ListOptions)
|
|
tagsByDigest[dgst] = append(tagsByDigest[dgst], reference.FamiliarString(ref))
|
|
tagsByDigest[dgst] = append(tagsByDigest[dgst], reference.FamiliarString(ref))
|
|
}
|
|
}
|
|
|
|
|
|
- if opts.ContainerCount {
|
|
|
|
- allContainers = i.containers.List()
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
type tempImage struct {
|
|
type tempImage struct {
|
|
img *ImageManifest
|
|
img *ImageManifest
|
|
indexPlatform *ocispec.Platform
|
|
indexPlatform *ocispec.Platform
|
|
@@ -169,6 +163,7 @@ func (i *ImageService) Images(ctx context.Context, opts imagetypes.ListOptions)
|
|
var presentImages []tempImage
|
|
var presentImages []tempImage
|
|
var totalSize int64
|
|
var totalSize int64
|
|
var allChainsIDs []digest.Digest
|
|
var allChainsIDs []digest.Digest
|
|
|
|
+ var containersCount int64
|
|
|
|
|
|
err := i.walkImageManifests(ctx, img, func(img *ImageManifest) error {
|
|
err := i.walkImageManifests(ctx, img, func(img *ImageManifest) error {
|
|
if isPseudo, err := img.IsPseudoImage(ctx); isPseudo || err != nil {
|
|
if isPseudo, err := img.IsPseudoImage(ctx); isPseudo || err != nil {
|
|
@@ -218,6 +213,14 @@ func (i *ImageService) Images(ctx context.Context, opts imagetypes.ListOptions)
|
|
totalSize += ts
|
|
totalSize += ts
|
|
allChainsIDs = append(allChainsIDs, chainIDs...)
|
|
allChainsIDs = append(allChainsIDs, chainIDs...)
|
|
|
|
|
|
|
|
+ if opts.ContainerCount {
|
|
|
|
+ i.containers.ApplyAll(func(c *container.Container) {
|
|
|
|
+ if c.ImageManifest != nil && c.ImageManifest.Digest == img.Target().Digest {
|
|
|
|
+ containersCount++
|
|
|
|
+ }
|
|
|
|
+ })
|
|
|
|
+ }
|
|
|
|
+
|
|
return nil
|
|
return nil
|
|
})
|
|
})
|
|
if err != nil {
|
|
if err != nil {
|
|
@@ -244,12 +247,16 @@ func (i *ImageService) Images(ctx context.Context, opts imagetypes.ListOptions)
|
|
})
|
|
})
|
|
|
|
|
|
best := presentImages[0].img
|
|
best := presentImages[0].img
|
|
- image, _, err := i.singlePlatformImage(ctx, contentStore, tagsByDigest[best.RealTarget.Digest], best, opts, allContainers)
|
|
|
|
|
|
+ image, err := i.singlePlatformImage(ctx, contentStore, tagsByDigest[best.RealTarget.Digest], best)
|
|
if err != nil {
|
|
if err != nil {
|
|
return nil, err
|
|
return nil, err
|
|
}
|
|
}
|
|
image.Size = totalSize
|
|
image.Size = totalSize
|
|
|
|
|
|
|
|
+ if opts.ContainerCount {
|
|
|
|
+ image.Containers = containersCount
|
|
|
|
+ }
|
|
|
|
+
|
|
summaries = append(summaries, image)
|
|
summaries = append(summaries, image)
|
|
|
|
|
|
if opts.SharedSize {
|
|
if opts.SharedSize {
|
|
@@ -307,7 +314,7 @@ func (i *ImageService) singlePlatformSize(ctx context.Context, imgMfst *ImageMan
|
|
return totalSize, contentSize, nil
|
|
return totalSize, contentSize, nil
|
|
}
|
|
}
|
|
|
|
|
|
-func (i *ImageService) singlePlatformImage(ctx context.Context, contentStore content.Store, repoTags []string, imageManifest *ImageManifest, opts imagetypes.ListOptions, allContainers []*container.Container) (*imagetypes.Summary, []digest.Digest, error) {
|
|
|
|
|
|
+func (i *ImageService) singlePlatformImage(ctx context.Context, contentStore content.Store, repoTags []string, imageManifest *ImageManifest) (*imagetypes.Summary, error) {
|
|
var repoDigests []string
|
|
var repoDigests []string
|
|
rawImg := imageManifest.Metadata()
|
|
rawImg := imageManifest.Metadata()
|
|
target := rawImg.Target.Digest
|
|
target := rawImg.Target.Digest
|
|
@@ -339,16 +346,16 @@ func (i *ImageService) singlePlatformImage(ctx context.Context, contentStore con
|
|
|
|
|
|
cfgDesc, err := imageManifest.Image.Config(ctx)
|
|
cfgDesc, err := imageManifest.Image.Config(ctx)
|
|
if err != nil {
|
|
if err != nil {
|
|
- return nil, nil, err
|
|
|
|
|
|
+ return nil, err
|
|
}
|
|
}
|
|
var cfg configLabels
|
|
var cfg configLabels
|
|
if err := readConfig(ctx, contentStore, cfgDesc, &cfg); err != nil {
|
|
if err := readConfig(ctx, contentStore, cfgDesc, &cfg); err != nil {
|
|
- return nil, nil, err
|
|
|
|
|
|
+ return nil, err
|
|
}
|
|
}
|
|
|
|
|
|
totalSize, _, err := i.singlePlatformSize(ctx, imageManifest)
|
|
totalSize, _, err := i.singlePlatformSize(ctx, imageManifest)
|
|
if err != nil {
|
|
if err != nil {
|
|
- return nil, nil, errors.Wrapf(err, "failed to calculate size of image %s", imageManifest.Name())
|
|
|
|
|
|
+ return nil, errors.Wrapf(err, "failed to calculate size of image %s", imageManifest.Name())
|
|
}
|
|
}
|
|
|
|
|
|
summary := &imagetypes.Summary{
|
|
summary := &imagetypes.Summary{
|
|
@@ -369,23 +376,7 @@ func (i *ImageService) singlePlatformImage(ctx context.Context, contentStore con
|
|
summary.Created = cfg.Created.Unix()
|
|
summary.Created = cfg.Created.Unix()
|
|
}
|
|
}
|
|
|
|
|
|
- if opts.ContainerCount {
|
|
|
|
- // Get container count
|
|
|
|
- var containers int64
|
|
|
|
- for _, c := range allContainers {
|
|
|
|
- if c.ImageID == image.ID(target.String()) {
|
|
|
|
- containers++
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- summary.Containers = containers
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- diffIDs, err := imageManifest.RootFS(ctx)
|
|
|
|
- if err != nil {
|
|
|
|
- return nil, nil, errors.Wrapf(err, "failed to get rootfs of image %s", imageManifest.Name())
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- return summary, identity.ChainIDs(diffIDs), nil
|
|
|
|
|
|
+ return summary, nil
|
|
}
|
|
}
|
|
|
|
|
|
type imageFilterFunc func(image images.Image) bool
|
|
type imageFilterFunc func(image images.Image) bool
|