forked from TrueCloudLab/restic
Wrap errors #2
This commit is contained in:
parent
b53679a24d
commit
4a0f77650b
9 changed files with 65 additions and 68 deletions
|
@ -25,7 +25,7 @@ func ParseID(s string) (ID, error) {
|
||||||
b, err := hex.DecodeString(s)
|
b, err := hex.DecodeString(s)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return ID{}, err
|
return ID{}, errors.Wrap(err, "hex.DecodeString")
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(b) != IDSize {
|
if len(b) != IDSize {
|
||||||
|
@ -73,7 +73,7 @@ func (id ID) Equal(other ID) bool {
|
||||||
func (id ID) EqualString(other string) (bool, error) {
|
func (id ID) EqualString(other string) (bool, error) {
|
||||||
s, err := hex.DecodeString(other)
|
s, err := hex.DecodeString(other)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return false, err
|
return false, errors.Wrap(err, "hex.DecodeString")
|
||||||
}
|
}
|
||||||
|
|
||||||
id2 := ID{}
|
id2 := ID{}
|
||||||
|
@ -97,12 +97,12 @@ func (id *ID) UnmarshalJSON(b []byte) error {
|
||||||
var s string
|
var s string
|
||||||
err := json.Unmarshal(b, &s)
|
err := json.Unmarshal(b, &s)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return errors.Wrap(err, "Unmarshal")
|
||||||
}
|
}
|
||||||
|
|
||||||
_, err = hex.Decode(id[:], []byte(s))
|
_, err = hex.Decode(id[:], []byte(s))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return errors.Wrap(err, "hex.Decode")
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
|
|
|
@ -35,7 +35,7 @@ func Open(dir string) (*Local, error) {
|
||||||
// test if all necessary dirs are there
|
// test if all necessary dirs are there
|
||||||
for _, d := range paths(dir) {
|
for _, d := range paths(dir) {
|
||||||
if _, err := fs.Stat(d); err != nil {
|
if _, err := fs.Stat(d); err != nil {
|
||||||
return nil, errors.Errorf("%s does not exist", d)
|
return nil, errors.Wrap(err, "Open")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -55,7 +55,7 @@ func Create(dir string) (*Local, error) {
|
||||||
for _, d := range paths(dir) {
|
for _, d := range paths(dir) {
|
||||||
err := fs.MkdirAll(d, backend.Modes.Dir)
|
err := fs.MkdirAll(d, backend.Modes.Dir)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, errors.Wrap(err, "MkdirAll")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -110,13 +110,13 @@ func (b *Local) Load(h backend.Handle, p []byte, off int64) (n int, err error) {
|
||||||
|
|
||||||
f, err := fs.Open(filename(b.p, h.Type, h.Name))
|
f, err := fs.Open(filename(b.p, h.Type, h.Name))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, err
|
return 0, errors.Wrap(err, "Open")
|
||||||
}
|
}
|
||||||
|
|
||||||
defer func() {
|
defer func() {
|
||||||
e := f.Close()
|
e := f.Close()
|
||||||
if err == nil && e != nil {
|
if err == nil && e != nil {
|
||||||
err = e
|
err = errors.Wrap(e, "Close")
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
|
||||||
|
@ -128,7 +128,7 @@ func (b *Local) Load(h backend.Handle, p []byte, off int64) (n int, err error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, err
|
return 0, errors.Wrap(err, "Seek")
|
||||||
}
|
}
|
||||||
|
|
||||||
return io.ReadFull(f, p)
|
return io.ReadFull(f, p)
|
||||||
|
@ -138,12 +138,12 @@ func (b *Local) Load(h backend.Handle, p []byte, off int64) (n int, err error) {
|
||||||
func writeToTempfile(tempdir string, p []byte) (filename string, err error) {
|
func writeToTempfile(tempdir string, p []byte) (filename string, err error) {
|
||||||
tmpfile, err := ioutil.TempFile(tempdir, "temp-")
|
tmpfile, err := ioutil.TempFile(tempdir, "temp-")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", errors.Wrap(err, "TempFile")
|
||||||
}
|
}
|
||||||
|
|
||||||
n, err := tmpfile.Write(p)
|
n, err := tmpfile.Write(p)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", errors.Wrap(err, "Write")
|
||||||
}
|
}
|
||||||
|
|
||||||
if n != len(p) {
|
if n != len(p) {
|
||||||
|
@ -151,17 +151,17 @@ func writeToTempfile(tempdir string, p []byte) (filename string, err error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if err = tmpfile.Sync(); err != nil {
|
if err = tmpfile.Sync(); err != nil {
|
||||||
return "", err
|
return "", errors.Wrap(err, "Syncn")
|
||||||
}
|
}
|
||||||
|
|
||||||
err = fs.ClearCache(tmpfile)
|
err = fs.ClearCache(tmpfile)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", errors.Wrap(err, "ClearCache")
|
||||||
}
|
}
|
||||||
|
|
||||||
err = tmpfile.Close()
|
err = tmpfile.Close()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", errors.Wrap(err, "Close")
|
||||||
}
|
}
|
||||||
|
|
||||||
return tmpfile.Name(), nil
|
return tmpfile.Name(), nil
|
||||||
|
@ -191,7 +191,7 @@ func (b *Local) Save(h backend.Handle, p []byte) (err error) {
|
||||||
if h.Type == backend.Data {
|
if h.Type == backend.Data {
|
||||||
err = fs.MkdirAll(filepath.Dir(filename), backend.Modes.Dir)
|
err = fs.MkdirAll(filepath.Dir(filename), backend.Modes.Dir)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return errors.Wrap(err, "MkdirAll")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -200,13 +200,13 @@ func (b *Local) Save(h backend.Handle, p []byte) (err error) {
|
||||||
h, filepath.Base(tmpfile), filepath.Base(filename), err)
|
h, filepath.Base(tmpfile), filepath.Base(filename), err)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return errors.Wrap(err, "Rename")
|
||||||
}
|
}
|
||||||
|
|
||||||
// set mode to read-only
|
// set mode to read-only
|
||||||
fi, err := fs.Stat(filename)
|
fi, err := fs.Stat(filename)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return errors.Wrap(err, "Stat")
|
||||||
}
|
}
|
||||||
|
|
||||||
return setNewFileMode(filename, fi)
|
return setNewFileMode(filename, fi)
|
||||||
|
@ -221,7 +221,7 @@ func (b *Local) Stat(h backend.Handle) (backend.BlobInfo, error) {
|
||||||
|
|
||||||
fi, err := fs.Stat(filename(b.p, h.Type, h.Name))
|
fi, err := fs.Stat(filename(b.p, h.Type, h.Name))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return backend.BlobInfo{}, err
|
return backend.BlobInfo{}, errors.Wrap(err, "Stat")
|
||||||
}
|
}
|
||||||
|
|
||||||
return backend.BlobInfo{Size: fi.Size()}, nil
|
return backend.BlobInfo{Size: fi.Size()}, nil
|
||||||
|
@ -235,7 +235,7 @@ func (b *Local) Test(t backend.Type, name string) (bool, error) {
|
||||||
if os.IsNotExist(errors.Cause(err)) {
|
if os.IsNotExist(errors.Cause(err)) {
|
||||||
return false, nil
|
return false, nil
|
||||||
}
|
}
|
||||||
return false, err
|
return false, errors.Wrap(err, "Stat")
|
||||||
}
|
}
|
||||||
|
|
||||||
return true, nil
|
return true, nil
|
||||||
|
@ -249,7 +249,7 @@ func (b *Local) Remove(t backend.Type, name string) error {
|
||||||
// reset read-only flag
|
// reset read-only flag
|
||||||
err := fs.Chmod(fn, 0666)
|
err := fs.Chmod(fn, 0666)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return errors.Wrap(err, "Chmod")
|
||||||
}
|
}
|
||||||
|
|
||||||
return fs.Remove(fn)
|
return fs.Remove(fn)
|
||||||
|
@ -262,13 +262,13 @@ func isFile(fi os.FileInfo) bool {
|
||||||
func readdir(d string) (fileInfos []os.FileInfo, err error) {
|
func readdir(d string) (fileInfos []os.FileInfo, err error) {
|
||||||
f, e := fs.Open(d)
|
f, e := fs.Open(d)
|
||||||
if e != nil {
|
if e != nil {
|
||||||
return nil, e
|
return nil, errors.Wrap(e, "Open")
|
||||||
}
|
}
|
||||||
|
|
||||||
defer func() {
|
defer func() {
|
||||||
e := f.Close()
|
e := f.Close()
|
||||||
if err == nil {
|
if err == nil {
|
||||||
err = e
|
err = errors.Wrap(e, "Close")
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
|
||||||
|
|
|
@ -22,7 +22,7 @@ func ParseConfig(s string) (interface{}, error) {
|
||||||
u, err := url.Parse(s)
|
u, err := url.Parse(s)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, errors.Wrap(err, "url.Parse")
|
||||||
}
|
}
|
||||||
|
|
||||||
cfg := Config{URL: u}
|
cfg := Config{URL: u}
|
||||||
|
|
|
@ -80,7 +80,7 @@ func (b *restBackend) Load(h backend.Handle, p []byte, off int64) (n int, err er
|
||||||
if off < 0 {
|
if off < 0 {
|
||||||
info, err := b.Stat(h)
|
info, err := b.Stat(h)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, err
|
return 0, errors.Wrap(err, "Stat")
|
||||||
}
|
}
|
||||||
|
|
||||||
if -off > info.Size {
|
if -off > info.Size {
|
||||||
|
@ -92,7 +92,7 @@ func (b *restBackend) Load(h backend.Handle, p []byte, off int64) (n int, err er
|
||||||
|
|
||||||
req, err := http.NewRequest("GET", restPath(b.url, h), nil)
|
req, err := http.NewRequest("GET", restPath(b.url, h), nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, err
|
return 0, errors.Wrap(err, "http.NewRequest")
|
||||||
}
|
}
|
||||||
req.Header.Add("Range", fmt.Sprintf("bytes=%d-%d", off, off+int64(len(p))))
|
req.Header.Add("Range", fmt.Sprintf("bytes=%d-%d", off, off+int64(len(p))))
|
||||||
<-b.connChan
|
<-b.connChan
|
||||||
|
@ -104,13 +104,13 @@ func (b *restBackend) Load(h backend.Handle, p []byte, off int64) (n int, err er
|
||||||
e := resp.Body.Close()
|
e := resp.Body.Close()
|
||||||
|
|
||||||
if err == nil {
|
if err == nil {
|
||||||
err = e
|
err = errors.Wrap(e, "Close")
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
}
|
}
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, err
|
return 0, errors.Wrap(err, "client.Do")
|
||||||
}
|
}
|
||||||
if resp.StatusCode != 200 && resp.StatusCode != 206 {
|
if resp.StatusCode != 200 && resp.StatusCode != 206 {
|
||||||
return 0, errors.Errorf("unexpected HTTP response code %v", resp.StatusCode)
|
return 0, errors.Errorf("unexpected HTTP response code %v", resp.StatusCode)
|
||||||
|
@ -134,13 +134,13 @@ func (b *restBackend) Save(h backend.Handle, p []byte) (err error) {
|
||||||
e := resp.Body.Close()
|
e := resp.Body.Close()
|
||||||
|
|
||||||
if err == nil {
|
if err == nil {
|
||||||
err = e
|
err = errors.Wrap(e, "Close")
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
}
|
}
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return errors.Wrap(err, "client.Post")
|
||||||
}
|
}
|
||||||
|
|
||||||
if resp.StatusCode != 200 {
|
if resp.StatusCode != 200 {
|
||||||
|
@ -160,11 +160,11 @@ func (b *restBackend) Stat(h backend.Handle) (backend.BlobInfo, error) {
|
||||||
resp, err := b.client.Head(restPath(b.url, h))
|
resp, err := b.client.Head(restPath(b.url, h))
|
||||||
b.connChan <- struct{}{}
|
b.connChan <- struct{}{}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return backend.BlobInfo{}, err
|
return backend.BlobInfo{}, errors.Wrap(err, "client.Head")
|
||||||
}
|
}
|
||||||
|
|
||||||
if err = resp.Body.Close(); err != nil {
|
if err = resp.Body.Close(); err != nil {
|
||||||
return backend.BlobInfo{}, err
|
return backend.BlobInfo{}, errors.Wrap(err, "Close")
|
||||||
}
|
}
|
||||||
|
|
||||||
if resp.StatusCode != 200 {
|
if resp.StatusCode != 200 {
|
||||||
|
@ -201,14 +201,14 @@ func (b *restBackend) Remove(t backend.Type, name string) error {
|
||||||
|
|
||||||
req, err := http.NewRequest("DELETE", restPath(b.url, h), nil)
|
req, err := http.NewRequest("DELETE", restPath(b.url, h), nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return errors.Wrap(err, "http.NewRequest")
|
||||||
}
|
}
|
||||||
<-b.connChan
|
<-b.connChan
|
||||||
resp, err := b.client.Do(req)
|
resp, err := b.client.Do(req)
|
||||||
b.connChan <- struct{}{}
|
b.connChan <- struct{}{}
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return errors.Wrap(err, "client.Do")
|
||||||
}
|
}
|
||||||
|
|
||||||
if resp.StatusCode != 200 {
|
if resp.StatusCode != 200 {
|
||||||
|
|
|
@ -32,7 +32,7 @@ func ParseConfig(s string) (interface{}, error) {
|
||||||
// bucket name and prefix
|
// bucket name and prefix
|
||||||
url, err := url.Parse(s[3:])
|
url, err := url.Parse(s[3:])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, errors.Wrap(err, "url.Parse")
|
||||||
}
|
}
|
||||||
|
|
||||||
if url.Path == "" {
|
if url.Path == "" {
|
||||||
|
|
|
@ -30,7 +30,7 @@ func Open(cfg Config) (backend.Backend, error) {
|
||||||
|
|
||||||
client, err := minio.New(cfg.Endpoint, cfg.KeyID, cfg.Secret, !cfg.UseHTTP)
|
client, err := minio.New(cfg.Endpoint, cfg.KeyID, cfg.Secret, !cfg.UseHTTP)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, errors.Wrap(err, "minio.New")
|
||||||
}
|
}
|
||||||
|
|
||||||
be := &s3{client: client, bucketname: cfg.Bucket, prefix: cfg.Prefix}
|
be := &s3{client: client, bucketname: cfg.Bucket, prefix: cfg.Prefix}
|
||||||
|
@ -39,14 +39,14 @@ func Open(cfg Config) (backend.Backend, error) {
|
||||||
ok, err := client.BucketExists(cfg.Bucket)
|
ok, err := client.BucketExists(cfg.Bucket)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
debug.Log("s3.Open", "BucketExists(%v) returned err %v, trying to create the bucket", cfg.Bucket, err)
|
debug.Log("s3.Open", "BucketExists(%v) returned err %v, trying to create the bucket", cfg.Bucket, err)
|
||||||
return nil, err
|
return nil, errors.Wrap(err, "client.BucketExists")
|
||||||
}
|
}
|
||||||
|
|
||||||
if !ok {
|
if !ok {
|
||||||
// create new bucket with default ACL in default region
|
// create new bucket with default ACL in default region
|
||||||
err = client.MakeBucket(cfg.Bucket, "")
|
err = client.MakeBucket(cfg.Bucket, "")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, errors.Wrap(err, "client.MakeBucket")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -95,20 +95,20 @@ func (be s3) Load(h backend.Handle, p []byte, off int64) (n int, err error) {
|
||||||
obj, err = be.client.GetObject(be.bucketname, path)
|
obj, err = be.client.GetObject(be.bucketname, path)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
debug.Log("s3.Load", " err %v", err)
|
debug.Log("s3.Load", " err %v", err)
|
||||||
return 0, err
|
return 0, errors.Wrap(err, "client.GetObject")
|
||||||
}
|
}
|
||||||
|
|
||||||
// make sure that the object is closed properly.
|
// make sure that the object is closed properly.
|
||||||
defer func() {
|
defer func() {
|
||||||
e := obj.Close()
|
e := obj.Close()
|
||||||
if err == nil {
|
if err == nil {
|
||||||
err = e
|
err = errors.Wrap(e, "Close")
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
|
||||||
info, err := obj.Stat()
|
info, err := obj.Stat()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, err
|
return 0, errors.Wrap(err, "obj.Stat")
|
||||||
}
|
}
|
||||||
|
|
||||||
// handle negative offsets
|
// handle negative offsets
|
||||||
|
@ -179,7 +179,7 @@ func (be s3) Save(h backend.Handle, p []byte) (err error) {
|
||||||
n, err := be.client.PutObject(be.bucketname, path, bytes.NewReader(p), "binary/octet-stream")
|
n, err := be.client.PutObject(be.bucketname, path, bytes.NewReader(p), "binary/octet-stream")
|
||||||
debug.Log("s3.Save", "%v -> %v bytes, err %#v", path, n, err)
|
debug.Log("s3.Save", "%v -> %v bytes, err %#v", path, n, err)
|
||||||
|
|
||||||
return err
|
return errors.Wrap(err, "client.PutObject")
|
||||||
}
|
}
|
||||||
|
|
||||||
// Stat returns information about a blob.
|
// Stat returns information about a blob.
|
||||||
|
@ -192,21 +192,21 @@ func (be s3) Stat(h backend.Handle) (bi backend.BlobInfo, err error) {
|
||||||
obj, err = be.client.GetObject(be.bucketname, path)
|
obj, err = be.client.GetObject(be.bucketname, path)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
debug.Log("s3.Stat", "GetObject() err %v", err)
|
debug.Log("s3.Stat", "GetObject() err %v", err)
|
||||||
return backend.BlobInfo{}, err
|
return backend.BlobInfo{}, errors.Wrap(err, "client.GetObject")
|
||||||
}
|
}
|
||||||
|
|
||||||
// make sure that the object is closed properly.
|
// make sure that the object is closed properly.
|
||||||
defer func() {
|
defer func() {
|
||||||
e := obj.Close()
|
e := obj.Close()
|
||||||
if err == nil {
|
if err == nil {
|
||||||
err = e
|
err = errors.Wrap(e, "Close")
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
|
||||||
fi, err := obj.Stat()
|
fi, err := obj.Stat()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
debug.Log("s3.Stat", "Stat() err %v", err)
|
debug.Log("s3.Stat", "Stat() err %v", err)
|
||||||
return backend.BlobInfo{}, err
|
return backend.BlobInfo{}, errors.Wrap(err, "Stat")
|
||||||
}
|
}
|
||||||
|
|
||||||
return backend.BlobInfo{Size: fi.Size}, nil
|
return backend.BlobInfo{Size: fi.Size}, nil
|
||||||
|
@ -230,7 +230,7 @@ func (be *s3) Remove(t backend.Type, name string) error {
|
||||||
path := be.s3path(t, name)
|
path := be.s3path(t, name)
|
||||||
err := be.client.RemoveObject(be.bucketname, path)
|
err := be.client.RemoveObject(be.bucketname, path)
|
||||||
debug.Log("s3.Remove", "%v %v -> err %v", t, name, err)
|
debug.Log("s3.Remove", "%v %v -> err %v", t, name, err)
|
||||||
return err
|
return errors.Wrap(err, "client.RemoveObject")
|
||||||
}
|
}
|
||||||
|
|
||||||
// List returns a channel that yields all names of blobs of type t. A
|
// List returns a channel that yields all names of blobs of type t. A
|
||||||
|
|
|
@ -26,7 +26,7 @@ func ParseConfig(s string) (interface{}, error) {
|
||||||
// parse the "sftp://user@host/path" url format
|
// parse the "sftp://user@host/path" url format
|
||||||
url, err := url.Parse(s)
|
url, err := url.Parse(s)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, errors.Wrap(err, "url.Parse")
|
||||||
}
|
}
|
||||||
if url.User != nil {
|
if url.User != nil {
|
||||||
user = url.User.Username()
|
user = url.User.Username()
|
||||||
|
|
|
@ -41,7 +41,7 @@ func startClient(program string, args ...string) (*SFTP, error) {
|
||||||
// prefix the errors with the program name
|
// prefix the errors with the program name
|
||||||
stderr, err := cmd.StderrPipe()
|
stderr, err := cmd.StderrPipe()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, errors.Wrap(err, "cmd.StderrPipe")
|
||||||
}
|
}
|
||||||
|
|
||||||
go func() {
|
go func() {
|
||||||
|
@ -57,16 +57,16 @@ func startClient(program string, args ...string) (*SFTP, error) {
|
||||||
// get stdin and stdout
|
// get stdin and stdout
|
||||||
wr, err := cmd.StdinPipe()
|
wr, err := cmd.StdinPipe()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, errors.Wrap(err, "cmd.StdinPipe")
|
||||||
}
|
}
|
||||||
rd, err := cmd.StdoutPipe()
|
rd, err := cmd.StdoutPipe()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, errors.Wrap(err, "cmd.StdoutPipe")
|
||||||
}
|
}
|
||||||
|
|
||||||
// start the process
|
// start the process
|
||||||
if err := cmd.Start(); err != nil {
|
if err := cmd.Start(); err != nil {
|
||||||
return nil, err
|
return nil, errors.Wrap(err, "cmd.Start")
|
||||||
}
|
}
|
||||||
|
|
||||||
// wait in a different goroutine
|
// wait in a different goroutine
|
||||||
|
@ -74,7 +74,7 @@ func startClient(program string, args ...string) (*SFTP, error) {
|
||||||
go func() {
|
go func() {
|
||||||
err := cmd.Wait()
|
err := cmd.Wait()
|
||||||
debug.Log("sftp.Wait", "ssh command exited, err %v", err)
|
debug.Log("sftp.Wait", "ssh command exited, err %v", err)
|
||||||
ch <- err
|
ch <- errors.Wrap(err, "cmd.Wait")
|
||||||
}()
|
}()
|
||||||
|
|
||||||
// open the SFTP session
|
// open the SFTP session
|
||||||
|
@ -182,7 +182,7 @@ func Create(dir string, program string, args ...string) (*SFTP, error) {
|
||||||
|
|
||||||
err = sftp.Close()
|
err = sftp.Close()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, errors.Wrap(err, "Close")
|
||||||
}
|
}
|
||||||
|
|
||||||
// open backend
|
// open backend
|
||||||
|
@ -274,16 +274,17 @@ func (r *SFTP) renameFile(oldname string, t backend.Type, name string) error {
|
||||||
|
|
||||||
err := r.c.Rename(oldname, filename)
|
err := r.c.Rename(oldname, filename)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return errors.Wrap(err, "Rename")
|
||||||
}
|
}
|
||||||
|
|
||||||
// set mode to read-only
|
// set mode to read-only
|
||||||
fi, err := r.c.Lstat(filename)
|
fi, err := r.c.Lstat(filename)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return errors.Wrap(err, "Lstat")
|
||||||
}
|
}
|
||||||
|
|
||||||
return r.c.Chmod(filename, fi.Mode()&os.FileMode(^uint32(0222)))
|
err = r.c.Chmod(filename, fi.Mode()&os.FileMode(^uint32(0222)))
|
||||||
|
return errors.Wrap(err, "Chmod")
|
||||||
}
|
}
|
||||||
|
|
||||||
// Join joins the given paths and cleans them afterwards. This always uses
|
// Join joins the given paths and cleans them afterwards. This always uses
|
||||||
|
@ -336,13 +337,13 @@ func (r *SFTP) Load(h backend.Handle, p []byte, off int64) (n int, err error) {
|
||||||
|
|
||||||
f, err := r.c.Open(r.filename(h.Type, h.Name))
|
f, err := r.c.Open(r.filename(h.Type, h.Name))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, err
|
return 0, errors.Wrap(err, "Open")
|
||||||
}
|
}
|
||||||
|
|
||||||
defer func() {
|
defer func() {
|
||||||
e := f.Close()
|
e := f.Close()
|
||||||
if err == nil && e != nil {
|
if err == nil && e != nil {
|
||||||
err = e
|
err = errors.Wrap(e, "Close")
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
|
||||||
|
@ -354,7 +355,7 @@ func (r *SFTP) Load(h backend.Handle, p []byte, off int64) (n int, err error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, err
|
return 0, errors.Wrap(err, "Seek")
|
||||||
}
|
}
|
||||||
|
|
||||||
return io.ReadFull(f, p)
|
return io.ReadFull(f, p)
|
||||||
|
@ -380,7 +381,7 @@ func (r *SFTP) Save(h backend.Handle, p []byte) (err error) {
|
||||||
|
|
||||||
n, err := tmpfile.Write(p)
|
n, err := tmpfile.Write(p)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return errors.Wrap(err, "Write")
|
||||||
}
|
}
|
||||||
|
|
||||||
if n != len(p) {
|
if n != len(p) {
|
||||||
|
@ -389,17 +390,13 @@ func (r *SFTP) Save(h backend.Handle, p []byte) (err error) {
|
||||||
|
|
||||||
err = tmpfile.Close()
|
err = tmpfile.Close()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return errors.Wrap(err, "Close")
|
||||||
}
|
}
|
||||||
|
|
||||||
err = r.renameFile(filename, h.Type, h.Name)
|
err = r.renameFile(filename, h.Type, h.Name)
|
||||||
debug.Log("sftp.Save", "save %v: rename %v: %v",
|
debug.Log("sftp.Save", "save %v: rename %v: %v",
|
||||||
h, path.Base(filename), err)
|
h, path.Base(filename), err)
|
||||||
if err != nil {
|
return err
|
||||||
return errors.Errorf("sftp: renameFile: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Stat returns information about a blob.
|
// Stat returns information about a blob.
|
||||||
|
@ -415,7 +412,7 @@ func (r *SFTP) Stat(h backend.Handle) (backend.BlobInfo, error) {
|
||||||
|
|
||||||
fi, err := r.c.Lstat(r.filename(h.Type, h.Name))
|
fi, err := r.c.Lstat(r.filename(h.Type, h.Name))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return backend.BlobInfo{}, err
|
return backend.BlobInfo{}, errors.Wrap(err, "Lstat")
|
||||||
}
|
}
|
||||||
|
|
||||||
return backend.BlobInfo{Size: fi.Size()}, nil
|
return backend.BlobInfo{Size: fi.Size()}, nil
|
||||||
|
@ -434,7 +431,7 @@ func (r *SFTP) Test(t backend.Type, name string) (bool, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return false, err
|
return false, errors.Wrap(err, "Lstat")
|
||||||
}
|
}
|
||||||
|
|
||||||
return true, nil
|
return true, nil
|
||||||
|
|
|
@ -13,7 +13,7 @@ import (
|
||||||
func LoadAll(be Backend, h Handle, buf []byte) ([]byte, error) {
|
func LoadAll(be Backend, h Handle, buf []byte) ([]byte, error) {
|
||||||
fi, err := be.Stat(h)
|
fi, err := be.Stat(h)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, errors.Wrap(err, "Stat")
|
||||||
}
|
}
|
||||||
|
|
||||||
if fi.Size > int64(len(buf)) {
|
if fi.Size > int64(len(buf)) {
|
||||||
|
|
Loading…
Reference in a new issue