From 6ecb5794bc16ffdec66a3d1d9216e2f814d4f4af Mon Sep 17 00:00:00 2001 From: Nick Craig-Wood Date: Sat, 12 Dec 2020 17:40:29 +0000 Subject: [PATCH] rc: add _config parameter to set global config for just this rc call --- docs/content/rc.md | 34 ++++++++++++++++++++++++++++++++-- fs/rc/jobs/job.go | 20 ++++++++++++++++++++ fs/rc/jobs/job_test.go | 24 ++++++++++++++++++++++++ 3 files changed, 76 insertions(+), 2 deletions(-) diff --git a/docs/content/rc.md b/docs/content/rc.md index fb6df1cae..af30eb938 100644 --- a/docs/content/rc.md +++ b/docs/content/rc.md @@ -273,6 +273,36 @@ $ rclone rc job/list } ``` +### Setting config flags with _config + +If you wish to set config (the equivalent of the global flags) for the +duration of an rc call only then pass in the `_config` parameter. + +This should be in the same format as the `config` key returned by +[options/get](#options-get). + +For example, if you wished to run a sync with the `--checksum` +parameter, you would pass this parameter in your JSON blob. + + "_config":{"CheckSum": true} + +If using `rclone rc` this could be passed as + + rclone rc operations/sync ... _config='{"CheckSum": true}' + +Any config parameters you don't set will inherit the global defaults +which were set with command line flags or environment variables. + +Note that it is possible to set some values as strings or integers - +see [data types](/#data-types) for more info. Here is an example +setting the equivalent of `--buffer-size` in string or integer format. + + "_config":{"BufferSize": "42M"} + "_config":{"BufferSize": 44040192} + +If you wish to check the `_config` assignment has worked properly then +calling `options/local` will show what the value got set to. + ### Assigning operations to groups with _group = value Each rc call has its own stats group for tracking its metrics. By default @@ -292,14 +322,14 @@ $ rclone rc --json '{ "group": "job/1" }' core/stats } ``` -## Data types +## Data types {#data-types} When the API returns types, these will mostly be straight forward integer, string or boolean types. However some of the types returned by the [options/get](#options-get) call and taken by the [options/set](#options-set) calls as well as the -`vfsOpt` and the `mountOpt` are as follows: +`vfsOpt`, `mountOpt` and the `_config` parameters. - `Duration` - these are returned as an integer duration in nanoseconds. They may be set as an integer, or they may be set with diff --git a/fs/rc/jobs/job.go b/fs/rc/jobs/job.go index e5fdae076..9dbb34fa6 100644 --- a/fs/rc/jobs/job.go +++ b/fs/rc/jobs/job.go @@ -11,6 +11,7 @@ import ( "time" "github.com/pkg/errors" + "github.com/rclone/rclone/fs" "github.com/rclone/rclone/fs/accounting" "github.com/rclone/rclone/fs/rc" ) @@ -201,6 +202,20 @@ func getAsync(ctx context.Context, in rc.Params) (context.Context, bool, error) return ctx, isAsync, nil } +// See if _config is set and if so adjust ctx to include it +func getConfig(ctx context.Context, in rc.Params) (context.Context, error) { + if _, ok := in["_config"]; !ok { + return ctx, nil + } + ctx, ci := fs.AddConfig(ctx) + err := in.GetStruct("_config", ci) + if err != nil { + return ctx, err + } + delete(in, "_config") // remove the parameter + return ctx, nil +} + // NewJob creates a Job and executes it, possibly in the background if _async is set func (jobs *Jobs) NewJob(ctx context.Context, fn rc.Func, in rc.Params) (job *Job, out rc.Params, err error) { id := atomic.AddInt64(&jobID, 1) @@ -211,6 +226,11 @@ func (jobs *Jobs) NewJob(ctx context.Context, fn rc.Func, in rc.Params) (job *Jo return nil, nil, err } + ctx, err = getConfig(ctx, in) + if err != nil { + return nil, nil, err + } + ctx, group, err := getGroup(ctx, in, id) if err != nil { return nil, nil, err diff --git a/fs/rc/jobs/job_test.go b/fs/rc/jobs/job_test.go index 6af2455b3..557509497 100644 --- a/fs/rc/jobs/job_test.go +++ b/fs/rc/jobs/job_test.go @@ -7,6 +7,7 @@ import ( "time" "github.com/pkg/errors" + "github.com/rclone/rclone/fs" "github.com/rclone/rclone/fs/rc" "github.com/rclone/rclone/fs/rc/rcflags" "github.com/rclone/rclone/fstest/testy" @@ -248,6 +249,29 @@ func TestExecuteJob(t *testing.T) { assert.Equal(t, rc.Params{}, out) } +func TestExecuteJobWithConfig(t *testing.T) { + ctx := context.Background() + jobID = 0 + jobFn := func(ctx context.Context, in rc.Params) (rc.Params, error) { + ci := fs.GetConfig(ctx) + assert.Equal(t, 42*fs.MebiByte, ci.BufferSize) + return nil, nil + } + _, _, err := NewJob(context.Background(), jobFn, rc.Params{ + "_config": rc.Params{ + "BufferSize": "42M", + }, + }) + require.NoError(t, err) + jobID = 0 + _, _, err = NewJob(ctx, jobFn, rc.Params{ + "_config": `{"BufferSize": "42M"}`, + }) + require.NoError(t, err) + ci := fs.GetConfig(ctx) + assert.NotEqual(t, 42*fs.MebiByte, ci.BufferSize) +} + func TestExecuteJobErrorPropagation(t *testing.T) { ctx := context.Background() jobID = 0