mount: fix mount failure on macOS with on the fly remote

This commit

3567a47258 fs: make ConfigString properly reverse suffixed file systems

made fs.ConfigString() return the full config of the backend. Because
mount was using this to make a volume name it started to make volume
names with illegal characters in which couldn't be mounted by macOS.

This fixes the problem by making a separate fs.ConfigStringFull() and
using that where appropriate and leaving the original
fs.ConfigString() function untouched.

Fixes #7063
See: https://forum.rclone.org/t/1-63-beta-fails-to-mount-on-macos-with-on-the-fly-crypt-remote/39090
This commit is contained in:
Nick Craig-Wood 2023-06-20 17:38:17 +01:00
parent 22d6c8d30d
commit 2c50f26c36
3 changed files with 24 additions and 7 deletions

View File

@ -318,7 +318,7 @@ func (f *Fs) InternalTestVersions(t *testing.T) {
// Check we can make a NewFs from that object with a version suffix // Check we can make a NewFs from that object with a version suffix
t.Run("NewFs", func(t *testing.T) { t.Run("NewFs", func(t *testing.T) {
newPath := bucket.Join(fs.ConfigString(f), fileNameVersion) newPath := bucket.Join(fs.ConfigStringFull(f), fileNameVersion)
// Make sure --s3-versions is set in the config of the new remote // Make sure --s3-versions is set in the config of the new remote
fs.Debugf(nil, "oldPath = %q", newPath) fs.Debugf(nil, "oldPath = %q", newPath)
lastColon := strings.LastIndex(newPath, ":") lastColon := strings.LastIndex(newPath, ":")
@ -330,7 +330,7 @@ func (f *Fs) InternalTestVersions(t *testing.T) {
require.Equal(t, fs.ErrorIsFile, err) require.Equal(t, fs.ErrorIsFile, err)
require.NotNil(t, fNew) require.NotNil(t, fNew)
// With the directory the directory above // With the directory the directory above
assert.Equal(t, dirName, path.Base(fs.ConfigString(fNew))) assert.Equal(t, dirName, path.Base(fs.ConfigStringFull(fNew)))
}) })
}) })

View File

@ -115,11 +115,11 @@ func ParseRemote(path string) (fsInfo *RegInfo, configName, fsPath string, conne
return fsInfo, configName, fsPath, parsed.Config, err return fsInfo, configName, fsPath, parsed.Config, err
} }
// ConfigString returns a canonical version of the config string used // configString returns a canonical version of the config string used
// to configure the Fs as passed to fs.NewFs // to configure the Fs as passed to fs.NewFs
func ConfigString(f Fs) string { func configString(f Fs, full bool) string {
name := f.Name() name := f.Name()
if open := strings.IndexRune(name, '{'); open >= 0 && strings.HasSuffix(name, "}") { if open := strings.IndexRune(name, '{'); full && open >= 0 && strings.HasSuffix(name, "}") {
suffix := name[open:] suffix := name[open:]
overriddenConfigMu.Lock() overriddenConfigMu.Lock()
config, ok := overriddenConfig[suffix] config, ok := overriddenConfig[suffix]
@ -137,6 +137,21 @@ func ConfigString(f Fs) string {
return name + ":" + root return name + ":" + root
} }
// ConfigString returns a canonical version of the config string used
// to configure the Fs as passed to fs.NewFs. For Fs with extra
// parameters this will include a canonical {hexstring} suffix.
func ConfigString(f Fs) string {
return configString(f, false)
}
// ConfigStringFull returns a canonical version of the config string
// used to configure the Fs as passed to fs.NewFs. This string can be
// used to re-instantiate the Fs exactly so includes all the extra
// parameters passed in.
func ConfigStringFull(f Fs) string {
return configString(f, true)
}
// 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.

View File

@ -32,12 +32,14 @@ func TestNewFs(t *testing.T) {
assert.Equal(t, ":mockfs{S_NHG}", f2.Name()) assert.Equal(t, ":mockfs{S_NHG}", f2.Name())
assert.Equal(t, "/tmp", f2.Root()) assert.Equal(t, "/tmp", f2.Root())
assert.Equal(t, ":mockfs,potato='true':/tmp", fs.ConfigString(f2)) assert.Equal(t, ":mockfs{S_NHG}:/tmp", fs.ConfigString(f2))
assert.Equal(t, ":mockfs,potato='true':/tmp", fs.ConfigStringFull(f2))
f3, err := fs.NewFs(ctx, ":mockfs,potato='true':/tmp") f3, err := fs.NewFs(ctx, ":mockfs,potato='true':/tmp")
require.NoError(t, err) require.NoError(t, err)
assert.Equal(t, ":mockfs{S_NHG}", f3.Name()) assert.Equal(t, ":mockfs{S_NHG}", f3.Name())
assert.Equal(t, "/tmp", f3.Root()) assert.Equal(t, "/tmp", f3.Root())
assert.Equal(t, ":mockfs,potato='true':/tmp", fs.ConfigString(f3)) assert.Equal(t, ":mockfs{S_NHG}:/tmp", fs.ConfigString(f3))
assert.Equal(t, ":mockfs,potato='true':/tmp", fs.ConfigStringFull(f3))
} }