From b49060ef993d9e9c0c9ee31d49a2562807679e1a Mon Sep 17 00:00:00 2001 From: Timofey Kirillov Date: Wed, 29 Mar 2023 15:59:18 +0300 Subject: [PATCH] fix(multiarch): do not override image metadata for secondary platforms Only first specified target platform will be used during converge, so publish commit-stageID metadata only for this first target platform image. Also added assertion to check all final built images built for all target platforms and there is no mismatch between Image.TargetPlatform setting and target platforms. Signed-off-by: Timofey Kirillov --- pkg/build/build_phase.go | 35 +++++++++++++++++++++++++++++++++++ pkg/build/image/image_tree.go | 16 ++++++++++++++++ 2 files changed, 51 insertions(+) diff --git a/pkg/build/build_phase.go b/pkg/build/build_phase.go index 8b39b302a0..8bd21f33bd 100644 --- a/pkg/build/build_phase.go +++ b/pkg/build/build_phase.go @@ -188,6 +188,27 @@ func (phase *BuildPhase) BeforeImages(ctx context.Context) error { } func (phase *BuildPhase) AfterImages(ctx context.Context) error { + targetPlatforms, err := phase.Conveyor.GetTargetPlatforms() + if err != nil { + return fmt.Errorf("unable to get target platforms: %w", err) + } + if len(targetPlatforms) == 0 { + targetPlatforms = []string{phase.Conveyor.ContainerBackend.GetDefaultPlatform()} + } + + for imageName, imagePlatforms := range phase.Conveyor.imagesTree.GetImagePlatformsByName(true) { + AssertAllTargetPlatformsPresent: + for _, targetPlatform := range targetPlatforms { + for _, imagePlatform := range imagePlatforms { + if targetPlatform == imagePlatform { + fmt.Printf("Found image %q built for target platform %q\n", imageName, targetPlatform) + continue AssertAllTargetPlatformsPresent + } + } + panic(fmt.Sprintf("there is no image %q built for target platform %q, please report a bug", imageName, targetPlatform)) + } + } + return phase.createReport(ctx) } @@ -362,6 +383,20 @@ func (phase *BuildPhase) addManagedImage(ctx context.Context, img *image.Image) } func (phase *BuildPhase) publishImageMetadata(ctx context.Context, img *image.Image) error { + targetPlatforms, err := phase.Conveyor.GetTargetPlatforms() + if err != nil { + return fmt.Errorf("unable to get target platforms: %w", err) + } + if len(targetPlatforms) == 0 { + targetPlatforms = []string{phase.Conveyor.ContainerBackend.GetDefaultPlatform()} + } + targetPlatform := targetPlatforms[0] + + // FIXME(multiarch): publish image metadata for multiarch manifest instead of per-platform-images + if targetPlatform != img.TargetPlatform { + return nil + } + return logboek.Context(ctx).Info().LogProcess(fmt.Sprintf("Processing image %s git metadata", img.GetName())). DoError(func() error { var commits []string diff --git a/pkg/build/image/image_tree.go b/pkg/build/image/image_tree.go index 37d56169f3..bec55cb6a6 100644 --- a/pkg/build/image/image_tree.go +++ b/pkg/build/image/image_tree.go @@ -120,6 +120,22 @@ func (tree *ImagesTree) GetImage(name string) *Image { return nil } +func (tree *ImagesTree) GetImagePlatformsByName(finalOnly bool) map[string][]string { + res := make(map[string][]string) + for _, img := range tree.GetImages() { + if finalOnly { + for _, finalImageName := range tree.werfConfig.GetAllImages() { + if finalImageName.GetName() == img.Name { + res[img.Name] = append(res[img.Name], img.TargetPlatform) + } + } + } else { + res[img.Name] = append(res[img.Name], img.TargetPlatform) + } + } + return res +} + func (tree *ImagesTree) GetImages() []*Image { return tree.allImages }