Merge pull request #576 from stevvooe/seek-reset-handling
content: allow reset via Truncate
This commit is contained in:
commit
317b884110
7 changed files with 64 additions and 13 deletions
|
@ -199,6 +199,7 @@ func (rw *remoteWriter) Commit(size int64, expected digest.Digest) error {
|
|||
resp, err := rw.send(&contentapi.WriteRequest{
|
||||
Action: contentapi.WriteActionCommit,
|
||||
Total: size,
|
||||
Offset: rw.offset,
|
||||
Expected: expected,
|
||||
})
|
||||
if err != nil {
|
||||
|
@ -216,6 +217,12 @@ func (rw *remoteWriter) Commit(size int64, expected digest.Digest) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
func (rw *remoteWriter) Truncate(size int64) error {
|
||||
// This truncation won't actually be validated until a write is issued.
|
||||
rw.offset = size
|
||||
return nil
|
||||
}
|
||||
|
||||
func (rw *remoteWriter) Close() error {
|
||||
return rw.client.CloseSend()
|
||||
}
|
||||
|
|
|
@ -44,6 +44,7 @@ type Writer interface {
|
|||
Status() (Status, error)
|
||||
Digest() digest.Digest
|
||||
Commit(size int64, expected digest.Digest) error
|
||||
Truncate(size int64) error
|
||||
}
|
||||
|
||||
type Ingester interface {
|
||||
|
|
|
@ -36,7 +36,14 @@ func WriteBlob(ctx context.Context, cs Ingester, ref string, r io.Reader, size i
|
|||
if ws.Offset > 0 {
|
||||
r, err = seekReader(r, ws.Offset, size)
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "unabled to resume write to %v", ref)
|
||||
if !isUnseekable(err) {
|
||||
return errors.Wrapf(err, "unabled to resume write to %v", ref)
|
||||
}
|
||||
|
||||
// reader is unseekable, try to move the writer back to the start.
|
||||
if err := cw.Truncate(0); err != nil {
|
||||
return errors.Wrapf(err, "content writer truncate failed")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -49,13 +56,19 @@ func WriteBlob(ctx context.Context, cs Ingester, ref string, r io.Reader, size i
|
|||
|
||||
if err := cw.Commit(size, expected); err != nil {
|
||||
if !IsExists(err) {
|
||||
return err
|
||||
return errors.Wrapf(err, "failed commit on ref %q", ref)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
var errUnseekable = errors.New("seek not supported")
|
||||
|
||||
func isUnseekable(err error) bool {
|
||||
return errors.Cause(err) == errUnseekable
|
||||
}
|
||||
|
||||
// seekReader attempts to seek the reader to the given offset, either by
|
||||
// resolving `io.Seeker` or by detecting `io.ReaderAt`.
|
||||
func seekReader(r io.Reader, offset, size int64) (io.Reader, error) {
|
||||
|
@ -81,7 +94,7 @@ func seekReader(r io.Reader, offset, size int64) (io.Reader, error) {
|
|||
return sr, nil
|
||||
}
|
||||
|
||||
return nil, errors.Errorf("cannot seek to offset %v", offset)
|
||||
return r, errors.Wrapf(errUnseekable, "seek to offset %v failed", offset)
|
||||
}
|
||||
|
||||
func readFileString(path string) (string, error) {
|
||||
|
|
|
@ -74,7 +74,7 @@ func (w *writer) Commit(size int64, expected digest.Digest) error {
|
|||
}
|
||||
|
||||
if size > 0 && size != fi.Size() {
|
||||
return errors.Errorf("failed size validation: %v != %v", fi.Size(), size)
|
||||
return errors.Errorf("%q failed size validation: %v != %v", w.ref, fi.Size(), size)
|
||||
}
|
||||
|
||||
if err := w.fp.Close(); err != nil {
|
||||
|
@ -133,3 +133,12 @@ func (cw *writer) Close() (err error) {
|
|||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (w *writer) Truncate(size int64) error {
|
||||
if size != 0 {
|
||||
return errors.New("Truncate: unsupported size")
|
||||
}
|
||||
w.offset = 0
|
||||
w.digester.Hash().Reset()
|
||||
return w.fp.Truncate(0)
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue