Skip to content

Commit e62cd78

Browse files
committed
fix(report): fix panic occured when using final-repo and report
Panic occurs when published image in the primary repo becomes broken (MANIFEST_UNKNOWN), despite the fact it is listed in the repository tags. * Reworked report information gathering to use cached stage description for report when possible. * Check final repo for image existance and repush this image when manifest becomes broken. Signed-off-by: Timofey Kirillov <timofey.kirillov@flant.com>
1 parent 7f4530d commit e62cd78

File tree

4 files changed

+48
-37
lines changed

4 files changed

+48
-37
lines changed

pkg/build/build_phase.go

Lines changed: 4 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -179,22 +179,10 @@ func (phase *BuildPhase) createReport(ctx context.Context) error {
179179
continue
180180
}
181181

182-
var desc *imagePkg.StageDescription
183-
stageImage := img.GetLastNonEmptyStage().GetStageImage()
184-
stageID := stageImage.Image.GetStageDescription().StageID
185-
186-
if phase.Conveyor.StorageManager.GetFinalStagesStorage() != nil {
187-
var err error
188-
desc, err = phase.Conveyor.StorageManager.GetFinalStagesStorage().GetStageDescription(ctx, phase.Conveyor.ProjectName(), stageID.Digest, stageID.UniqueID)
189-
if err != nil {
190-
return fmt.Errorf("unable to get stage %s descriptor from final repo %s: %w", stageID.String(), phase.Conveyor.StorageManager.GetFinalStagesStorage().String(), err)
191-
}
192-
} else {
193-
var err error
194-
desc, err = phase.Conveyor.StorageManager.GetStagesStorage().GetStageDescription(ctx, phase.Conveyor.ProjectName(), stageID.Digest, stageID.UniqueID)
195-
if err != nil {
196-
return fmt.Errorf("unable to get stage %s descriptor from primary repo %s: %w", stageID.String(), phase.Conveyor.StorageManager.GetStagesStorage().String(), err)
197-
}
182+
stageImage := img.GetLastNonEmptyStage().GetStageImage().Image
183+
desc := stageImage.GetFinalStageDescription()
184+
if desc == nil {
185+
desc = stageImage.GetStageDescription()
198186
}
199187

200188
phase.ImagesReport.SetImageRecord(img.GetName(), ReportImageRecord{

pkg/container_backend/legacy_base_image.go

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,10 @@ import (
88
)
99

1010
type legacyBaseImage struct {
11-
name string
12-
info *image.Info
13-
stageDesc *image.StageDescription
11+
name string
12+
info *image.Info
13+
stageDesc *image.StageDescription
14+
finalStageDesc *image.StageDescription
1415

1516
ContainerBackend ContainerBackend
1617
}
@@ -64,6 +65,14 @@ func (i *legacyBaseImage) GetStageDescription() *image.StageDescription {
6465
return i.stageDesc
6566
}
6667

68+
func (i *legacyBaseImage) SetFinalStageDescription(stageDesc *image.StageDescription) {
69+
i.finalStageDesc = stageDesc
70+
}
71+
72+
func (i *legacyBaseImage) GetFinalStageDescription() *image.StageDescription {
73+
return i.finalStageDesc
74+
}
75+
6776
func (i *legacyBaseImage) IsExistsLocally() bool {
6877
return i.info != nil
6978
}

pkg/container_backend/legacy_interface.go

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ type LegacyImageInterface interface {
2222
// TODO: should be under a single separate interface
2323
Container() LegacyContainer
2424
BuilderContainer() LegacyBuilderContainer
25+
SetCommitChangeOptions(opts LegacyCommitChangeOptions)
2526

2627
Build(context.Context, BuildOptions) error
2728
SetBuiltID(builtID string)
@@ -37,7 +38,9 @@ type LegacyImageInterface interface {
3738

3839
SetStageDescription(stage *image.StageDescription)
3940
GetStageDescription() *image.StageDescription
40-
SetCommitChangeOptions(opts LegacyCommitChangeOptions)
41+
42+
GetFinalStageDescription() *image.StageDescription
43+
SetFinalStageDescription(stage *image.StageDescription)
4144

4245
GetCopy() LegacyImageInterface
4346
}

pkg/storage/manager/storage_manager.go

Lines changed: 28 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -415,28 +415,28 @@ func doFetchStage(ctx context.Context, projectName string, stagesStorage storage
415415
})
416416
}
417417

418-
func copyStageIntoStagesStorage(ctx context.Context, projectName string, stageID image.StageID, img container_backend.LegacyImageInterface, stagesStorage storage.StagesStorage, containerBackend container_backend.ContainerBackend) error {
418+
func copyStageIntoStagesStorage(ctx context.Context, projectName string, stageID image.StageID, img container_backend.LegacyImageInterface, stagesStorage storage.StagesStorage, containerBackend container_backend.ContainerBackend) (*image.StageDescription, error) {
419419
newImg := img.GetCopy()
420420

421421
targetStagesStorageImageName := stagesStorage.ConstructStageImageName(projectName, stageID.Digest, stageID.UniqueID)
422422

423423
if err := containerBackend.RenameImage(ctx, newImg, targetStagesStorageImageName, false); err != nil {
424-
return fmt.Errorf("unable to rename image %s to %s: %w", img.Name(), targetStagesStorageImageName, err)
424+
return nil, fmt.Errorf("unable to rename image %s to %s: %w", img.Name(), targetStagesStorageImageName, err)
425425
}
426426

427427
if err := stagesStorage.StoreImage(ctx, newImg); err != nil {
428-
return fmt.Errorf("unable to store stage %s into the cache stages storage %s: %w", stageID.String(), stagesStorage.String(), err)
428+
return nil, fmt.Errorf("unable to store stage %s into the cache stages storage %s: %w", stageID.String(), stagesStorage.String(), err)
429429
}
430430

431431
if err := storeStageDescriptionIntoLocalManifestCache(ctx, projectName, stageID, stagesStorage, ConvertStageDescriptionForStagesStorage(newImg.GetStageDescription(), stagesStorage)); err != nil {
432-
return fmt.Errorf("error storing stage %s description into local manifest cache: %w", targetStagesStorageImageName, err)
432+
return nil, fmt.Errorf("error storing stage %s description into local manifest cache: %w", targetStagesStorageImageName, err)
433433
}
434434

435435
if err := lrumeta.CommonLRUImagesCache.AccessImage(ctx, targetStagesStorageImageName); err != nil {
436-
return fmt.Errorf("error accessing last recently used images cache for %s: %w", targetStagesStorageImageName, err)
436+
return nil, fmt.Errorf("error accessing last recently used images cache for %s: %w", targetStagesStorageImageName, err)
437437
}
438438

439-
return nil
439+
return newImg.GetStageDescription(), nil
440440
}
441441

442442
func (m *StorageManager) FetchStage(ctx context.Context, containerBackend container_backend.ContainerBackend, stg stage.Interface) error {
@@ -579,14 +579,14 @@ func (m *StorageManager) FetchStage(ctx context.Context, containerBackend contai
579579
})
580580

581581
if IsErrStageNotFound(err) {
582-
logboek.Context(ctx).Error().LogF("Stage is no longer available in the %q!\n", stg.LogDetailedName(), stg.GetStageImage().Image.Name(), m.StagesStorage.String(), m.ProjectName)
582+
logboek.Context(ctx).Error().LogF("Stage %s image %s is no longer available!\n", stg.LogDetailedName(), stg.GetStageImage().Image.Name())
583583
return ErrUnexpectedStagesStorageState
584584
}
585585

586586
if storage.IsErrBrokenImage(err) {
587-
logboek.Context(ctx).Error().LogF("Invalid stage %q!\n", stg.LogDetailedName(), stg.GetStageImage().Image.Name(), m.StagesStorage.String(), m.ProjectName)
587+
logboek.Context(ctx).Error().LogF("Broken stage %s image %s!\n", stg.LogDetailedName(), stg.GetStageImage().Image.Name())
588588

589-
logboek.Context(ctx).Error().LogF("Will mark image %q as rejected in the stages storage %s\n", stg.GetStageImage().Image.Name(), m.StagesStorage.String())
589+
logboek.Context(ctx).Error().LogF("Will mark image %s as rejected in the stages storage %s\n", stg.GetStageImage().Image.Name(), m.StagesStorage.String())
590590
if err := m.StagesStorage.RejectStage(ctx, m.ProjectName, stageID.Digest, stageID.UniqueID); err != nil {
591591
return fmt.Errorf("unable to reject stage %s image %s in the stages storage %s: %w", stg.LogDetailedName(), stg.GetStageImage().Image.Name(), m.StagesStorage.String(), err)
592592
}
@@ -606,7 +606,7 @@ func (m *StorageManager) FetchStage(ctx context.Context, containerBackend contai
606606

607607
err := logboek.Context(ctx).Default().LogProcess("Copy stage %s into cache %s", stg.LogDetailedName(), cacheStagesStorage.String()).
608608
DoError(func() error {
609-
if err := copyStageIntoStagesStorage(ctx, m.ProjectName, *stageID, fetchedImg, cacheStagesStorage, containerBackend); err != nil {
609+
if _, err := copyStageIntoStagesStorage(ctx, m.ProjectName, *stageID, fetchedImg, cacheStagesStorage, containerBackend); err != nil {
610610
return fmt.Errorf("unable to copy stage %s into cache stages storage %s: %w", stageID.String(), cacheStagesStorage.String(), err)
611611
}
612612
return nil
@@ -626,7 +626,7 @@ func (m *StorageManager) CopyStageIntoCacheStorages(ctx context.Context, stg sta
626626

627627
err := logboek.Context(ctx).Default().LogProcess("Copy stage %s into cache %s", stg.LogDetailedName(), cacheStagesStorage.String()).
628628
DoError(func() error {
629-
if err := copyStageIntoStagesStorage(ctx, m.ProjectName, *stageID, img.Image, cacheStagesStorage, containerBackend); err != nil {
629+
if _, err := copyStageIntoStagesStorage(ctx, m.ProjectName, *stageID, img.Image, cacheStagesStorage, containerBackend); err != nil {
630630
return fmt.Errorf("unable to copy stage %s into cache stages storage %s: %w", stageID.String(), cacheStagesStorage.String(), err)
631631
}
632632
return nil
@@ -669,16 +669,25 @@ func (m *StorageManager) CopyStageIntoFinalStorage(ctx context.Context, stg stag
669669
logboek.Context(ctx).Debug().LogF("[%p] Got existing final stages list cache: %#v\n", m, existingStagesListCache.StageIDs)
670670

671671
stageID := stg.GetStageImage().Image.GetStageDescription().StageID
672-
finalImageName := m.FinalStagesStorage.ConstructStageImageName(m.ProjectName, stageID.Digest, stageID.UniqueID)
672+
673+
finalImageName := m.GetFinalStagesStorage().ConstructStageImageName(m.ProjectName, stageID.Digest, stageID.UniqueID)
673674

674675
for _, existingStg := range existingStagesListCache.GetStageIDs() {
675676
if existingStg.IsEqual(*stageID) {
676-
logboek.Context(ctx).Info().LogF("Stage %s already exists in the final repo, skipping\n", stageID.String())
677+
desc, err := m.GetFinalStagesStorage().GetStageDescription(ctx, m.ProjectName, stageID.Digest, stageID.UniqueID)
678+
if err != nil {
679+
return fmt.Errorf("unable to get stage %s descriptor from final repo %s: %w", stageID.String(), m.GetFinalStagesStorage().String(), err)
680+
}
681+
if desc != nil {
682+
stg.GetStageImage().Image.SetFinalStageDescription(desc)
677683

678-
logboek.Context(ctx).Default().LogFHighlight("Use cache final image for %s\n", stg.LogDetailedName())
679-
container_backend.LogImageName(ctx, finalImageName)
684+
logboek.Context(ctx).Info().LogF("Stage %s already exists in the final repo, skipping\n", stageID.String())
680685

681-
return nil
686+
logboek.Context(ctx).Default().LogFHighlight("Use cache final image for %s\n", stg.LogDetailedName())
687+
container_backend.LogImageName(ctx, finalImageName)
688+
689+
return nil
690+
}
682691
}
683692
}
684693

@@ -697,8 +706,10 @@ func (m *StorageManager) CopyStageIntoFinalStorage(ctx context.Context, stg stag
697706
options.Style(style.Highlight())
698707
}).
699708
DoError(func() error {
700-
if err := copyStageIntoStagesStorage(ctx, m.ProjectName, *stageID, img.Image, m.FinalStagesStorage, containerBackend); err != nil {
709+
if desc, err := copyStageIntoStagesStorage(ctx, m.ProjectName, *stageID, img.Image, m.FinalStagesStorage, containerBackend); err != nil {
701710
return fmt.Errorf("unable to copy stage %s into the final repo %s: %w", stageID.String(), m.FinalStagesStorage.String(), err)
711+
} else {
712+
stg.GetStageImage().Image.SetFinalStageDescription(desc)
702713
}
703714

704715
logboek.Context(ctx).Default().LogFDetails(" name: %s\n", finalImageName)

0 commit comments

Comments
 (0)