Merge pull request #1916 from dnephin/fix-pull-after-failure
Fix image pull after a failure
This commit is contained in:
commit
5971d369e0
@ -77,7 +77,7 @@ func Copy(ctx context.Context, cw Writer, r io.Reader, size int64, expected dige
|
|||||||
r, err = seekReader(r, ws.Offset, size)
|
r, err = seekReader(r, ws.Offset, size)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if !isUnseekable(err) {
|
if !isUnseekable(err) {
|
||||||
return errors.Wrapf(err, "unabled to resume write to %v", ws.Ref)
|
return errors.Wrapf(err, "unable to resume write to %v", ws.Ref)
|
||||||
}
|
}
|
||||||
|
|
||||||
// reader is unseekable, try to move the writer back to the start.
|
// reader is unseekable, try to move the writer back to the start.
|
||||||
|
@ -22,6 +22,7 @@ import (
|
|||||||
"github.com/containerd/containerd/content/testsuite"
|
"github.com/containerd/containerd/content/testsuite"
|
||||||
"github.com/containerd/containerd/testutil"
|
"github.com/containerd/containerd/testutil"
|
||||||
"github.com/opencontainers/go-digest"
|
"github.com/opencontainers/go-digest"
|
||||||
|
"github.com/stretchr/testify/require"
|
||||||
)
|
)
|
||||||
|
|
||||||
type memoryLabelStore struct {
|
type memoryLabelStore struct {
|
||||||
@ -335,3 +336,42 @@ func checkWrite(ctx context.Context, t checker, cs content.Store, dgst digest.Di
|
|||||||
|
|
||||||
return dgst
|
return dgst
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestWriterTruncateRecoversFromIncompleteWrite(t *testing.T) {
|
||||||
|
tmpdir, err := ioutil.TempDir("", "test-local-content-store-recover")
|
||||||
|
require.NoError(t, err)
|
||||||
|
defer os.RemoveAll(tmpdir)
|
||||||
|
|
||||||
|
cs, err := NewStore(tmpdir)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
ctx, cancel := context.WithCancel(context.Background())
|
||||||
|
defer cancel()
|
||||||
|
|
||||||
|
ref := "ref"
|
||||||
|
content := []byte("this is the content")
|
||||||
|
total := int64(len(content))
|
||||||
|
setupIncompleteWrite(ctx, t, cs, ref, total)
|
||||||
|
|
||||||
|
writer, err := cs.Writer(ctx, ref, total, "")
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
require.NoError(t, writer.Truncate(0))
|
||||||
|
|
||||||
|
_, err = writer.Write(content)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
dgst := digest.FromBytes(content)
|
||||||
|
err = writer.Commit(ctx, total, dgst)
|
||||||
|
require.NoError(t, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
func setupIncompleteWrite(ctx context.Context, t *testing.T, cs content.Store, ref string, total int64) {
|
||||||
|
writer, err := cs.Writer(ctx, ref, total, "")
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
_, err = writer.Write([]byte("bad data"))
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
require.NoError(t, writer.Close())
|
||||||
|
}
|
||||||
|
@ -2,6 +2,7 @@ package local
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"io"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"runtime"
|
"runtime"
|
||||||
@ -167,5 +168,8 @@ func (w *writer) Truncate(size int64) error {
|
|||||||
}
|
}
|
||||||
w.offset = 0
|
w.offset = 0
|
||||||
w.digester.Hash().Reset()
|
w.digester.Hash().Reset()
|
||||||
|
if _, err := w.fp.Seek(0, io.SeekStart); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
return w.fp.Truncate(0)
|
return w.fp.Truncate(0)
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user