mirror of
https://github.com/rclone/rclone
synced 2024-11-19 20:07:15 +01:00
union: fix --backup-dir on union backend
Before this fix --backup-dir would fail. This is fixed by wrapping objects returned so that they belong to the union Fs rather than the underlying Fs.
This commit is contained in:
parent
c3a8eb1c10
commit
5dac8e055f
@ -35,7 +35,7 @@ type Options struct {
|
|||||||
Remotes fs.SpaceSepList `config:"remotes"`
|
Remotes fs.SpaceSepList `config:"remotes"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// Fs represents a remote acd server
|
// Fs represents a union of remotes
|
||||||
type Fs struct {
|
type Fs struct {
|
||||||
name string // name of this remote
|
name string // name of this remote
|
||||||
features *fs.Features // optional features
|
features *fs.Features // optional features
|
||||||
@ -46,6 +46,27 @@ type Fs struct {
|
|||||||
hashSet hash.Set // intersection of hash types
|
hashSet hash.Set // intersection of hash types
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Object describes a union Object
|
||||||
|
//
|
||||||
|
// This is a wrapped object which returns the Union Fs as its parent
|
||||||
|
type Object struct {
|
||||||
|
fs.Object
|
||||||
|
fs *Fs // what this object is part of
|
||||||
|
}
|
||||||
|
|
||||||
|
// Wrap an existing object in the union Object
|
||||||
|
func (f *Fs) wrapObject(o fs.Object) *Object {
|
||||||
|
return &Object{
|
||||||
|
Object: o,
|
||||||
|
fs: f,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fs returns the union Fs as the parent
|
||||||
|
func (o *Object) Fs() fs.Info {
|
||||||
|
return o.fs
|
||||||
|
}
|
||||||
|
|
||||||
// Name of the remote (as passed into NewFs)
|
// Name of the remote (as passed into NewFs)
|
||||||
func (f *Fs) Name() string {
|
func (f *Fs) Name() string {
|
||||||
return f.name
|
return f.name
|
||||||
@ -105,7 +126,11 @@ func (f *Fs) Copy(src fs.Object, remote string) (fs.Object, error) {
|
|||||||
fs.Debugf(src, "Can't copy - not same remote type")
|
fs.Debugf(src, "Can't copy - not same remote type")
|
||||||
return nil, fs.ErrorCantCopy
|
return nil, fs.ErrorCantCopy
|
||||||
}
|
}
|
||||||
return f.wr.Features().Copy(src, remote)
|
o, err := f.wr.Features().Copy(src, remote)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return f.wrapObject(o), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Move src to this remote using server side move operations.
|
// Move src to this remote using server side move operations.
|
||||||
@ -122,7 +147,11 @@ func (f *Fs) Move(src fs.Object, remote string) (fs.Object, error) {
|
|||||||
fs.Debugf(src, "Can't move - not same remote type")
|
fs.Debugf(src, "Can't move - not same remote type")
|
||||||
return nil, fs.ErrorCantMove
|
return nil, fs.ErrorCantMove
|
||||||
}
|
}
|
||||||
return f.wr.Features().Move(src, remote)
|
o, err := f.wr.Features().Move(src, remote)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return f.wrapObject(o), err
|
||||||
}
|
}
|
||||||
|
|
||||||
// DirMove moves src, srcRemote to this remote at dstRemote
|
// DirMove moves src, srcRemote to this remote at dstRemote
|
||||||
@ -190,7 +219,11 @@ func (f *Fs) DirCacheFlush() {
|
|||||||
// will return the object and the error, otherwise will return
|
// will return the object and the error, otherwise will return
|
||||||
// nil and the error
|
// nil and the error
|
||||||
func (f *Fs) PutStream(in io.Reader, src fs.ObjectInfo, options ...fs.OpenOption) (fs.Object, error) {
|
func (f *Fs) PutStream(in io.Reader, src fs.ObjectInfo, options ...fs.OpenOption) (fs.Object, error) {
|
||||||
return f.wr.Features().PutStream(in, src, options...)
|
o, err := f.wr.Features().PutStream(in, src, options...)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return f.wrapObject(o), err
|
||||||
}
|
}
|
||||||
|
|
||||||
// About gets quota information from the Fs
|
// About gets quota information from the Fs
|
||||||
@ -204,7 +237,11 @@ func (f *Fs) About() (*fs.Usage, error) {
|
|||||||
// will return the object and the error, otherwise will return
|
// will return the object and the error, otherwise will return
|
||||||
// nil and the error
|
// nil and the error
|
||||||
func (f *Fs) Put(in io.Reader, src fs.ObjectInfo, options ...fs.OpenOption) (fs.Object, error) {
|
func (f *Fs) Put(in io.Reader, src fs.ObjectInfo, options ...fs.OpenOption) (fs.Object, error) {
|
||||||
return f.wr.Put(in, src, options...)
|
o, err := f.wr.Put(in, src, options...)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return f.wrapObject(o), err
|
||||||
}
|
}
|
||||||
|
|
||||||
// List the objects and directories in dir into entries. The
|
// List the objects and directories in dir into entries. The
|
||||||
@ -235,8 +272,11 @@ func (f *Fs) List(dir string) (entries fs.DirEntries, err error) {
|
|||||||
if !found {
|
if !found {
|
||||||
return nil, fs.ErrorDirNotFound
|
return nil, fs.ErrorDirNotFound
|
||||||
}
|
}
|
||||||
for key := range set {
|
for _, entry := range set {
|
||||||
entries = append(entries, set[key])
|
if o, ok := entry.(fs.Object); ok {
|
||||||
|
entry = f.wrapObject(o)
|
||||||
|
}
|
||||||
|
entries = append(entries, entry)
|
||||||
}
|
}
|
||||||
return entries, nil
|
return entries, nil
|
||||||
}
|
}
|
||||||
@ -252,7 +292,7 @@ func (f *Fs) NewObject(path string) (fs.Object, error) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errors.Wrapf(err, "NewObject failed on %v", remote)
|
return nil, errors.Wrapf(err, "NewObject failed on %v", remote)
|
||||||
}
|
}
|
||||||
return obj, nil
|
return f.wrapObject(obj), nil
|
||||||
}
|
}
|
||||||
return nil, fs.ErrorObjectNotFound
|
return nil, fs.ErrorObjectNotFound
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user