Skip to content

Commit

Permalink
Fix warnings not being printed on "create", only on "run"
Browse files Browse the repository at this point in the history
Previously, these errors were only printed when using `docker run`, but were
omitted when using `docker container create` and `docker container start`
separately.

Given that these warnings apply to both situations, this patch moves generation
of these warnings to `docker container create` (which is also called by
`docker run`)

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
  • Loading branch information
thaJeztah committed Dec 13, 2018
1 parent e576089 commit 03eca4c
Show file tree
Hide file tree
Showing 7 changed files with 103 additions and 33 deletions.
34 changes: 34 additions & 0 deletions cli/command/container/create.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"fmt"
"io"
"os"
"regexp"

"github.com/docker/cli/cli"
"github.com/docker/cli/cli/command"
Expand Down Expand Up @@ -165,6 +166,9 @@ func createContainer(ctx context.Context, dockerCli command.Cli, containerConfig
networkingConfig := containerConfig.NetworkingConfig
stderr := dockerCli.Err()

warnOnOomKillDisable(*hostConfig, stderr)
warnOnLocalhostDNS(*hostConfig, stderr)

var (
trustedRef reference.Canonical
namedRef reference.Named
Expand Down Expand Up @@ -227,3 +231,33 @@ func createContainer(ctx context.Context, dockerCli command.Cli, containerConfig
err = containerIDFile.Write(response.ID)
return &response, err
}

func warnOnOomKillDisable(hostConfig container.HostConfig, stderr io.Writer) {
if hostConfig.OomKillDisable != nil && *hostConfig.OomKillDisable && hostConfig.Memory == 0 {
fmt.Fprintln(stderr, "WARNING: Disabling the OOM killer on containers without setting a '-m/--memory' limit may be dangerous.")
}
}

// check the DNS settings passed via --dns against localhost regexp to warn if
// they are trying to set a DNS to a localhost address
func warnOnLocalhostDNS(hostConfig container.HostConfig, stderr io.Writer) {
for _, dnsIP := range hostConfig.DNS {
if isLocalhost(dnsIP) {
fmt.Fprintf(stderr, "WARNING: Localhost DNS setting (--dns=%s) may fail in containers.\n", dnsIP)
return
}
}
}

// IPLocalhost is a regex pattern for IPv4 or IPv6 loopback range.
const ipLocalhost = `((127\.([0-9]{1,3}\.){2}[0-9]{1,3})|(::1)$)`

var localhostIPRegexp = regexp.MustCompile(ipLocalhost)

// IsLocalhost returns true if ip matches the localhost IP regular expression.
// Used for determining if nameserver settings are being passed which are
// localhost addresses
func isLocalhost(ip string) bool {
return localhostIPRegexp.MatchString(ip)
}

65 changes: 65 additions & 0 deletions cli/command/container/create_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import (
"gotest.tools/assert"
is "gotest.tools/assert/cmp"
"gotest.tools/fs"
"gotest.tools/golden"
)

func TestCIDFileNoOPWithNoFilename(t *testing.T) {
Expand Down Expand Up @@ -166,6 +167,70 @@ func TestNewCreateCommandWithContentTrustErrors(t *testing.T) {
}
}

func TestNewCreateCommandWithWarnings(t *testing.T) {
testCases := []struct {
name string
args []string
warning bool
}{
{
name: "container-create-without-oom-kill-disable",
args: []string{"image:tag"},
},
{
name: "container-create-oom-kill-disable-false",
args: []string{"--oom-kill-disable=false", "image:tag"},
},
{
name: "container-create-oom-kill-without-memory-limit",
args: []string{"--oom-kill-disable", "image:tag"},
warning: true,
},
{
name: "container-create-oom-kill-true-without-memory-limit",
args: []string{"--oom-kill-disable=true", "image:tag"},
warning: true,
},
{
name: "container-create-oom-kill-true-with-memory-limit",
args: []string{"--oom-kill-disable=true", "--memory=100M", "image:tag"},
},
{
name: "container-create-localhost-dns",
args: []string{"--dns=127.0.0.11", "image:tag"},
warning: true,
},
{
name: "container-create-localhost-dns-ipv6",
args: []string{"--dns=::1", "image:tag"},
warning: true,
},
}
for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T){
cli := test.NewFakeCli(&fakeClient{
createContainerFunc: func(config *container.Config,
hostConfig *container.HostConfig,
networkingConfig *network.NetworkingConfig,
containerName string,
) (container.ContainerCreateCreatedBody, error) {
return container.ContainerCreateCreatedBody{},nil
},
})
cmd := NewCreateCommand(cli)
cmd.SetOutput(ioutil.Discard)
cmd.SetArgs(tc.args)
err := cmd.Execute()
assert.NilError(t, err)
if tc.warning {
golden.Assert(t, cli.ErrBuffer().String(), tc.name+".golden")
} else {
assert.Equal(t, cli.ErrBuffer().String(), "")
}
})
}
}

type fakeNotFound struct{}

func (f fakeNotFound) NotFound() bool { return true }
Expand Down
33 changes: 0 additions & 33 deletions cli/command/container/run.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import (
"io"
"net/http/httputil"
"os"
"regexp"
"runtime"
"strings"
"syscall"
Expand Down Expand Up @@ -68,35 +67,6 @@ func NewRunCommand(dockerCli command.Cli) *cobra.Command {
return cmd
}

func warnOnOomKillDisable(hostConfig container.HostConfig, stderr io.Writer) {
if hostConfig.OomKillDisable != nil && *hostConfig.OomKillDisable && hostConfig.Memory == 0 {
fmt.Fprintln(stderr, "WARNING: Disabling the OOM killer on containers without setting a '-m/--memory' limit may be dangerous.")
}
}

// check the DNS settings passed via --dns against localhost regexp to warn if
// they are trying to set a DNS to a localhost address
func warnOnLocalhostDNS(hostConfig container.HostConfig, stderr io.Writer) {
for _, dnsIP := range hostConfig.DNS {
if isLocalhost(dnsIP) {
fmt.Fprintf(stderr, "WARNING: Localhost DNS setting (--dns=%s) may fail in containers.\n", dnsIP)
return
}
}
}

// IPLocalhost is a regex pattern for IPv4 or IPv6 loopback range.
const ipLocalhost = `((127\.([0-9]{1,3}\.){2}[0-9]{1,3})|(::1)$)`

var localhostIPRegexp = regexp.MustCompile(ipLocalhost)

// IsLocalhost returns true if ip matches the localhost IP regular expression.
// Used for determining if nameserver settings are being passed which are
// localhost addresses
func isLocalhost(ip string) bool {
return localhostIPRegexp.MatchString(ip)
}

func runRun(dockerCli command.Cli, flags *pflag.FlagSet, ropts *runOptions, copts *containerOptions) error {
proxyConfig := dockerCli.ConfigFile().ParseProxyConfig(dockerCli.Client().DaemonHost(), copts.env.GetAll())
newEnv := []string{}
Expand Down Expand Up @@ -124,9 +94,6 @@ func runContainer(dockerCli command.Cli, opts *runOptions, copts *containerOptio
stdout, stderr := dockerCli.Out(), dockerCli.Err()
client := dockerCli.Client()

warnOnOomKillDisable(*hostConfig, stderr)
warnOnLocalhostDNS(*hostConfig, stderr)

config.ArgsEscaped = false

if !opts.detach {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
WARNING: Localhost DNS setting (--dns=::1) may fail in containers.
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
WARNING: Localhost DNS setting (--dns=127.0.0.11) may fail in containers.
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
WARNING: Disabling the OOM killer on containers without setting a '-m/--memory' limit may be dangerous.
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
WARNING: Disabling the OOM killer on containers without setting a '-m/--memory' limit may be dangerous.

0 comments on commit 03eca4c

Please sign in to comment.