Skip to content

Commit

Permalink
When copying extended run image layers, use the original number of la…
Browse files Browse the repository at this point in the history
…yers

in addition to the original top layer digest
to determine what is an extension layer and what is an original layer.
Relying on the original top layer digest (only) introduced errors
if the original run image had a duplicated top layer.

Fixes #1300

Signed-off-by: Natalie Arellano <narellano@vmware.com>
  • Loading branch information
natalieparellano committed Mar 1, 2024
1 parent 41d885b commit e3fa523
Showing 1 changed file with 13 additions and 10 deletions.
23 changes: 13 additions & 10 deletions phase/extender.go
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,7 @@ func (e *Extender) extendRun(logger log.Logger) error {
return fmt.Errorf("getting run image to extend: %w", err)
}

origTopLayer, err := topLayerDigest(origBaseImage, logger)
origTopLayer, origNumLayers, err := topLayerDigest(origBaseImage, logger)
if err != nil {
return fmt.Errorf("getting original run image top layer: %w", err)
}
Expand All @@ -151,35 +151,35 @@ func (e *Extender) extendRun(logger log.Logger) error {
return fmt.Errorf("extending run image: %w", err)
}

if err = e.saveSparse(extendedImage, origTopLayer, logger); err != nil {
if err = e.saveSparse(extendedImage, origTopLayer, origNumLayers, logger); err != nil {
return fmt.Errorf("failed to copy extended image to output directory: %w", err)
}
return e.DockerfileApplier.Cleanup()
}

func topLayerDigest(image v1.Image, logger log.Logger) (string, error) {
func topLayerDigest(image v1.Image, logger log.Logger) (string, int, error) {
imageHash, err := image.Digest()
if err != nil {
return "", err
return "", -1, err

Check warning on line 163 in phase/extender.go

View check run for this annotation

Codecov / codecov/patch

phase/extender.go#L163

Added line #L163 was not covered by tests
}

manifest, err := image.Manifest()
if err != nil {
return "", fmt.Errorf("getting image manifest: %w", err)
return "", -1, fmt.Errorf("getting image manifest: %w", err)

Check warning on line 168 in phase/extender.go

View check run for this annotation

Codecov / codecov/patch

phase/extender.go#L168

Added line #L168 was not covered by tests
}

allLayers := manifest.Layers
logger.Debugf("Found %d layers in original image with digest: %s", len(allLayers), imageHash)

if len(allLayers) == 0 {
return "", nil
return "", 0, nil
}

layer := allLayers[len(allLayers)-1]
return layer.Digest.String(), nil
return layer.Digest.String(), len(allLayers), nil

Check warning on line 179 in phase/extender.go

View check run for this annotation

Codecov / codecov/patch

phase/extender.go#L179

Added line #L179 was not covered by tests
}

func (e *Extender) saveSparse(image v1.Image, origTopLayerHash string, logger log.Logger) error {
func (e *Extender) saveSparse(image v1.Image, origTopLayerHash string, origNumLayers int, logger log.Logger) error {
// save sparse image (manifest and config)
imageHash, err := image.Digest()
if err != nil {
Expand Down Expand Up @@ -209,7 +209,7 @@ func (e *Extender) saveSparse(image v1.Image, origTopLayerHash string, logger lo
needsCopying = true
}
group, _ := errgroup.WithContext(context.TODO())
for _, currentLayer := range allLayers {
for idx, currentLayer := range allLayers {
currentHash, err = currentLayer.Digest()
if err != nil {
return fmt.Errorf("getting layer hash: %w", err)
Expand All @@ -221,10 +221,13 @@ func (e *Extender) saveSparse(image v1.Image, origTopLayerHash string, logger lo
group.Go(func() error {
return copyLayer(currentLayer, toPath)
})
case currentHash.String() == origTopLayerHash:
case currentHash.String() == origTopLayerHash && idx+1 == origNumLayers:

Check warning on line 224 in phase/extender.go

View check run for this annotation

Codecov / codecov/patch

phase/extender.go#L224

Added line #L224 was not covered by tests
logger.Debugf("Found original top layer with digest: %s", currentHash)
needsCopying = true
continue
case currentHash.String() == origTopLayerHash:
logger.Warnf("Original run image has duplicated top layer with digest: %s", currentHash)
continue

Check warning on line 230 in phase/extender.go

View check run for this annotation

Codecov / codecov/patch

phase/extender.go#L228-L230

Added lines #L228 - L230 were not covered by tests
default:
logger.Debugf("Skipping base layer with digest: %s", currentHash)
continue
Expand Down

0 comments on commit e3fa523

Please sign in to comment.