From d28bd54f2a064841982fa60810c413e23e650ab9 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Pawe=C5=82=20Gronowski?= <pawel.gronowski@docker.com>
Date: Mon, 16 Oct 2023 13:43:36 +0200
Subject: [PATCH] c8d/history: Fix Tags assigned from parents
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

The `Tags` slice of each history entry was filled with tags of parent
image. Change it to correctly assign the current image tags.

Signed-off-by: Paweł Gronowski <pawel.gronowski@docker.com>
---
 daemon/containerd/image_history.go | 50 ++++++++++++++++++++++--------
 1 file changed, 37 insertions(+), 13 deletions(-)

diff --git a/daemon/containerd/image_history.go b/daemon/containerd/image_history.go
index 53e54c1f30..e9a4738c68 100644
--- a/daemon/containerd/image_history.go
+++ b/daemon/containerd/image_history.go
@@ -97,32 +97,34 @@ func (i *ImageService) ImageHistory(ctx context.Context, name string) ([]*imaget
 			log.G(ctx).WithFields(log.Fields{
 				"error": err,
 				"image": img,
-			}).Warnf("failed to list parent images")
+			}).Warn("failed to list parent images")
 			return nil
 		}
 		return imgs
 	}
 
+	is := i.client.ImageService()
 	currentImg := img
 	for _, h := range history {
-		h.ID = currentImg.Target.Digest.String()
-		imgs := findParents(currentImg)
+		dgst := currentImg.Target.Digest.String()
+		h.ID = dgst
+
+		imgs, err := is.List(ctx, "target.digest=="+dgst)
+		if err != nil {
+			return nil, err
+		}
+
+		tags := getImageTags(ctx, imgs)
+		h.Tags = append(h.Tags, tags...)
+
+		parents := findParents(currentImg)
 
 		foundNext := false
-		for _, img := range imgs {
+		for _, img := range parents {
 			if _, ok := img.Labels[imageLabelClassicBuilderParent]; ok {
 				currentImg = img
 				foundNext = true
 			}
-
-			if isDanglingImage(img) {
-				continue
-			}
-			name, err := reference.ParseNamed(img.Name)
-			if err != nil {
-				return nil, err
-			}
-			h.Tags = append(h.Tags, reference.FamiliarString(name))
 		}
 
 		if !foundNext {
@@ -132,3 +134,25 @@ func (i *ImageService) ImageHistory(ctx context.Context, name string) ([]*imaget
 
 	return history, nil
 }
+
+func getImageTags(ctx context.Context, imgs []images.Image) []string {
+	var tags []string
+	for _, img := range imgs {
+		if isDanglingImage(img) {
+			continue
+		}
+
+		name, err := reference.ParseNamed(img.Name)
+		if err != nil {
+			log.G(ctx).WithFields(log.Fields{
+				"name":  name,
+				"error": err,
+			}).Warn("image with a name that's not a valid named reference")
+			continue
+		}
+
+		tags = append(tags, reference.FamiliarString(name))
+	}
+
+	return tags
+}