mirror of
https://github.com/moby/moby.git
synced 2022-11-09 12:21:53 -05:00
support env for docker plugin set
Signed-off-by: Victor Vieux <vieux@docker.com>
This commit is contained in:
parent
7eb4a1d616
commit
efbed4500e
15 changed files with 334 additions and 23 deletions
|
@ -89,7 +89,11 @@ func (pr *pluginRouter) setPlugin(ctx context.Context, w http.ResponseWriter, r
|
||||||
if err := json.NewDecoder(r.Body).Decode(&args); err != nil {
|
if err := json.NewDecoder(r.Body).Decode(&args); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
return pr.backend.Set(vars["name"], args)
|
if err := pr.backend.Set(vars["name"], args); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
w.WriteHeader(http.StatusNoContent)
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (pr *pluginRouter) listPlugins(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
|
func (pr *pluginRouter) listPlugins(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
|
||||||
|
|
|
@ -4290,16 +4290,26 @@ Content-Type: application/json
|
||||||
- **200** - no error
|
- **200** - no error
|
||||||
- **404** - plugin not installed
|
- **404** - plugin not installed
|
||||||
|
|
||||||
<!-- TODO Document "docker plugin set" endpoint once implemented
|
|
||||||
### Configure a plugin
|
### Configure a plugin
|
||||||
|
|
||||||
`POST /plugins/(plugin name)/set`
|
POST /plugins/(plugin name)/set`
|
||||||
|
|
||||||
|
**Example request**:
|
||||||
|
|
||||||
|
|
||||||
|
POST /plugins/tiborvass/no-remove/set
|
||||||
|
Content-Type: application/json
|
||||||
|
|
||||||
|
["DEBUG=1"]
|
||||||
|
|
||||||
|
**Example response**:
|
||||||
|
|
||||||
|
HTTP/1.1 204 No Content
|
||||||
|
|
||||||
**Status codes**:
|
**Status codes**:
|
||||||
|
|
||||||
- **500** - not implemented
|
- **204** - no error
|
||||||
|
- **404** - plugin not installed
|
||||||
-->
|
|
||||||
|
|
||||||
### Enable a plugin
|
### Enable a plugin
|
||||||
|
|
||||||
|
|
|
@ -59,3 +59,4 @@ tiborvass/no-remove latest A test plugin for Docker false
|
||||||
* [plugin inspect](plugin_inspect.md)
|
* [plugin inspect](plugin_inspect.md)
|
||||||
* [plugin install](plugin_install.md)
|
* [plugin install](plugin_install.md)
|
||||||
* [plugin rm](plugin_rm.md)
|
* [plugin rm](plugin_rm.md)
|
||||||
|
* [plugin set](plugin_set.md)
|
||||||
|
|
|
@ -59,3 +59,4 @@ tiborvass/no-remove latest A test plugin for Docker true
|
||||||
* [plugin inspect](plugin_inspect.md)
|
* [plugin inspect](plugin_inspect.md)
|
||||||
* [plugin install](plugin_install.md)
|
* [plugin install](plugin_install.md)
|
||||||
* [plugin rm](plugin_rm.md)
|
* [plugin rm](plugin_rm.md)
|
||||||
|
* [plugin set](plugin_set.md)
|
||||||
|
|
|
@ -159,3 +159,4 @@ $ docker plugin inspect -f '{{.Id}}' tiborvass/no-remove:latest
|
||||||
* [plugin disable](plugin_disable.md)
|
* [plugin disable](plugin_disable.md)
|
||||||
* [plugin install](plugin_install.md)
|
* [plugin install](plugin_install.md)
|
||||||
* [plugin rm](plugin_rm.md)
|
* [plugin rm](plugin_rm.md)
|
||||||
|
* [plugin set](plugin_set.md)
|
||||||
|
|
|
@ -64,3 +64,4 @@ tiborvass/no-remove latest A test plugin for Docker true
|
||||||
* [plugin disable](plugin_disable.md)
|
* [plugin disable](plugin_disable.md)
|
||||||
* [plugin inspect](plugin_inspect.md)
|
* [plugin inspect](plugin_inspect.md)
|
||||||
* [plugin rm](plugin_rm.md)
|
* [plugin rm](plugin_rm.md)
|
||||||
|
* [plugin set](plugin_set.md)
|
||||||
|
|
|
@ -48,3 +48,4 @@ tiborvass/no-remove latest A test plugin for Docker true
|
||||||
* [plugin inspect](plugin_inspect.md)
|
* [plugin inspect](plugin_inspect.md)
|
||||||
* [plugin install](plugin_install.md)
|
* [plugin install](plugin_install.md)
|
||||||
* [plugin rm](plugin_rm.md)
|
* [plugin rm](plugin_rm.md)
|
||||||
|
* [plugin set](plugin_set.md)
|
||||||
|
|
|
@ -51,3 +51,4 @@ tiborvass/no-remove
|
||||||
* [plugin disable](plugin_disable.md)
|
* [plugin disable](plugin_disable.md)
|
||||||
* [plugin inspect](plugin_inspect.md)
|
* [plugin inspect](plugin_inspect.md)
|
||||||
* [plugin install](plugin_install.md)
|
* [plugin install](plugin_install.md)
|
||||||
|
* [plugin set](plugin_set.md)
|
||||||
|
|
51
docs/reference/commandline/plugin_set.md
Normal file
51
docs/reference/commandline/plugin_set.md
Normal file
|
@ -0,0 +1,51 @@
|
||||||
|
---
|
||||||
|
title: "plugin set"
|
||||||
|
description: "the plugin set command description and usage"
|
||||||
|
keywords: "plugin, set"
|
||||||
|
advisory: "experimental"
|
||||||
|
---
|
||||||
|
|
||||||
|
<!-- This file is maintained within the docker/docker Github
|
||||||
|
repository at https://github.com/docker/docker/. Make all
|
||||||
|
pull requests against that repo. If you see this file in
|
||||||
|
another repository, consider it read-only there, as it will
|
||||||
|
periodically be overwritten by the definitive file. Pull
|
||||||
|
requests which include edits to this file in other repositories
|
||||||
|
will be rejected.
|
||||||
|
-->
|
||||||
|
|
||||||
|
# plugin set (experimental)
|
||||||
|
|
||||||
|
```markdown
|
||||||
|
Usage: docker plugin set PLUGIN key1=value1 [key2=value2...]
|
||||||
|
|
||||||
|
Change settings for a plugin
|
||||||
|
|
||||||
|
Options:
|
||||||
|
--help Print usage
|
||||||
|
```
|
||||||
|
|
||||||
|
Change settings for a plugin. The plugin must be disabled.
|
||||||
|
|
||||||
|
|
||||||
|
The following example installs change the env variable `DEBUG` of the
|
||||||
|
`no-remove` plugin.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
$ docker plugin inspect -f {{.Config.Env}} tiborvass/no-remove
|
||||||
|
[DEBUG=0]
|
||||||
|
|
||||||
|
$ docker plugin set DEBUG=1 tiborvass/no-remove
|
||||||
|
|
||||||
|
$ docker plugin inspect -f {{.Config.Env}} tiborvass/no-remove
|
||||||
|
[DEBUG=1]
|
||||||
|
```
|
||||||
|
|
||||||
|
## Related information
|
||||||
|
|
||||||
|
* [plugin ls](plugin_ls.md)
|
||||||
|
* [plugin enable](plugin_enable.md)
|
||||||
|
* [plugin disable](plugin_disable.md)
|
||||||
|
* [plugin inspect](plugin_inspect.md)
|
||||||
|
* [plugin install](plugin_install.md)
|
||||||
|
* [plugin rm](plugin_rm.md)
|
|
@ -117,6 +117,20 @@ func (s *DockerSuite) TestPluginInstallDisableVolumeLs(c *check.C) {
|
||||||
dockerCmd(c, "volume", "ls")
|
dockerCmd(c, "volume", "ls")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *DockerSuite) TestPluginSet(c *check.C) {
|
||||||
|
testRequires(c, DaemonIsLinux, ExperimentalDaemon, Network)
|
||||||
|
out, _ := dockerCmd(c, "plugin", "install", "--grant-all-permissions", "--disable", pName)
|
||||||
|
c.Assert(strings.TrimSpace(out), checker.Contains, pName)
|
||||||
|
|
||||||
|
env, _ := dockerCmd(c, "plugin", "inspect", "-f", "{{.Config.Env}}", pName)
|
||||||
|
c.Assert(strings.TrimSpace(env), checker.Equals, "[DEBUG=0]")
|
||||||
|
|
||||||
|
dockerCmd(c, "plugin", "set", pName, "DEBUG=1")
|
||||||
|
|
||||||
|
env, _ = dockerCmd(c, "plugin", "inspect", "-f", "{{.Config.Env}}", pName)
|
||||||
|
c.Assert(strings.TrimSpace(env), checker.Equals, "[DEBUG=1]")
|
||||||
|
}
|
||||||
|
|
||||||
func (s *DockerSuite) TestPluginInstallImage(c *check.C) {
|
func (s *DockerSuite) TestPluginInstallImage(c *check.C) {
|
||||||
testRequires(c, DaemonIsLinux, ExperimentalDaemon)
|
testRequires(c, DaemonIsLinux, ExperimentalDaemon)
|
||||||
out, _, err := dockerCmdWithError("plugin", "install", "redis")
|
out, _, err := dockerCmdWithError("plugin", "install", "redis")
|
||||||
|
|
|
@ -85,8 +85,8 @@ func (pm *Manager) Pull(name string, metaHeader http.Header, authConfig *types.A
|
||||||
}
|
}
|
||||||
|
|
||||||
tag := distribution.GetTag(ref)
|
tag := distribution.GetTag(ref)
|
||||||
p := v2.NewPlugin(ref.Name(), pluginID, pm.runRoot, tag)
|
p := v2.NewPlugin(ref.Name(), pluginID, pm.runRoot, pm.libRoot, tag)
|
||||||
if err := p.InitPlugin(pm.libRoot); err != nil {
|
if err := p.InitPlugin(); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
pm.pluginStore.Add(p)
|
pm.pluginStore.Add(p)
|
||||||
|
|
|
@ -8,7 +8,7 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestFilterByCapNeg(t *testing.T) {
|
func TestFilterByCapNeg(t *testing.T) {
|
||||||
p := v2.NewPlugin("test", "1234567890", "/run/docker", "latest")
|
p := v2.NewPlugin("test", "1234567890", "/run/docker", "/var/lib/docker/plugins", "latest")
|
||||||
|
|
||||||
iType := types.PluginInterfaceType{"volumedriver", "docker", "1.0"}
|
iType := types.PluginInterfaceType{"volumedriver", "docker", "1.0"}
|
||||||
i := types.PluginManifestInterface{"plugins.sock", []types.PluginInterfaceType{iType}}
|
i := types.PluginManifestInterface{"plugins.sock", []types.PluginInterfaceType{iType}}
|
||||||
|
@ -21,7 +21,7 @@ func TestFilterByCapNeg(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestFilterByCapPos(t *testing.T) {
|
func TestFilterByCapPos(t *testing.T) {
|
||||||
p := v2.NewPlugin("test", "1234567890", "/run/docker", "latest")
|
p := v2.NewPlugin("test", "1234567890", "/run/docker", "/var/lib/docker/plugins", "latest")
|
||||||
|
|
||||||
iType := types.PluginInterfaceType{"volumedriver", "docker", "1.0"}
|
iType := types.PluginInterfaceType{"volumedriver", "docker", "1.0"}
|
||||||
i := types.PluginManifestInterface{"plugins.sock", []types.PluginInterfaceType{iType}}
|
i := types.PluginManifestInterface{"plugins.sock", []types.PluginInterfaceType{iType}}
|
||||||
|
|
|
@ -2,7 +2,6 @@ package v2
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"errors"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
@ -24,6 +23,7 @@ type Plugin struct {
|
||||||
RefCount int `json:"-"`
|
RefCount int `json:"-"`
|
||||||
Restart bool `json:"-"`
|
Restart bool `json:"-"`
|
||||||
ExitChan chan bool `json:"-"`
|
ExitChan chan bool `json:"-"`
|
||||||
|
LibRoot string `json:"-"`
|
||||||
}
|
}
|
||||||
|
|
||||||
const defaultPluginRuntimeDestination = "/run/docker/plugins"
|
const defaultPluginRuntimeDestination = "/run/docker/plugins"
|
||||||
|
@ -42,10 +42,11 @@ func newPluginObj(name, id, tag string) types.Plugin {
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewPlugin creates a plugin.
|
// NewPlugin creates a plugin.
|
||||||
func NewPlugin(name, id, runRoot, tag string) *Plugin {
|
func NewPlugin(name, id, runRoot, libRoot, tag string) *Plugin {
|
||||||
return &Plugin{
|
return &Plugin{
|
||||||
PluginObj: newPluginObj(name, id, tag),
|
PluginObj: newPluginObj(name, id, tag),
|
||||||
RuntimeSourcePath: filepath.Join(runRoot, id),
|
RuntimeSourcePath: filepath.Join(runRoot, id),
|
||||||
|
LibRoot: libRoot,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -86,8 +87,8 @@ func (p *Plugin) RemoveFromDisk() error {
|
||||||
}
|
}
|
||||||
|
|
||||||
// InitPlugin populates the plugin object from the plugin manifest file.
|
// InitPlugin populates the plugin object from the plugin manifest file.
|
||||||
func (p *Plugin) InitPlugin(libRoot string) error {
|
func (p *Plugin) InitPlugin() error {
|
||||||
dt, err := os.Open(filepath.Join(libRoot, p.PluginObj.ID, "manifest.json"))
|
dt, err := os.Open(filepath.Join(p.LibRoot, p.PluginObj.ID, "manifest.json"))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -109,7 +110,11 @@ func (p *Plugin) InitPlugin(libRoot string) error {
|
||||||
}
|
}
|
||||||
copy(p.PluginObj.Config.Args, p.PluginObj.Manifest.Args.Value)
|
copy(p.PluginObj.Config.Args, p.PluginObj.Manifest.Args.Value)
|
||||||
|
|
||||||
f, err := os.Create(filepath.Join(libRoot, p.PluginObj.ID, "plugin-config.json"))
|
return p.writeConfig()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *Plugin) writeConfig() error {
|
||||||
|
f, err := os.Create(filepath.Join(p.LibRoot, p.PluginObj.ID, "plugin-config.json"))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -120,15 +125,43 @@ func (p *Plugin) InitPlugin(libRoot string) error {
|
||||||
|
|
||||||
// Set is used to pass arguments to the plugin.
|
// Set is used to pass arguments to the plugin.
|
||||||
func (p *Plugin) Set(args []string) error {
|
func (p *Plugin) Set(args []string) error {
|
||||||
m := make(map[string]string, len(args))
|
p.Lock()
|
||||||
for _, arg := range args {
|
defer p.Unlock()
|
||||||
i := strings.Index(arg, "=")
|
|
||||||
if i < 0 {
|
if p.PluginObj.Enabled {
|
||||||
return fmt.Errorf("No equal sign '=' found in %s", arg)
|
return fmt.Errorf("cannot set on an active plugin, disable plugin before setting")
|
||||||
}
|
|
||||||
m[arg[:i]] = arg[i+1:]
|
|
||||||
}
|
}
|
||||||
return errors.New("not implemented")
|
|
||||||
|
sets, err := newSettables(args)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
next:
|
||||||
|
for _, s := range sets {
|
||||||
|
// range over all the envs in the manifest
|
||||||
|
for _, env := range p.PluginObj.Manifest.Env {
|
||||||
|
// found the env in the manifest
|
||||||
|
if env.Name == s.name {
|
||||||
|
// is it settable ?
|
||||||
|
if ok, err := s.isSettable(allowedSettableFieldsEnv, env.Settable); err != nil {
|
||||||
|
return err
|
||||||
|
} else if !ok {
|
||||||
|
return fmt.Errorf("%q is not settable", s.prettyName())
|
||||||
|
}
|
||||||
|
// is it, so lets update the config in memory
|
||||||
|
updateConfigEnv(&p.PluginObj.Config.Env, &s)
|
||||||
|
continue next
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//TODO: check devices, mount and args
|
||||||
|
|
||||||
|
return fmt.Errorf("setting %q not found in the plugin configuration", s.name)
|
||||||
|
}
|
||||||
|
|
||||||
|
// update the config on disk
|
||||||
|
return p.writeConfig()
|
||||||
}
|
}
|
||||||
|
|
||||||
// ComputePrivileges takes the manifest file and computes the list of access necessary
|
// ComputePrivileges takes the manifest file and computes the list of access necessary
|
||||||
|
|
102
plugin/v2/settable.go
Normal file
102
plugin/v2/settable.go
Normal file
|
@ -0,0 +1,102 @@
|
||||||
|
package v2
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
type settable struct {
|
||||||
|
name string
|
||||||
|
field string
|
||||||
|
value string
|
||||||
|
}
|
||||||
|
|
||||||
|
var (
|
||||||
|
allowedSettableFieldsEnv = []string{"value"}
|
||||||
|
allowedSettableFieldsArgs = []string{"value"}
|
||||||
|
allowedSettableFieldsDevices = []string{"path"}
|
||||||
|
allowedSettableFieldsMounts = []string{"source"}
|
||||||
|
|
||||||
|
errMultipleFields = errors.New("multiple fields are settable, one must be specified")
|
||||||
|
errInvalidFormat = errors.New("invalid format, must be <name>[.<field>][=<value>]")
|
||||||
|
)
|
||||||
|
|
||||||
|
func newSettables(args []string) ([]settable, error) {
|
||||||
|
sets := make([]settable, 0, len(args))
|
||||||
|
for _, arg := range args {
|
||||||
|
set, err := newSettable(arg)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
sets = append(sets, set)
|
||||||
|
}
|
||||||
|
return sets, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func newSettable(arg string) (settable, error) {
|
||||||
|
var set settable
|
||||||
|
if i := strings.Index(arg, "="); i == 0 {
|
||||||
|
return set, errInvalidFormat
|
||||||
|
} else if i < 0 {
|
||||||
|
set.name = arg
|
||||||
|
} else {
|
||||||
|
set.name = arg[:i]
|
||||||
|
set.value = arg[i+1:]
|
||||||
|
}
|
||||||
|
|
||||||
|
if i := strings.LastIndex(set.name, "."); i > 0 {
|
||||||
|
set.field = set.name[i+1:]
|
||||||
|
set.name = arg[:i]
|
||||||
|
}
|
||||||
|
|
||||||
|
return set, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// prettyName return name.field if there is a field, otherwise name.
|
||||||
|
func (set *settable) prettyName() string {
|
||||||
|
if set.field != "" {
|
||||||
|
return fmt.Sprintf("%s.%s", set.name, set.field)
|
||||||
|
}
|
||||||
|
return set.name
|
||||||
|
}
|
||||||
|
|
||||||
|
func (set *settable) isSettable(allowedSettableFields []string, settable []string) (bool, error) {
|
||||||
|
if set.field == "" {
|
||||||
|
if len(settable) == 1 {
|
||||||
|
// if field is not specified and there only one settable, default to it.
|
||||||
|
set.field = settable[0]
|
||||||
|
} else if len(settable) > 1 {
|
||||||
|
return false, errMultipleFields
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
isAllowed := false
|
||||||
|
for _, allowedSettableField := range allowedSettableFields {
|
||||||
|
if set.field == allowedSettableField {
|
||||||
|
isAllowed = true
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if isAllowed {
|
||||||
|
for _, settableField := range settable {
|
||||||
|
if set.field == settableField {
|
||||||
|
return true, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func updateConfigEnv(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)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
*env = append(*env, fmt.Sprintf("%s=%s", set.name, set.value))
|
||||||
|
}
|
91
plugin/v2/settable_test.go
Normal file
91
plugin/v2/settable_test.go
Normal file
|
@ -0,0 +1,91 @@
|
||||||
|
package v2
|
||||||
|
|
||||||
|
import (
|
||||||
|
"reflect"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestNewSettable(t *testing.T) {
|
||||||
|
contexts := []struct {
|
||||||
|
arg string
|
||||||
|
name string
|
||||||
|
field string
|
||||||
|
value string
|
||||||
|
err error
|
||||||
|
}{
|
||||||
|
{"name=value", "name", "", "value", nil},
|
||||||
|
{"name", "name", "", "", nil},
|
||||||
|
{"name.field=value", "name", "field", "value", nil},
|
||||||
|
{"name.field", "name", "field", "", nil},
|
||||||
|
{"=value", "", "", "", errInvalidFormat},
|
||||||
|
{"=", "", "", "", errInvalidFormat},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, c := range contexts {
|
||||||
|
s, err := newSettable(c.arg)
|
||||||
|
if err != c.err {
|
||||||
|
t.Fatalf("expected error to be %v, got %v", c.err, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if s.name != c.name {
|
||||||
|
t.Fatalf("expected name to be %q, got %q", c.name, s.name)
|
||||||
|
}
|
||||||
|
|
||||||
|
if s.field != c.field {
|
||||||
|
t.Fatalf("expected field to be %q, got %q", c.field, s.field)
|
||||||
|
}
|
||||||
|
|
||||||
|
if s.value != c.value {
|
||||||
|
t.Fatalf("expected value to be %q, got %q", c.value, s.value)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestIsSettable(t *testing.T) {
|
||||||
|
contexts := []struct {
|
||||||
|
allowedSettableFields []string
|
||||||
|
set settable
|
||||||
|
settable []string
|
||||||
|
result bool
|
||||||
|
err error
|
||||||
|
}{
|
||||||
|
{allowedSettableFieldsEnv, settable{}, []string{}, false, nil},
|
||||||
|
{allowedSettableFieldsEnv, settable{field: "value"}, []string{}, false, nil},
|
||||||
|
{allowedSettableFieldsEnv, settable{}, []string{"value"}, true, nil},
|
||||||
|
{allowedSettableFieldsEnv, settable{field: "value"}, []string{"value"}, true, nil},
|
||||||
|
{allowedSettableFieldsEnv, settable{field: "foo"}, []string{"value"}, false, nil},
|
||||||
|
{allowedSettableFieldsEnv, settable{field: "foo"}, []string{"foo"}, false, nil},
|
||||||
|
{allowedSettableFieldsEnv, settable{}, []string{"value1", "value2"}, false, errMultipleFields},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, c := range contexts {
|
||||||
|
if res, err := c.set.isSettable(c.allowedSettableFields, c.settable); res != c.result {
|
||||||
|
t.Fatalf("expected result to be %t, got %t", c.result, res)
|
||||||
|
} else if err != c.err {
|
||||||
|
t.Fatalf("expected error to be %v, got %v", c.err, err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestUpdateConfigEnv(t *testing.T) {
|
||||||
|
contexts := []struct {
|
||||||
|
env []string
|
||||||
|
set settable
|
||||||
|
newEnv []string
|
||||||
|
}{
|
||||||
|
{[]string{}, settable{name: "DEBUG", value: "1"}, []string{"DEBUG=1"}},
|
||||||
|
{[]string{"DEBUG=0"}, settable{name: "DEBUG", value: "1"}, []string{"DEBUG=1"}},
|
||||||
|
{[]string{"FOO=0"}, settable{name: "DEBUG", value: "1"}, []string{"FOO=0", "DEBUG=1"}},
|
||||||
|
{[]string{"FOO=0", "DEBUG=0"}, settable{name: "DEBUG", value: "1"}, []string{"FOO=0", "DEBUG=1"}},
|
||||||
|
{[]string{"FOO=0", "DEBUG=0", "BAR=1"}, settable{name: "DEBUG", value: "1"}, []string{"FOO=0", "DEBUG=1", "BAR=1"}},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, c := range contexts {
|
||||||
|
updateConfigEnv(&c.env, &c.set)
|
||||||
|
|
||||||
|
if !reflect.DeepEqual(c.env, c.newEnv) {
|
||||||
|
t.Fatalf("expected env to be %q, got %q", c.newEnv, c.env)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue