Add warning for plugin configs with unknown fields
Signed-off-by: Derek McGowan <derek@mcg.dev>
This commit is contained in:
parent
0f3d312aca
commit
4c344f2fa5
@ -31,7 +31,7 @@ import (
|
|||||||
"github.com/urfave/cli"
|
"github.com/urfave/cli"
|
||||||
)
|
)
|
||||||
|
|
||||||
func outputConfig(config *srvconfig.Config) error {
|
func outputConfig(ctx gocontext.Context, config *srvconfig.Config) error {
|
||||||
plugins, err := server.LoadPlugins(gocontext.Background(), config)
|
plugins, err := server.LoadPlugins(gocontext.Background(), config)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@ -43,7 +43,7 @@ func outputConfig(config *srvconfig.Config) error {
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
pc, err := config.Decode(p)
|
pc, err := config.Decode(ctx, p)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -83,7 +83,7 @@ var configCommand = cli.Command{
|
|||||||
Name: "default",
|
Name: "default",
|
||||||
Usage: "See the output of the default config",
|
Usage: "See the output of the default config",
|
||||||
Action: func(context *cli.Context) error {
|
Action: func(context *cli.Context) error {
|
||||||
return outputConfig(defaultConfig())
|
return outputConfig(gocontext.Background(), defaultConfig())
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -91,11 +91,12 @@ var configCommand = cli.Command{
|
|||||||
Usage: "See the output of the final main config with imported in subconfig files",
|
Usage: "See the output of the final main config with imported in subconfig files",
|
||||||
Action: func(context *cli.Context) error {
|
Action: func(context *cli.Context) error {
|
||||||
config := defaultConfig()
|
config := defaultConfig()
|
||||||
if err := srvconfig.LoadConfig(gocontext.Background(), context.GlobalString("config"), config); err != nil && !os.IsNotExist(err) {
|
ctx := gocontext.Background()
|
||||||
|
if err := srvconfig.LoadConfig(ctx, context.GlobalString("config"), config); err != nil && !os.IsNotExist(err) {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
return outputConfig(config)
|
return outputConfig(ctx, config)
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -96,7 +96,7 @@ func buildLocalContainerdClient(t *testing.T, tmpDir string) *containerd.Client
|
|||||||
|
|
||||||
// load the plugin specific configuration if it is provided
|
// load the plugin specific configuration if it is provided
|
||||||
if p.Config != nil {
|
if p.Config != nil {
|
||||||
pc, err := config.Decode(p)
|
pc, err := config.Decode(ctx, p)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
|
||||||
initContext.Config = pc
|
initContext.Config = pc
|
||||||
|
@ -17,6 +17,7 @@
|
|||||||
package config
|
package config
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bytes"
|
||||||
"context"
|
"context"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
@ -177,23 +178,35 @@ type ProxyPlugin struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Decode unmarshals a plugin specific configuration by plugin id
|
// Decode unmarshals a plugin specific configuration by plugin id
|
||||||
func (c *Config) Decode(p *plugin.Registration) (interface{}, error) {
|
func (c *Config) Decode(ctx context.Context, p *plugin.Registration) (interface{}, error) {
|
||||||
id := p.URI()
|
id := p.URI()
|
||||||
data, ok := c.Plugins[id]
|
data, ok := c.Plugins[id]
|
||||||
if !ok {
|
if !ok {
|
||||||
return p.Config, nil
|
return p.Config, nil
|
||||||
}
|
}
|
||||||
r, w := io.Pipe()
|
|
||||||
go func() {
|
|
||||||
err := toml.NewEncoder(w).Encode(data)
|
|
||||||
w.CloseWithError(err)
|
|
||||||
}()
|
|
||||||
|
|
||||||
// TODO: Add DisallowUnknownFields, requires better testing and bubbling errors
|
b, err := toml.Marshal(data)
|
||||||
if err := toml.NewDecoder(r).Decode(p.Config); err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if err := toml.NewDecoder(bytes.NewReader(b)).DisallowUnknownFields().Decode(p.Config); err != nil {
|
||||||
|
var serr *toml.StrictMissingError
|
||||||
|
if errors.As(err, &serr) {
|
||||||
|
for _, derr := range serr.Errors {
|
||||||
|
log.G(ctx).WithFields(log.Fields{
|
||||||
|
"plugin": id,
|
||||||
|
"key": strings.Join(derr.Key(), " "),
|
||||||
|
}).WithError(err).Warn("Ignoring unknown key in TOML for plugin")
|
||||||
|
}
|
||||||
|
err = toml.Unmarshal(b, p.Config)
|
||||||
|
}
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
return p.Config, nil
|
return p.Config, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -26,6 +26,7 @@ import (
|
|||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
|
|
||||||
"github.com/containerd/containerd/plugin"
|
"github.com/containerd/containerd/plugin"
|
||||||
|
"github.com/containerd/log/logtest"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestMergeConfigs(t *testing.T) {
|
func TestMergeConfigs(t *testing.T) {
|
||||||
@ -191,6 +192,7 @@ imports = ["data1.toml", "data2.toml"]
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestDecodePlugin(t *testing.T) {
|
func TestDecodePlugin(t *testing.T) {
|
||||||
|
ctx := logtest.WithT(context.Background(), t)
|
||||||
data := `
|
data := `
|
||||||
version = 2
|
version = 2
|
||||||
[plugins."io.containerd.runtime.v1.linux"]
|
[plugins."io.containerd.runtime.v1.linux"]
|
||||||
@ -208,7 +210,7 @@ version = 2
|
|||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
|
||||||
pluginConfig := map[string]interface{}{}
|
pluginConfig := map[string]interface{}{}
|
||||||
_, err = out.Decode(&plugin.Registration{Type: "io.containerd.runtime.v1", ID: "linux", Config: &pluginConfig})
|
_, err = out.Decode(ctx, &plugin.Registration{Type: "io.containerd.runtime.v1", ID: "linux", Config: &pluginConfig})
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.Equal(t, true, pluginConfig["shim_debug"])
|
assert.Equal(t, true, pluginConfig["shim_debug"])
|
||||||
}
|
}
|
||||||
|
@ -201,6 +201,7 @@ func New(ctx context.Context, config *srvconfig.Config) (*Server, error) {
|
|||||||
for _, r := range config.RequiredPlugins {
|
for _, r := range config.RequiredPlugins {
|
||||||
required[r] = struct{}{}
|
required[r] = struct{}{}
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, p := range plugins {
|
for _, p := range plugins {
|
||||||
id := p.URI()
|
id := p.URI()
|
||||||
log.G(ctx).WithField("type", p.Type).Infof("loading plugin %q...", id)
|
log.G(ctx).WithField("type", p.Type).Infof("loading plugin %q...", id)
|
||||||
@ -218,7 +219,7 @@ func New(ctx context.Context, config *srvconfig.Config) (*Server, error) {
|
|||||||
|
|
||||||
// load the plugin specific configuration if it is provided
|
// load the plugin specific configuration if it is provided
|
||||||
if p.Config != nil {
|
if p.Config != nil {
|
||||||
pc, err := config.Decode(p)
|
pc, err := config.Decode(ctx, p)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user