mirror of
https://github.com/moby/moby.git
synced 2022-11-09 12:21:53 -05:00
Merge pull request #42393 from aiordache/daemon_config
Daemon config validation
This commit is contained in:
commit
314759dc2f
12 changed files with 148 additions and 34 deletions
|
@ -75,14 +75,18 @@ func NewDaemonCli() *DaemonCli {
|
|||
}
|
||||
|
||||
func (cli *DaemonCli) start(opts *daemonOptions) (err error) {
|
||||
stopc := make(chan bool)
|
||||
defer close(stopc)
|
||||
|
||||
opts.SetDefaultOptions(opts.flags)
|
||||
|
||||
if cli.Config, err = loadDaemonCliConfig(opts); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if opts.Validate {
|
||||
// If config wasn't OK we wouldn't have made it this far.
|
||||
fmt.Fprintln(os.Stderr, "configuration OK")
|
||||
return nil
|
||||
}
|
||||
|
||||
warnOnDeprecatedConfigOptions(cli.Config)
|
||||
|
||||
if err := configureDaemonLogs(cli.Config); err != nil {
|
||||
|
@ -176,6 +180,9 @@ func (cli *DaemonCli) start(opts *daemonOptions) (err error) {
|
|||
}
|
||||
defer cancel()
|
||||
|
||||
stopc := make(chan bool)
|
||||
defer close(stopc)
|
||||
|
||||
signal.Trap(func() {
|
||||
cli.stop()
|
||||
<-stopc // wait for daemonCli.start() to return
|
||||
|
|
|
@ -41,6 +41,7 @@ type daemonOptions struct {
|
|||
TLS bool
|
||||
TLSVerify bool
|
||||
TLSOptions *tlsconfig.Options
|
||||
Validate bool
|
||||
}
|
||||
|
||||
// newDaemonOptions returns a new daemonFlags
|
||||
|
@ -59,6 +60,7 @@ func (o *daemonOptions) InstallFlags(flags *pflag.FlagSet) {
|
|||
}
|
||||
|
||||
flags.BoolVarP(&o.Debug, "debug", "D", false, "Enable debug mode")
|
||||
flags.BoolVar(&o.Validate, "validate", false, "Validate configuration file and exit")
|
||||
flags.StringVarP(&o.LogLevel, "log-level", "l", "info", `Set the logging level ("debug"|"info"|"warn"|"error"|"fatal")`)
|
||||
flags.BoolVar(&o.TLS, FlagTLS, DefaultTLSValue, "Use TLS; implied by --tlsverify")
|
||||
flags.BoolVar(&o.TLSVerify, FlagTLSVerify, dockerTLSVerify || DefaultTLSValue, "Use TLS and verify the remote")
|
||||
|
|
|
@ -4,7 +4,6 @@ import (
|
|||
"bytes"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"net"
|
||||
"os"
|
||||
|
@ -399,11 +398,16 @@ func getConflictFreeConfiguration(configFile string, flags *pflag.FlagSet) (*Con
|
|||
}
|
||||
|
||||
var config Config
|
||||
var reader io.Reader
|
||||
|
||||
b = bytes.TrimSpace(b)
|
||||
if len(b) == 0 {
|
||||
// empty config file
|
||||
return &config, nil
|
||||
}
|
||||
|
||||
if flags != nil {
|
||||
var jsonConfig map[string]interface{}
|
||||
reader = bytes.NewReader(b)
|
||||
if err := json.NewDecoder(reader).Decode(&jsonConfig); err != nil {
|
||||
if err := json.Unmarshal(b, &jsonConfig); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
|
@ -446,8 +450,7 @@ func getConflictFreeConfiguration(configFile string, flags *pflag.FlagSet) (*Con
|
|||
config.ValuesSet = configSet
|
||||
}
|
||||
|
||||
reader = bytes.NewReader(b)
|
||||
if err := json.NewDecoder(reader).Decode(&config); err != nil {
|
||||
if err := json.Unmarshal(b, &config); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
|
|
|
@ -4,8 +4,6 @@ import (
|
|||
"bytes"
|
||||
"context"
|
||||
"encoding/json"
|
||||
"io/ioutil"
|
||||
"path/filepath"
|
||||
"sort"
|
||||
"testing"
|
||||
"time"
|
||||
|
@ -17,7 +15,6 @@ import (
|
|||
"github.com/docker/docker/errdefs"
|
||||
"github.com/docker/docker/integration/internal/swarm"
|
||||
"github.com/docker/docker/pkg/stdcopy"
|
||||
"github.com/docker/docker/testutil/daemon"
|
||||
"gotest.tools/v3/assert"
|
||||
is "gotest.tools/v3/assert/cmp"
|
||||
"gotest.tools/v3/poll"
|
||||
|
@ -379,26 +376,6 @@ func TestConfigCreateResolve(t *testing.T) {
|
|||
assert.Assert(t, is.Equal(0, len(entries)))
|
||||
}
|
||||
|
||||
func TestConfigDaemonLibtrustID(t *testing.T) {
|
||||
skip.If(t, testEnv.DaemonInfo.OSType != "linux")
|
||||
defer setupTest(t)()
|
||||
|
||||
d := daemon.New(t)
|
||||
defer d.Stop(t)
|
||||
|
||||
trustKey := filepath.Join(d.RootDir(), "key.json")
|
||||
err := ioutil.WriteFile(trustKey, []byte(`{"crv":"P-256","d":"dm28PH4Z4EbyUN8L0bPonAciAQa1QJmmyYd876mnypY","kid":"WTJ3:YSIP:CE2E:G6KJ:PSBD:YX2Y:WEYD:M64G:NU2V:XPZV:H2CR:VLUB","kty":"EC","x":"Mh5-JINSjaa_EZdXDttri255Z5fbCEOTQIZjAcScFTk","y":"eUyuAjfxevb07hCCpvi4Zi334Dy4GDWQvEToGEX4exQ"}`), 0644)
|
||||
assert.NilError(t, err)
|
||||
|
||||
config := filepath.Join(d.RootDir(), "daemon.json")
|
||||
err = ioutil.WriteFile(config, []byte(`{"deprecated-key-path": "`+trustKey+`"}`), 0644)
|
||||
assert.NilError(t, err)
|
||||
|
||||
d.Start(t, "--config-file", config)
|
||||
info := d.Info(t)
|
||||
assert.Equal(t, info.ID, "WTJ3:YSIP:CE2E:G6KJ:PSBD:YX2Y:WEYD:M64G:NU2V:XPZV:H2CR:VLUB")
|
||||
}
|
||||
|
||||
func assertAttachedStream(t *testing.T, attach types.HijackedResponse, expect string) {
|
||||
buf := bytes.NewBuffer(nil)
|
||||
_, err := stdcopy.StdCopy(buf, buf, attach.Reader)
|
||||
|
|
101
integration/daemon/daemon_test.go
Normal file
101
integration/daemon/daemon_test.go
Normal file
|
@ -0,0 +1,101 @@
|
|||
package daemon // import "github.com/docker/docker/integration/daemon"
|
||||
|
||||
import (
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
"testing"
|
||||
|
||||
"github.com/docker/docker/testutil/daemon"
|
||||
"gotest.tools/v3/assert"
|
||||
"gotest.tools/v3/skip"
|
||||
|
||||
is "gotest.tools/v3/assert/cmp"
|
||||
)
|
||||
|
||||
func TestConfigDaemonLibtrustID(t *testing.T) {
|
||||
skip.If(t, runtime.GOOS != "linux")
|
||||
|
||||
d := daemon.New(t)
|
||||
defer d.Stop(t)
|
||||
|
||||
trustKey := filepath.Join(d.RootDir(), "key.json")
|
||||
err := ioutil.WriteFile(trustKey, []byte(`{"crv":"P-256","d":"dm28PH4Z4EbyUN8L0bPonAciAQa1QJmmyYd876mnypY","kid":"WTJ3:YSIP:CE2E:G6KJ:PSBD:YX2Y:WEYD:M64G:NU2V:XPZV:H2CR:VLUB","kty":"EC","x":"Mh5-JINSjaa_EZdXDttri255Z5fbCEOTQIZjAcScFTk","y":"eUyuAjfxevb07hCCpvi4Zi334Dy4GDWQvEToGEX4exQ"}`), 0644)
|
||||
assert.NilError(t, err)
|
||||
|
||||
config := filepath.Join(d.RootDir(), "daemon.json")
|
||||
err = ioutil.WriteFile(config, []byte(`{"deprecated-key-path": "`+trustKey+`"}`), 0644)
|
||||
assert.NilError(t, err)
|
||||
|
||||
d.Start(t, "--config-file", config)
|
||||
info := d.Info(t)
|
||||
assert.Equal(t, info.ID, "WTJ3:YSIP:CE2E:G6KJ:PSBD:YX2Y:WEYD:M64G:NU2V:XPZV:H2CR:VLUB")
|
||||
}
|
||||
|
||||
func TestDaemonConfigValidation(t *testing.T) {
|
||||
skip.If(t, runtime.GOOS != "linux")
|
||||
|
||||
d := daemon.New(t)
|
||||
dockerBinary, err := d.BinaryPath()
|
||||
assert.NilError(t, err)
|
||||
params := []string{"--validate", "--config-file"}
|
||||
|
||||
dest := os.Getenv("DOCKER_INTEGRATION_DAEMON_DEST")
|
||||
if dest == "" {
|
||||
dest = os.Getenv("DEST")
|
||||
}
|
||||
testdata := filepath.Join(dest, "..", "..", "integration", "daemon", "testdata")
|
||||
|
||||
const (
|
||||
validOut = "configuration OK"
|
||||
failedOut = "unable to configure the Docker daemon with file"
|
||||
)
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
args []string
|
||||
expectedOut string
|
||||
}{
|
||||
{
|
||||
name: "config with no content",
|
||||
args: append(params, filepath.Join(testdata, "empty-config-1.json")),
|
||||
expectedOut: validOut,
|
||||
},
|
||||
{
|
||||
name: "config with {}",
|
||||
args: append(params, filepath.Join(testdata, "empty-config-2.json")),
|
||||
expectedOut: validOut,
|
||||
},
|
||||
{
|
||||
name: "invalid config",
|
||||
args: append(params, filepath.Join(testdata, "invalid-config-1.json")),
|
||||
expectedOut: failedOut,
|
||||
},
|
||||
{
|
||||
name: "malformed config",
|
||||
args: append(params, filepath.Join(testdata, "malformed-config.json")),
|
||||
expectedOut: failedOut,
|
||||
},
|
||||
{
|
||||
name: "valid config",
|
||||
args: append(params, filepath.Join(testdata, "valid-config-1.json")),
|
||||
expectedOut: validOut,
|
||||
},
|
||||
}
|
||||
for _, tc := range tests {
|
||||
tc := tc
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
cmd := exec.Command(dockerBinary, tc.args...)
|
||||
out, err := cmd.CombinedOutput()
|
||||
assert.Check(t, is.Contains(string(out), tc.expectedOut))
|
||||
if tc.expectedOut == failedOut {
|
||||
assert.ErrorContains(t, err, "", "expected an error, but got none")
|
||||
} else {
|
||||
assert.NilError(t, err)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
10
integration/daemon/main_test.go
Normal file
10
integration/daemon/main_test.go
Normal file
|
@ -0,0 +1,10 @@
|
|||
package daemon // import "github.com/docker/docker/integration/daemon"
|
||||
|
||||
import (
|
||||
"os"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestMain(m *testing.M) {
|
||||
os.Exit(m.Run())
|
||||
}
|
1
integration/daemon/testdata/empty-config-1.json
vendored
Normal file
1
integration/daemon/testdata/empty-config-1.json
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
|
1
integration/daemon/testdata/empty-config-2.json
vendored
Normal file
1
integration/daemon/testdata/empty-config-2.json
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
{}
|
1
integration/daemon/testdata/invalid-config-1.json
vendored
Normal file
1
integration/daemon/testdata/invalid-config-1.json
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
{"unknown-option": true}
|
1
integration/daemon/testdata/malformed-config.json
vendored
Normal file
1
integration/daemon/testdata/malformed-config.json
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
{
|
1
integration/daemon/testdata/valid-config-1.json
vendored
Normal file
1
integration/daemon/testdata/valid-config-1.json
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
{"debug": true}
|
|
@ -217,6 +217,15 @@ func New(t testing.TB, ops ...Option) *Daemon {
|
|||
return d
|
||||
}
|
||||
|
||||
// BinaryPath returns the binary and its arguments.
|
||||
func (d *Daemon) BinaryPath() (string, error) {
|
||||
dockerdBinary, err := exec.LookPath(d.dockerdBinary)
|
||||
if err != nil {
|
||||
return "", errors.Wrapf(err, "[%s] could not find docker binary in $PATH", d.id)
|
||||
}
|
||||
return dockerdBinary, nil
|
||||
}
|
||||
|
||||
// ContainersNamespace returns the containerd namespace used for containers.
|
||||
func (d *Daemon) ContainersNamespace() string {
|
||||
return d.id
|
||||
|
@ -307,9 +316,9 @@ func (d *Daemon) StartWithError(args ...string) error {
|
|||
// StartWithLogFile will start the daemon and attach its streams to a given file.
|
||||
func (d *Daemon) StartWithLogFile(out *os.File, providedArgs ...string) error {
|
||||
d.handleUserns()
|
||||
dockerdBinary, err := exec.LookPath(d.dockerdBinary)
|
||||
dockerdBinary, err := d.BinaryPath()
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "[%s] could not find docker binary in $PATH", d.id)
|
||||
return err
|
||||
}
|
||||
|
||||
if d.pidFile == "" {
|
||||
|
|
Loading…
Reference in a new issue