diff --git a/api/swagger.yaml b/api/swagger.yaml index da20bb6d34..45c53189c4 100644 --- a/api/swagger.yaml +++ b/api/swagger.yaml @@ -6471,7 +6471,9 @@ paths: /plugins/{name}/set: post: summary: "Configure a plugin" - operationId: "PluginsSet" + operationId: "PostPluginsSet" + consumes: + - "application/json" parameters: - name: "name" in: "path" diff --git a/docs/reference/commandline/plugin_set.md b/docs/reference/commandline/plugin_set.md index 6dbd6ec389..36a24f2061 100644 --- a/docs/reference/commandline/plugin_set.md +++ b/docs/reference/commandline/plugin_set.md @@ -27,20 +27,67 @@ Options: Change settings for a plugin. The plugin must be disabled. +The settings currently supported are: + * env variables + * source of mounts + * path of devices + * args -The following example installs change the env variable `DEBUG` of the +The following example change the env variable `DEBUG` on the `no-remove` plugin. ```bash -$ docker plugin inspect -f {{.Config.Env}} tiborvass/no-remove +$ docker plugin inspect -f {{.Settings.Env}} tiborvass/no-remove [DEBUG=0] -$ docker plugin set DEBUG=1 tiborvass/no-remove +$ docker plugin set tiborvass/no-remove DEBUG=1 -$ docker plugin inspect -f {{.Config.Env}} tiborvass/no-remove +$ docker plugin inspect -f {{.Settings.Env}} tiborvass/no-remove [DEBUG=1] ``` +The following example change the source of the `mymount` mount on +the `myplugin` plugin. + +```bash +$ docker plugin inspect -f '{{with $mount := index .Settings.Mounts 0}}{{$mount.Source}}{{end}}' myplugin +/foo + +$ docker plugins set myplugin mymount.source=/bar + +$ docker plugin inspect -f '{{with $mount := index .Settings.Mounts 0}}{{$mount.Source}}{{end}}' myplugin +/bar +``` + +Note: since only `source` is settable in `mymount`, `docker plugins set mymount=/bar myplugin` would work too. + +The following example change the path of the `mydevice` device on +the `myplugin` plugin. + +```bash +$ docker plugin inspect -f '{{with $device := index .Settings.Devices 0}}{{$device.Path}}{{end}}' myplugin +/dev/foo + +$ docker plugins set myplugin mydevice.path=/dev/bar + +$ docker plugin inspect -f '{{with $device := index .Settings.Devices 0}}{{$device.Path}}{{end}}' myplugin +/dev/bar +``` + +Note: since only `path` is settable in `mydevice`, `docker plugins set mydevice=/dev/bar myplugin` would work too. + +The following example change the source of the args on the `myplugin` plugin. + +```bash +$ docker plugin inspect -f '{{.Settings.Args}}' myplugin +["foo", "bar"] + +$ docker plugins set myplugin args="foo bar baz" + +$ docker plugin inspect -f '{{.Settings.Args}}' myplugin +["foo", "bar", "baz"] +``` + ## Related information * [plugin create](plugin_create.md) diff --git a/plugin/v2/plugin.go b/plugin/v2/plugin.go index 33c53fb105..b48e56b8ac 100644 --- a/plugin/v2/plugin.go +++ b/plugin/v2/plugin.go @@ -137,6 +137,8 @@ func (p *Plugin) Set(args []string) error { return err } + // TODO(vieux): lots of code duplication here, needs to be refactored. + next: for _, s := range sets { // range over all the envs in the config @@ -150,12 +152,58 @@ next: return fmt.Errorf("%q is not settable", s.prettyName()) } // is it, so lets update the settings in memory - updateConfigEnv(&p.PluginObj.Settings.Env, &s) + updateSettingsEnv(&p.PluginObj.Settings.Env, &s) continue next } } - //TODO: check devices, mount and args + // range over all the mounts in the config + for _, mount := range p.PluginObj.Config.Mounts { + // found the mount in the config + if mount.Name == s.name { + // is it settable ? + if ok, err := s.isSettable(allowedSettableFieldsMounts, mount.Settable); err != nil { + return err + } else if !ok { + return fmt.Errorf("%q is not settable", s.prettyName()) + } + + // it is, so lets update the settings in memory + *mount.Source = s.value + continue next + } + } + + // range over all the devices in the config + for _, device := range p.PluginObj.Config.Devices { + // found the device in the config + if device.Name == s.name { + // is it settable ? + if ok, err := s.isSettable(allowedSettableFieldsDevices, device.Settable); err != nil { + return err + } else if !ok { + return fmt.Errorf("%q is not settable", s.prettyName()) + } + + // it is, so lets update the settings in memory + *device.Path = s.value + continue next + } + } + + // found the name in the config + if p.PluginObj.Config.Args.Name == s.name { + // is it settable ? + if ok, err := s.isSettable(allowedSettableFieldsArgs, p.PluginObj.Config.Args.Settable); err != nil { + return err + } else if !ok { + return fmt.Errorf("%q is not settable", s.prettyName()) + } + + // it is, so lets update the settings in memory + p.PluginObj.Settings.Args = strings.Split(s.value, " ") + continue next + } return fmt.Errorf("setting %q not found in the plugin configuration", s.name) } diff --git a/plugin/v2/settable.go b/plugin/v2/settable.go index dc0f56a844..79c6befc24 100644 --- a/plugin/v2/settable.go +++ b/plugin/v2/settable.go @@ -90,7 +90,7 @@ func (set *settable) isSettable(allowedSettableFields []string, settable []strin return false, nil } -func updateConfigEnv(env *[]string, set *settable) { +func updateSettingsEnv(env *[]string, set *settable) { for i, e := range *env { if parts := strings.SplitN(e, "=", 2); parts[0] == set.name { (*env)[i] = fmt.Sprintf("%s=%s", set.name, set.value) diff --git a/plugin/v2/settable_test.go b/plugin/v2/settable_test.go index 57260bf7a3..7183f3a679 100644 --- a/plugin/v2/settable_test.go +++ b/plugin/v2/settable_test.go @@ -68,7 +68,7 @@ func TestIsSettable(t *testing.T) { } } -func TestUpdateConfigEnv(t *testing.T) { +func TestUpdateSettinsEnv(t *testing.T) { contexts := []struct { env []string set settable @@ -82,7 +82,7 @@ func TestUpdateConfigEnv(t *testing.T) { } for _, c := range contexts { - updateConfigEnv(&c.env, &c.set) + updateSettingsEnv(&c.env, &c.set) if !reflect.DeepEqual(c.env, c.newEnv) { t.Fatalf("expected env to be %q, got %q", c.newEnv, c.env)