Non-interactive rc mount

I am using the rc mount code in my own GoLang implementation. Is there a way to execute this in non-interactive mode? At the moment when I execute a mount on an encrypted file I get:

2022/10/25 09:52:39 ERROR : Couldn't decrypt configuration, most likely wrong password.
Enter configuration password:
password:

I would like it to exit as an error. I see lots of flags for silencing, but none that seem to be accessible through the rc?

_, err := mountRclone(context.Background(), rc.Params{"fs": "encrypted_storage:", "mountPoint": "./test338", "mountType": "mount", "mountOpt": "{\"AllowNonEmpty\": true}"})
func mountRclone(ctx context.Context, in rc.Params) (out rc.Params, err error) {
	mountPoint, err := in.GetString("mountPoint")
	if err != nil {
		fmt.Println(err)
		return nil, err
	}

	vfsOpt := vfsflags.Opt
	err = in.GetStructMissingOK("vfsOpt", &vfsOpt)
	if err != nil {
		fmt.Println(err)
		return nil, err
	}

	mountOpt := mountlib.Options{AllowOther: true}
	err = in.GetStructMissingOK("mountOpt", &mountOpt)
	if err != nil {
		fmt.Println(err)
		return nil, err
	}

	mountType, err := in.GetString("mountType")

	mountMu.Lock()
	defer mountMu.Unlock()

	if err != nil {
		mountType = ""
	}
	mountType, mountFn := mountlib.ResolveMountMethod(mountType)
	if mountFn == nil {
		return nil, errors.New("mount Option specified is not registered, or is invalid")
	}

	// Get Fs.fs to be mounted from fs parameter in the params
	fdst, err := rc.GetFs(ctx, in)
	if err != nil {
		fmt.Println(err)
		return nil, err
	}

	mnt := mountlib.NewMountPoint(mountFn, mountPoint, fdst, &mountOpt, &vfsOpt)
	_, err = mnt.Mount()
	if err != nil {
		log.Printf("mount FAILED: %v", err)
		return nil, err
	}

	// Add mount to list if mount point was successfully created
	liveMounts[mountPoint] = mnt

	fmt.Println(nil, "Mount for %s created at %s using %s", fdst.String(), mountPoint, mountType) //TODO: Remove this line
	return nil, nil
}

I think this is the flag you want

  --ask-password                    Allow prompt for password for encrypted configuration (default true)

You should be able to set it to False when passing in global options.

Like this?

	mountParams := rc.Params{
		"fs":         "encrypted_storage:",
		"mountPoint": mountPoint, // TODO:
		"mountType":  "mount",
		"mountOpt":   "{\"AllowNonEmpty\": true}",
		"_config":    "{\"AskPassword\": false}"}

	// Mount the volumes
	_, err := mountRclone(context.Background(), mountParams)

I can't see where _config gets processed, and is still prompting for a password.

I think you will have to set the global config rather than the command specific config as I can see from the code the context isn't passed into the decrypt routines.

If you were using rclone rc that would be

rclone rc options/set --json '{"main": {"AskPassword": false}}'

I'm using the rc code snippet, but doing it all directly in GoLang rather than through the CLI. I have called that snippet of code above but can't pass through the AskPassword or NonInteractive there. Is there a way to set it globally? I had a look for something like config.Options(x, x), like I use config.SetConfigPath(rcloneConfFile). Not sure how else to get around this one.

You will need a separate rc call to options/set first - that should work.

1 Like

This one is definitely keeping me up. I am trying the function from rc:

// Set an option in an option block
func rcOptionsSet(ctx context.Context, in Params) (out Params, err error) {
	for name, options := range in {
		current := optionBlock[name]
		if current == nil {
			return nil, fmt.Errorf("unknown option block %q", name)
		}
		err := Reshape(current, options)
		if err != nil {
			return nil, fmt.Errorf("failed to write options from block %q: %w", name, err)
		}
		if reload := optionReload[name]; reload != nil {
			err = reload(ctx)
			if err != nil {
				return nil, fmt.Errorf("failed to reload options from block %q: %w", name, err)
			}
		}
	}
	return out, nil
}

It seems like the option block is always empty, I keep getting unknown option block

The JSON needs to look like this

{
    "main": {
        "AskPassword": false
    }
}

Are you running a standard rclone rcd or are you running in process? Maybe you didn't initialise the config properly?

I think you're probably right, I haven't initiated the config properly. When passing this in to the function:

	globalParams := Params{
		"main": "{\"AskPassword\": false}"}

I get this error:
unknown option block "main"

The easiest way to do this is to use librclone and call the Initialize function - I think that should do it

I already had the config.Install() in their which I think was taking care of the initialisation.

I ended up managing to apply it with:

// Never ask for passwords, fail instead.
ci := fs.GetConfig(context.Background())
ci.AskPassword = false

And then the rest of the script, including configfile.Install().

I really appreciate all your input you have been giving on these things, it makes all the difference to push through when these things arise. :pray:

1 Like

This topic was automatically closed 60 days after the last reply. New replies are no longer allowed.