diff --git a/api/swagger.yaml b/api/swagger.yaml index da20bb6d3473255b1ae8037e902d38fccf61587e..45c53189c496f2b9ed0674ba45f6b933a58cb934 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 6dbd6ec3898121e2b04b61171d97ff76135bea1a..36a24f20614eb1a8d4bef81649ed9c144bc81687 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 33c53fb10513ea3719eb11da066beaa4536f7123..b48e56b8aca9c030e1f4eba205dab71e90ae652b 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 + } + } + + // 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 } } - //TODO: check devices, mount and args + // 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 dc0f56a8442863350992e5569d2bba5133a3b100..79c6befc24bf88e7c35ee076bb873524a406ddb5 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 57260bf7a316ce086f832829def7cab45c064718..7183f3a67917eecf68b20a9ecbd72d1376367d6f 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)