diff --git a/api/server/router/local/container.go b/api/server/router/local/container.go index 76244f193c..d1e352dd32 100644 --- a/api/server/router/local/container.go +++ b/api/server/router/local/container.go @@ -116,9 +116,10 @@ func (s *router) getContainersLogs(ctx context.Context, w http.ResponseWriter, r closeNotifier = notifier.CloseNotify() } - c, err := s.daemon.Get(vars["name"]) - if err != nil { - return err + containerName := vars["name"] + + if !s.daemon.Exists(containerName) { + return derr.ErrorCodeNoSuchContainer.WithArgs(containerName) } outStream := ioutils.NewWriteFlusher(w) @@ -138,7 +139,7 @@ func (s *router) getContainersLogs(ctx context.Context, w http.ResponseWriter, r Stop: closeNotifier, } - if err := s.daemon.ContainerLogs(c, logsConfig); err != nil { + if err := s.daemon.ContainerLogs(containerName, logsConfig); err != nil { // The client may be expecting all of the data we're sending to // be multiplexed, so send it through OutStream, which will // have been set up to handle that if needed. diff --git a/daemon/logs.go b/daemon/logs.go index d52a5dc527..e4a4853c39 100644 --- a/daemon/logs.go +++ b/daemon/logs.go @@ -30,7 +30,12 @@ type ContainerLogsConfig struct { // ContainerLogs hooks up a container's stdout and stderr streams // configured with the given struct. -func (daemon *Daemon) ContainerLogs(container *Container, config *ContainerLogsConfig) error { +func (daemon *Daemon) ContainerLogs(containerName string, config *ContainerLogsConfig) error { + container, err := daemon.Get(containerName) + if err != nil { + return derr.ErrorCodeNoSuchContainer.WithArgs(containerName) + } + if !(config.UseStdout || config.UseStderr) { return derr.ErrorCodeNeedStream } diff --git a/integration-cli/docker_api_logs_test.go b/integration-cli/docker_api_logs_test.go index 6b7642f25c..26c59fed72 100644 --- a/integration-cli/docker_api_logs_test.go +++ b/integration-cli/docker_api_logs_test.go @@ -82,3 +82,10 @@ func (s *DockerSuite) TestLogsApiFollowEmptyOutput(c *check.C) { c.Fatalf("HTTP response was not immediate (elapsed %.1fs)", elapsed) } } + +func (s *DockerSuite) TestLogsAPIContainerNotFound(c *check.C) { + name := "nonExistentContainer" + resp, _, err := sockRequestRaw("GET", fmt.Sprintf("/containers/%s/logs?follow=1&stdout=1&stderr=1&tail=all", name), bytes.NewBuffer(nil), "") + c.Assert(err, check.IsNil) + c.Assert(resp.StatusCode, check.Equals, http.StatusNotFound) +} diff --git a/integration-cli/docker_cli_logs_test.go b/integration-cli/docker_cli_logs_test.go index 26456f34c1..c7454fb2fd 100644 --- a/integration-cli/docker_cli_logs_test.go +++ b/integration-cli/docker_cli_logs_test.go @@ -374,3 +374,10 @@ func (s *DockerSuite) TestLogsFollowGoroutinesNoOutput(c *check.C) { } } } + +func (s *DockerSuite) TestLogsCLIContainerNotFound(c *check.C) { + name := "testlogsnocontainer" + out, _, _ := dockerCmdWithError("logs", name) + message := fmt.Sprintf(".*no such id: %s.*\n", name) + c.Assert(out, check.Matches, message) +}