- 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>
| ... | ... |
@@ -116,9 +116,10 @@ func (s *router) getContainersLogs(ctx context.Context, w http.ResponseWriter, r |
| 116 | 116 |
closeNotifier = notifier.CloseNotify() |
| 117 | 117 |
} |
| 118 | 118 |
|
| 119 |
- c, err := s.daemon.Get(vars["name"]) |
|
| 120 |
- if err != nil {
|
|
| 121 |
- return err |
|
| 119 |
+ containerName := vars["name"] |
|
| 120 |
+ |
|
| 121 |
+ if !s.daemon.Exists(containerName) {
|
|
| 122 |
+ return derr.ErrorCodeNoSuchContainer.WithArgs(containerName) |
|
| 122 | 123 |
} |
| 123 | 124 |
|
| 124 | 125 |
outStream := ioutils.NewWriteFlusher(w) |
| ... | ... |
@@ -138,7 +139,7 @@ func (s *router) getContainersLogs(ctx context.Context, w http.ResponseWriter, r |
| 138 | 138 |
Stop: closeNotifier, |
| 139 | 139 |
} |
| 140 | 140 |
|
| 141 |
- if err := s.daemon.ContainerLogs(c, logsConfig); err != nil {
|
|
| 141 |
+ if err := s.daemon.ContainerLogs(containerName, logsConfig); err != nil {
|
|
| 142 | 142 |
// The client may be expecting all of the data we're sending to |
| 143 | 143 |
// be multiplexed, so send it through OutStream, which will |
| 144 | 144 |
// have been set up to handle that if needed. |
| ... | ... |
@@ -30,7 +30,12 @@ type ContainerLogsConfig struct {
|
| 30 | 30 |
|
| 31 | 31 |
// ContainerLogs hooks up a container's stdout and stderr streams |
| 32 | 32 |
// configured with the given struct. |
| 33 |
-func (daemon *Daemon) ContainerLogs(container *Container, config *ContainerLogsConfig) error {
|
|
| 33 |
+func (daemon *Daemon) ContainerLogs(containerName string, config *ContainerLogsConfig) error {
|
|
| 34 |
+ container, err := daemon.Get(containerName) |
|
| 35 |
+ if err != nil {
|
|
| 36 |
+ return derr.ErrorCodeNoSuchContainer.WithArgs(containerName) |
|
| 37 |
+ } |
|
| 38 |
+ |
|
| 34 | 39 |
if !(config.UseStdout || config.UseStderr) {
|
| 35 | 40 |
return derr.ErrorCodeNeedStream |
| 36 | 41 |
} |
| ... | ... |
@@ -82,3 +82,10 @@ func (s *DockerSuite) TestLogsApiFollowEmptyOutput(c *check.C) {
|
| 82 | 82 |
c.Fatalf("HTTP response was not immediate (elapsed %.1fs)", elapsed)
|
| 83 | 83 |
} |
| 84 | 84 |
} |
| 85 |
+ |
|
| 86 |
+func (s *DockerSuite) TestLogsAPIContainerNotFound(c *check.C) {
|
|
| 87 |
+ name := "nonExistentContainer" |
|
| 88 |
+ resp, _, err := sockRequestRaw("GET", fmt.Sprintf("/containers/%s/logs?follow=1&stdout=1&stderr=1&tail=all", name), bytes.NewBuffer(nil), "")
|
|
| 89 |
+ c.Assert(err, check.IsNil) |
|
| 90 |
+ c.Assert(resp.StatusCode, check.Equals, http.StatusNotFound) |
|
| 91 |
+} |
| ... | ... |
@@ -374,3 +374,10 @@ func (s *DockerSuite) TestLogsFollowGoroutinesNoOutput(c *check.C) {
|
| 374 | 374 |
} |
| 375 | 375 |
} |
| 376 | 376 |
} |
| 377 |
+ |
|
| 378 |
+func (s *DockerSuite) TestLogsCLIContainerNotFound(c *check.C) {
|
|
| 379 |
+ name := "testlogsnocontainer" |
|
| 380 |
+ out, _, _ := dockerCmdWithError("logs", name)
|
|
| 381 |
+ message := fmt.Sprintf(".*no such id: %s.*\n", name)
|
|
| 382 |
+ c.Assert(out, check.Matches, message) |
|
| 383 |
+} |