Skip to content
Permalink
Browse files
fix(cache-repo): panic when using cache repo and fromImage directive
```
goroutine 1623 [running]:
github.com/werf/werf/pkg/build/stage.(*BaseStage).getServiceMountsFromLabels(0xc0016ed300?, 0xc001b00100)
	/home/distorhead/werf/pkg/build/stage/base.go:283 +0xc4
github.com/werf/werf/pkg/build/stage.(*BaseStage).getServiceMounts(0xc000e50d80?, 0x3bde920?)
	/home/distorhead/werf/pkg/build/stage/base.go:274 +0x36
github.com/werf/werf/pkg/build/stage.(*FromStage).PrepareImage(0xc0014c5140, {0xc001508420?, 0x3be22c8?}, {0x3be06b0, 0xc0006ac2c0}, {0x3bde920, 0xc000f622e0}, 0x0?, 0xc001b01640)
	/home/distorhead/werf/pkg/build/stage/from.go:82 +0x194
github.com/werf/werf/pkg/build.(*BuildPhase).prepareStageInstructions(0xc00188a2d0, {0x3bcc730?, 0xc001858300}, 0xc001508420, {0x3be22c8, 0xc0014c5140})
	/home/distorhead/werf/pkg/build/build_phase.go:693 +0xdff
...
```

Refactor the process of copying of stage-image descriptors objects into cache storage.

Signed-off-by: Timofey Kirillov <timofey.kirillov@flant.com>
  • Loading branch information
distorhead committed May 27, 2022
1 parent a6258e9 commit 3ceb622860d7bffe3e66db7e353faad87b04a6f5
Show file tree
Hide file tree
Showing 6 changed files with 32 additions and 13 deletions.
@@ -800,20 +800,21 @@ func (phase *BuildPhase) atomicBuildStageImage(ctx context.Context, img *Image,

// use newly built image
newStageImageName, uniqueID := phase.Conveyor.StorageManager.GenerateStageUniqueID(stg.GetDigest(), stages)
stageImageObj := phase.Conveyor.GetStageImage(stageImage.Image.Name())
phase.Conveyor.UnsetStageImage(stageImageObj.Image.Name())
stageImageObj.Image.SetName(newStageImageName)
phase.Conveyor.SetStageImage(stageImageObj)
phase.Conveyor.UnsetStageImage(stageImage.Image.Name())
stageImage.Image.SetName(newStageImageName)
phase.Conveyor.SetStageImage(stageImage)

if err := logboek.Context(ctx).Default().LogProcess("Store stage into %s", phase.Conveyor.StorageManager.GetStagesStorage().String()).DoError(func() error {
if err := phase.Conveyor.StorageManager.GetStagesStorage().StoreImage(ctx, stageImage.Image); err != nil {
return fmt.Errorf("unable to store stage %s digest %s image %s into repo %s: %w", stg.LogDetailedName(), stg.GetDigest(), stageImage.Image.Name(), phase.Conveyor.StorageManager.GetStagesStorage().String(), err)
}

if desc, err := phase.Conveyor.StorageManager.GetStagesStorage().GetStageDescription(ctx, phase.Conveyor.projectName(), stg.GetDigest(), uniqueID); err != nil {
return fmt.Errorf("unable to get stage %s digest %s image %s description from repo %s after stages has been stored into repo: %w", stg.LogDetailedName(), stg.GetDigest(), stageImage.Image.Name(), phase.Conveyor.StorageManager.GetStagesStorage().String(), err)
} else {
stageImageObj.Image.SetStageDescription(desc)
stageImage.Image.SetStageDescription(desc)
}

return nil
}); err != nil {
return err
@@ -824,7 +825,6 @@ func (phase *BuildPhase) atomicBuildStageImage(ctx context.Context, img *Image,
if err := phase.Conveyor.StorageManager.CopyStageIntoCacheStorages(ctx, stg, phase.Conveyor.ContainerBackend); err != nil {
return fmt.Errorf("unable to copy stage %s into cache storages: %w", stageImage.Image.GetStageDescription().StageID.String(), err)
}

return nil
}
}
@@ -126,7 +126,7 @@ func (i *Image) SetupBaseImage(c *Conveyor) {
if i.baseImageImageName != "" {
i.baseImageType = StageAsBaseImage
i.stageAsBaseImage = c.GetImage(i.baseImageImageName).GetLastNonEmptyStage()
i.baseImage = c.GetOrCreateStageImage(nil, i.stageAsBaseImage.GetStageImage().Image.Name())
i.baseImage = i.stageAsBaseImage.GetStageImage()
} else {
i.baseImageType = ImageFromRegistryAsBaseImage
i.baseImage = c.GetOrCreateStageImage(nil, i.baseImageName)
@@ -613,9 +613,11 @@ func (runtime *BuildahBackend) RenameImage(ctx context.Context, img LegacyImageI

desc := img.GetStageDescription()

repository, tag := image.ParseRepositoryAndTag(newImageName)
desc.Info.Repository = repository
desc.Info.Tag = tag
if desc != nil {
repository, tag := image.ParseRepositoryAndTag(newImageName)
desc.Info.Repository = repository
desc.Info.Tag = tag
}

return nil
}
@@ -37,6 +37,8 @@ type LegacyImageInterface interface {

SetStageDescription(stage *image.StageDescription)
GetStageDescription() *image.StageDescription

GetCopy() LegacyImageInterface
}

type LegacyContainer interface {
@@ -29,6 +29,19 @@ func NewLegacyStageImage(fromImage *LegacyStageImage, name string, containerBack
return stage
}

func (i *LegacyStageImage) GetCopy() LegacyImageInterface {
ni := NewLegacyStageImage(i.fromImage, i.name, i.ContainerBackend)

if info := i.GetInfo(); info != nil {
ni.SetInfo(info)
}
if desc := i.GetStageDescription(); desc != nil {
ni.SetStageDescription(desc)
}

return ni
}

func (i *LegacyStageImage) BuilderContainer() LegacyBuilderContainer {
return &LegacyStageImageBuilderContainer{i}
}
@@ -383,17 +383,19 @@ func doFetchStage(ctx context.Context, projectName string, stagesStorage storage
}

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

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

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

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

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

0 comments on commit 3ceb622

Please sign in to comment.