vfs: add context parameter to New() for config propagation
Add a ctx parameter to vfs.New() so callers can pass in context carrying ConfigInfo and FilterInfo. The context is stripped of cancellation but config and filter values are preserved into a fresh background context.
This commit is contained in:
@@ -36,7 +36,7 @@ func New(ctx context.Context, wrappedFs fs.Fs, remote, prefix, root string) (*Fs
|
|||||||
// FIXME vfs cache?
|
// FIXME vfs cache?
|
||||||
// FIXME could factor out ReadFileHandle and just use that rather than the full VFS
|
// FIXME could factor out ReadFileHandle and just use that rather than the full VFS
|
||||||
fs.Debugf(nil, "New: remote=%q, prefix=%q, root=%q", remote, prefix, root)
|
fs.Debugf(nil, "New: remote=%q, prefix=%q, root=%q", remote, prefix, root)
|
||||||
VFS := vfs.New(wrappedFs, nil)
|
VFS := vfs.New(ctx, wrappedFs, nil)
|
||||||
node, err := VFS.Stat(remote)
|
node, err := VFS.Stat(remote)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("failed to find %q archive: %w", remote, err)
|
return nil, fmt.Errorf("failed to find %q archive: %w", remote, err)
|
||||||
|
|||||||
@@ -50,7 +50,7 @@ func New(ctx context.Context, wrappedFs fs.Fs, remote, prefix, root string) (fs.
|
|||||||
fs.Debugf(nil, "Squashfs: New: remote=%q, prefix=%q, root=%q", remote, prefix, root)
|
fs.Debugf(nil, "Squashfs: New: remote=%q, prefix=%q, root=%q", remote, prefix, root)
|
||||||
vfsOpt := vfscommon.Opt
|
vfsOpt := vfscommon.Opt
|
||||||
vfsOpt.ReadWait = 0
|
vfsOpt.ReadWait = 0
|
||||||
VFS := vfs.New(wrappedFs, &vfsOpt)
|
VFS := vfs.New(ctx, wrappedFs, &vfsOpt)
|
||||||
node, err := VFS.Stat(remote)
|
node, err := VFS.Stat(remote)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("failed to find %q archive: %w", remote, err)
|
return nil, fmt.Errorf("failed to find %q archive: %w", remote, err)
|
||||||
|
|||||||
@@ -52,7 +52,7 @@ func New(ctx context.Context, wrappedFs fs.Fs, remote, prefix, root string) (fs.
|
|||||||
fs.Debugf(nil, "Zip: New: remote=%q, prefix=%q, root=%q", remote, prefix, root)
|
fs.Debugf(nil, "Zip: New: remote=%q, prefix=%q, root=%q", remote, prefix, root)
|
||||||
vfsOpt := vfscommon.Opt
|
vfsOpt := vfscommon.Opt
|
||||||
vfsOpt.ReadWait = 0
|
vfsOpt.ReadWait = 0
|
||||||
VFS := vfs.New(wrappedFs, &vfsOpt)
|
VFS := vfs.New(ctx, wrappedFs, &vfsOpt)
|
||||||
node, err := VFS.Stat(remote)
|
node, err := VFS.Stat(remote)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("failed to find %q archive: %w", remote, err)
|
return nil, fmt.Errorf("failed to find %q archive: %w", remote, err)
|
||||||
|
|||||||
@@ -369,7 +369,7 @@ func (m *MountPoint) Mount() (mountDaemon *os.Process, err error) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
m.VFS = vfs.New(m.Fs, &m.VFSOpt)
|
m.VFS = vfs.New(context.Background(), m.Fs, &m.VFSOpt)
|
||||||
|
|
||||||
m.ErrChan, m.UnmountFn, err = m.MountFn(m.VFS, m.MountPoint, &m.MountOpt)
|
m.ErrChan, m.UnmountFn, err = m.MountFn(m.VFS, m.MountPoint, &m.MountOpt)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
@@ -40,7 +40,7 @@ func TestMount(t *testing.T) {
|
|||||||
nfs.Opt.HandleCacheDir = t.TempDir()
|
nfs.Opt.HandleCacheDir = t.TempDir()
|
||||||
require.NoError(t, nfs.Opt.HandleCache.Set(cacheType))
|
require.NoError(t, nfs.Opt.HandleCache.Set(cacheType))
|
||||||
// Check we can create a handler
|
// Check we can create a handler
|
||||||
_, err := nfs.NewHandler(context.Background(), vfs.New(object.MemoryFs, nil), &nfs.Opt)
|
_, err := nfs.NewHandler(context.Background(), vfs.New(context.Background(), object.MemoryFs, nil), &nfs.Opt)
|
||||||
if errors.Is(err, nfs.ErrorSymlinkCacheNotSupported) || errors.Is(err, nfs.ErrorSymlinkCacheNoPermission) {
|
if errors.Is(err, nfs.ErrorSymlinkCacheNotSupported) || errors.Is(err, nfs.ErrorSymlinkCacheNoPermission) {
|
||||||
t.Skip(err.Error() + ": run with: go test -c && sudo setcap cap_dac_read_search+ep ./nfsmount.test && ./nfsmount.test -test.v")
|
t.Skip(err.Error() + ": run with: go test -c && sudo setcap cap_dac_read_search+ep ./nfsmount.test && ./nfsmount.test -test.v")
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ func TestMediaWithResources(t *testing.T) {
|
|||||||
fs, err := localBackend.NewFs(context.Background(), "testdatafiles", "testdata/files", configmap.New())
|
fs, err := localBackend.NewFs(context.Background(), "testdatafiles", "testdata/files", configmap.New())
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
myvfs := vfs.New(fs, nil)
|
myvfs := vfs.New(context.Background(), fs, nil)
|
||||||
{
|
{
|
||||||
rootNode, err := myvfs.Stat("")
|
rootNode, err := myvfs.Stat("")
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|||||||
@@ -203,7 +203,7 @@ func newServer(ctx context.Context, f fs.Fs, opt *Options, vfsOpt *vfscommon.Opt
|
|||||||
waitChan: make(chan struct{}),
|
waitChan: make(chan struct{}),
|
||||||
httpListenAddr: opt.ListenAddr,
|
httpListenAddr: opt.ListenAddr,
|
||||||
f: f,
|
f: f,
|
||||||
vfs: vfs.New(f, vfsOpt),
|
vfs: vfs.New(ctx, f, vfsOpt),
|
||||||
}
|
}
|
||||||
|
|
||||||
s.services = map[string]UPnPService{
|
s.services = map[string]UPnPService{
|
||||||
|
|||||||
@@ -203,7 +203,7 @@ func newServer(ctx context.Context, f fs.Fs, opt *Options, vfsOpt *vfscommon.Opt
|
|||||||
d.proxy = proxy.New(ctx, proxyOpt, vfsOpt)
|
d.proxy = proxy.New(ctx, proxyOpt, vfsOpt)
|
||||||
d.userPass = make(map[string]string, 16)
|
d.userPass = make(map[string]string, 16)
|
||||||
} else {
|
} else {
|
||||||
d.globalVFS = vfs.New(f, vfsOpt)
|
d.globalVFS = vfs.New(ctx, f, vfsOpt)
|
||||||
}
|
}
|
||||||
d.useTLS = d.opt.TLSKey != ""
|
d.useTLS = d.opt.TLSKey != ""
|
||||||
|
|
||||||
|
|||||||
@@ -188,7 +188,7 @@ func newServer(ctx context.Context, f fs.Fs, opt *Options, vfsOpt *vfscommon.Opt
|
|||||||
// override auth
|
// override auth
|
||||||
s.opt.Auth.CustomAuthFn = s.auth
|
s.opt.Auth.CustomAuthFn = s.auth
|
||||||
} else {
|
} else {
|
||||||
s._vfs = vfs.New(f, vfsOpt)
|
s._vfs = vfs.New(ctx, f, vfsOpt)
|
||||||
}
|
}
|
||||||
|
|
||||||
s.server, err = libhttp.NewServer(ctx,
|
s.server, err = libhttp.NewServer(ctx,
|
||||||
|
|||||||
@@ -122,7 +122,7 @@ func TestCache(t *testing.T) {
|
|||||||
for _, cacheType := range []handleCache{cacheMemory, cacheDisk, cacheSymlink} {
|
for _, cacheType := range []handleCache{cacheMemory, cacheDisk, cacheSymlink} {
|
||||||
t.Run(cacheType.String(), func(t *testing.T) {
|
t.Run(cacheType.String(), func(t *testing.T) {
|
||||||
h := &Handler{
|
h := &Handler{
|
||||||
vfs: vfs.New(object.MemoryFs, nil),
|
vfs: vfs.New(context.Background(), object.MemoryFs, nil),
|
||||||
billyFS: billyFS,
|
billyFS: billyFS,
|
||||||
}
|
}
|
||||||
h.vfs.Opt.MetadataExtension = ".metadata"
|
h.vfs.Opt.MetadataExtension = ".metadata"
|
||||||
|
|||||||
@@ -94,7 +94,7 @@ func init() {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
VFS := vfs.New(f, &vfsOpt)
|
VFS := vfs.New(ctx, f, &vfsOpt)
|
||||||
// Read opts
|
// Read opts
|
||||||
var opt = Opt // set default opts
|
var opt = Opt // set default opts
|
||||||
err = configstruct.SetAny(in, &opt)
|
err = configstruct.SetAny(in, &opt)
|
||||||
@@ -112,7 +112,7 @@ func Run(command *cobra.Command, args []string) {
|
|||||||
cmd.CheckArgs(1, 1, command, args)
|
cmd.CheckArgs(1, 1, command, args)
|
||||||
f = cmd.NewFsSrc(args)
|
f = cmd.NewFsSrc(args)
|
||||||
cmd.Run(false, true, command, func() error {
|
cmd.Run(false, true, command, func() error {
|
||||||
s, err := NewServer(context.Background(), vfs.New(f, &vfscommon.Opt), &Opt)
|
s, err := NewServer(context.Background(), vfs.New(context.Background(), f, &vfscommon.Opt), &Opt)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -257,7 +257,7 @@ func (p *Proxy) call(user, auth string, isPublicKey bool) (value any, err error)
|
|||||||
// need to in memory. An attacker would find it easier to go
|
// need to in memory. An attacker would find it easier to go
|
||||||
// after the unencrypted password in memory most likely.
|
// after the unencrypted password in memory most likely.
|
||||||
entry := cacheEntry{
|
entry := cacheEntry{
|
||||||
vfs: vfs.New(f, &p.vfsOpt),
|
vfs: vfs.New(p.ctx, f, &p.vfsOpt),
|
||||||
pwHash: sha256.Sum256([]byte(auth)),
|
pwHash: sha256.Sum256([]byte(auth)),
|
||||||
}
|
}
|
||||||
return entry, true, nil
|
return entry, true, nil
|
||||||
|
|||||||
@@ -94,7 +94,7 @@ func newServer(ctx context.Context, f fs.Fs, opt *Options, vfsOpt *vfscommon.Opt
|
|||||||
w.handler = proxyAuthMiddleware(w.handler, w)
|
w.handler = proxyAuthMiddleware(w.handler, w)
|
||||||
w.handler = authPairMiddleware(w.handler, w)
|
w.handler = authPairMiddleware(w.handler, w)
|
||||||
} else {
|
} else {
|
||||||
w._vfs = vfs.New(f, vfsOpt)
|
w._vfs = vfs.New(ctx, f, vfsOpt)
|
||||||
|
|
||||||
if len(opt.AuthKey) > 0 {
|
if len(opt.AuthKey) > 0 {
|
||||||
w.faker.AddAuthKeys(authList)
|
w.faker.AddAuthKeys(authList)
|
||||||
|
|||||||
@@ -358,7 +358,7 @@ func serveStdio(f fs.Fs) error {
|
|||||||
stdin: os.Stdin,
|
stdin: os.Stdin,
|
||||||
stdout: os.Stdout,
|
stdout: os.Stdout,
|
||||||
}
|
}
|
||||||
handlers := newVFSHandler(vfs.New(f, &vfscommon.Opt))
|
handlers := newVFSHandler(vfs.New(context.Background(), f, &vfscommon.Opt))
|
||||||
return serveChannel(sshChannel, handlers, "stdio")
|
return serveChannel(sshChannel, handlers, "stdio")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -55,7 +55,7 @@ func newServer(ctx context.Context, f fs.Fs, opt *Options, vfsOpt *vfscommon.Opt
|
|||||||
if proxy.Opt.AuthProxy != "" {
|
if proxy.Opt.AuthProxy != "" {
|
||||||
s.proxy = proxy.New(ctx, proxyOpt, vfsOpt)
|
s.proxy = proxy.New(ctx, proxyOpt, vfsOpt)
|
||||||
} else {
|
} else {
|
||||||
s.vfs = vfs.New(f, vfsOpt)
|
s.vfs = vfs.New(ctx, f, vfsOpt)
|
||||||
}
|
}
|
||||||
err := s.configure()
|
err := s.configure()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
@@ -263,7 +263,7 @@ func newWebDAV(ctx context.Context, f fs.Fs, opt *Options, vfsOpt *vfscommon.Opt
|
|||||||
// override auth
|
// override auth
|
||||||
w.opt.Auth.CustomAuthFn = w.auth
|
w.opt.Auth.CustomAuthFn = w.auth
|
||||||
} else {
|
} else {
|
||||||
w._vfs = vfs.New(f, vfsOpt)
|
w._vfs = vfs.New(ctx, f, vfsOpt)
|
||||||
}
|
}
|
||||||
|
|
||||||
w.server, err = libhttp.NewServer(ctx,
|
w.server, err = libhttp.NewServer(ctx,
|
||||||
|
|||||||
+1
-1
@@ -202,7 +202,7 @@ func TestFileOpenReadUnknownSize(t *testing.T) {
|
|||||||
assert.Equal(t, int64(-1), testObj.Size())
|
assert.Equal(t, int64(-1), testObj.Size())
|
||||||
|
|
||||||
// create a VFS from that mockfs
|
// create a VFS from that mockfs
|
||||||
vfs := New(f, nil)
|
vfs := New(context.Background(), f, nil)
|
||||||
defer cleanupVFS(t, vfs)
|
defer cleanupVFS(t, vfs)
|
||||||
|
|
||||||
// find the file
|
// find the file
|
||||||
|
|||||||
+1
-1
@@ -48,7 +48,7 @@ func TestRcGetVFS(t *testing.T) {
|
|||||||
|
|
||||||
opt := vfscommon.Opt
|
opt := vfscommon.Opt
|
||||||
opt.NoModTime = true
|
opt.NoModTime = true
|
||||||
vfs3 := New(r.Fremote, &opt)
|
vfs3 := New(context.Background(), r.Fremote, &opt)
|
||||||
defer vfs3.Shutdown()
|
defer vfs3.Shutdown()
|
||||||
|
|
||||||
vfs, err = getVFS(in)
|
vfs, err = getVFS(in)
|
||||||
|
|||||||
+12
-3
@@ -38,6 +38,7 @@ import (
|
|||||||
"github.com/go-git/go-billy/v5"
|
"github.com/go-git/go-billy/v5"
|
||||||
"github.com/rclone/rclone/fs"
|
"github.com/rclone/rclone/fs"
|
||||||
"github.com/rclone/rclone/fs/cache"
|
"github.com/rclone/rclone/fs/cache"
|
||||||
|
"github.com/rclone/rclone/fs/filter"
|
||||||
"github.com/rclone/rclone/fs/log"
|
"github.com/rclone/rclone/fs/log"
|
||||||
"github.com/rclone/rclone/fs/rc"
|
"github.com/rclone/rclone/fs/rc"
|
||||||
"github.com/rclone/rclone/fs/walk"
|
"github.com/rclone/rclone/fs/walk"
|
||||||
@@ -196,10 +197,18 @@ var (
|
|||||||
)
|
)
|
||||||
|
|
||||||
// New creates a new VFS and root directory. If opt is nil, then
|
// New creates a new VFS and root directory. If opt is nil, then
|
||||||
// DefaultOpt will be used
|
// DefaultOpt will be used.
|
||||||
func New(f fs.Fs, opt *vfscommon.Options) *VFS {
|
//
|
||||||
|
// The ctx passed in is not used for cancellation but is used to find
|
||||||
|
// the config in the context (if any) and filter config in the context
|
||||||
|
// (if any).
|
||||||
|
func New(ctx context.Context, f fs.Fs, opt *vfscommon.Options) *VFS {
|
||||||
fsDir := fs.NewDir("", time.Now())
|
fsDir := fs.NewDir("", time.Now())
|
||||||
ctx, cancel := context.WithCancel(context.Background())
|
// Strip the ctx of any cancellation but copy the config across
|
||||||
|
newCtx := context.Background()
|
||||||
|
newCtx = fs.CopyConfig(newCtx, ctx)
|
||||||
|
newCtx = filter.CopyConfig(newCtx, ctx)
|
||||||
|
ctx, cancel := context.WithCancel(newCtx)
|
||||||
vfs := &VFS{
|
vfs := &VFS{
|
||||||
f: f,
|
f: f,
|
||||||
ctx: ctx,
|
ctx: ctx,
|
||||||
|
|||||||
@@ -36,12 +36,12 @@ func TestCaseSensitivity(t *testing.T) {
|
|||||||
// Create a case-Sensitive and case-INsensitive VFS
|
// Create a case-Sensitive and case-INsensitive VFS
|
||||||
optCS := vfscommon.Opt
|
optCS := vfscommon.Opt
|
||||||
optCS.CaseInsensitive = false
|
optCS.CaseInsensitive = false
|
||||||
vfsCS := New(r.Fremote, &optCS)
|
vfsCS := New(context.Background(), r.Fremote, &optCS)
|
||||||
defer cleanupVFS(t, vfsCS)
|
defer cleanupVFS(t, vfsCS)
|
||||||
|
|
||||||
optCI := vfscommon.Opt
|
optCI := vfscommon.Opt
|
||||||
optCI.CaseInsensitive = true
|
optCI.CaseInsensitive = true
|
||||||
vfsCI := New(r.Fremote, &optCI)
|
vfsCI := New(context.Background(), r.Fremote, &optCI)
|
||||||
defer cleanupVFS(t, vfsCI)
|
defer cleanupVFS(t, vfsCI)
|
||||||
|
|
||||||
// Run basic checks that must pass on VFS of any type.
|
// Run basic checks that must pass on VFS of any type.
|
||||||
@@ -180,7 +180,7 @@ func TestUnicodeNormalization(t *testing.T) {
|
|||||||
|
|
||||||
// Create VFS
|
// Create VFS
|
||||||
opt := vfscommon.Opt
|
opt := vfscommon.Opt
|
||||||
vfs := New(r.Fremote, &opt)
|
vfs := New(context.Background(), r.Fremote, &opt)
|
||||||
defer cleanupVFS(t, vfs)
|
defer cleanupVFS(t, vfs)
|
||||||
|
|
||||||
// assert that both files are found under NFD-normalized names
|
// assert that both files are found under NFD-normalized names
|
||||||
|
|||||||
+2
-2
@@ -47,7 +47,7 @@ func cleanupVFS(t *testing.T, vfs *VFS) {
|
|||||||
// Create a new VFS
|
// Create a new VFS
|
||||||
func newTestVFSOpt(t *testing.T, opt *vfscommon.Options) (r *fstest.Run, vfs *VFS) {
|
func newTestVFSOpt(t *testing.T, opt *vfscommon.Options) (r *fstest.Run, vfs *VFS) {
|
||||||
r = fstest.NewRun(t)
|
r = fstest.NewRun(t)
|
||||||
vfs = New(r.Fremote, opt)
|
vfs = New(context.Background(), r.Fremote, opt)
|
||||||
t.Cleanup(func() {
|
t.Cleanup(func() {
|
||||||
cleanupVFS(t, vfs)
|
cleanupVFS(t, vfs)
|
||||||
})
|
})
|
||||||
@@ -144,7 +144,7 @@ func TestVFSNew(t *testing.T) {
|
|||||||
|
|
||||||
// Check that we get the same VFS if we ask for it again with
|
// Check that we get the same VFS if we ask for it again with
|
||||||
// the same options
|
// the same options
|
||||||
vfs2 := New(r.Fremote, nil)
|
vfs2 := New(context.Background(), r.Fremote, nil)
|
||||||
assert.Equal(t, fmt.Sprintf("%p", vfs), fmt.Sprintf("%p", vfs2))
|
assert.Equal(t, fmt.Sprintf("%p", vfs), fmt.Sprintf("%p", vfs2))
|
||||||
|
|
||||||
checkActiveCacheEntries(1)
|
checkActiveCacheEntries(1)
|
||||||
|
|||||||
@@ -41,7 +41,7 @@ func (r *Run) startMountSubProcess() {
|
|||||||
// If testing the VFS we don't start a subprocess, we just use
|
// If testing the VFS we don't start a subprocess, we just use
|
||||||
// the VFS directly
|
// the VFS directly
|
||||||
if r.useVFS {
|
if r.useVFS {
|
||||||
vfs := vfs.New(r.fremote, r.vfsOpt)
|
vfs := vfs.New(context.Background(), r.fremote, r.vfsOpt)
|
||||||
r.os = vfsOs{vfs}
|
r.os = vfsOs{vfs}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user