Browse Source

Fix: use image created time when last tag time is not present
Signed-off-by: Kian Eliasi <[email protected]>

Kian Eliasi 3 months ago
parent
commit
6078b4d99d
4 changed files with 22 additions and 5 deletions
  1. 1 1
      cmd/compose/images.go
  2. 1 0
      pkg/api/api.go
  3. 7 0
      pkg/compose/images.go
  4. 13 4
      pkg/compose/images_test.go

+ 1 - 1
cmd/compose/images.go

@@ -103,7 +103,7 @@ func runImages(ctx context.Context, dockerCli command.Cli, backend api.Service,
 		for ctr, i := range images {
 			lastTagTime := i.LastTagTime
 			if lastTagTime.IsZero() {
-				lastTagTime = time.Now()
+				lastTagTime = i.Created
 			}
 			imageList = append(imageList, img{
 				ContainerName: ctr,

+ 1 - 0
pkg/api/api.go

@@ -558,6 +558,7 @@ type ImageSummary struct {
 	Tag         string
 	Platform    platforms.Platform
 	Size        int64
+	Created     time.Time
 	LastTagTime time.Time
 }
 

+ 7 - 0
pkg/compose/images.go

@@ -22,6 +22,7 @@ import (
 	"slices"
 	"strings"
 	"sync"
+	"time"
 
 	"github.com/containerd/errdefs"
 	"github.com/containerd/platforms"
@@ -90,6 +91,11 @@ func (s *composeService) Images(ctx context.Context, projectName string, options
 				}
 			}
 
+			created, err := time.Parse(time.RFC3339Nano, image.Created)
+			if err != nil {
+				return err
+			}
+
 			mux.Lock()
 			defer mux.Unlock()
 			summary[getCanonicalContainerName(c)] = api.ImageSummary{
@@ -103,6 +109,7 @@ func (s *composeService) Images(ctx context.Context, projectName string, options
 					Variant:      image.Variant,
 				},
 				Size:        image.Size,
+				Created:     created,
 				LastTagTime: image.Metadata.LastTagTime,
 			}
 			return nil

+ 13 - 4
pkg/compose/images_test.go

@@ -20,6 +20,7 @@ import (
 	"context"
 	"strings"
 	"testing"
+	"time"
 
 	"github.com/docker/docker/api/types"
 	"github.com/docker/docker/api/types/container"
@@ -44,8 +45,12 @@ func TestImages(t *testing.T) {
 	args := filters.NewArgs(projectFilter(strings.ToLower(testProject)))
 	listOpts := container.ListOptions{All: true, Filters: args}
 	api.EXPECT().ServerVersion(gomock.Any()).Return(types.Version{APIVersion: "1.96"}, nil).AnyTimes()
-	image1 := imageInspect("image1", "foo:1", 12345)
-	image2 := imageInspect("image2", "bar:2", 67890)
+	timeStr1 := "2025-06-06T06:06:06.000000000Z"
+	created1, _ := time.Parse(time.RFC3339Nano, timeStr1)
+	timeStr2 := "2025-03-03T03:03:03.000000000Z"
+	created2, _ := time.Parse(time.RFC3339Nano, timeStr2)
+	image1 := imageInspect("image1", "foo:1", 12345, timeStr1)
+	image2 := imageInspect("image2", "bar:2", 67890, timeStr2)
 	api.EXPECT().ImageInspect(anyCancellableContext(), "foo:1").Return(image1, nil).MaxTimes(2)
 	api.EXPECT().ImageInspect(anyCancellableContext(), "bar:2").Return(image2, nil)
 	c1 := containerDetail("service1", "123", "running", "foo:1")
@@ -62,32 +67,36 @@ func TestImages(t *testing.T) {
 			Repository: "foo",
 			Tag:        "1",
 			Size:       12345,
+			Created:    created1,
 		},
 		"456": {
 			ID:         "image2",
 			Repository: "bar",
 			Tag:        "2",
 			Size:       67890,
+			Created:    created2,
 		},
 		"789": {
 			ID:         "image1",
 			Repository: "foo",
 			Tag:        "1",
 			Size:       12345,
+			Created:    created1,
 		},
 	}
 	assert.NilError(t, err)
 	assert.DeepEqual(t, images, expected)
 }
 
-func imageInspect(id string, imageReference string, size int64) image.InspectResponse {
+func imageInspect(id string, imageReference string, size int64, created string) image.InspectResponse {
 	return image.InspectResponse{
 		ID: id,
 		RepoTags: []string{
 			"someRepo:someTag",
 			imageReference,
 		},
-		Size: size,
+		Size:    size,
+		Created: created,
 	}
 }