Skip to content

Commit 015da02

Browse files
committed
include platform and creation date listing image used by running compose application
Signed-off-by: Nicolas De Loof <[email protected]>
1 parent 7e198ee commit 015da02

File tree

7 files changed

+80
-108
lines changed

7 files changed

+80
-108
lines changed

cmd/compose/images.go

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,12 @@ import (
2020
"context"
2121
"fmt"
2222
"io"
23-
"sort"
23+
"slices"
2424
"strings"
25+
"time"
26+
"maps"
2527

28+
"github.com/containerd/platforms"
2629
"github.com/docker/cli/cli/command"
2730
"github.com/docker/docker/pkg/stringid"
2831
"github.com/docker/go-units"
@@ -86,13 +89,10 @@ func runImages(ctx context.Context, dockerCli command.Cli, backend api.Service,
8689
return nil
8790
}
8891

89-
sort.Slice(images, func(i, j int) bool {
90-
return images[i].ContainerName < images[j].ContainerName
91-
})
92-
9392
return formatter.Print(images, opts.Format, dockerCli.Out(),
9493
func(w io.Writer) {
95-
for _, img := range images {
94+
for _, container := range slices.Sorted(maps.Keys(images)) {
95+
img := images[container]
9696
id := stringid.TruncateID(img.ID)
9797
size := units.HumanSizeWithPrecision(float64(img.Size), 3)
9898
repo := img.Repository
@@ -103,8 +103,10 @@ func runImages(ctx context.Context, dockerCli command.Cli, backend api.Service,
103103
if tag == "" {
104104
tag = "<none>"
105105
}
106-
_, _ = fmt.Fprintf(w, "%s\t%s\t%s\t%s\t%s\n", img.ContainerName, repo, tag, id, size)
106+
created := units.HumanDuration(time.Now().UTC().Sub(img.LastTagTime)) + " ago"
107+
_, _ = fmt.Fprintf(w, "%s\t%s\t%s\t%s\t%s\t%s\t%s\n",
108+
container, repo, tag, platforms.Format(img.Platform), id, size, created)
107109
}
108110
},
109-
"CONTAINER", "REPOSITORY", "TAG", "IMAGE ID", "SIZE")
111+
"CONTAINER", "REPOSITORY", "TAG", "PLATFORM", "IMAGE ID", "SIZE", "CREATED")
110112
}

pkg/api/api.go

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ import (
2323
"time"
2424

2525
"github.com/compose-spec/compose-go/v2/types"
26+
"github.com/containerd/platforms"
2627
"github.com/docker/cli/opts"
2728
"github.com/docker/compose/v2/pkg/utils"
2829
)
@@ -78,7 +79,7 @@ type Service interface {
7879
// Publish executes the equivalent to a `compose publish`
7980
Publish(ctx context.Context, project *types.Project, repository string, options PublishOptions) error
8081
// Images executes the equivalent of a `compose images`
81-
Images(ctx context.Context, projectName string, options ImagesOptions) ([]ImageSummary, error)
82+
Images(ctx context.Context, projectName string, options ImagesOptions) (map[string]ImageSummary, error)
8283
// MaxConcurrency defines upper limit for concurrent operations against engine API
8384
MaxConcurrency(parallel int)
8485
// DryRunMode defines if dry run applies to the command
@@ -535,12 +536,12 @@ type ContainerProcSummary struct {
535536

536537
// ImageSummary holds container image description
537538
type ImageSummary struct {
538-
ID string
539-
ContainerName string
540-
Repository string
541-
Tag string
542-
Size int64
543-
LastTagTime time.Time
539+
ID string
540+
Repository string
541+
Tag string
542+
Platform platforms.Platform
543+
Size int64
544+
LastTagTime time.Time
544545
}
545546

546547
// ServiceStatus hold status about a service

pkg/compose/images.go

Lines changed: 40 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ import (
2222
"strings"
2323
"sync"
2424

25+
"github.com/containerd/platforms"
2526
"github.com/distribution/reference"
2627
"github.com/docker/docker/api/types/container"
2728
"github.com/docker/docker/api/types/filters"
@@ -32,7 +33,7 @@ import (
3233
"github.com/docker/compose/v2/pkg/utils"
3334
)
3435

35-
func (s *composeService) Images(ctx context.Context, projectName string, options api.ImagesOptions) ([]api.ImageSummary, error) {
36+
func (s *composeService) Images(ctx context.Context, projectName string, options api.ImagesOptions) (map[string]api.ImageSummary, error) {
3637
projectName = strings.ToLower(projectName)
3738
allContainers, err := s.apiClient().ContainerList(ctx, container.ListOptions{
3839
All: true,
@@ -53,27 +54,47 @@ func (s *composeService) Images(ctx context.Context, projectName string, options
5354
containers = allContainers
5455
}
5556

56-
images := []string{}
57+
summary := map[string]api.ImageSummary{}
58+
var mux sync.Mutex
59+
eg, ctx := errgroup.WithContext(ctx)
5760
for _, c := range containers {
58-
if !utils.StringContains(images, c.Image) {
59-
images = append(images, c.Image)
60-
}
61-
}
62-
imageSummaries, err := s.getImageSummaries(ctx, images)
63-
if err != nil {
64-
return nil, err
65-
}
66-
summary := make([]api.ImageSummary, len(containers))
67-
for i, c := range containers {
68-
img, ok := imageSummaries[c.Image]
69-
if !ok {
70-
return nil, fmt.Errorf("failed to retrieve image for container %s", getCanonicalContainerName(c))
71-
}
61+
eg.Go(func() error {
62+
image, err := s.apiClient().ImageInspect(ctx, c.Image)
63+
if err != nil {
64+
return err
65+
}
7266

73-
summary[i] = img
74-
summary[i].ContainerName = getCanonicalContainerName(c)
67+
var repository, tag string
68+
ref, err := reference.ParseDockerRef(c.Image)
69+
if err == nil {
70+
// ParseDockerRef will reject a local image ID
71+
repository = reference.FamiliarName(ref)
72+
if tagged, ok := ref.(reference.Tagged); ok {
73+
tag = tagged.Tag()
74+
}
75+
}
76+
77+
mux.Lock()
78+
defer mux.Unlock()
79+
summary[getCanonicalContainerName(c)] = api.ImageSummary{
80+
ID: image.ID,
81+
Repository: repository,
82+
Tag: tag,
83+
Platform: platforms.Platform{
84+
Architecture: image.Architecture,
85+
OS: image.Os,
86+
OSVersion: image.OsVersion,
87+
Variant: image.Variant,
88+
},
89+
Size: image.Size,
90+
LastTagTime: image.Metadata.LastTagTime,
91+
}
92+
return nil
93+
})
7594
}
76-
return summary, nil
95+
96+
err = eg.Wait()
97+
return summary, err
7798
}
7899

79100
func (s *composeService) getImageSummaries(ctx context.Context, repoTags []string) (map[string]api.ImageSummary, error) {

pkg/compose/images_test.go

Lines changed: 17 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -54,27 +54,25 @@ func TestImages(t *testing.T) {
5454

5555
images, err := tested.Images(ctx, strings.ToLower(testProject), compose.ImagesOptions{})
5656

57-
expected := []compose.ImageSummary{
58-
{
59-
ID: "image1",
60-
ContainerName: "123",
61-
Repository: "foo",
62-
Tag: "1",
63-
Size: 12345,
57+
expected := map[string]compose.ImageSummary{
58+
"123": {
59+
ID: "image1",
60+
61+
Repository: "foo",
62+
Tag: "1",
63+
Size: 12345,
6464
},
65-
{
66-
ID: "image2",
67-
ContainerName: "456",
68-
Repository: "bar",
69-
Tag: "2",
70-
Size: 67890,
65+
"456": {
66+
ID: "image2",
67+
Repository: "bar",
68+
Tag: "2",
69+
Size: 67890,
7170
},
72-
{
73-
ID: "image1",
74-
ContainerName: "789",
75-
Repository: "foo",
76-
Tag: "1",
77-
Size: 12345,
71+
"789": {
72+
ID: "image1",
73+
Repository: "foo",
74+
Tag: "1",
75+
Size: 12345,
7876
},
7977
}
8078
assert.NilError(t, err)

pkg/mocks/mock_docker_api.go

Lines changed: 0 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

pkg/mocks/mock_docker_cli.go

Lines changed: 3 additions & 51 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

pkg/mocks/mock_docker_compose_api.go

Lines changed: 2 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)