diff --git a/integration-cli/docker_cli_info_test.go b/integration-cli/docker_cli_info_test.go index 353601f5d2..36718741e3 100644 --- a/integration-cli/docker_cli_info_test.go +++ b/integration-cli/docker_cli_info_test.go @@ -3,12 +3,9 @@ package main import ( "encoding/json" "fmt" - "net" "strings" "testing" - "github.com/docker/docker/integration-cli/daemon" - testdaemon "github.com/docker/docker/testutil/daemon" "gotest.tools/assert" ) @@ -56,77 +53,6 @@ func (s *DockerSuite) TestInfoEnsureSucceeds(c *testing.T) { } } -// TestInfoFormat tests `docker info --format` -func (s *DockerSuite) TestInfoFormat(c *testing.T) { - out, status := dockerCmd(c, "info", "--format", "{{json .}}") - assert.Equal(c, status, 0) - var m map[string]interface{} - err := json.Unmarshal([]byte(out), &m) - assert.NilError(c, err) - _, _, err = dockerCmdWithError("info", "--format", "{{.badString}}") - assert.ErrorContains(c, err, "") -} - -// TestInfoDiscoveryBackend verifies that a daemon run with `--cluster-advertise` and -// `--cluster-store` properly show the backend's endpoint in info output. -func (s *DockerSuite) TestInfoDiscoveryBackend(c *testing.T) { - testRequires(c, testEnv.IsLocalDaemon, DaemonIsLinux) - - d := daemon.New(c, dockerBinary, dockerdBinary, testdaemon.WithEnvironment(testEnv.Execution)) - discoveryBackend := "consul://consuladdr:consulport/some/path" - discoveryAdvertise := "1.1.1.1:2375" - d.Start(c, fmt.Sprintf("--cluster-store=%s", discoveryBackend), fmt.Sprintf("--cluster-advertise=%s", discoveryAdvertise)) - defer d.Stop(c) - - out, err := d.Cmd("info") - assert.NilError(c, err) - assert.Assert(c, strings.Contains(out, fmt.Sprintf("Cluster Store: %s\n", discoveryBackend))) - assert.Assert(c, strings.Contains(out, fmt.Sprintf("Cluster Advertise: %s\n", discoveryAdvertise))) -} - -// TestInfoDiscoveryInvalidAdvertise verifies that a daemon run with -// an invalid `--cluster-advertise` configuration -func (s *DockerSuite) TestInfoDiscoveryInvalidAdvertise(c *testing.T) { - testRequires(c, testEnv.IsLocalDaemon, DaemonIsLinux) - - d := daemon.New(c, dockerBinary, dockerdBinary, testdaemon.WithEnvironment(testEnv.Execution)) - discoveryBackend := "consul://consuladdr:consulport/some/path" - - // --cluster-advertise with an invalid string is an error - err := d.StartWithError(fmt.Sprintf("--cluster-store=%s", discoveryBackend), "--cluster-advertise=invalid") - assert.ErrorContains(c, err, "") - - // --cluster-advertise without --cluster-store is also an error - err = d.StartWithError("--cluster-advertise=1.1.1.1:2375") - assert.ErrorContains(c, err, "") -} - -// TestInfoDiscoveryAdvertiseInterfaceName verifies that a daemon run with `--cluster-advertise` -// configured with interface name properly show the advertise ip-address in info output. -func (s *DockerSuite) TestInfoDiscoveryAdvertiseInterfaceName(c *testing.T) { - testRequires(c, testEnv.IsLocalDaemon, Network, DaemonIsLinux) - - d := daemon.New(c, dockerBinary, dockerdBinary, testdaemon.WithEnvironment(testEnv.Execution)) - discoveryBackend := "consul://consuladdr:consulport/some/path" - discoveryAdvertise := "eth0" - - d.Start(c, fmt.Sprintf("--cluster-store=%s", discoveryBackend), fmt.Sprintf("--cluster-advertise=%s:2375", discoveryAdvertise)) - defer d.Stop(c) - - iface, err := net.InterfaceByName(discoveryAdvertise) - assert.NilError(c, err) - addrs, err := iface.Addrs() - assert.NilError(c, err) - assert.Assert(c, len(addrs) > 0) - ip, _, err := net.ParseCIDR(addrs[0].String()) - assert.NilError(c, err) - - out, err := d.Cmd("info") - assert.NilError(c, err) - assert.Assert(c, strings.Contains(out, fmt.Sprintf("Cluster Store: %s\n", discoveryBackend))) - assert.Assert(c, strings.Contains(out, fmt.Sprintf("Cluster Advertise: %s:2375\n", ip.String()))) -} - func (s *DockerSuite) TestInfoDisplaysRunningContainers(c *testing.T) { testRequires(c, DaemonIsLinux) @@ -174,55 +100,6 @@ func (s *DockerSuite) TestInfoDisplaysStoppedContainers(c *testing.T) { assert.Assert(c, strings.Contains(out, fmt.Sprintf(" Stopped: %d\n", existing["ContainersStopped"]+1))) } -func (s *DockerSuite) TestInfoDebug(c *testing.T) { - testRequires(c, testEnv.IsLocalDaemon, DaemonIsLinux) - - d := daemon.New(c, dockerBinary, dockerdBinary, testdaemon.WithEnvironment(testEnv.Execution)) - d.Start(c, "--debug") - defer d.Stop(c) - - out, err := d.Cmd("--debug", "info") - assert.NilError(c, err) - assert.Assert(c, strings.Contains(out, "Debug Mode (client): true\n")) - assert.Assert(c, strings.Contains(out, "Debug Mode (server): true\n")) - assert.Assert(c, strings.Contains(out, "File Descriptors")) - assert.Assert(c, strings.Contains(out, "Goroutines")) - assert.Assert(c, strings.Contains(out, "System Time")) - assert.Assert(c, strings.Contains(out, "EventsListeners")) - assert.Assert(c, strings.Contains(out, "Docker Root Dir")) -} - -func (s *DockerSuite) TestInsecureRegistries(c *testing.T) { - testRequires(c, testEnv.IsLocalDaemon, DaemonIsLinux) - - registryCIDR := "192.168.1.0/24" - registryHost := "insecurehost.com:5000" - - d := daemon.New(c, dockerBinary, dockerdBinary, testdaemon.WithEnvironment(testEnv.Execution)) - d.Start(c, "--insecure-registry="+registryCIDR, "--insecure-registry="+registryHost) - defer d.Stop(c) - - out, err := d.Cmd("info") - assert.NilError(c, err) - assert.Assert(c, strings.Contains(out, "Insecure Registries:\n")) - assert.Assert(c, strings.Contains(out, fmt.Sprintf(" %s\n", registryHost))) - assert.Assert(c, strings.Contains(out, fmt.Sprintf(" %s\n", registryCIDR))) -} - -func (s *DockerDaemonSuite) TestRegistryMirrors(c *testing.T) { - - registryMirror1 := "https://192.168.1.2" - registryMirror2 := "http://registry.mirror.com:5000" - - s.d.Start(c, "--registry-mirror="+registryMirror1, "--registry-mirror="+registryMirror2) - - out, err := s.d.Cmd("info") - assert.NilError(c, err) - assert.Assert(c, strings.Contains(out, "Registry Mirrors:\n")) - assert.Assert(c, strings.Contains(out, fmt.Sprintf(" %s", registryMirror1))) - assert.Assert(c, strings.Contains(out, fmt.Sprintf(" %s", registryMirror2))) -} - func existingContainerStates(c *testing.T) map[string]int { out, _ := dockerCmd(c, "info", "--format", "{{json .}}") var m map[string]interface{} diff --git a/integration-cli/docker_cli_info_unix_test.go b/integration-cli/docker_cli_info_unix_test.go index 59e0764336..ab9c9468d9 100644 --- a/integration-cli/docker_cli_info_unix_test.go +++ b/integration-cli/docker_cli_info_unix_test.go @@ -3,15 +3,30 @@ package main import ( - "strings" + "context" "testing" + "github.com/docker/docker/client" "gotest.tools/assert" + is "gotest.tools/assert/cmp" ) func (s *DockerSuite) TestInfoSecurityOptions(c *testing.T) { - testRequires(c, testEnv.IsLocalDaemon, seccompEnabled, Apparmor, DaemonIsLinux) + testRequires(c, testEnv.IsLocalDaemon, DaemonIsLinux) + if !seccompEnabled() && !Apparmor() { + c.Skip("test requires Seccomp and/or AppArmor") + } - out, _ := dockerCmd(c, "info") - assert.Assert(c, strings.Contains(out, "Security Options:\n apparmor\n seccomp\n Profile: default\n")) + cli, err := client.NewClientWithOpts(client.FromEnv) + assert.NilError(c, err) + defer cli.Close() + info, err := cli.Info(context.Background()) + assert.NilError(c, err) + + if Apparmor() { + assert.Check(c, is.Contains(info.SecurityOptions, "name=apparmor")) + } + if seccompEnabled() { + assert.Check(c, is.Contains(info.SecurityOptions, "name=seccomp,profile=default")) + } } diff --git a/integration/system/info_linux_test.go b/integration/system/info_linux_test.go index 434373b369..c51e7a3a39 100644 --- a/integration/system/info_linux_test.go +++ b/integration/system/info_linux_test.go @@ -4,12 +4,16 @@ package system // import "github.com/docker/docker/integration/system" import ( "context" + "fmt" + "net" "net/http" "testing" + "github.com/docker/docker/testutil/daemon" req "github.com/docker/docker/testutil/request" "gotest.tools/assert" is "gotest.tools/assert/cmp" + "gotest.tools/skip" ) func TestInfoBinaryCommits(t *testing.T) { @@ -43,3 +47,71 @@ func TestInfoAPIVersioned(t *testing.T) { assert.Check(t, is.Contains(out, "ExecutionDriver")) assert.Check(t, is.Contains(out, "not supported")) } + +// TestInfoDiscoveryBackend verifies that a daemon run with `--cluster-advertise` and +// `--cluster-store` properly returns the backend's endpoint in info output. +func TestInfoDiscoveryBackend(t *testing.T) { + skip.If(t, testEnv.IsRemoteDaemon, "cannot run daemon when remote daemon") + + const ( + discoveryBackend = "consul://consuladdr:consulport/some/path" + discoveryAdvertise = "1.1.1.1:2375" + ) + + d := daemon.New(t) + d.Start(t, "--cluster-store="+discoveryBackend, "--cluster-advertise="+discoveryAdvertise) + defer d.Stop(t) + + info := d.Info(t) + assert.Equal(t, info.ClusterStore, discoveryBackend) + assert.Equal(t, info.ClusterAdvertise, discoveryAdvertise) +} + +// TestInfoDiscoveryInvalidAdvertise verifies that a daemon run with +// an invalid `--cluster-advertise` configuration +func TestInfoDiscoveryInvalidAdvertise(t *testing.T) { + skip.If(t, testEnv.IsRemoteDaemon, "cannot run daemon when remote daemon") + d := daemon.New(t) + + // --cluster-advertise with an invalid string is an error + err := d.StartWithError("--cluster-store=consul://consuladdr:consulport/some/path", "--cluster-advertise=invalid") + if err == nil { + d.Stop(t) + } + assert.ErrorContains(t, err, "", "expected error when starting daemon") + + // --cluster-advertise without --cluster-store is also an error + err = d.StartWithError("--cluster-advertise=1.1.1.1:2375") + if err == nil { + d.Stop(t) + } + assert.ErrorContains(t, err, "", "expected error when starting daemon") +} + +// TestInfoDiscoveryAdvertiseInterfaceName verifies that a daemon run with `--cluster-advertise` +// configured with interface name properly show the advertise ip-address in info output. +func TestInfoDiscoveryAdvertiseInterfaceName(t *testing.T) { + skip.If(t, testEnv.IsRemoteDaemon, "cannot run daemon when remote daemon") + // TODO should we check for networking availability (integration-cli suite checks for networking through `Network()`) + + d := daemon.New(t) + const ( + discoveryStore = "consul://consuladdr:consulport/some/path" + discoveryInterface = "eth0" + ) + + d.Start(t, "--cluster-store="+discoveryStore, fmt.Sprintf("--cluster-advertise=%s:2375", discoveryInterface)) + defer d.Stop(t) + + iface, err := net.InterfaceByName(discoveryInterface) + assert.NilError(t, err) + addrs, err := iface.Addrs() + assert.NilError(t, err) + assert.Assert(t, len(addrs) > 0) + ip, _, err := net.ParseCIDR(addrs[0].String()) + assert.NilError(t, err) + + info := d.Info(t) + assert.Equal(t, info.ClusterStore, discoveryStore) + assert.Equal(t, info.ClusterAdvertise, ip.String()+":2375") +} diff --git a/integration/system/info_test.go b/integration/system/info_test.go index 56a735714e..e47b0ed4ea 100644 --- a/integration/system/info_test.go +++ b/integration/system/info_test.go @@ -3,8 +3,10 @@ package system // import "github.com/docker/docker/integration/system" import ( "context" "fmt" + "sort" "testing" + "github.com/docker/docker/api/types/registry" "github.com/docker/docker/testutil/daemon" "gotest.tools/assert" is "gotest.tools/assert/cmp" @@ -49,7 +51,7 @@ func TestInfoAPIWarnings(t *testing.T) { d := daemon.New(t) c := d.NewClientT(t) - d.StartWithBusybox(t, "-H=0.0.0.0:23756", "-H="+d.Sock()) + d.Start(t, "-H=0.0.0.0:23756", "-H="+d.Sock()) defer d.Stop(t) info, err := c.Info(context.Background()) @@ -65,3 +67,64 @@ func TestInfoAPIWarnings(t *testing.T) { assert.Check(t, is.Contains(out, linePrefix)) } } + +func TestInfoDebug(t *testing.T) { + skip.If(t, testEnv.IsRemoteDaemon, "cannot run daemon when remote daemon") + + d := daemon.New(t) + d.Start(t, "--debug") + defer d.Stop(t) + + info := d.Info(t) + assert.Equal(t, info.Debug, true) + + // Note that the information below is not tied to debug-mode being enabled. + assert.Check(t, info.NFd != 0) + + // TODO need a stable way to generate event listeners + // assert.Check(t, info.NEventsListener != 0) + assert.Check(t, info.NGoroutines != 0) + assert.Check(t, info.SystemTime != "") + assert.Equal(t, info.DockerRootDir, d.Root) +} + +func TestInfoInsecureRegistries(t *testing.T) { + skip.If(t, testEnv.IsRemoteDaemon, "cannot run daemon when remote daemon") + + const ( + registryCIDR = "192.168.1.0/24" + registryHost = "insecurehost.com:5000" + ) + + d := daemon.New(t) + d.Start(t, "--insecure-registry="+registryCIDR, "--insecure-registry="+registryHost) + defer d.Stop(t) + + info := d.Info(t) + assert.Assert(t, is.Len(info.RegistryConfig.InsecureRegistryCIDRs, 2)) + cidrs := []string{ + info.RegistryConfig.InsecureRegistryCIDRs[0].String(), + info.RegistryConfig.InsecureRegistryCIDRs[1].String(), + } + assert.Assert(t, is.Contains(cidrs, registryCIDR)) + assert.Assert(t, is.Contains(cidrs, "127.0.0.0/8")) + assert.DeepEqual(t, *info.RegistryConfig.IndexConfigs["docker.io"], registry.IndexInfo{Name: "docker.io", Mirrors: []string{}, Secure: true, Official: true}) + assert.DeepEqual(t, *info.RegistryConfig.IndexConfigs[registryHost], registry.IndexInfo{Name: registryHost, Mirrors: []string{}, Secure: false, Official: false}) +} + +func TestInfoRegistryMirrors(t *testing.T) { + skip.If(t, testEnv.IsRemoteDaemon, "cannot run daemon when remote daemon") + + const ( + registryMirror1 = "https://192.168.1.2" + registryMirror2 = "http://registry.mirror.com:5000" + ) + + d := daemon.New(t) + d.Start(t, "--registry-mirror="+registryMirror1, "--registry-mirror="+registryMirror2) + defer d.Stop(t) + + info := d.Info(t) + sort.Strings(info.RegistryConfig.Mirrors) + assert.DeepEqual(t, info.RegistryConfig.Mirrors, []string{registryMirror2 + "/", registryMirror1 + "/"}) +}