forked from TrueCloudLab/rclone
This adds a context.Context parameter to NewFs and related calls. This is necessary as part of reading config from the context - backends need to be able to read the global config.
This commit is contained in:
parent
30c8b1b84f
commit
d846210978
82 changed files with 231 additions and 227 deletions
|
@ -1,6 +1,7 @@
|
||||||
package alias
|
package alias
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
"errors"
|
"errors"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
@ -34,7 +35,7 @@ type Options struct {
|
||||||
// NewFs constructs an Fs from the path.
|
// NewFs constructs an Fs from the path.
|
||||||
//
|
//
|
||||||
// The returned Fs is the actual Fs, referenced by remote in the config
|
// The returned Fs is the actual Fs, referenced by remote in the config
|
||||||
func NewFs(name, root string, m configmap.Mapper) (fs.Fs, error) {
|
func NewFs(ctx context.Context, name, root string, m configmap.Mapper) (fs.Fs, error) {
|
||||||
// Parse config into Options struct
|
// Parse config into Options struct
|
||||||
opt := new(Options)
|
opt := new(Options)
|
||||||
err := configstruct.Set(m, opt)
|
err := configstruct.Set(m, opt)
|
||||||
|
@ -47,5 +48,5 @@ func NewFs(name, root string, m configmap.Mapper) (fs.Fs, error) {
|
||||||
if strings.HasPrefix(opt.Remote, name+":") {
|
if strings.HasPrefix(opt.Remote, name+":") {
|
||||||
return nil, errors.New("can't point alias remote at itself - check the value of the remote setting")
|
return nil, errors.New("can't point alias remote at itself - check the value of the remote setting")
|
||||||
}
|
}
|
||||||
return cache.Get(fspath.JoinRootPath(opt.Remote, root))
|
return cache.Get(ctx, fspath.JoinRootPath(opt.Remote, root))
|
||||||
}
|
}
|
||||||
|
|
|
@ -68,7 +68,7 @@ func TestNewFS(t *testing.T) {
|
||||||
remoteRoot, err := filepath.Abs(filepath.FromSlash(path.Join("test/files", test.remoteRoot)))
|
remoteRoot, err := filepath.Abs(filepath.FromSlash(path.Join("test/files", test.remoteRoot)))
|
||||||
require.NoError(t, err, what)
|
require.NoError(t, err, what)
|
||||||
prepare(t, remoteRoot)
|
prepare(t, remoteRoot)
|
||||||
f, err := fs.NewFs(fmt.Sprintf("%s:%s", remoteName, test.fsRoot))
|
f, err := fs.NewFs(context.Background(), fmt.Sprintf("%s:%s", remoteName, test.fsRoot))
|
||||||
require.NoError(t, err, what)
|
require.NoError(t, err, what)
|
||||||
gotEntries, err := f.List(context.Background(), test.fsList)
|
gotEntries, err := f.List(context.Background(), test.fsList)
|
||||||
require.NoError(t, err, what)
|
require.NoError(t, err, what)
|
||||||
|
@ -90,7 +90,7 @@ func TestNewFS(t *testing.T) {
|
||||||
|
|
||||||
func TestNewFSNoRemote(t *testing.T) {
|
func TestNewFSNoRemote(t *testing.T) {
|
||||||
prepare(t, "")
|
prepare(t, "")
|
||||||
f, err := fs.NewFs(fmt.Sprintf("%s:", remoteName))
|
f, err := fs.NewFs(context.Background(), fmt.Sprintf("%s:", remoteName))
|
||||||
|
|
||||||
require.Error(t, err)
|
require.Error(t, err)
|
||||||
require.Nil(t, f)
|
require.Nil(t, f)
|
||||||
|
@ -98,7 +98,7 @@ func TestNewFSNoRemote(t *testing.T) {
|
||||||
|
|
||||||
func TestNewFSInvalidRemote(t *testing.T) {
|
func TestNewFSInvalidRemote(t *testing.T) {
|
||||||
prepare(t, "not_existing_test_remote:")
|
prepare(t, "not_existing_test_remote:")
|
||||||
f, err := fs.NewFs(fmt.Sprintf("%s:", remoteName))
|
f, err := fs.NewFs(context.Background(), fmt.Sprintf("%s:", remoteName))
|
||||||
|
|
||||||
require.Error(t, err)
|
require.Error(t, err)
|
||||||
require.Nil(t, f)
|
require.Nil(t, f)
|
||||||
|
|
|
@ -239,8 +239,7 @@ func filterRequest(req *http.Request) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewFs constructs an Fs from the path, container:path
|
// NewFs constructs an Fs from the path, container:path
|
||||||
func NewFs(name, root string, m configmap.Mapper) (fs.Fs, error) {
|
func NewFs(ctx context.Context, name, root string, m configmap.Mapper) (fs.Fs, error) {
|
||||||
ctx := context.Background()
|
|
||||||
// Parse config into Options struct
|
// Parse config into Options struct
|
||||||
opt := new(Options)
|
opt := new(Options)
|
||||||
err := configstruct.Set(m, opt)
|
err := configstruct.Set(m, opt)
|
||||||
|
|
|
@ -379,8 +379,7 @@ func (f *Fs) setRoot(root string) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewFs constructs an Fs from the path, container:path
|
// NewFs constructs an Fs from the path, container:path
|
||||||
func NewFs(name, root string, m configmap.Mapper) (fs.Fs, error) {
|
func NewFs(ctx context.Context, name, root string, m configmap.Mapper) (fs.Fs, error) {
|
||||||
ctx := context.Background()
|
|
||||||
// Parse config into Options struct
|
// Parse config into Options struct
|
||||||
opt := new(Options)
|
opt := new(Options)
|
||||||
err := configstruct.Set(m, opt)
|
err := configstruct.Set(m, opt)
|
||||||
|
|
|
@ -391,8 +391,7 @@ func (f *Fs) setRoot(root string) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewFs constructs an Fs from the path, bucket:path
|
// NewFs constructs an Fs from the path, bucket:path
|
||||||
func NewFs(name, root string, m configmap.Mapper) (fs.Fs, error) {
|
func NewFs(ctx context.Context, name, root string, m configmap.Mapper) (fs.Fs, error) {
|
||||||
ctx := context.Background()
|
|
||||||
// Parse config into Options struct
|
// Parse config into Options struct
|
||||||
opt := new(Options)
|
opt := new(Options)
|
||||||
err := configstruct.Set(m, opt)
|
err := configstruct.Set(m, opt)
|
||||||
|
|
|
@ -372,8 +372,7 @@ func errorHandler(resp *http.Response) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewFs constructs an Fs from the path, container:path
|
// NewFs constructs an Fs from the path, container:path
|
||||||
func NewFs(name, root string, m configmap.Mapper) (fs.Fs, error) {
|
func NewFs(ctx context.Context, name, root string, m configmap.Mapper) (fs.Fs, error) {
|
||||||
ctx := context.Background()
|
|
||||||
// Parse config into Options struct
|
// Parse config into Options struct
|
||||||
opt := new(Options)
|
opt := new(Options)
|
||||||
err := configstruct.Set(m, opt)
|
err := configstruct.Set(m, opt)
|
||||||
|
|
8
backend/cache/cache.go
vendored
8
backend/cache/cache.go
vendored
|
@ -340,7 +340,7 @@ func parseRootPath(path string) (string, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewFs constructs an Fs from the path, container:path
|
// NewFs constructs an Fs from the path, container:path
|
||||||
func NewFs(name, rootPath string, m configmap.Mapper) (fs.Fs, error) {
|
func NewFs(ctx context.Context, name, rootPath string, m configmap.Mapper) (fs.Fs, error) {
|
||||||
// Parse config into Options struct
|
// Parse config into Options struct
|
||||||
opt := new(Options)
|
opt := new(Options)
|
||||||
err := configstruct.Set(m, opt)
|
err := configstruct.Set(m, opt)
|
||||||
|
@ -362,7 +362,7 @@ func NewFs(name, rootPath string, m configmap.Mapper) (fs.Fs, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
remotePath := fspath.JoinRootPath(opt.Remote, rootPath)
|
remotePath := fspath.JoinRootPath(opt.Remote, rootPath)
|
||||||
wrappedFs, wrapErr := cache.Get(remotePath)
|
wrappedFs, wrapErr := cache.Get(ctx, remotePath)
|
||||||
if wrapErr != nil && wrapErr != fs.ErrorIsFile {
|
if wrapErr != nil && wrapErr != fs.ErrorIsFile {
|
||||||
return nil, errors.Wrapf(wrapErr, "failed to make remote %q to wrap", remotePath)
|
return nil, errors.Wrapf(wrapErr, "failed to make remote %q to wrap", remotePath)
|
||||||
}
|
}
|
||||||
|
@ -479,7 +479,7 @@ func NewFs(name, rootPath string, m configmap.Mapper) (fs.Fs, error) {
|
||||||
return nil, errors.Wrapf(err, "failed to create cache directory %v", f.opt.TempWritePath)
|
return nil, errors.Wrapf(err, "failed to create cache directory %v", f.opt.TempWritePath)
|
||||||
}
|
}
|
||||||
f.opt.TempWritePath = filepath.ToSlash(f.opt.TempWritePath)
|
f.opt.TempWritePath = filepath.ToSlash(f.opt.TempWritePath)
|
||||||
f.tempFs, err = cache.Get(f.opt.TempWritePath)
|
f.tempFs, err = cache.Get(ctx, f.opt.TempWritePath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errors.Wrapf(err, "failed to create temp fs: %v", err)
|
return nil, errors.Wrapf(err, "failed to create temp fs: %v", err)
|
||||||
}
|
}
|
||||||
|
@ -506,7 +506,7 @@ func NewFs(name, rootPath string, m configmap.Mapper) (fs.Fs, error) {
|
||||||
if doChangeNotify := wrappedFs.Features().ChangeNotify; doChangeNotify != nil {
|
if doChangeNotify := wrappedFs.Features().ChangeNotify; doChangeNotify != nil {
|
||||||
pollInterval := make(chan time.Duration, 1)
|
pollInterval := make(chan time.Duration, 1)
|
||||||
pollInterval <- time.Duration(f.opt.ChunkCleanInterval)
|
pollInterval <- time.Duration(f.opt.ChunkCleanInterval)
|
||||||
doChangeNotify(context.Background(), f.receiveChangeNotify, pollInterval)
|
doChangeNotify(ctx, f.receiveChangeNotify, pollInterval)
|
||||||
}
|
}
|
||||||
|
|
||||||
f.features = (&fs.Features{
|
f.features = (&fs.Features{
|
||||||
|
|
2
backend/cache/cache_internal_test.go
vendored
2
backend/cache/cache_internal_test.go
vendored
|
@ -932,7 +932,7 @@ func (r *run) newCacheFs(t *testing.T, remote, id string, needRemote, purge bool
|
||||||
boltDb.PurgeTempUploads()
|
boltDb.PurgeTempUploads()
|
||||||
_ = os.RemoveAll(path.Join(runInstance.tmpUploadDir, id))
|
_ = os.RemoveAll(path.Join(runInstance.tmpUploadDir, id))
|
||||||
}
|
}
|
||||||
f, err := cache.NewFs(remote, id, m)
|
f, err := cache.NewFs(context.Background(), remote, id, m)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
cfs, err := r.getCacheFs(f)
|
cfs, err := r.getCacheFs(f)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
|
@ -223,7 +223,7 @@ It has the following fields: ver, size, nchunks, md5, sha1.`,
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewFs constructs an Fs from the path, container:path
|
// NewFs constructs an Fs from the path, container:path
|
||||||
func NewFs(name, rpath string, m configmap.Mapper) (fs.Fs, error) {
|
func NewFs(ctx context.Context, name, rpath string, m configmap.Mapper) (fs.Fs, error) {
|
||||||
// Parse config into Options struct
|
// Parse config into Options struct
|
||||||
opt := new(Options)
|
opt := new(Options)
|
||||||
err := configstruct.Set(m, opt)
|
err := configstruct.Set(m, opt)
|
||||||
|
@ -248,7 +248,7 @@ func NewFs(name, rpath string, m configmap.Mapper) (fs.Fs, error) {
|
||||||
}
|
}
|
||||||
// Look for a file first
|
// Look for a file first
|
||||||
remotePath := fspath.JoinRootPath(basePath, rpath)
|
remotePath := fspath.JoinRootPath(basePath, rpath)
|
||||||
baseFs, err := cache.Get(baseName + remotePath)
|
baseFs, err := cache.Get(ctx, baseName+remotePath)
|
||||||
if err != fs.ErrorIsFile && err != nil {
|
if err != fs.ErrorIsFile && err != nil {
|
||||||
return nil, errors.Wrapf(err, "failed to make remote %q to wrap", baseName+remotePath)
|
return nil, errors.Wrapf(err, "failed to make remote %q to wrap", baseName+remotePath)
|
||||||
}
|
}
|
||||||
|
@ -276,7 +276,7 @@ func NewFs(name, rpath string, m configmap.Mapper) (fs.Fs, error) {
|
||||||
// (yet can't satisfy fstest.CheckListing, will ignore)
|
// (yet can't satisfy fstest.CheckListing, will ignore)
|
||||||
if err == nil && !f.useMeta && strings.Contains(rpath, "/") {
|
if err == nil && !f.useMeta && strings.Contains(rpath, "/") {
|
||||||
firstChunkPath := f.makeChunkName(remotePath, 0, "", "")
|
firstChunkPath := f.makeChunkName(remotePath, 0, "", "")
|
||||||
_, testErr := cache.Get(baseName + firstChunkPath)
|
_, testErr := cache.Get(ctx, baseName+firstChunkPath)
|
||||||
if testErr == fs.ErrorIsFile {
|
if testErr == fs.ErrorIsFile {
|
||||||
err = testErr
|
err = testErr
|
||||||
}
|
}
|
||||||
|
|
|
@ -144,7 +144,7 @@ func NewCipher(m configmap.Mapper) (*Cipher, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewFs constructs an Fs from the path, container:path
|
// NewFs constructs an Fs from the path, container:path
|
||||||
func NewFs(name, rpath string, m configmap.Mapper) (fs.Fs, error) {
|
func NewFs(ctx context.Context, name, rpath string, m configmap.Mapper) (fs.Fs, error) {
|
||||||
// Parse config into Options struct
|
// Parse config into Options struct
|
||||||
opt := new(Options)
|
opt := new(Options)
|
||||||
err := configstruct.Set(m, opt)
|
err := configstruct.Set(m, opt)
|
||||||
|
@ -166,14 +166,14 @@ func NewFs(name, rpath string, m configmap.Mapper) (fs.Fs, error) {
|
||||||
// Look for a file first
|
// Look for a file first
|
||||||
var wrappedFs fs.Fs
|
var wrappedFs fs.Fs
|
||||||
if rpath == "" {
|
if rpath == "" {
|
||||||
wrappedFs, err = cache.Get(remote)
|
wrappedFs, err = cache.Get(ctx, remote)
|
||||||
} else {
|
} else {
|
||||||
remotePath := fspath.JoinRootPath(remote, cipher.EncryptFileName(rpath))
|
remotePath := fspath.JoinRootPath(remote, cipher.EncryptFileName(rpath))
|
||||||
wrappedFs, err = cache.Get(remotePath)
|
wrappedFs, err = cache.Get(ctx, remotePath)
|
||||||
// if that didn't produce a file, look for a directory
|
// if that didn't produce a file, look for a directory
|
||||||
if err != fs.ErrorIsFile {
|
if err != fs.ErrorIsFile {
|
||||||
remotePath = fspath.JoinRootPath(remote, cipher.EncryptDirName(rpath))
|
remotePath = fspath.JoinRootPath(remote, cipher.EncryptDirName(rpath))
|
||||||
wrappedFs, err = cache.Get(remotePath)
|
wrappedFs, err = cache.Get(ctx, remotePath)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if err != fs.ErrorIsFile && err != nil {
|
if err != fs.ErrorIsFile && err != nil {
|
||||||
|
|
|
@ -33,7 +33,7 @@ func (o testWrapper) UnWrap() fs.Object {
|
||||||
// Create a temporary local fs to upload things from
|
// Create a temporary local fs to upload things from
|
||||||
|
|
||||||
func makeTempLocalFs(t *testing.T) (localFs fs.Fs, cleanup func()) {
|
func makeTempLocalFs(t *testing.T) (localFs fs.Fs, cleanup func()) {
|
||||||
localFs, err := fs.TemporaryLocalFs()
|
localFs, err := fs.TemporaryLocalFs(context.Background())
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
cleanup = func() {
|
cleanup = func() {
|
||||||
require.NoError(t, localFs.Rmdir(context.Background(), ""))
|
require.NoError(t, localFs.Rmdir(context.Background(), ""))
|
||||||
|
|
|
@ -1129,8 +1129,7 @@ func newFs(name, path string, m configmap.Mapper) (*Fs, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewFs constructs an Fs from the path, container:path
|
// NewFs constructs an Fs from the path, container:path
|
||||||
func NewFs(name, path string, m configmap.Mapper) (fs.Fs, error) {
|
func NewFs(ctx context.Context, name, path string, m configmap.Mapper) (fs.Fs, error) {
|
||||||
ctx := context.Background()
|
|
||||||
f, err := newFs(name, path, m)
|
f, err := newFs(name, path, m)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
@ -3000,7 +2999,7 @@ func (f *Fs) copyID(ctx context.Context, id, dest string) (err error) {
|
||||||
if destLeaf == "" {
|
if destLeaf == "" {
|
||||||
destLeaf = info.Name
|
destLeaf = info.Name
|
||||||
}
|
}
|
||||||
dstFs, err := cache.Get(destDir)
|
dstFs, err := cache.Get(ctx, destDir)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -3187,7 +3186,7 @@ func (f *Fs) Command(ctx context.Context, name string, arg []string, opt map[str
|
||||||
dstFs := f
|
dstFs := f
|
||||||
target, ok := opt["target"]
|
target, ok := opt["target"]
|
||||||
if ok {
|
if ok {
|
||||||
targetFs, err := cache.Get(target)
|
targetFs, err := cache.Get(ctx, target)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errors.Wrap(err, "couldn't find target")
|
return nil, errors.Wrap(err, "couldn't find target")
|
||||||
}
|
}
|
||||||
|
|
|
@ -196,7 +196,7 @@ func (f *Fs) InternalTestDocumentImport(t *testing.T) {
|
||||||
testFilesPath, err := filepath.Abs(filepath.FromSlash("test/files"))
|
testFilesPath, err := filepath.Abs(filepath.FromSlash("test/files"))
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
testFilesFs, err := fs.NewFs(testFilesPath)
|
testFilesFs, err := fs.NewFs(context.Background(), testFilesPath)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
_, f.importMimeTypes, err = parseExtensions("odt,ods,doc")
|
_, f.importMimeTypes, err = parseExtensions("odt,ods,doc")
|
||||||
|
@ -210,7 +210,7 @@ func (f *Fs) InternalTestDocumentUpdate(t *testing.T) {
|
||||||
testFilesPath, err := filepath.Abs(filepath.FromSlash("test/files"))
|
testFilesPath, err := filepath.Abs(filepath.FromSlash("test/files"))
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
testFilesFs, err := fs.NewFs(testFilesPath)
|
testFilesFs, err := fs.NewFs(context.Background(), testFilesPath)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
_, f.importMimeTypes, err = parseExtensions("odt,ods,doc")
|
_, f.importMimeTypes, err = parseExtensions("odt,ods,doc")
|
||||||
|
|
|
@ -291,7 +291,7 @@ func (f *Fs) setUploadChunkSize(cs fs.SizeSuffix) (old fs.SizeSuffix, err error)
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewFs constructs an Fs from the path, container:path
|
// NewFs constructs an Fs from the path, container:path
|
||||||
func NewFs(name, root string, m configmap.Mapper) (fs.Fs, error) {
|
func NewFs(ctx context.Context, name, root string, m configmap.Mapper) (fs.Fs, error) {
|
||||||
// Parse config into Options struct
|
// Parse config into Options struct
|
||||||
opt := new(Options)
|
opt := new(Options)
|
||||||
err := configstruct.Set(m, opt)
|
err := configstruct.Set(m, opt)
|
||||||
|
|
|
@ -167,7 +167,7 @@ func (f *Fs) Features() *fs.Features {
|
||||||
//
|
//
|
||||||
// On Windows avoid single character remote names as they can be mixed
|
// On Windows avoid single character remote names as they can be mixed
|
||||||
// up with drive letters.
|
// up with drive letters.
|
||||||
func NewFs(name string, root string, config configmap.Mapper) (fs.Fs, error) {
|
func NewFs(ctx context.Context, name string, root string, config configmap.Mapper) (fs.Fs, error) {
|
||||||
opt := new(Options)
|
opt := new(Options)
|
||||||
err := configstruct.Set(config, opt)
|
err := configstruct.Set(config, opt)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -203,8 +203,6 @@ func NewFs(name string, root string, config configmap.Mapper) (fs.Fs, error) {
|
||||||
|
|
||||||
f.dirCache = dircache.New(root, rootID, f)
|
f.dirCache = dircache.New(root, rootID, f)
|
||||||
|
|
||||||
ctx := context.Background()
|
|
||||||
|
|
||||||
// Find the current root
|
// Find the current root
|
||||||
err = f.dirCache.FindRoot(ctx, false)
|
err = f.dirCache.FindRoot(ctx, false)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -300,8 +300,7 @@ func (f *Fs) putFtpConnection(pc **ftp.ServerConn, err error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewFs constructs an Fs from the path, container:path
|
// NewFs constructs an Fs from the path, container:path
|
||||||
func NewFs(name, root string, m configmap.Mapper) (ff fs.Fs, err error) {
|
func NewFs(ctx context.Context, name, root string, m configmap.Mapper) (ff fs.Fs, err error) {
|
||||||
ctx := context.Background()
|
|
||||||
// defer fs.Trace(nil, "name=%q, root=%q", name, root)("fs=%v, err=%v", &ff, &err)
|
// defer fs.Trace(nil, "name=%q, root=%q", name, root)("fs=%v, err=%v", &ff, &err)
|
||||||
// Parse config into Options struct
|
// Parse config into Options struct
|
||||||
opt := new(Options)
|
opt := new(Options)
|
||||||
|
|
|
@ -386,8 +386,7 @@ func (f *Fs) setRoot(root string) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewFs constructs an Fs from the path, bucket:path
|
// NewFs constructs an Fs from the path, bucket:path
|
||||||
func NewFs(name, root string, m configmap.Mapper) (fs.Fs, error) {
|
func NewFs(ctx context.Context, name, root string, m configmap.Mapper) (fs.Fs, error) {
|
||||||
ctx := context.TODO()
|
|
||||||
var oAuthClient *http.Client
|
var oAuthClient *http.Client
|
||||||
|
|
||||||
// Parse config into Options struct
|
// Parse config into Options struct
|
||||||
|
|
|
@ -246,7 +246,7 @@ func errorHandler(resp *http.Response) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewFs constructs an Fs from the path, bucket:path
|
// NewFs constructs an Fs from the path, bucket:path
|
||||||
func NewFs(name, root string, m configmap.Mapper) (fs.Fs, error) {
|
func NewFs(ctx context.Context, name, root string, m configmap.Mapper) (fs.Fs, error) {
|
||||||
// Parse config into Options struct
|
// Parse config into Options struct
|
||||||
opt := new(Options)
|
opt := new(Options)
|
||||||
err := configstruct.Set(m, opt)
|
err := configstruct.Set(m, opt)
|
||||||
|
@ -288,7 +288,7 @@ func NewFs(name, root string, m configmap.Mapper) (fs.Fs, error) {
|
||||||
var leaf string
|
var leaf string
|
||||||
f.root, leaf = path.Split(f.root)
|
f.root, leaf = path.Split(f.root)
|
||||||
f.root = strings.TrimRight(f.root, "/")
|
f.root = strings.TrimRight(f.root, "/")
|
||||||
_, err := f.NewObject(context.TODO(), leaf)
|
_, err := f.NewObject(ctx, leaf)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
return f, fs.ErrorIsFile
|
return f, fs.ErrorIsFile
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,14 +35,14 @@ func TestIntegration(t *testing.T) {
|
||||||
if *fstest.RemoteName == "" {
|
if *fstest.RemoteName == "" {
|
||||||
*fstest.RemoteName = "TestGooglePhotos:"
|
*fstest.RemoteName = "TestGooglePhotos:"
|
||||||
}
|
}
|
||||||
f, err := fs.NewFs(*fstest.RemoteName)
|
f, err := fs.NewFs(ctx, *fstest.RemoteName)
|
||||||
if err == fs.ErrorNotFoundInConfigFile {
|
if err == fs.ErrorNotFoundInConfigFile {
|
||||||
t.Skip(fmt.Sprintf("Couldn't create google photos backend - skipping tests: %v", err))
|
t.Skip(fmt.Sprintf("Couldn't create google photos backend - skipping tests: %v", err))
|
||||||
}
|
}
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
// Create local Fs pointing at testfiles
|
// Create local Fs pointing at testfiles
|
||||||
localFs, err := fs.NewFs("testfiles")
|
localFs, err := fs.NewFs(ctx, "testfiles")
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
t.Run("CreateAlbum", func(t *testing.T) {
|
t.Run("CreateAlbum", func(t *testing.T) {
|
||||||
|
@ -155,7 +155,7 @@ func TestIntegration(t *testing.T) {
|
||||||
})
|
})
|
||||||
|
|
||||||
t.Run("NewFsIsFile", func(t *testing.T) {
|
t.Run("NewFsIsFile", func(t *testing.T) {
|
||||||
fNew, err := fs.NewFs(*fstest.RemoteName + remote)
|
fNew, err := fs.NewFs(ctx, *fstest.RemoteName+remote)
|
||||||
assert.Equal(t, fs.ErrorIsFile, err)
|
assert.Equal(t, fs.ErrorIsFile, err)
|
||||||
leaf := path.Base(remote)
|
leaf := path.Base(remote)
|
||||||
o, err := fNew.NewObject(ctx, leaf)
|
o, err := fNew.NewObject(ctx, leaf)
|
||||||
|
|
|
@ -145,8 +145,7 @@ func statusError(res *http.Response, err error) error {
|
||||||
|
|
||||||
// NewFs creates a new Fs object from the name and root. It connects to
|
// NewFs creates a new Fs object from the name and root. It connects to
|
||||||
// the host specified in the config file.
|
// the host specified in the config file.
|
||||||
func NewFs(name, root string, m configmap.Mapper) (fs.Fs, error) {
|
func NewFs(ctx context.Context, name, root string, m configmap.Mapper) (fs.Fs, error) {
|
||||||
ctx := context.TODO()
|
|
||||||
// Parse config into Options struct
|
// Parse config into Options struct
|
||||||
opt := new(Options)
|
opt := new(Options)
|
||||||
err := configstruct.Set(m, opt)
|
err := configstruct.Set(m, opt)
|
||||||
|
|
|
@ -69,7 +69,7 @@ func prepare(t *testing.T) (fs.Fs, func()) {
|
||||||
m, tidy := prepareServer(t)
|
m, tidy := prepareServer(t)
|
||||||
|
|
||||||
// Instantiate it
|
// Instantiate it
|
||||||
f, err := NewFs(remoteName, "", m)
|
f, err := NewFs(context.Background(), remoteName, "", m)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
return f, tidy
|
return f, tidy
|
||||||
|
@ -214,7 +214,7 @@ func TestIsAFileRoot(t *testing.T) {
|
||||||
m, tidy := prepareServer(t)
|
m, tidy := prepareServer(t)
|
||||||
defer tidy()
|
defer tidy()
|
||||||
|
|
||||||
f, err := NewFs(remoteName, "one%.txt", m)
|
f, err := NewFs(context.Background(), remoteName, "one%.txt", m)
|
||||||
assert.Equal(t, err, fs.ErrorIsFile)
|
assert.Equal(t, err, fs.ErrorIsFile)
|
||||||
|
|
||||||
testListRoot(t, f, false)
|
testListRoot(t, f, false)
|
||||||
|
@ -224,7 +224,7 @@ func TestIsAFileSubDir(t *testing.T) {
|
||||||
m, tidy := prepareServer(t)
|
m, tidy := prepareServer(t)
|
||||||
defer tidy()
|
defer tidy()
|
||||||
|
|
||||||
f, err := NewFs(remoteName, "three/underthree.txt", m)
|
f, err := NewFs(context.Background(), remoteName, "three/underthree.txt", m)
|
||||||
assert.Equal(t, err, fs.ErrorIsFile)
|
assert.Equal(t, err, fs.ErrorIsFile)
|
||||||
|
|
||||||
entries, err := f.List(context.Background(), "")
|
entries, err := f.List(context.Background(), "")
|
||||||
|
|
|
@ -146,7 +146,7 @@ func (f *Fs) getCredentials(ctx context.Context) (err error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewFs constructs an Fs from the path, container:path
|
// NewFs constructs an Fs from the path, container:path
|
||||||
func NewFs(name, root string, m configmap.Mapper) (fs.Fs, error) {
|
func NewFs(ctx context.Context, name, root string, m configmap.Mapper) (fs.Fs, error) {
|
||||||
client, _, err := oauthutil.NewClient(name, m, oauthConfig)
|
client, _, err := oauthutil.NewClient(name, m, oauthConfig)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errors.Wrap(err, "failed to configure Hubic")
|
return nil, errors.Wrap(err, "failed to configure Hubic")
|
||||||
|
@ -176,7 +176,7 @@ func NewFs(name, root string, m configmap.Mapper) (fs.Fs, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Make inner swift Fs from the connection
|
// Make inner swift Fs from the connection
|
||||||
swiftFs, err := swift.NewFsWithConnection(opt, name, root, c, true)
|
swiftFs, err := swift.NewFsWithConnection(ctx, opt, name, root, c, true)
|
||||||
if err != nil && err != fs.ErrorIsFile {
|
if err != nil && err != fs.ErrorIsFile {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
|
@ -641,8 +641,7 @@ func grantTypeFilter(req *http.Request) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewFs constructs an Fs from the path, container:path
|
// NewFs constructs an Fs from the path, container:path
|
||||||
func NewFs(name, root string, m configmap.Mapper) (fs.Fs, error) {
|
func NewFs(ctx context.Context, name, root string, m configmap.Mapper) (fs.Fs, error) {
|
||||||
ctx := context.TODO()
|
|
||||||
// Parse config into Options struct
|
// Parse config into Options struct
|
||||||
opt := new(Options)
|
opt := new(Options)
|
||||||
err := configstruct.Set(m, opt)
|
err := configstruct.Set(m, opt)
|
||||||
|
|
|
@ -256,7 +256,7 @@ func (f *Fs) fullPath(part string) string {
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewFs constructs a new filesystem given a root path and configuration options
|
// NewFs constructs a new filesystem given a root path and configuration options
|
||||||
func NewFs(name, root string, m configmap.Mapper) (ff fs.Fs, err error) {
|
func NewFs(ctx context.Context, name, root string, m configmap.Mapper) (ff fs.Fs, err error) {
|
||||||
opt := new(Options)
|
opt := new(Options)
|
||||||
err = configstruct.Set(m, opt)
|
err = configstruct.Set(m, opt)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -217,7 +217,7 @@ type Object struct {
|
||||||
var errLinksAndCopyLinks = errors.New("can't use -l/--links with -L/--copy-links")
|
var errLinksAndCopyLinks = errors.New("can't use -l/--links with -L/--copy-links")
|
||||||
|
|
||||||
// NewFs constructs an Fs from the path
|
// NewFs constructs an Fs from the path
|
||||||
func NewFs(name, root string, m configmap.Mapper) (fs.Fs, error) {
|
func NewFs(ctx context.Context, name, root string, m configmap.Mapper) (fs.Fs, error) {
|
||||||
// Parse config into Options struct
|
// Parse config into Options struct
|
||||||
opt := new(Options)
|
opt := new(Options)
|
||||||
err := configstruct.Set(m, opt)
|
err := configstruct.Set(m, opt)
|
||||||
|
|
|
@ -163,6 +163,6 @@ func TestSymlinkError(t *testing.T) {
|
||||||
"links": "true",
|
"links": "true",
|
||||||
"copy_links": "true",
|
"copy_links": "true",
|
||||||
}
|
}
|
||||||
_, err := NewFs("local", "/", m)
|
_, err := NewFs(context.Background(), "local", "/", m)
|
||||||
assert.Equal(t, errLinksAndCopyLinks, err)
|
assert.Equal(t, errLinksAndCopyLinks, err)
|
||||||
}
|
}
|
||||||
|
|
|
@ -294,9 +294,8 @@ type Fs struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewFs constructs an Fs from the path, container:path
|
// NewFs constructs an Fs from the path, container:path
|
||||||
func NewFs(name, root string, m configmap.Mapper) (fs.Fs, error) {
|
func NewFs(ctx context.Context, name, root string, m configmap.Mapper) (fs.Fs, error) {
|
||||||
// fs.Debugf(nil, ">>> NewFs %q %q", name, root)
|
// fs.Debugf(nil, ">>> NewFs %q %q", name, root)
|
||||||
ctx := context.Background() // Note: NewFs does not pass context!
|
|
||||||
|
|
||||||
// Parse config into Options struct
|
// Parse config into Options struct
|
||||||
opt := new(Options)
|
opt := new(Options)
|
||||||
|
@ -1662,7 +1661,7 @@ func (o *Object) Update(ctx context.Context, in io.Reader, src fs.ObjectInfo, op
|
||||||
|
|
||||||
// Attempt to put by hash using a spool file
|
// Attempt to put by hash using a spool file
|
||||||
if trySpeedup {
|
if trySpeedup {
|
||||||
tmpFs, err := fs.TemporaryLocalFs()
|
tmpFs, err := fs.TemporaryLocalFs(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fs.Infof(tmpFs, "Failed to create spool FS: %v", err)
|
fs.Infof(tmpFs, "Failed to create spool FS: %v", err)
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -180,7 +180,7 @@ func (f *Fs) readMetaDataForPath(remote string) (info *mega.Node, err error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewFs constructs an Fs from the path, container:path
|
// NewFs constructs an Fs from the path, container:path
|
||||||
func NewFs(name, root string, m configmap.Mapper) (fs.Fs, error) {
|
func NewFs(ctx context.Context, name, root string, m configmap.Mapper) (fs.Fs, error) {
|
||||||
// Parse config into Options struct
|
// Parse config into Options struct
|
||||||
opt := new(Options)
|
opt := new(Options)
|
||||||
err := configstruct.Set(m, opt)
|
err := configstruct.Set(m, opt)
|
||||||
|
|
|
@ -222,7 +222,7 @@ func (f *Fs) setRoot(root string) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewFs constructs an Fs from the path, bucket:path
|
// NewFs constructs an Fs from the path, bucket:path
|
||||||
func NewFs(name, root string, m configmap.Mapper) (fs.Fs, error) {
|
func NewFs(ctx context.Context, name, root string, m configmap.Mapper) (fs.Fs, error) {
|
||||||
// Parse config into Options struct
|
// Parse config into Options struct
|
||||||
opt := new(Options)
|
opt := new(Options)
|
||||||
err := configstruct.Set(m, opt)
|
err := configstruct.Set(m, opt)
|
||||||
|
|
|
@ -596,8 +596,7 @@ func (f *Fs) setUploadChunkSize(cs fs.SizeSuffix) (old fs.SizeSuffix, err error)
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewFs constructs an Fs from the path, container:path
|
// NewFs constructs an Fs from the path, container:path
|
||||||
func NewFs(name, root string, m configmap.Mapper) (fs.Fs, error) {
|
func NewFs(ctx context.Context, name, root string, m configmap.Mapper) (fs.Fs, error) {
|
||||||
ctx := context.Background()
|
|
||||||
// Parse config into Options struct
|
// Parse config into Options struct
|
||||||
opt := new(Options)
|
opt := new(Options)
|
||||||
err := configstruct.Set(m, opt)
|
err := configstruct.Set(m, opt)
|
||||||
|
|
|
@ -164,8 +164,7 @@ func (f *Fs) DirCacheFlush() {
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewFs constructs an Fs from the path, bucket:path
|
// NewFs constructs an Fs from the path, bucket:path
|
||||||
func NewFs(name, root string, m configmap.Mapper) (fs.Fs, error) {
|
func NewFs(ctx context.Context, name, root string, m configmap.Mapper) (fs.Fs, error) {
|
||||||
ctx := context.Background()
|
|
||||||
// Parse config into Options struct
|
// Parse config into Options struct
|
||||||
opt := new(Options)
|
opt := new(Options)
|
||||||
err := configstruct.Set(m, opt)
|
err := configstruct.Set(m, opt)
|
||||||
|
|
|
@ -280,8 +280,7 @@ func errorHandler(resp *http.Response) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewFs constructs an Fs from the path, container:path
|
// NewFs constructs an Fs from the path, container:path
|
||||||
func NewFs(name, root string, m configmap.Mapper) (fs.Fs, error) {
|
func NewFs(ctx context.Context, name, root string, m configmap.Mapper) (fs.Fs, error) {
|
||||||
ctx := context.Background()
|
|
||||||
// Parse config into Options struct
|
// Parse config into Options struct
|
||||||
opt := new(Options)
|
opt := new(Options)
|
||||||
err := configstruct.Set(m, opt)
|
err := configstruct.Set(m, opt)
|
||||||
|
|
|
@ -234,8 +234,7 @@ func (f *Fs) baseParams() url.Values {
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewFs constructs an Fs from the path, container:path
|
// NewFs constructs an Fs from the path, container:path
|
||||||
func NewFs(name, root string, m configmap.Mapper) (fs.Fs, error) {
|
func NewFs(ctx context.Context, name, root string, m configmap.Mapper) (fs.Fs, error) {
|
||||||
ctx := context.Background()
|
|
||||||
// Parse config into Options struct
|
// Parse config into Options struct
|
||||||
opt := new(Options)
|
opt := new(Options)
|
||||||
err := configstruct.Set(m, opt)
|
err := configstruct.Set(m, opt)
|
||||||
|
|
|
@ -68,7 +68,7 @@ func parsePath(path string) (root string) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewFs constructs an Fs from the path, container:path
|
// NewFs constructs an Fs from the path, container:path
|
||||||
func NewFs(name, root string, m configmap.Mapper) (f fs.Fs, err error) {
|
func NewFs(ctx context.Context, name, root string, m configmap.Mapper) (f fs.Fs, err error) {
|
||||||
// defer log.Trace(name, "root=%v", root)("f=%+v, err=%v", &f, &err)
|
// defer log.Trace(name, "root=%v", root)("f=%+v, err=%v", &f, &err)
|
||||||
// Parse config into Options struct
|
// Parse config into Options struct
|
||||||
opt := new(Options)
|
opt := new(Options)
|
||||||
|
@ -97,7 +97,6 @@ func NewFs(name, root string, m configmap.Mapper) (f fs.Fs, err error) {
|
||||||
CanHaveEmptyDirectories: true,
|
CanHaveEmptyDirectories: true,
|
||||||
}).Fill(p)
|
}).Fill(p)
|
||||||
p.dirCache = dircache.New(root, "0", p)
|
p.dirCache = dircache.New(root, "0", p)
|
||||||
ctx := context.Background()
|
|
||||||
// Find the current root
|
// Find the current root
|
||||||
err = p.dirCache.FindRoot(ctx, false)
|
err = p.dirCache.FindRoot(ctx, false)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -319,7 +319,7 @@ func (f *Fs) setRoot(root string) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewFs constructs an Fs from the path, bucket:path
|
// NewFs constructs an Fs from the path, bucket:path
|
||||||
func NewFs(name, root string, m configmap.Mapper) (fs.Fs, error) {
|
func NewFs(ctx context.Context, name, root string, m configmap.Mapper) (fs.Fs, error) {
|
||||||
// Parse config into Options struct
|
// Parse config into Options struct
|
||||||
opt := new(Options)
|
opt := new(Options)
|
||||||
err := configstruct.Set(m, opt)
|
err := configstruct.Set(m, opt)
|
||||||
|
|
|
@ -1569,7 +1569,7 @@ func (f *Fs) setRoot(root string) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewFs constructs an Fs from the path, bucket:path
|
// NewFs constructs an Fs from the path, bucket:path
|
||||||
func NewFs(name, root string, m configmap.Mapper) (fs.Fs, error) {
|
func NewFs(ctx context.Context, name, root string, m configmap.Mapper) (fs.Fs, error) {
|
||||||
// Parse config into Options struct
|
// Parse config into Options struct
|
||||||
opt := new(Options)
|
opt := new(Options)
|
||||||
err := configstruct.Set(m, opt)
|
err := configstruct.Set(m, opt)
|
||||||
|
|
|
@ -147,7 +147,7 @@ type Fs struct {
|
||||||
// ------------------------------------------------------------
|
// ------------------------------------------------------------
|
||||||
|
|
||||||
// NewFs constructs an Fs from the path, container:path
|
// NewFs constructs an Fs from the path, container:path
|
||||||
func NewFs(name, root string, m configmap.Mapper) (fs.Fs, error) {
|
func NewFs(ctx context.Context, name, root string, m configmap.Mapper) (fs.Fs, error) {
|
||||||
// Parse config into Options struct
|
// Parse config into Options struct
|
||||||
opt := new(Options)
|
opt := new(Options)
|
||||||
err := configstruct.Set(m, opt)
|
err := configstruct.Set(m, opt)
|
||||||
|
@ -205,7 +205,6 @@ func NewFs(name, root string, m configmap.Mapper) (fs.Fs, error) {
|
||||||
BucketBased: opt.LibraryName == "",
|
BucketBased: opt.LibraryName == "",
|
||||||
}).Fill(f)
|
}).Fill(f)
|
||||||
|
|
||||||
ctx := context.Background()
|
|
||||||
serverInfo, err := f.getServerInfo(ctx)
|
serverInfo, err := f.getServerInfo(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
|
|
@ -413,12 +413,11 @@ func (f *Fs) putSftpConnection(pc **conn, err error) {
|
||||||
|
|
||||||
// NewFs creates a new Fs object from the name and root. It connects to
|
// NewFs creates a new Fs object from the name and root. It connects to
|
||||||
// the host specified in the config file.
|
// the host specified in the config file.
|
||||||
func NewFs(name, root string, m configmap.Mapper) (fs.Fs, error) {
|
func NewFs(ctx context.Context, name, root string, m configmap.Mapper) (fs.Fs, error) {
|
||||||
// This will hold the Fs object. We need to create it here
|
// This will hold the Fs object. We need to create it here
|
||||||
// so we can refer to it in the SSH callback, but it's populated
|
// so we can refer to it in the SSH callback, but it's populated
|
||||||
// in NewFsWithConnection
|
// in NewFsWithConnection
|
||||||
f := &Fs{}
|
f := &Fs{}
|
||||||
ctx := context.Background()
|
|
||||||
// Parse config into Options struct
|
// Parse config into Options struct
|
||||||
opt := new(Options)
|
opt := new(Options)
|
||||||
err := configstruct.Set(m, opt)
|
err := configstruct.Set(m, opt)
|
||||||
|
|
|
@ -410,8 +410,7 @@ func (f *Fs) setUploadCutoff(cs fs.SizeSuffix) (old fs.SizeSuffix, err error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewFs constructs an Fs from the path, container:path
|
// NewFs constructs an Fs from the path, container:path
|
||||||
func NewFs(name, root string, m configmap.Mapper) (fs.Fs, error) {
|
func NewFs(ctx context.Context, name, root string, m configmap.Mapper) (fs.Fs, error) {
|
||||||
ctx := context.Background()
|
|
||||||
// Parse config into Options struct
|
// Parse config into Options struct
|
||||||
opt := new(Options)
|
opt := new(Options)
|
||||||
err := configstruct.Set(m, opt)
|
err := configstruct.Set(m, opt)
|
||||||
|
|
|
@ -395,9 +395,7 @@ func parseExpiry(expiryString string) time.Time {
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewFs constructs an Fs from the path, container:path
|
// NewFs constructs an Fs from the path, container:path
|
||||||
func NewFs(name, root string, m configmap.Mapper) (fs.Fs, error) {
|
func NewFs(ctx context.Context, name, root string, m configmap.Mapper) (fs.Fs, error) {
|
||||||
ctx := context.Background()
|
|
||||||
|
|
||||||
opt := new(Options)
|
opt := new(Options)
|
||||||
err := configstruct.Set(m, opt)
|
err := configstruct.Set(m, opt)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -432,7 +432,7 @@ func (f *Fs) setRoot(root string) {
|
||||||
//
|
//
|
||||||
// if noCheckContainer is set then the Fs won't check the container
|
// if noCheckContainer is set then the Fs won't check the container
|
||||||
// exists before creating it.
|
// exists before creating it.
|
||||||
func NewFsWithConnection(opt *Options, name, root string, c *swift.Connection, noCheckContainer bool) (fs.Fs, error) {
|
func NewFsWithConnection(ctx context.Context, opt *Options, name, root string, c *swift.Connection, noCheckContainer bool) (fs.Fs, error) {
|
||||||
f := &Fs{
|
f := &Fs{
|
||||||
name: name,
|
name: name,
|
||||||
opt: *opt,
|
opt: *opt,
|
||||||
|
@ -473,7 +473,7 @@ func NewFsWithConnection(opt *Options, name, root string, c *swift.Connection, n
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewFs constructs an Fs from the path, container:path
|
// NewFs constructs an Fs from the path, container:path
|
||||||
func NewFs(name, root string, m configmap.Mapper) (fs.Fs, error) {
|
func NewFs(ctx context.Context, name, root string, m configmap.Mapper) (fs.Fs, error) {
|
||||||
// Parse config into Options struct
|
// Parse config into Options struct
|
||||||
opt := new(Options)
|
opt := new(Options)
|
||||||
err := configstruct.Set(m, opt)
|
err := configstruct.Set(m, opt)
|
||||||
|
@ -489,7 +489,7 @@ func NewFs(name, root string, m configmap.Mapper) (fs.Fs, error) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return NewFsWithConnection(opt, name, root, c, false)
|
return NewFsWithConnection(ctx, opt, name, root, c, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Return an Object from a path
|
// Return an Object from a path
|
||||||
|
|
|
@ -165,9 +165,7 @@ var (
|
||||||
)
|
)
|
||||||
|
|
||||||
// NewFs creates a filesystem backed by Tardigrade.
|
// NewFs creates a filesystem backed by Tardigrade.
|
||||||
func NewFs(name, root string, m configmap.Mapper) (_ fs.Fs, err error) {
|
func NewFs(ctx context.Context, name, root string, m configmap.Mapper) (_ fs.Fs, err error) {
|
||||||
ctx := context.Background()
|
|
||||||
|
|
||||||
// Setup filesystem and connection to Tardigrade
|
// Setup filesystem and connection to Tardigrade
|
||||||
root = norm.NFC.String(root)
|
root = norm.NFC.String(root)
|
||||||
root = strings.Trim(root, "/")
|
root = strings.Trim(root, "/")
|
||||||
|
|
|
@ -757,7 +757,7 @@ func (f *Fs) mergeDirEntries(entriesList [][]upstream.Entry) (fs.DirEntries, err
|
||||||
// NewFs constructs an Fs from the path.
|
// NewFs constructs an Fs from the path.
|
||||||
//
|
//
|
||||||
// The returned Fs is the actual Fs, referenced by remote in the config
|
// The returned Fs is the actual Fs, referenced by remote in the config
|
||||||
func NewFs(name, root string, m configmap.Mapper) (fs.Fs, error) {
|
func NewFs(ctx context.Context, name, root string, m configmap.Mapper) (fs.Fs, error) {
|
||||||
// Parse config into Options struct
|
// Parse config into Options struct
|
||||||
opt := new(Options)
|
opt := new(Options)
|
||||||
err := configstruct.Set(m, opt)
|
err := configstruct.Set(m, opt)
|
||||||
|
@ -787,7 +787,7 @@ func NewFs(name, root string, m configmap.Mapper) (fs.Fs, error) {
|
||||||
errs := Errors(make([]error, len(opt.Upstreams)))
|
errs := Errors(make([]error, len(opt.Upstreams)))
|
||||||
multithread(len(opt.Upstreams), func(i int) {
|
multithread(len(opt.Upstreams), func(i int) {
|
||||||
u := opt.Upstreams[i]
|
u := opt.Upstreams[i]
|
||||||
upstreams[i], errs[i] = upstream.New(u, root, time.Duration(opt.CacheTime)*time.Second)
|
upstreams[i], errs[i] = upstream.New(ctx, u, root, time.Duration(opt.CacheTime)*time.Second)
|
||||||
})
|
})
|
||||||
var usedUpstreams []*upstream.Fs
|
var usedUpstreams []*upstream.Fs
|
||||||
var fserr error
|
var fserr error
|
||||||
|
|
|
@ -61,7 +61,7 @@ type Entry interface {
|
||||||
|
|
||||||
// New creates a new Fs based on the
|
// New creates a new Fs based on the
|
||||||
// string formatted `type:root_path(:ro/:nc)`
|
// string formatted `type:root_path(:ro/:nc)`
|
||||||
func New(remote, root string, cacheTime time.Duration) (*Fs, error) {
|
func New(ctx context.Context, remote, root string, cacheTime time.Duration) (*Fs, error) {
|
||||||
_, configName, fsPath, err := fs.ParseRemote(remote)
|
_, configName, fsPath, err := fs.ParseRemote(remote)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
@ -86,13 +86,13 @@ func New(remote, root string, cacheTime time.Duration) (*Fs, error) {
|
||||||
if configName != "local" {
|
if configName != "local" {
|
||||||
fsPath = configName + ":" + fsPath
|
fsPath = configName + ":" + fsPath
|
||||||
}
|
}
|
||||||
rFs, err := cache.Get(fsPath)
|
rFs, err := cache.Get(ctx, fsPath)
|
||||||
if err != nil && err != fs.ErrorIsFile {
|
if err != nil && err != fs.ErrorIsFile {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
f.RootFs = rFs
|
f.RootFs = rFs
|
||||||
rootString := path.Join(fsPath, filepath.ToSlash(root))
|
rootString := path.Join(fsPath, filepath.ToSlash(root))
|
||||||
myFs, err := cache.Get(rootString)
|
myFs, err := cache.Get(ctx, rootString)
|
||||||
if err != nil && err != fs.ErrorIsFile {
|
if err != nil && err != fs.ErrorIsFile {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
|
@ -299,8 +299,7 @@ func (o *Object) filePath() string {
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewFs constructs an Fs from the path, container:path
|
// NewFs constructs an Fs from the path, container:path
|
||||||
func NewFs(name, root string, m configmap.Mapper) (fs.Fs, error) {
|
func NewFs(ctx context.Context, name, root string, m configmap.Mapper) (fs.Fs, error) {
|
||||||
ctx := context.Background()
|
|
||||||
// Parse config into Options struct
|
// Parse config into Options struct
|
||||||
opt := new(Options)
|
opt := new(Options)
|
||||||
err := configstruct.Set(m, opt)
|
err := configstruct.Set(m, opt)
|
||||||
|
|
|
@ -237,8 +237,7 @@ func (f *Fs) readMetaDataForPath(ctx context.Context, path string, options *api.
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewFs constructs an Fs from the path, container:path
|
// NewFs constructs an Fs from the path, container:path
|
||||||
func NewFs(name, root string, m configmap.Mapper) (fs.Fs, error) {
|
func NewFs(ctx context.Context, name, root string, m configmap.Mapper) (fs.Fs, error) {
|
||||||
ctx := context.TODO()
|
|
||||||
// Parse config into Options struct
|
// Parse config into Options struct
|
||||||
opt := new(Options)
|
opt := new(Options)
|
||||||
err := configstruct.Set(m, opt)
|
err := configstruct.Set(m, opt)
|
||||||
|
|
|
@ -74,7 +74,7 @@ Note to run these commands on a running backend then see
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
f, err := fsInfo.NewFs(configName, fsPath, config)
|
f, err := fsInfo.NewFs(context.Background(), configName, fsPath, config)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,6 +7,7 @@ package cmd
|
||||||
// would probably mean bringing all the flags in to here? Or define some flagsets in fs...
|
// would probably mean bringing all the flags in to here? Or define some flagsets in fs...
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
"log"
|
"log"
|
||||||
"math/rand"
|
"math/rand"
|
||||||
|
@ -88,7 +89,7 @@ func NewFsFile(remote string) (fs.Fs, string) {
|
||||||
err = fs.CountError(err)
|
err = fs.CountError(err)
|
||||||
log.Fatalf("Failed to create file system for %q: %v", remote, err)
|
log.Fatalf("Failed to create file system for %q: %v", remote, err)
|
||||||
}
|
}
|
||||||
f, err := cache.Get(remote)
|
f, err := cache.Get(context.Background(), remote)
|
||||||
switch err {
|
switch err {
|
||||||
case fs.ErrorIsFile:
|
case fs.ErrorIsFile:
|
||||||
cache.Pin(f) // pin indefinitely since it was on the CLI
|
cache.Pin(f) // pin indefinitely since it was on the CLI
|
||||||
|
@ -138,7 +139,7 @@ func NewFsSrc(args []string) fs.Fs {
|
||||||
//
|
//
|
||||||
// This must point to a directory
|
// This must point to a directory
|
||||||
func newFsDir(remote string) fs.Fs {
|
func newFsDir(remote string) fs.Fs {
|
||||||
f, err := cache.Get(remote)
|
f, err := cache.Get(context.Background(), remote)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
err = fs.CountError(err)
|
err = fs.CountError(err)
|
||||||
log.Fatalf("Failed to create file system for %q: %v", remote, err)
|
log.Fatalf("Failed to create file system for %q: %v", remote, err)
|
||||||
|
@ -192,7 +193,7 @@ func NewFsSrcDstFiles(args []string) (fsrc fs.Fs, srcFileName string, fdst fs.Fs
|
||||||
log.Fatalf("%q is a directory", args[1])
|
log.Fatalf("%q is a directory", args[1])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fdst, err := cache.Get(dstRemote)
|
fdst, err := cache.Get(context.Background(), dstRemote)
|
||||||
switch err {
|
switch err {
|
||||||
case fs.ErrorIsFile:
|
case fs.ErrorIsFile:
|
||||||
_ = fs.CountError(err)
|
_ = fs.CountError(err)
|
||||||
|
@ -400,7 +401,7 @@ func initConfig() {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Start the remote control server if configured
|
// Start the remote control server if configured
|
||||||
_, err = rcserver.Start(&rcflags.Opt)
|
_, err = rcserver.Start(context.Background(), &rcflags.Opt)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalf("Failed to start remote control: %v", err)
|
log.Fatalf("Failed to start remote control: %v", err)
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,7 +17,7 @@ func TestDefaultLsf(t *testing.T) {
|
||||||
fstest.Initialise()
|
fstest.Initialise()
|
||||||
buf := new(bytes.Buffer)
|
buf := new(bytes.Buffer)
|
||||||
|
|
||||||
f, err := fs.NewFs("testfiles")
|
f, err := fs.NewFs(context.Background(), "testfiles")
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
err = Lsf(context.Background(), f, buf)
|
err = Lsf(context.Background(), f, buf)
|
||||||
|
@ -33,7 +33,7 @@ func TestRecurseFlag(t *testing.T) {
|
||||||
fstest.Initialise()
|
fstest.Initialise()
|
||||||
buf := new(bytes.Buffer)
|
buf := new(bytes.Buffer)
|
||||||
|
|
||||||
f, err := fs.NewFs("testfiles")
|
f, err := fs.NewFs(context.Background(), "testfiles")
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
recurse = true
|
recurse = true
|
||||||
|
@ -54,7 +54,7 @@ func TestDirSlashFlag(t *testing.T) {
|
||||||
fstest.Initialise()
|
fstest.Initialise()
|
||||||
buf := new(bytes.Buffer)
|
buf := new(bytes.Buffer)
|
||||||
|
|
||||||
f, err := fs.NewFs("testfiles")
|
f, err := fs.NewFs(context.Background(), "testfiles")
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
dirSlash = true
|
dirSlash = true
|
||||||
|
@ -80,7 +80,7 @@ subdir
|
||||||
|
|
||||||
func TestFormat(t *testing.T) {
|
func TestFormat(t *testing.T) {
|
||||||
fstest.Initialise()
|
fstest.Initialise()
|
||||||
f, err := fs.NewFs("testfiles")
|
f, err := fs.NewFs(context.Background(), "testfiles")
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
buf := new(bytes.Buffer)
|
buf := new(bytes.Buffer)
|
||||||
|
@ -160,7 +160,7 @@ file3
|
||||||
|
|
||||||
func TestSeparator(t *testing.T) {
|
func TestSeparator(t *testing.T) {
|
||||||
fstest.Initialise()
|
fstest.Initialise()
|
||||||
f, err := fs.NewFs("testfiles")
|
f, err := fs.NewFs(context.Background(), "testfiles")
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
format = "ps"
|
format = "ps"
|
||||||
|
|
||||||
|
@ -188,7 +188,7 @@ subdir__SEP__-1
|
||||||
|
|
||||||
func TestWholeLsf(t *testing.T) {
|
func TestWholeLsf(t *testing.T) {
|
||||||
fstest.Initialise()
|
fstest.Initialise()
|
||||||
f, err := fs.NewFs("testfiles")
|
f, err := fs.NewFs(context.Background(), "testfiles")
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
format = "pst"
|
format = "pst"
|
||||||
separator = "_+_"
|
separator = "_+_"
|
||||||
|
|
|
@ -76,7 +76,7 @@ The vfsOpt are as described in options/get and can be seen in the the
|
||||||
}
|
}
|
||||||
|
|
||||||
// mountRc allows the mount command to be run from rc
|
// mountRc allows the mount command to be run from rc
|
||||||
func mountRc(_ context.Context, in rc.Params) (out rc.Params, err error) {
|
func mountRc(ctx context.Context, in rc.Params) (out rc.Params, err error) {
|
||||||
mountPoint, err := in.GetString("mountPoint")
|
mountPoint, err := in.GetString("mountPoint")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
@ -110,7 +110,7 @@ func mountRc(_ context.Context, in rc.Params) (out rc.Params, err error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get Fs.fs to be mounted from fs parameter in the params
|
// Get Fs.fs to be mounted from fs parameter in the params
|
||||||
fdst, err := rc.GetFs(in)
|
fdst, err := rc.GetFs(ctx, in)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
package rcd
|
package rcd
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
"log"
|
"log"
|
||||||
|
|
||||||
"github.com/rclone/rclone/cmd"
|
"github.com/rclone/rclone/cmd"
|
||||||
|
@ -39,7 +40,7 @@ See the [rc documentation](/rc/) for more info on the rc flags.
|
||||||
rcflags.Opt.Files = args[0]
|
rcflags.Opt.Files = args[0]
|
||||||
}
|
}
|
||||||
|
|
||||||
s, err := rcserver.Start(&rcflags.Opt)
|
s, err := rcserver.Start(context.Background(), &rcflags.Opt)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalf("Failed to start remote control: %v", err)
|
log.Fatalf("Failed to start remote control: %v", err)
|
||||||
}
|
}
|
||||||
|
|
|
@ -43,7 +43,7 @@ func startServer(t *testing.T, f fs.Fs) {
|
||||||
func TestInit(t *testing.T) {
|
func TestInit(t *testing.T) {
|
||||||
config.LoadConfig()
|
config.LoadConfig()
|
||||||
|
|
||||||
f, err := fs.NewFs("testdata/files")
|
f, err := fs.NewFs(context.Background(), "testdata/files")
|
||||||
l, _ := f.List(context.Background(), "")
|
l, _ := f.List(context.Background(), "")
|
||||||
fmt.Println(l)
|
fmt.Println(l)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
package ftp
|
package ftp
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"net"
|
"net"
|
||||||
|
@ -101,7 +102,7 @@ You can set a single username and password with the --user and --pass flags.
|
||||||
cmd.CheckArgs(0, 0, command, args)
|
cmd.CheckArgs(0, 0, command, args)
|
||||||
}
|
}
|
||||||
cmd.Run(false, false, command, func() error {
|
cmd.Run(false, false, command, func() error {
|
||||||
s, err := newServer(f, &Opt)
|
s, err := newServer(context.Background(), f, &Opt)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -114,13 +115,14 @@ You can set a single username and password with the --user and --pass flags.
|
||||||
type server struct {
|
type server struct {
|
||||||
f fs.Fs
|
f fs.Fs
|
||||||
srv *ftp.Server
|
srv *ftp.Server
|
||||||
|
ctx context.Context // for global config
|
||||||
opt Options
|
opt Options
|
||||||
vfs *vfs.VFS
|
vfs *vfs.VFS
|
||||||
proxy *proxy.Proxy
|
proxy *proxy.Proxy
|
||||||
}
|
}
|
||||||
|
|
||||||
// Make a new FTP to serve the remote
|
// Make a new FTP to serve the remote
|
||||||
func newServer(f fs.Fs, opt *Options) (*server, error) {
|
func newServer(ctx context.Context, f fs.Fs, opt *Options) (*server, error) {
|
||||||
host, port, err := net.SplitHostPort(opt.ListenAddr)
|
host, port, err := net.SplitHostPort(opt.ListenAddr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errors.New("Failed to parse host:port")
|
return nil, errors.New("Failed to parse host:port")
|
||||||
|
@ -132,10 +134,11 @@ func newServer(f fs.Fs, opt *Options) (*server, error) {
|
||||||
|
|
||||||
s := &server{
|
s := &server{
|
||||||
f: f,
|
f: f,
|
||||||
|
ctx: ctx,
|
||||||
opt: *opt,
|
opt: *opt,
|
||||||
}
|
}
|
||||||
if proxyflags.Opt.AuthProxy != "" {
|
if proxyflags.Opt.AuthProxy != "" {
|
||||||
s.proxy = proxy.New(&proxyflags.Opt)
|
s.proxy = proxy.New(ctx, &proxyflags.Opt)
|
||||||
} else {
|
} else {
|
||||||
s.vfs = vfs.New(f, &vfsflags.Opt)
|
s.vfs = vfs.New(f, &vfsflags.Opt)
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
package ftp
|
package ftp
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
_ "github.com/rclone/rclone/backend/local"
|
_ "github.com/rclone/rclone/backend/local"
|
||||||
|
@ -38,7 +39,7 @@ func TestFTP(t *testing.T) {
|
||||||
opt.BasicUser = testUSER
|
opt.BasicUser = testUSER
|
||||||
opt.BasicPass = testPASS
|
opt.BasicPass = testPASS
|
||||||
|
|
||||||
w, err := newServer(f, &opt)
|
w, err := newServer(context.Background(), f, &opt)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
|
||||||
quit := make(chan struct{})
|
quit := make(chan struct{})
|
||||||
|
|
|
@ -70,7 +70,7 @@ func TestInit(t *testing.T) {
|
||||||
require.NoError(t, filter.Active.AddRule("- hidden/**"))
|
require.NoError(t, filter.Active.AddRule("- hidden/**"))
|
||||||
|
|
||||||
// Create a test Fs
|
// Create a test Fs
|
||||||
f, err := fs.NewFs("testdata/files")
|
f, err := fs.NewFs(context.Background(), "testdata/files")
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
// set date of datedObject to expectedTime
|
// set date of datedObject to expectedTime
|
||||||
|
|
|
@ -3,6 +3,7 @@ package proxy
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
|
"context"
|
||||||
"crypto/sha256"
|
"crypto/sha256"
|
||||||
"crypto/subtle"
|
"crypto/subtle"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
|
@ -118,6 +119,7 @@ var DefaultOpt = Options{
|
||||||
type Proxy struct {
|
type Proxy struct {
|
||||||
cmdLine []string // broken down command line
|
cmdLine []string // broken down command line
|
||||||
vfsCache *libcache.Cache
|
vfsCache *libcache.Cache
|
||||||
|
ctx context.Context // for global config
|
||||||
Opt Options
|
Opt Options
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -128,8 +130,9 @@ type cacheEntry struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
// New creates a new proxy with the Options passed in
|
// New creates a new proxy with the Options passed in
|
||||||
func New(opt *Options) *Proxy {
|
func New(ctx context.Context, opt *Options) *Proxy {
|
||||||
return &Proxy{
|
return &Proxy{
|
||||||
|
ctx: ctx,
|
||||||
Opt: *opt,
|
Opt: *opt,
|
||||||
cmdLine: strings.Fields(opt.AuthProxy),
|
cmdLine: strings.Fields(opt.AuthProxy),
|
||||||
vfsCache: libcache.New(),
|
vfsCache: libcache.New(),
|
||||||
|
@ -220,7 +223,7 @@ func (p *Proxy) call(user, auth string, isPublicKey bool) (value interface{}, er
|
||||||
// Look for fs in the VFS cache
|
// Look for fs in the VFS cache
|
||||||
value, err = p.vfsCache.Get(user, func(key string) (value interface{}, ok bool, err error) {
|
value, err = p.vfsCache.Get(user, func(key string) (value interface{}, ok bool, err error) {
|
||||||
// Create the Fs from the cache
|
// Create the Fs from the cache
|
||||||
f, err := cache.GetFn(fsString, func(fsString string) (fs.Fs, error) {
|
f, err := cache.GetFn(p.ctx, fsString, func(ctx context.Context, fsString string) (fs.Fs, error) {
|
||||||
// Update the config with the default values
|
// Update the config with the default values
|
||||||
for i := range fsInfo.Options {
|
for i := range fsInfo.Options {
|
||||||
o := &fsInfo.Options[i]
|
o := &fsInfo.Options[i]
|
||||||
|
@ -228,7 +231,7 @@ func (p *Proxy) call(user, auth string, isPublicKey bool) (value interface{}, er
|
||||||
config.Set(o.Name, o.String())
|
config.Set(o.Name, o.String())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return fsInfo.NewFs(name, root, config)
|
return fsInfo.NewFs(ctx, name, root, config)
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, false, err
|
return nil, false, err
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
package proxy
|
package proxy
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
"crypto/rand"
|
"crypto/rand"
|
||||||
"crypto/rsa"
|
"crypto/rsa"
|
||||||
"crypto/sha256"
|
"crypto/sha256"
|
||||||
|
@ -21,7 +22,7 @@ func TestRun(t *testing.T) {
|
||||||
opt := DefaultOpt
|
opt := DefaultOpt
|
||||||
cmd := "go run proxy_code.go"
|
cmd := "go run proxy_code.go"
|
||||||
opt.AuthProxy = cmd
|
opt.AuthProxy = cmd
|
||||||
p := New(&opt)
|
p := New(context.Background(), &opt)
|
||||||
|
|
||||||
t.Run("Normal", func(t *testing.T) {
|
t.Run("Normal", func(t *testing.T) {
|
||||||
config, err := p.run(map[string]string{
|
config, err := p.run(map[string]string{
|
||||||
|
|
|
@ -4,6 +4,7 @@ package sftp
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
|
"context"
|
||||||
"crypto/rand"
|
"crypto/rand"
|
||||||
"crypto/rsa"
|
"crypto/rsa"
|
||||||
"crypto/subtle"
|
"crypto/subtle"
|
||||||
|
@ -33,20 +34,22 @@ type server struct {
|
||||||
f fs.Fs
|
f fs.Fs
|
||||||
opt Options
|
opt Options
|
||||||
vfs *vfs.VFS
|
vfs *vfs.VFS
|
||||||
|
ctx context.Context // for global config
|
||||||
config *ssh.ServerConfig
|
config *ssh.ServerConfig
|
||||||
listener net.Listener
|
listener net.Listener
|
||||||
waitChan chan struct{} // for waiting on the listener to close
|
waitChan chan struct{} // for waiting on the listener to close
|
||||||
proxy *proxy.Proxy
|
proxy *proxy.Proxy
|
||||||
}
|
}
|
||||||
|
|
||||||
func newServer(f fs.Fs, opt *Options) *server {
|
func newServer(ctx context.Context, f fs.Fs, opt *Options) *server {
|
||||||
s := &server{
|
s := &server{
|
||||||
f: f,
|
f: f,
|
||||||
|
ctx: ctx,
|
||||||
opt: *opt,
|
opt: *opt,
|
||||||
waitChan: make(chan struct{}),
|
waitChan: make(chan struct{}),
|
||||||
}
|
}
|
||||||
if proxyflags.Opt.AuthProxy != "" {
|
if proxyflags.Opt.AuthProxy != "" {
|
||||||
s.proxy = proxy.New(&proxyflags.Opt)
|
s.proxy = proxy.New(ctx, &proxyflags.Opt)
|
||||||
} else {
|
} else {
|
||||||
s.vfs = vfs.New(f, &vfsflags.Opt)
|
s.vfs = vfs.New(f, &vfsflags.Opt)
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,6 +5,8 @@
|
||||||
package sftp
|
package sftp
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
|
|
||||||
"github.com/rclone/rclone/cmd"
|
"github.com/rclone/rclone/cmd"
|
||||||
"github.com/rclone/rclone/cmd/serve/proxy"
|
"github.com/rclone/rclone/cmd/serve/proxy"
|
||||||
"github.com/rclone/rclone/cmd/serve/proxy/proxyflags"
|
"github.com/rclone/rclone/cmd/serve/proxy/proxyflags"
|
||||||
|
@ -98,7 +100,7 @@ sftp backend, but it may not be with other SFTP clients.
|
||||||
cmd.CheckArgs(0, 0, command, args)
|
cmd.CheckArgs(0, 0, command, args)
|
||||||
}
|
}
|
||||||
cmd.Run(false, true, command, func() error {
|
cmd.Run(false, true, command, func() error {
|
||||||
s := newServer(f, &Opt)
|
s := newServer(context.Background(), f, &Opt)
|
||||||
err := s.Serve()
|
err := s.Serve()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
package sftp
|
package sftp
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
"strings"
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
@ -44,7 +45,7 @@ func TestSftp(t *testing.T) {
|
||||||
opt.User = testUser
|
opt.User = testUser
|
||||||
opt.Pass = testPass
|
opt.Pass = testPass
|
||||||
|
|
||||||
w := newServer(f, &opt)
|
w := newServer(context.Background(), f, &opt)
|
||||||
require.NoError(t, w.serve())
|
require.NoError(t, w.serve())
|
||||||
|
|
||||||
// Read the host and port we started on
|
// Read the host and port we started on
|
||||||
|
|
|
@ -84,7 +84,7 @@ Use "rclone hashsum" to see the full list.
|
||||||
fs.Debugf(f, "Using hash %v for ETag", hashType)
|
fs.Debugf(f, "Using hash %v for ETag", hashType)
|
||||||
}
|
}
|
||||||
cmd.Run(false, false, command, func() error {
|
cmd.Run(false, false, command, func() error {
|
||||||
s := newWebDAV(f, &httpflags.Opt)
|
s := newWebDAV(context.Background(), f, &httpflags.Opt)
|
||||||
err := s.serve()
|
err := s.serve()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -114,18 +114,20 @@ type WebDAV struct {
|
||||||
_vfs *vfs.VFS // don't use directly, use getVFS
|
_vfs *vfs.VFS // don't use directly, use getVFS
|
||||||
webdavhandler *webdav.Handler
|
webdavhandler *webdav.Handler
|
||||||
proxy *proxy.Proxy
|
proxy *proxy.Proxy
|
||||||
|
ctx context.Context // for global config
|
||||||
}
|
}
|
||||||
|
|
||||||
// check interface
|
// check interface
|
||||||
var _ webdav.FileSystem = (*WebDAV)(nil)
|
var _ webdav.FileSystem = (*WebDAV)(nil)
|
||||||
|
|
||||||
// Make a new WebDAV to serve the remote
|
// Make a new WebDAV to serve the remote
|
||||||
func newWebDAV(f fs.Fs, opt *httplib.Options) *WebDAV {
|
func newWebDAV(ctx context.Context, f fs.Fs, opt *httplib.Options) *WebDAV {
|
||||||
w := &WebDAV{
|
w := &WebDAV{
|
||||||
f: f,
|
f: f,
|
||||||
|
ctx: ctx,
|
||||||
}
|
}
|
||||||
if proxyflags.Opt.AuthProxy != "" {
|
if proxyflags.Opt.AuthProxy != "" {
|
||||||
w.proxy = proxy.New(&proxyflags.Opt)
|
w.proxy = proxy.New(ctx, &proxyflags.Opt)
|
||||||
// override auth
|
// override auth
|
||||||
copyOpt := *opt
|
copyOpt := *opt
|
||||||
copyOpt.Auth = w.auth
|
copyOpt.Auth = w.auth
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
package webdav
|
package webdav
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
"flag"
|
"flag"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
@ -56,7 +57,7 @@ func TestWebDav(t *testing.T) {
|
||||||
hashType = hash.MD5
|
hashType = hash.MD5
|
||||||
|
|
||||||
// Start the server
|
// Start the server
|
||||||
w := newWebDAV(f, &opt)
|
w := newWebDAV(context.Background(), f, &opt)
|
||||||
assert.NoError(t, w.serve())
|
assert.NoError(t, w.serve())
|
||||||
|
|
||||||
// Config for the backend we'll use to connect to the server
|
// Config for the backend we'll use to connect to the server
|
||||||
|
@ -91,7 +92,7 @@ func TestHTTPFunction(t *testing.T) {
|
||||||
require.NoError(t, filter.Active.AddRule("- hidden/**"))
|
require.NoError(t, filter.Active.AddRule("- hidden/**"))
|
||||||
|
|
||||||
// Uses the same test files as http tests but with different golden.
|
// Uses the same test files as http tests but with different golden.
|
||||||
f, err := fs.NewFs("../http/testdata/files")
|
f, err := fs.NewFs(context.Background(), "../http/testdata/files")
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
|
||||||
opt := httplib.DefaultOpt
|
opt := httplib.DefaultOpt
|
||||||
|
@ -99,7 +100,7 @@ func TestHTTPFunction(t *testing.T) {
|
||||||
opt.Template = testTemplate
|
opt.Template = testTemplate
|
||||||
|
|
||||||
// Start the server
|
// Start the server
|
||||||
w := newWebDAV(f, &opt)
|
w := newWebDAV(context.Background(), f, &opt)
|
||||||
assert.NoError(t, w.serve())
|
assert.NoError(t, w.serve())
|
||||||
defer func() {
|
defer func() {
|
||||||
w.Close()
|
w.Close()
|
||||||
|
|
|
@ -2,6 +2,7 @@ package tree
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
|
"context"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/a8m/tree"
|
"github.com/a8m/tree"
|
||||||
|
@ -17,7 +18,7 @@ func TestTree(t *testing.T) {
|
||||||
|
|
||||||
buf := new(bytes.Buffer)
|
buf := new(bytes.Buffer)
|
||||||
|
|
||||||
f, err := fs.NewFs("testfiles")
|
f, err := fs.NewFs(context.Background(), "testfiles")
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
err = Tree(f, buf, new(tree.Options))
|
err = Tree(f, buf, new(tree.Options))
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
9
fs/cache/cache.go
vendored
9
fs/cache/cache.go
vendored
|
@ -2,6 +2,7 @@
|
||||||
package cache
|
package cache
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
"runtime"
|
"runtime"
|
||||||
"sync"
|
"sync"
|
||||||
|
|
||||||
|
@ -40,11 +41,11 @@ func addMapping(fsString, canonicalName string) {
|
||||||
|
|
||||||
// GetFn gets an fs.Fs named fsString either from the cache or creates
|
// GetFn gets an fs.Fs named fsString either from the cache or creates
|
||||||
// it afresh with the create function
|
// it afresh with the create function
|
||||||
func GetFn(fsString string, create func(fsString string) (fs.Fs, error)) (f fs.Fs, err error) {
|
func GetFn(ctx context.Context, fsString string, create func(ctx context.Context, fsString string) (fs.Fs, error)) (f fs.Fs, err error) {
|
||||||
fsString = Canonicalize(fsString)
|
fsString = Canonicalize(fsString)
|
||||||
created := false
|
created := false
|
||||||
value, err := c.Get(fsString, func(fsString string) (f interface{}, ok bool, err error) {
|
value, err := c.Get(fsString, func(fsString string) (f interface{}, ok bool, err error) {
|
||||||
f, err = create(fsString)
|
f, err = create(ctx, fsString)
|
||||||
ok = err == nil || err == fs.ErrorIsFile
|
ok = err == nil || err == fs.ErrorIsFile
|
||||||
created = ok
|
created = ok
|
||||||
return f, ok, err
|
return f, ok, err
|
||||||
|
@ -99,8 +100,8 @@ func Unpin(f fs.Fs) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get gets an fs.Fs named fsString either from the cache or creates it afresh
|
// Get gets an fs.Fs named fsString either from the cache or creates it afresh
|
||||||
func Get(fsString string) (f fs.Fs, err error) {
|
func Get(ctx context.Context, fsString string) (f fs.Fs, err error) {
|
||||||
return GetFn(fsString, fs.NewFs)
|
return GetFn(ctx, fsString, fs.NewFs)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Put puts an fs.Fs named fsString into the cache
|
// Put puts an fs.Fs named fsString into the cache
|
||||||
|
|
31
fs/cache/cache_test.go
vendored
31
fs/cache/cache_test.go
vendored
|
@ -1,6 +1,7 @@
|
||||||
package cache
|
package cache
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
"errors"
|
"errors"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
@ -15,9 +16,9 @@ var (
|
||||||
errSentinel = errors.New("an error")
|
errSentinel = errors.New("an error")
|
||||||
)
|
)
|
||||||
|
|
||||||
func mockNewFs(t *testing.T) (func(), func(path string) (fs.Fs, error)) {
|
func mockNewFs(t *testing.T) (func(), func(ctx context.Context, path string) (fs.Fs, error)) {
|
||||||
called = 0
|
called = 0
|
||||||
create := func(path string) (f fs.Fs, err error) {
|
create := func(ctx context.Context, path string) (f fs.Fs, err error) {
|
||||||
assert.Equal(t, 0, called)
|
assert.Equal(t, 0, called)
|
||||||
called++
|
called++
|
||||||
switch path {
|
switch path {
|
||||||
|
@ -43,12 +44,12 @@ func TestGet(t *testing.T) {
|
||||||
|
|
||||||
assert.Equal(t, 0, c.Entries())
|
assert.Equal(t, 0, c.Entries())
|
||||||
|
|
||||||
f, err := GetFn("mock:/", create)
|
f, err := GetFn(context.Background(), "mock:/", create)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
assert.Equal(t, 1, c.Entries())
|
assert.Equal(t, 1, c.Entries())
|
||||||
|
|
||||||
f2, err := GetFn("mock:/", create)
|
f2, err := GetFn(context.Background(), "mock:/", create)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
assert.Equal(t, f, f2)
|
assert.Equal(t, f, f2)
|
||||||
|
@ -60,20 +61,20 @@ func TestGetFile(t *testing.T) {
|
||||||
|
|
||||||
assert.Equal(t, 0, c.Entries())
|
assert.Equal(t, 0, c.Entries())
|
||||||
|
|
||||||
f, err := GetFn("mock:/file.txt", create)
|
f, err := GetFn(context.Background(), "mock:/file.txt", create)
|
||||||
require.Equal(t, fs.ErrorIsFile, err)
|
require.Equal(t, fs.ErrorIsFile, err)
|
||||||
require.NotNil(t, f)
|
require.NotNil(t, f)
|
||||||
|
|
||||||
assert.Equal(t, 2, c.Entries())
|
assert.Equal(t, 2, c.Entries())
|
||||||
|
|
||||||
f2, err := GetFn("mock:/file.txt", create)
|
f2, err := GetFn(context.Background(), "mock:/file.txt", create)
|
||||||
require.Equal(t, fs.ErrorIsFile, err)
|
require.Equal(t, fs.ErrorIsFile, err)
|
||||||
require.NotNil(t, f2)
|
require.NotNil(t, f2)
|
||||||
|
|
||||||
assert.Equal(t, f, f2)
|
assert.Equal(t, f, f2)
|
||||||
|
|
||||||
// check parent is there too
|
// check parent is there too
|
||||||
f2, err = GetFn("mock:/", create)
|
f2, err = GetFn(context.Background(), "mock:/", create)
|
||||||
require.Nil(t, err)
|
require.Nil(t, err)
|
||||||
require.NotNil(t, f2)
|
require.NotNil(t, f2)
|
||||||
|
|
||||||
|
@ -86,20 +87,20 @@ func TestGetFile2(t *testing.T) {
|
||||||
|
|
||||||
assert.Equal(t, 0, c.Entries())
|
assert.Equal(t, 0, c.Entries())
|
||||||
|
|
||||||
f, err := GetFn("mock:file.txt", create)
|
f, err := GetFn(context.Background(), "mock:file.txt", create)
|
||||||
require.Equal(t, fs.ErrorIsFile, err)
|
require.Equal(t, fs.ErrorIsFile, err)
|
||||||
require.NotNil(t, f)
|
require.NotNil(t, f)
|
||||||
|
|
||||||
assert.Equal(t, 2, c.Entries())
|
assert.Equal(t, 2, c.Entries())
|
||||||
|
|
||||||
f2, err := GetFn("mock:file.txt", create)
|
f2, err := GetFn(context.Background(), "mock:file.txt", create)
|
||||||
require.Equal(t, fs.ErrorIsFile, err)
|
require.Equal(t, fs.ErrorIsFile, err)
|
||||||
require.NotNil(t, f2)
|
require.NotNil(t, f2)
|
||||||
|
|
||||||
assert.Equal(t, f, f2)
|
assert.Equal(t, f, f2)
|
||||||
|
|
||||||
// check parent is there too
|
// check parent is there too
|
||||||
f2, err = GetFn("mock:/", create)
|
f2, err = GetFn(context.Background(), "mock:/", create)
|
||||||
require.Nil(t, err)
|
require.Nil(t, err)
|
||||||
require.NotNil(t, f2)
|
require.NotNil(t, f2)
|
||||||
|
|
||||||
|
@ -112,7 +113,7 @@ func TestGetError(t *testing.T) {
|
||||||
|
|
||||||
assert.Equal(t, 0, c.Entries())
|
assert.Equal(t, 0, c.Entries())
|
||||||
|
|
||||||
f, err := GetFn("mock:/error", create)
|
f, err := GetFn(context.Background(), "mock:/error", create)
|
||||||
require.Equal(t, errSentinel, err)
|
require.Equal(t, errSentinel, err)
|
||||||
require.Equal(t, nil, f)
|
require.Equal(t, nil, f)
|
||||||
|
|
||||||
|
@ -131,7 +132,7 @@ func TestPut(t *testing.T) {
|
||||||
|
|
||||||
assert.Equal(t, 1, c.Entries())
|
assert.Equal(t, 1, c.Entries())
|
||||||
|
|
||||||
fNew, err := GetFn("mock:/alien", create)
|
fNew, err := GetFn(context.Background(), "mock:/alien", create)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.Equal(t, f, fNew)
|
require.Equal(t, f, fNew)
|
||||||
|
|
||||||
|
@ -141,7 +142,7 @@ func TestPut(t *testing.T) {
|
||||||
|
|
||||||
Put("mock:/alien/", f)
|
Put("mock:/alien/", f)
|
||||||
|
|
||||||
fNew, err = GetFn("mock:/alien/", create)
|
fNew, err = GetFn(context.Background(), "mock:/alien/", create)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.Equal(t, f, fNew)
|
require.Equal(t, f, fNew)
|
||||||
|
|
||||||
|
@ -159,7 +160,7 @@ func TestPin(t *testing.T) {
|
||||||
Unpin(f)
|
Unpin(f)
|
||||||
|
|
||||||
// Now test pinning an existing
|
// Now test pinning an existing
|
||||||
f2, err := GetFn("mock:/", create)
|
f2, err := GetFn(context.Background(), "mock:/", create)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
Pin(f2)
|
Pin(f2)
|
||||||
Unpin(f2)
|
Unpin(f2)
|
||||||
|
@ -170,7 +171,7 @@ func TestClear(t *testing.T) {
|
||||||
defer cleanup()
|
defer cleanup()
|
||||||
|
|
||||||
// Create something
|
// Create something
|
||||||
_, err := GetFn("mock:/", create)
|
_, err := GetFn(context.Background(), "mock:/", create)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
assert.Equal(t, 1, c.Entries())
|
assert.Equal(t, 1, c.Entries())
|
||||||
|
|
10
fs/fs.go
10
fs/fs.go
|
@ -84,7 +84,7 @@ type RegInfo struct {
|
||||||
// Create a new file system. If root refers to an existing
|
// Create a new file system. If root refers to an existing
|
||||||
// object, then it should return an Fs which which points to
|
// object, then it should return an Fs which which points to
|
||||||
// the parent of that object and ErrorIsFile.
|
// the parent of that object and ErrorIsFile.
|
||||||
NewFs func(name string, root string, config configmap.Mapper) (Fs, error) `json:"-"`
|
NewFs func(ctx context.Context, name string, root string, config configmap.Mapper) (Fs, error) `json:"-"`
|
||||||
// Function to call to help with config
|
// Function to call to help with config
|
||||||
Config func(name string, config configmap.Mapper) `json:"-"`
|
Config func(name string, config configmap.Mapper) `json:"-"`
|
||||||
// Options for the Fs configuration
|
// Options for the Fs configuration
|
||||||
|
@ -1339,13 +1339,13 @@ func ConfigFs(path string) (fsInfo *RegInfo, configName, fsPath string, config *
|
||||||
//
|
//
|
||||||
// On Windows avoid single character remote names as they can be mixed
|
// On Windows avoid single character remote names as they can be mixed
|
||||||
// up with drive letters.
|
// up with drive letters.
|
||||||
func NewFs(path string) (Fs, error) {
|
func NewFs(ctx context.Context, path string) (Fs, error) {
|
||||||
Debugf(nil, "Creating backend with remote %q", path)
|
Debugf(nil, "Creating backend with remote %q", path)
|
||||||
fsInfo, configName, fsPath, config, err := ConfigFs(path)
|
fsInfo, configName, fsPath, config, err := ConfigFs(path)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return fsInfo.NewFs(configName, fsPath, config)
|
return fsInfo.NewFs(ctx, configName, fsPath, config)
|
||||||
}
|
}
|
||||||
|
|
||||||
// ConfigString returns a canonical version of the config string used
|
// ConfigString returns a canonical version of the config string used
|
||||||
|
@ -1362,7 +1362,7 @@ func ConfigString(f Fs) string {
|
||||||
// TemporaryLocalFs creates a local FS in the OS's temporary directory.
|
// TemporaryLocalFs creates a local FS in the OS's temporary directory.
|
||||||
//
|
//
|
||||||
// No cleanup is performed, the caller must call Purge on the Fs themselves.
|
// No cleanup is performed, the caller must call Purge on the Fs themselves.
|
||||||
func TemporaryLocalFs() (Fs, error) {
|
func TemporaryLocalFs(ctx context.Context) (Fs, error) {
|
||||||
path, err := ioutil.TempDir("", "rclone-spool")
|
path, err := ioutil.TempDir("", "rclone-spool")
|
||||||
if err == nil {
|
if err == nil {
|
||||||
err = os.Remove(path)
|
err = os.Remove(path)
|
||||||
|
@ -1371,7 +1371,7 @@ func TemporaryLocalFs() (Fs, error) {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
path = filepath.ToSlash(path)
|
path = filepath.ToSlash(path)
|
||||||
return NewFs(path)
|
return NewFs(ctx, path)
|
||||||
}
|
}
|
||||||
|
|
||||||
// CheckClose is a utility function used to check the return from
|
// CheckClose is a utility function used to check the return from
|
||||||
|
|
|
@ -182,11 +182,11 @@ func TestCheck(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestCheckFsError(t *testing.T) {
|
func TestCheckFsError(t *testing.T) {
|
||||||
dstFs, err := fs.NewFs("non-existent")
|
dstFs, err := fs.NewFs(context.Background(), "non-existent")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
srcFs, err := fs.NewFs("non-existent")
|
srcFs, err := fs.NewFs(context.Background(), "non-existent")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
|
@ -1157,7 +1157,7 @@ func Rcat(ctx context.Context, fdst fs.Fs, dstFileName string, in io.ReadCloser,
|
||||||
canStream := fdst.Features().PutStream != nil
|
canStream := fdst.Features().PutStream != nil
|
||||||
if !canStream {
|
if !canStream {
|
||||||
fs.Debugf(fdst, "Target remote doesn't support streaming uploads, creating temporary local FS to spool file")
|
fs.Debugf(fdst, "Target remote doesn't support streaming uploads, creating temporary local FS to spool file")
|
||||||
tmpLocalFs, err := fs.TemporaryLocalFs()
|
tmpLocalFs, err := fs.TemporaryLocalFs(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errors.Wrap(err, "Failed to create temporary local FS to spool file")
|
return nil, errors.Wrap(err, "Failed to create temporary local FS to spool file")
|
||||||
}
|
}
|
||||||
|
@ -1262,8 +1262,8 @@ func Rmdirs(ctx context.Context, f fs.Fs, dir string, leaveRoot bool) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetCompareDest sets up --compare-dest
|
// GetCompareDest sets up --compare-dest
|
||||||
func GetCompareDest() (CompareDest fs.Fs, err error) {
|
func GetCompareDest(ctx context.Context) (CompareDest fs.Fs, err error) {
|
||||||
CompareDest, err = cache.Get(fs.Config.CompareDest)
|
CompareDest, err = cache.Get(ctx, fs.Config.CompareDest)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fserrors.FatalError(errors.Errorf("Failed to make fs for --compare-dest %q: %v", fs.Config.CompareDest, err))
|
return nil, fserrors.FatalError(errors.Errorf("Failed to make fs for --compare-dest %q: %v", fs.Config.CompareDest, err))
|
||||||
}
|
}
|
||||||
|
@ -1298,8 +1298,8 @@ func compareDest(ctx context.Context, dst, src fs.Object, CompareDest fs.Fs) (No
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetCopyDest sets up --copy-dest
|
// GetCopyDest sets up --copy-dest
|
||||||
func GetCopyDest(fdst fs.Fs) (CopyDest fs.Fs, err error) {
|
func GetCopyDest(ctx context.Context, fdst fs.Fs) (CopyDest fs.Fs, err error) {
|
||||||
CopyDest, err = cache.Get(fs.Config.CopyDest)
|
CopyDest, err = cache.Get(ctx, fs.Config.CopyDest)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fserrors.FatalError(errors.Errorf("Failed to make fs for --copy-dest %q: %v", fs.Config.CopyDest, err))
|
return nil, fserrors.FatalError(errors.Errorf("Failed to make fs for --copy-dest %q: %v", fs.Config.CopyDest, err))
|
||||||
}
|
}
|
||||||
|
@ -1530,9 +1530,9 @@ func CopyURLToWriter(ctx context.Context, url string, out io.Writer) (err error)
|
||||||
}
|
}
|
||||||
|
|
||||||
// BackupDir returns the correctly configured --backup-dir
|
// BackupDir returns the correctly configured --backup-dir
|
||||||
func BackupDir(fdst fs.Fs, fsrc fs.Fs, srcFileName string) (backupDir fs.Fs, err error) {
|
func BackupDir(ctx context.Context, fdst fs.Fs, fsrc fs.Fs, srcFileName string) (backupDir fs.Fs, err error) {
|
||||||
if fs.Config.BackupDir != "" {
|
if fs.Config.BackupDir != "" {
|
||||||
backupDir, err = cache.Get(fs.Config.BackupDir)
|
backupDir, err = cache.Get(ctx, fs.Config.BackupDir)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fserrors.FatalError(errors.Errorf("Failed to make fs for --backup-dir %q: %v", fs.Config.BackupDir, err))
|
return nil, fserrors.FatalError(errors.Errorf("Failed to make fs for --backup-dir %q: %v", fs.Config.BackupDir, err))
|
||||||
}
|
}
|
||||||
|
@ -1636,18 +1636,18 @@ func moveOrCopyFile(ctx context.Context, fdst fs.Fs, fsrc fs.Fs, dstFileName str
|
||||||
|
|
||||||
var backupDir, copyDestDir fs.Fs
|
var backupDir, copyDestDir fs.Fs
|
||||||
if fs.Config.BackupDir != "" || fs.Config.Suffix != "" {
|
if fs.Config.BackupDir != "" || fs.Config.Suffix != "" {
|
||||||
backupDir, err = BackupDir(fdst, fsrc, srcFileName)
|
backupDir, err = BackupDir(ctx, fdst, fsrc, srcFileName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return errors.Wrap(err, "creating Fs for --backup-dir failed")
|
return errors.Wrap(err, "creating Fs for --backup-dir failed")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if fs.Config.CompareDest != "" {
|
if fs.Config.CompareDest != "" {
|
||||||
copyDestDir, err = GetCompareDest()
|
copyDestDir, err = GetCompareDest(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
} else if fs.Config.CopyDest != "" {
|
} else if fs.Config.CopyDest != "" {
|
||||||
copyDestDir, err = GetCopyDest(fdst)
|
copyDestDir, err = GetCopyDest(ctx, fdst)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
|
@ -819,7 +819,7 @@ func TestCopyFileCompareDest(t *testing.T) {
|
||||||
defer func() {
|
defer func() {
|
||||||
fs.Config.CompareDest = ""
|
fs.Config.CompareDest = ""
|
||||||
}()
|
}()
|
||||||
fdst, err := fs.NewFs(r.FremoteName + "/dst")
|
fdst, err := fs.NewFs(context.Background(), r.FremoteName+"/dst")
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
// check empty dest, empty compare
|
// check empty dest, empty compare
|
||||||
|
@ -904,7 +904,7 @@ func TestCopyFileCopyDest(t *testing.T) {
|
||||||
fs.Config.CopyDest = ""
|
fs.Config.CopyDest = ""
|
||||||
}()
|
}()
|
||||||
|
|
||||||
fdst, err := fs.NewFs(r.FremoteName + "/dst")
|
fdst, err := fs.NewFs(context.Background(), r.FremoteName+"/dst")
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
// check empty dest, empty copy
|
// check empty dest, empty copy
|
||||||
|
|
|
@ -44,7 +44,7 @@ See the [lsjson command](/commands/rclone_lsjson/) for more information on the a
|
||||||
|
|
||||||
// List the directory
|
// List the directory
|
||||||
func rcList(ctx context.Context, in rc.Params) (out rc.Params, err error) {
|
func rcList(ctx context.Context, in rc.Params) (out rc.Params, err error) {
|
||||||
f, remote, err := rc.GetFsAndRemote(in)
|
f, remote, err := rc.GetFsAndRemote(ctx, in)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -85,7 +85,7 @@ See the [about command](/commands/rclone_size/) command for more information on
|
||||||
|
|
||||||
// About the remote
|
// About the remote
|
||||||
func rcAbout(ctx context.Context, in rc.Params) (out rc.Params, err error) {
|
func rcAbout(ctx context.Context, in rc.Params) (out rc.Params, err error) {
|
||||||
f, err := rc.GetFs(in)
|
f, err := rc.GetFs(ctx, in)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -131,11 +131,11 @@ func init() {
|
||||||
|
|
||||||
// Copy a file
|
// Copy a file
|
||||||
func rcMoveOrCopyFile(ctx context.Context, in rc.Params, cp bool) (out rc.Params, err error) {
|
func rcMoveOrCopyFile(ctx context.Context, in rc.Params, cp bool) (out rc.Params, err error) {
|
||||||
srcFs, srcRemote, err := rc.GetFsAndRemoteNamed(in, "srcFs", "srcRemote")
|
srcFs, srcRemote, err := rc.GetFsAndRemoteNamed(ctx, in, "srcFs", "srcRemote")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
dstFs, dstRemote, err := rc.GetFsAndRemoteNamed(in, "dstFs", "dstRemote")
|
dstFs, dstRemote, err := rc.GetFsAndRemoteNamed(ctx, in, "dstFs", "dstRemote")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -190,9 +190,9 @@ func rcSingleCommand(ctx context.Context, in rc.Params, name string, noRemote bo
|
||||||
remote string
|
remote string
|
||||||
)
|
)
|
||||||
if noRemote {
|
if noRemote {
|
||||||
f, err = rc.GetFs(in)
|
f, err = rc.GetFs(ctx, in)
|
||||||
} else {
|
} else {
|
||||||
f, remote, err = rc.GetFsAndRemote(in)
|
f, remote, err = rc.GetFsAndRemote(ctx, in)
|
||||||
}
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
@ -291,7 +291,7 @@ See the [size command](/commands/rclone_size/) command for more information on t
|
||||||
|
|
||||||
// Size a directory
|
// Size a directory
|
||||||
func rcSize(ctx context.Context, in rc.Params) (out rc.Params, err error) {
|
func rcSize(ctx context.Context, in rc.Params) (out rc.Params, err error) {
|
||||||
f, err := rc.GetFs(in)
|
f, err := rc.GetFs(ctx, in)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -329,7 +329,7 @@ See the [link command](/commands/rclone_link/) command for more information on t
|
||||||
|
|
||||||
// Make a public link
|
// Make a public link
|
||||||
func rcPublicLink(ctx context.Context, in rc.Params) (out rc.Params, err error) {
|
func rcPublicLink(ctx context.Context, in rc.Params) (out rc.Params, err error) {
|
||||||
f, remote, err := rc.GetFsAndRemote(in)
|
f, remote, err := rc.GetFsAndRemote(ctx, in)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -413,7 +413,7 @@ This command does not have a command line equivalent so use this instead:
|
||||||
|
|
||||||
// Fsinfo the remote
|
// Fsinfo the remote
|
||||||
func rcFsInfo(ctx context.Context, in rc.Params) (out rc.Params, err error) {
|
func rcFsInfo(ctx context.Context, in rc.Params) (out rc.Params, err error) {
|
||||||
f, err := rc.GetFs(in)
|
f, err := rc.GetFs(ctx, in)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -478,7 +478,7 @@ See the [backend](/commands/rclone_backend/) command for more information.
|
||||||
|
|
||||||
// Make a public link
|
// Make a public link
|
||||||
func rcBackend(ctx context.Context, in rc.Params) (out rc.Params, err error) {
|
func rcBackend(ctx context.Context, in rc.Params) (out rc.Params, err error) {
|
||||||
f, err := rc.GetFs(in)
|
f, err := rc.GetFs(ctx, in)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,34 +3,36 @@
|
||||||
package rc
|
package rc
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
|
|
||||||
"github.com/rclone/rclone/fs"
|
"github.com/rclone/rclone/fs"
|
||||||
"github.com/rclone/rclone/fs/cache"
|
"github.com/rclone/rclone/fs/cache"
|
||||||
)
|
)
|
||||||
|
|
||||||
// GetFsNamed gets an fs.Fs named fsName either from the cache or creates it afresh
|
// GetFsNamed gets an fs.Fs named fsName either from the cache or creates it afresh
|
||||||
func GetFsNamed(in Params, fsName string) (f fs.Fs, err error) {
|
func GetFsNamed(ctx context.Context, in Params, fsName string) (f fs.Fs, err error) {
|
||||||
fsString, err := in.GetString(fsName)
|
fsString, err := in.GetString(fsName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return cache.Get(fsString)
|
return cache.Get(ctx, fsString)
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetFs gets an fs.Fs named "fs" either from the cache or creates it afresh
|
// GetFs gets an fs.Fs named "fs" either from the cache or creates it afresh
|
||||||
func GetFs(in Params) (f fs.Fs, err error) {
|
func GetFs(ctx context.Context, in Params) (f fs.Fs, err error) {
|
||||||
return GetFsNamed(in, "fs")
|
return GetFsNamed(ctx, in, "fs")
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetFsAndRemoteNamed gets the fsName parameter from in, makes a
|
// GetFsAndRemoteNamed gets the fsName parameter from in, makes a
|
||||||
// remote or fetches it from the cache then gets the remoteName
|
// remote or fetches it from the cache then gets the remoteName
|
||||||
// parameter from in too.
|
// parameter from in too.
|
||||||
func GetFsAndRemoteNamed(in Params, fsName, remoteName string) (f fs.Fs, remote string, err error) {
|
func GetFsAndRemoteNamed(ctx context.Context, in Params, fsName, remoteName string) (f fs.Fs, remote string, err error) {
|
||||||
remote, err = in.GetString(remoteName)
|
remote, err = in.GetString(remoteName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
f, err = GetFsNamed(in, fsName)
|
f, err = GetFsNamed(ctx, in, fsName)
|
||||||
return
|
return
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -38,6 +40,6 @@ func GetFsAndRemoteNamed(in Params, fsName, remoteName string) (f fs.Fs, remote
|
||||||
// GetFsAndRemote gets the `fs` parameter from in, makes a remote or
|
// GetFsAndRemote gets the `fs` parameter from in, makes a remote or
|
||||||
// fetches it from the cache then gets the `remote` parameter from in
|
// fetches it from the cache then gets the `remote` parameter from in
|
||||||
// too.
|
// too.
|
||||||
func GetFsAndRemote(in Params) (f fs.Fs, remote string, err error) {
|
func GetFsAndRemote(ctx context.Context, in Params) (f fs.Fs, remote string, err error) {
|
||||||
return GetFsAndRemoteNamed(in, "fs", "remote")
|
return GetFsAndRemoteNamed(ctx, in, "fs", "remote")
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
package rc
|
package rc
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/rclone/rclone/fs/cache"
|
"github.com/rclone/rclone/fs/cache"
|
||||||
|
@ -23,14 +24,14 @@ func TestGetFsNamed(t *testing.T) {
|
||||||
in := Params{
|
in := Params{
|
||||||
"potato": "/",
|
"potato": "/",
|
||||||
}
|
}
|
||||||
f, err := GetFsNamed(in, "potato")
|
f, err := GetFsNamed(context.Background(), in, "potato")
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
assert.NotNil(t, f)
|
assert.NotNil(t, f)
|
||||||
|
|
||||||
in = Params{
|
in = Params{
|
||||||
"sausage": "/",
|
"sausage": "/",
|
||||||
}
|
}
|
||||||
f, err = GetFsNamed(in, "potato")
|
f, err = GetFsNamed(context.Background(), in, "potato")
|
||||||
require.Error(t, err)
|
require.Error(t, err)
|
||||||
assert.Nil(t, f)
|
assert.Nil(t, f)
|
||||||
}
|
}
|
||||||
|
@ -41,7 +42,7 @@ func TestGetFs(t *testing.T) {
|
||||||
in := Params{
|
in := Params{
|
||||||
"fs": "/",
|
"fs": "/",
|
||||||
}
|
}
|
||||||
f, err := GetFs(in)
|
f, err := GetFs(context.Background(), in)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
assert.NotNil(t, f)
|
assert.NotNil(t, f)
|
||||||
}
|
}
|
||||||
|
@ -53,16 +54,16 @@ func TestGetFsAndRemoteNamed(t *testing.T) {
|
||||||
"fs": "/",
|
"fs": "/",
|
||||||
"remote": "hello",
|
"remote": "hello",
|
||||||
}
|
}
|
||||||
f, remote, err := GetFsAndRemoteNamed(in, "fs", "remote")
|
f, remote, err := GetFsAndRemoteNamed(context.Background(), in, "fs", "remote")
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
assert.NotNil(t, f)
|
assert.NotNil(t, f)
|
||||||
assert.Equal(t, "hello", remote)
|
assert.Equal(t, "hello", remote)
|
||||||
|
|
||||||
f, _, err = GetFsAndRemoteNamed(in, "fsX", "remote")
|
f, _, err = GetFsAndRemoteNamed(context.Background(), in, "fsX", "remote")
|
||||||
require.Error(t, err)
|
require.Error(t, err)
|
||||||
assert.Nil(t, f)
|
assert.Nil(t, f)
|
||||||
|
|
||||||
f, _, err = GetFsAndRemoteNamed(in, "fs", "remoteX")
|
f, _, err = GetFsAndRemoteNamed(context.Background(), in, "fs", "remoteX")
|
||||||
require.Error(t, err)
|
require.Error(t, err)
|
||||||
assert.Nil(t, f)
|
assert.Nil(t, f)
|
||||||
|
|
||||||
|
@ -75,7 +76,7 @@ func TestGetFsAndRemote(t *testing.T) {
|
||||||
"fs": "/",
|
"fs": "/",
|
||||||
"remote": "hello",
|
"remote": "hello",
|
||||||
}
|
}
|
||||||
f, remote, err := GetFsAndRemote(in)
|
f, remote, err := GetFsAndRemote(context.Background(), in)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
assert.NotNil(t, f)
|
assert.NotNil(t, f)
|
||||||
assert.Equal(t, "hello", remote)
|
assert.Equal(t, "hello", remote)
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
package rcserver
|
package rcserver
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
"encoding/base64"
|
"encoding/base64"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"flag"
|
"flag"
|
||||||
|
@ -49,11 +50,11 @@ func init() {
|
||||||
// Start the remote control server if configured
|
// Start the remote control server if configured
|
||||||
//
|
//
|
||||||
// If the server wasn't configured the *Server returned may be nil
|
// If the server wasn't configured the *Server returned may be nil
|
||||||
func Start(opt *rc.Options) (*Server, error) {
|
func Start(ctx context.Context, opt *rc.Options) (*Server, error) {
|
||||||
jobs.SetOpt(opt) // set the defaults for jobs
|
jobs.SetOpt(opt) // set the defaults for jobs
|
||||||
if opt.Enabled {
|
if opt.Enabled {
|
||||||
// Serve on the DefaultServeMux so can have global registrations appear
|
// Serve on the DefaultServeMux so can have global registrations appear
|
||||||
s := newServer(opt, http.DefaultServeMux)
|
s := newServer(ctx, opt, http.DefaultServeMux)
|
||||||
return s, s.Serve()
|
return s, s.Serve()
|
||||||
}
|
}
|
||||||
return nil, nil
|
return nil, nil
|
||||||
|
@ -62,12 +63,13 @@ func Start(opt *rc.Options) (*Server, error) {
|
||||||
// Server contains everything to run the rc server
|
// Server contains everything to run the rc server
|
||||||
type Server struct {
|
type Server struct {
|
||||||
*httplib.Server
|
*httplib.Server
|
||||||
|
ctx context.Context // for global config
|
||||||
files http.Handler
|
files http.Handler
|
||||||
pluginsHandler http.Handler
|
pluginsHandler http.Handler
|
||||||
opt *rc.Options
|
opt *rc.Options
|
||||||
}
|
}
|
||||||
|
|
||||||
func newServer(opt *rc.Options, mux *http.ServeMux) *Server {
|
func newServer(ctx context.Context, opt *rc.Options, mux *http.ServeMux) *Server {
|
||||||
fileHandler := http.Handler(nil)
|
fileHandler := http.Handler(nil)
|
||||||
pluginsHandler := http.Handler(nil)
|
pluginsHandler := http.Handler(nil)
|
||||||
// Add some more mime types which are often missing
|
// Add some more mime types which are often missing
|
||||||
|
@ -113,6 +115,7 @@ func newServer(opt *rc.Options, mux *http.ServeMux) *Server {
|
||||||
|
|
||||||
s := &Server{
|
s := &Server{
|
||||||
Server: httplib.NewServer(mux, &opt.HTTPOptions),
|
Server: httplib.NewServer(mux, &opt.HTTPOptions),
|
||||||
|
ctx: ctx,
|
||||||
opt: opt,
|
opt: opt,
|
||||||
files: fileHandler,
|
files: fileHandler,
|
||||||
pluginsHandler: pluginsHandler,
|
pluginsHandler: pluginsHandler,
|
||||||
|
@ -332,7 +335,7 @@ func (s *Server) serveRoot(w http.ResponseWriter, r *http.Request) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Server) serveRemote(w http.ResponseWriter, r *http.Request, path string, fsName string) {
|
func (s *Server) serveRemote(w http.ResponseWriter, r *http.Request, path string, fsName string) {
|
||||||
f, err := cache.Get(fsName)
|
f, err := cache.Get(s.ctx, fsName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
writeError(path, nil, w, errors.Wrap(err, "failed to make Fs"), http.StatusInternalServerError)
|
writeError(path, nil, w, errors.Wrap(err, "failed to make Fs"), http.StatusInternalServerError)
|
||||||
return
|
return
|
||||||
|
|
|
@ -2,6 +2,7 @@ package rcserver
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
|
@ -37,7 +38,7 @@ func TestRcServer(t *testing.T) {
|
||||||
opt.Serve = true
|
opt.Serve = true
|
||||||
opt.Files = testFs
|
opt.Files = testFs
|
||||||
mux := http.NewServeMux()
|
mux := http.NewServeMux()
|
||||||
rcServer := newServer(&opt, mux)
|
rcServer := newServer(context.Background(), &opt, mux)
|
||||||
assert.NoError(t, rcServer.Serve())
|
assert.NoError(t, rcServer.Serve())
|
||||||
defer func() {
|
defer func() {
|
||||||
rcServer.Close()
|
rcServer.Close()
|
||||||
|
@ -85,7 +86,7 @@ type testRun struct {
|
||||||
func testServer(t *testing.T, tests []testRun, opt *rc.Options) {
|
func testServer(t *testing.T, tests []testRun, opt *rc.Options) {
|
||||||
mux := http.NewServeMux()
|
mux := http.NewServeMux()
|
||||||
opt.HTTPOptions.Template = testTemplate
|
opt.HTTPOptions.Template = testTemplate
|
||||||
rcServer := newServer(opt, mux)
|
rcServer := newServer(context.Background(), opt, mux)
|
||||||
for _, test := range tests {
|
for _, test := range tests {
|
||||||
t.Run(test.Name, func(t *testing.T) {
|
t.Run(test.Name, func(t *testing.T) {
|
||||||
method := test.Method
|
method := test.Method
|
||||||
|
|
|
@ -33,11 +33,11 @@ See the [` + name + ` command](/commands/rclone_` + name + `/) command for more
|
||||||
|
|
||||||
// Sync/Copy/Move a file
|
// Sync/Copy/Move a file
|
||||||
func rcSyncCopyMove(ctx context.Context, in rc.Params, name string) (out rc.Params, err error) {
|
func rcSyncCopyMove(ctx context.Context, in rc.Params, name string) (out rc.Params, err error) {
|
||||||
srcFs, err := rc.GetFsNamed(in, "srcFs")
|
srcFs, err := rc.GetFsNamed(ctx, in, "srcFs")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
dstFs, err := rc.GetFsNamed(in, "dstFs")
|
dstFs, err := rc.GetFsNamed(ctx, in, "dstFs")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
|
@ -201,20 +201,20 @@ func newSyncCopyMove(ctx context.Context, fdst, fsrc fs.Fs, deleteMode fs.Delete
|
||||||
// Make Fs for --backup-dir if required
|
// Make Fs for --backup-dir if required
|
||||||
if fs.Config.BackupDir != "" || fs.Config.Suffix != "" {
|
if fs.Config.BackupDir != "" || fs.Config.Suffix != "" {
|
||||||
var err error
|
var err error
|
||||||
s.backupDir, err = operations.BackupDir(fdst, fsrc, "")
|
s.backupDir, err = operations.BackupDir(ctx, fdst, fsrc, "")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if fs.Config.CompareDest != "" {
|
if fs.Config.CompareDest != "" {
|
||||||
var err error
|
var err error
|
||||||
s.compareCopyDest, err = operations.GetCompareDest()
|
s.compareCopyDest, err = operations.GetCompareDest(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
} else if fs.Config.CopyDest != "" {
|
} else if fs.Config.CopyDest != "" {
|
||||||
var err error
|
var err error
|
||||||
s.compareCopyDest, err = operations.GetCopyDest(fdst)
|
s.compareCopyDest, err = operations.GetCopyDest(ctx, fdst)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
|
@ -71,7 +71,7 @@ func TestCopyMissingDirectory(t *testing.T) {
|
||||||
defer r.Finalise()
|
defer r.Finalise()
|
||||||
r.Mkdir(context.Background(), r.Fremote)
|
r.Mkdir(context.Background(), r.Fremote)
|
||||||
|
|
||||||
nonExistingFs, err := fs.NewFs("/non-existing")
|
nonExistingFs, err := fs.NewFs(context.Background(), "/non-existing")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
@ -1359,7 +1359,7 @@ func TestServerSideMoveOverlap(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
subRemoteName := r.FremoteName + "/rclone-move-test"
|
subRemoteName := r.FremoteName + "/rclone-move-test"
|
||||||
FremoteMove, err := fs.NewFs(subRemoteName)
|
FremoteMove, err := fs.NewFs(context.Background(), subRemoteName)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
file1 := r.WriteObject(context.Background(), "potato2", "------------------------------------------------------------", t1)
|
file1 := r.WriteObject(context.Background(), "potato2", "------------------------------------------------------------", t1)
|
||||||
|
@ -1384,7 +1384,7 @@ func TestSyncOverlap(t *testing.T) {
|
||||||
defer r.Finalise()
|
defer r.Finalise()
|
||||||
|
|
||||||
subRemoteName := r.FremoteName + "/rclone-sync-test"
|
subRemoteName := r.FremoteName + "/rclone-sync-test"
|
||||||
FremoteSync, err := fs.NewFs(subRemoteName)
|
FremoteSync, err := fs.NewFs(context.Background(), subRemoteName)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
checkErr := func(err error) {
|
checkErr := func(err error) {
|
||||||
|
@ -1409,7 +1409,7 @@ func TestSyncCompareDest(t *testing.T) {
|
||||||
fs.Config.CompareDest = ""
|
fs.Config.CompareDest = ""
|
||||||
}()
|
}()
|
||||||
|
|
||||||
fdst, err := fs.NewFs(r.FremoteName + "/dst")
|
fdst, err := fs.NewFs(context.Background(), r.FremoteName+"/dst")
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
// check empty dest, empty compare
|
// check empty dest, empty compare
|
||||||
|
@ -1500,7 +1500,7 @@ func TestSyncCopyDest(t *testing.T) {
|
||||||
fs.Config.CopyDest = ""
|
fs.Config.CopyDest = ""
|
||||||
}()
|
}()
|
||||||
|
|
||||||
fdst, err := fs.NewFs(r.FremoteName + "/dst")
|
fdst, err := fs.NewFs(context.Background(), r.FremoteName+"/dst")
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
// check empty dest, empty copy
|
// check empty dest, empty copy
|
||||||
|
@ -1635,7 +1635,7 @@ func testSyncBackupDir(t *testing.T, backupDir string, suffix string, suffixKeep
|
||||||
fstest.CheckItems(t, r.Fremote, file1, file2, file3)
|
fstest.CheckItems(t, r.Fremote, file1, file2, file3)
|
||||||
fstest.CheckItems(t, r.Flocal, file1a, file2a)
|
fstest.CheckItems(t, r.Flocal, file1a, file2a)
|
||||||
|
|
||||||
fdst, err := fs.NewFs(r.FremoteName + "/dst")
|
fdst, err := fs.NewFs(context.Background(), r.FremoteName+"/dst")
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
accounting.GlobalStats().ResetCounters()
|
accounting.GlobalStats().ResetCounters()
|
||||||
|
@ -1723,7 +1723,7 @@ func testSyncSuffix(t *testing.T, suffix string, suffixKeepExtension bool) {
|
||||||
fstest.CheckItems(t, r.Fremote, file1, file2, file3)
|
fstest.CheckItems(t, r.Fremote, file1, file2, file3)
|
||||||
fstest.CheckItems(t, r.Flocal, file1a, file2a, file3a)
|
fstest.CheckItems(t, r.Flocal, file1a, file2a, file3a)
|
||||||
|
|
||||||
fdst, err := fs.NewFs(r.FremoteName + "/dst")
|
fdst, err := fs.NewFs(context.Background(), r.FremoteName+"/dst")
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
accounting.GlobalStats().ResetCounters()
|
accounting.GlobalStats().ResetCounters()
|
||||||
|
|
|
@ -453,7 +453,7 @@ func RandomRemote() (fs.Fs, string, func(), error) {
|
||||||
return nil, "", nil, err
|
return nil, "", nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
remote, err := fs.NewFs(remoteName)
|
remote, err := fs.NewFs(context.Background(), remoteName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, "", nil, err
|
return nil, "", nil, err
|
||||||
}
|
}
|
||||||
|
|
|
@ -373,7 +373,7 @@ func Run(t *testing.T, opt *Opt) {
|
||||||
// remote - the result of fs.NewFs(TestRemote:subRemoteName)
|
// remote - the result of fs.NewFs(TestRemote:subRemoteName)
|
||||||
subRemoteName, subRemoteLeaf, err = fstest.RandomRemoteName(remoteName)
|
subRemoteName, subRemoteLeaf, err = fstest.RandomRemoteName(remoteName)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
remote, err = fs.NewFs(subRemoteName)
|
remote, err = fs.NewFs(context.Background(), subRemoteName)
|
||||||
if err == fs.ErrorNotFoundInConfigFile {
|
if err == fs.ErrorNotFoundInConfigFile {
|
||||||
t.Logf("Didn't find %q in config file - skipping tests", remoteName)
|
t.Logf("Didn't find %q in config file - skipping tests", remoteName)
|
||||||
return
|
return
|
||||||
|
@ -889,7 +889,7 @@ func Run(t *testing.T, opt *Opt) {
|
||||||
// TestFsListDirRoot tests that DirList works in the root
|
// TestFsListDirRoot tests that DirList works in the root
|
||||||
TestFsListDirRoot := func(t *testing.T) {
|
TestFsListDirRoot := func(t *testing.T) {
|
||||||
skipIfNotOk(t)
|
skipIfNotOk(t)
|
||||||
rootRemote, err := fs.NewFs(remoteName)
|
rootRemote, err := fs.NewFs(context.Background(), remoteName)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
_, dirs, err := walk.GetAll(ctx, rootRemote, "", true, 1)
|
_, dirs, err := walk.GetAll(ctx, rootRemote, "", true, 1)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
@ -1374,7 +1374,7 @@ func Run(t *testing.T, opt *Opt) {
|
||||||
remoteName := subRemoteName + "/" + file2.Path
|
remoteName := subRemoteName + "/" + file2.Path
|
||||||
file2Copy := file2
|
file2Copy := file2
|
||||||
file2Copy.Path = "z.txt"
|
file2Copy.Path = "z.txt"
|
||||||
fileRemote, err := fs.NewFs(remoteName)
|
fileRemote, err := fs.NewFs(context.Background(), remoteName)
|
||||||
require.NotNil(t, fileRemote)
|
require.NotNil(t, fileRemote)
|
||||||
assert.Equal(t, fs.ErrorIsFile, err)
|
assert.Equal(t, fs.ErrorIsFile, err)
|
||||||
|
|
||||||
|
@ -1390,7 +1390,7 @@ func Run(t *testing.T, opt *Opt) {
|
||||||
t.Run("FsIsFileNotFound", func(t *testing.T) {
|
t.Run("FsIsFileNotFound", func(t *testing.T) {
|
||||||
skipIfNotOk(t)
|
skipIfNotOk(t)
|
||||||
remoteName := subRemoteName + "/not found.txt"
|
remoteName := subRemoteName + "/not found.txt"
|
||||||
fileRemote, err := fs.NewFs(remoteName)
|
fileRemote, err := fs.NewFs(context.Background(), remoteName)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
fstest.CheckListing(t, fileRemote, []fstest.Item{})
|
fstest.CheckListing(t, fileRemote, []fstest.Item{})
|
||||||
})
|
})
|
||||||
|
@ -1409,7 +1409,7 @@ func Run(t *testing.T, opt *Opt) {
|
||||||
configName += ":"
|
configName += ":"
|
||||||
}
|
}
|
||||||
t.Logf("Opening root remote %q path %q from %q", configName, configLeaf, subRemoteName)
|
t.Logf("Opening root remote %q path %q from %q", configName, configLeaf, subRemoteName)
|
||||||
rootRemote, err := fs.NewFs(configName)
|
rootRemote, err := fs.NewFs(context.Background(), configName)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
file1Root := file1
|
file1Root := file1
|
||||||
|
@ -1851,7 +1851,7 @@ func Run(t *testing.T, opt *Opt) {
|
||||||
// https://github.com/rclone/rclone/issues/3164.
|
// https://github.com/rclone/rclone/issues/3164.
|
||||||
t.Run("FsRootCollapse", func(t *testing.T) {
|
t.Run("FsRootCollapse", func(t *testing.T) {
|
||||||
deepRemoteName := subRemoteName + "/deeper/nonexisting/directory"
|
deepRemoteName := subRemoteName + "/deeper/nonexisting/directory"
|
||||||
deepRemote, err := fs.NewFs(deepRemoteName)
|
deepRemote, err := fs.NewFs(context.Background(), deepRemoteName)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
colonIndex := strings.IndexRune(deepRemoteName, ':')
|
colonIndex := strings.IndexRune(deepRemoteName, ':')
|
||||||
|
|
|
@ -102,7 +102,7 @@ func newRun() *Run {
|
||||||
r.Fatalf("Failed to create temp dir: %v", err)
|
r.Fatalf("Failed to create temp dir: %v", err)
|
||||||
}
|
}
|
||||||
r.LocalName = filepath.ToSlash(r.LocalName)
|
r.LocalName = filepath.ToSlash(r.LocalName)
|
||||||
r.Flocal, err = fs.NewFs(r.LocalName)
|
r.Flocal, err = fs.NewFs(context.Background(), r.LocalName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
r.Fatalf("Failed to make %q: %v", r.LocalName, err)
|
r.Fatalf("Failed to make %q: %v", r.LocalName, err)
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,7 +20,7 @@ var MatchTestRemote = regexp.MustCompile(`^rclone-test-[abcdefghijklmnopqrstuvwx
|
||||||
|
|
||||||
// cleanFs runs a single clean fs for left over directories
|
// cleanFs runs a single clean fs for left over directories
|
||||||
func cleanFs(ctx context.Context, remote string, cleanup bool) error {
|
func cleanFs(ctx context.Context, remote string, cleanup bool) error {
|
||||||
f, err := fs.NewFs(remote)
|
f, err := fs.NewFs(context.Background(), remote)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -46,7 +46,7 @@ func cleanFs(ctx context.Context, remote string, cleanup bool) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
log.Printf("Purging %s", fullPath)
|
log.Printf("Purging %s", fullPath)
|
||||||
dir, err := fs.NewFs(fullPath)
|
dir, err := fs.NewFs(context.Background(), fullPath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
err = errors.Wrap(err, "NewFs failed")
|
err = errors.Wrap(err, "NewFs failed")
|
||||||
lastErr = err
|
lastErr = err
|
||||||
|
|
|
@ -86,11 +86,11 @@ func New(ctx context.Context, fremote fs.Fs, opt *vfscommon.Options, avFn AddVir
|
||||||
metaRoot := file.UNCPath(filepath.Join(config.CacheDir, "vfsMeta", fremote.Name(), fRoot))
|
metaRoot := file.UNCPath(filepath.Join(config.CacheDir, "vfsMeta", fremote.Name(), fRoot))
|
||||||
fs.Debugf(nil, "vfs cache: metadata root is %q", root)
|
fs.Debugf(nil, "vfs cache: metadata root is %q", root)
|
||||||
|
|
||||||
fcache, err := fscache.Get(root)
|
fcache, err := fscache.Get(ctx, root)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errors.Wrap(err, "failed to create cache remote")
|
return nil, errors.Wrap(err, "failed to create cache remote")
|
||||||
}
|
}
|
||||||
fcacheMeta, err := fscache.Get(root)
|
fcacheMeta, err := fscache.Get(ctx, root)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errors.Wrap(err, "failed to create cache meta remote")
|
return nil, errors.Wrap(err, "failed to create cache meta remote")
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue