ソースを参照

refactor logs to not use internal data structures

 - refactor to make it easier to split the api in the future
 - additional tests for non existent container case

Signed-off-by: Morgan Bauer <mbauer@us.ibm.com>
Morgan Bauer 9 年 前
コミット
1eecc1e7e5

+ 5 - 4
api/server/router/local/container.go

@@ -116,9 +116,10 @@ func (s *router) getContainersLogs(ctx context.Context, w http.ResponseWriter, r
 		closeNotifier = notifier.CloseNotify()
 		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)
 	outStream := ioutils.NewWriteFlusher(w)
@@ -138,7 +139,7 @@ func (s *router) getContainersLogs(ctx context.Context, w http.ResponseWriter, r
 		Stop:       closeNotifier,
 		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
 		// The client may be expecting all of the data we're sending to
 		// be multiplexed, so send it through OutStream, which will
 		// be multiplexed, so send it through OutStream, which will
 		// have been set up to handle that if needed.
 		// have been set up to handle that if needed.

+ 6 - 1
daemon/logs.go

@@ -30,7 +30,12 @@ type ContainerLogsConfig struct {
 
 
 // ContainerLogs hooks up a container's stdout and stderr streams
 // ContainerLogs hooks up a container's stdout and stderr streams
 // configured with the given struct.
 // 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) {
 	if !(config.UseStdout || config.UseStderr) {
 		return derr.ErrorCodeNeedStream
 		return derr.ErrorCodeNeedStream
 	}
 	}

+ 7 - 0
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)
 		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)
+}

+ 7 - 0
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)
+}