taildrop: add logic for resuming partial files (#9785)

We add the following API:
* type FileChecksums
* type Checksum
* func Manager.PartialFiles
* func Manager.HashPartialFile
* func ResumeReader

The Manager methods provide the ability to query for partial files
and retrieve a list of checksums for a given partial file.
The ResumeReader function is a helper that wraps an io.Reader
to discard content that is identical locally and remotely.
The FileChecksums type represents the checksums of a file
and is safe to JSON marshal and send over the wire.

Updates tailscale/corp#14772

Signed-off-by: Joe Tsai <joetsai@digital-static.net>
Co-authored-by: Rhea Ghosh <rhea@tailscale.com>
This commit is contained in:
Joe Tsai
2023-10-12 16:50:11 -07:00
committed by GitHub
parent 24f322bc43
commit b1867eb23f
7 changed files with 298 additions and 25 deletions

View File

@@ -167,9 +167,9 @@ func (m *Manager) DeleteFile(baseName string) error {
if m.DirectFileMode {
return errors.New("deletes not allowed in direct mode")
}
path, ok := m.joinDir(baseName)
if !ok {
return errors.New("bad filename")
path, err := m.joinDir(baseName)
if err != nil {
return err
}
var bo *backoff.Backoff
logf := m.Logf
@@ -224,9 +224,9 @@ func (m *Manager) OpenFile(baseName string) (rc io.ReadCloser, size int64, err e
if m.DirectFileMode {
return nil, 0, errors.New("opens not allowed in direct mode")
}
path, ok := m.joinDir(baseName)
if !ok {
return nil, 0, errors.New("bad filename")
path, err := m.joinDir(baseName)
if err != nil {
return nil, 0, err
}
if fi, err := os.Stat(path + deletedSuffix); err == nil && fi.Mode().IsRegular() {
tryDeleteAgain(path)