Skip to content

Commit 57d79e1

Browse files
committed
bugfix: cache empty layer for docker schema1 image
containerd should cache empty label for docker schema1 image. if not, the original empty layer will be non-empty layer and the image config will be changed too. in this case, the image ID will be changed. check the blob empty label to avoid changing image ID when repull docker schema1 image. Signed-off-by: Wei Fu <[email protected]>
1 parent 87d1118 commit 57d79e1

1 file changed

Lines changed: 19 additions & 3 deletions

File tree

remotes/docker/schema1/converter.go

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ import (
2424
"fmt"
2525
"io"
2626
"io/ioutil"
27+
"strconv"
2728
"strings"
2829
"sync"
2930
"time"
@@ -42,7 +43,10 @@ import (
4243
"github.com/pkg/errors"
4344
)
4445

45-
const manifestSizeLimit = 8e6 // 8MB
46+
const (
47+
manifestSizeLimit = 8e6 // 8MB
48+
labelDockerSchema1EmptyLayer = "containerd.io/docker.schema1.empty.layer"
49+
)
4650

4751
type blobState struct {
4852
diffID digest.Digest
@@ -353,10 +357,11 @@ func (c *Converter) fetchBlob(ctx context.Context, desc ocispec.Descriptor) erro
353357
Digest: desc.Digest,
354358
Labels: map[string]string{
355359
"containerd.io/uncompressed": state.diffID.String(),
360+
labelDockerSchema1EmptyLayer: strconv.FormatBool(state.empty),
356361
},
357362
}
358363

359-
if _, err := c.contentStore.Update(ctx, cinfo, "labels.containerd.io/uncompressed"); err != nil {
364+
if _, err := c.contentStore.Update(ctx, cinfo, "labels.containerd.io/uncompressed", fmt.Sprintf("labels.%s", labelDockerSchema1EmptyLayer)); err != nil {
360365
return errors.Wrap(err, "failed to update uncompressed label")
361366
}
362367

@@ -380,7 +385,18 @@ func (c *Converter) reuseLabelBlobState(ctx context.Context, desc ocispec.Descri
380385
return false, nil
381386
}
382387

383-
bState := blobState{empty: false}
388+
emptyVal, ok := cinfo.Labels[labelDockerSchema1EmptyLayer]
389+
if !ok {
390+
return false, nil
391+
}
392+
393+
isEmpty, err := strconv.ParseBool(emptyVal)
394+
if err != nil {
395+
log.G(ctx).WithField("id", desc.Digest).Warnf("failed to parse bool from label %s: %v", labelDockerSchema1EmptyLayer, isEmpty)
396+
return false, nil
397+
}
398+
399+
bState := blobState{empty: isEmpty}
384400

385401
if bState.diffID, err = digest.Parse(diffID); err != nil {
386402
log.G(ctx).WithField("id", desc.Digest).Warnf("failed to parse digest from label containerd.io/uncompressed: %v", diffID)

0 commit comments

Comments
 (0)