Skip to content

Commit 6c7abf7

Browse files
authored
Merge pull request containerd#1918 from crosbymichael/cherry-pull-fix
[cherry-pick] Fix image pull after a failure
2 parents dba5fa0 + 63e1963 commit 6c7abf7

3 files changed

Lines changed: 45 additions & 1 deletion

File tree

content/helpers.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ func Copy(ctx context.Context, cw Writer, r io.Reader, size int64, expected dige
7777
r, err = seekReader(r, ws.Offset, size)
7878
if err != nil {
7979
if !isUnseekable(err) {
80-
return errors.Wrapf(err, "unabled to resume write to %v", ws.Ref)
80+
return errors.Wrapf(err, "unable to resume write to %v", ws.Ref)
8181
}
8282

8383
// reader is unseekable, try to move the writer back to the start.

content/local/store_test.go

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ import (
2222
"github.com/containerd/containerd/content/testsuite"
2323
"github.com/containerd/containerd/testutil"
2424
"github.com/opencontainers/go-digest"
25+
"github.com/stretchr/testify/require"
2526
)
2627

2728
type memoryLabelStore struct {
@@ -335,3 +336,42 @@ func checkWrite(ctx context.Context, t checker, cs content.Store, dgst digest.Di
335336

336337
return dgst
337338
}
339+
340+
func TestWriterTruncateRecoversFromIncompleteWrite(t *testing.T) {
341+
tmpdir, err := ioutil.TempDir("", "test-local-content-store-recover")
342+
require.NoError(t, err)
343+
defer os.RemoveAll(tmpdir)
344+
345+
cs, err := NewStore(tmpdir)
346+
require.NoError(t, err)
347+
348+
ctx, cancel := context.WithCancel(context.Background())
349+
defer cancel()
350+
351+
ref := "ref"
352+
content := []byte("this is the content")
353+
total := int64(len(content))
354+
setupIncompleteWrite(ctx, t, cs, ref, total)
355+
356+
writer, err := cs.Writer(ctx, ref, total, "")
357+
require.NoError(t, err)
358+
359+
require.NoError(t, writer.Truncate(0))
360+
361+
_, err = writer.Write(content)
362+
require.NoError(t, err)
363+
364+
dgst := digest.FromBytes(content)
365+
err = writer.Commit(ctx, total, dgst)
366+
require.NoError(t, err)
367+
}
368+
369+
func setupIncompleteWrite(ctx context.Context, t *testing.T, cs content.Store, ref string, total int64) {
370+
writer, err := cs.Writer(ctx, ref, total, "")
371+
require.NoError(t, err)
372+
373+
_, err = writer.Write([]byte("bad data"))
374+
require.NoError(t, err)
375+
376+
require.NoError(t, writer.Close())
377+
}

content/local/writer.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package local
22

33
import (
44
"context"
5+
"io"
56
"os"
67
"path/filepath"
78
"runtime"
@@ -167,5 +168,8 @@ func (w *writer) Truncate(size int64) error {
167168
}
168169
w.offset = 0
169170
w.digester.Hash().Reset()
171+
if _, err := w.fp.Seek(0, io.SeekStart); err != nil {
172+
return err
173+
}
170174
return w.fp.Truncate(0)
171175
}

0 commit comments

Comments
 (0)