Signed-off-by: Andrea Luzzardi <aluzzardi@gmail.com>
| ... | ... |
@@ -237,10 +237,6 @@ func (sr *swarmRouter) getServiceLogs(ctx context.Context, w http.ResponseWriter |
| 237 | 237 |
OutStream: w, |
| 238 | 238 |
} |
| 239 | 239 |
|
| 240 |
- if !logsConfig.Follow {
|
|
| 241 |
- return fmt.Errorf("Bad parameters: Only follow mode is currently supported")
|
|
| 242 |
- } |
|
| 243 |
- |
|
| 244 | 240 |
if logsConfig.Details {
|
| 245 | 241 |
return fmt.Errorf("Bad parameters: details is not currently supported")
|
| 246 | 242 |
} |
| ... | ... |
@@ -1275,7 +1275,7 @@ func (c *Cluster) ServiceLogs(ctx context.Context, input string, config *backend |
| 1275 | 1275 |
ServiceIDs: []string{service.ID},
|
| 1276 | 1276 |
}, |
| 1277 | 1277 |
Options: &swarmapi.LogSubscriptionOptions{
|
| 1278 |
- Follow: true, |
|
| 1278 |
+ Follow: config.Follow, |
|
| 1279 | 1279 |
}, |
| 1280 | 1280 |
}) |
| 1281 | 1281 |
if err != nil {
|
| ... | ... |
@@ -419,7 +419,11 @@ func (c *containerAdapter) logs(ctx context.Context, options api.LogSubscription |
| 419 | 419 |
} |
| 420 | 420 |
|
| 421 | 421 |
chStarted := make(chan struct{})
|
| 422 |
- go c.backend.ContainerLogs(ctx, c.container.name(), apiOptions, chStarted) |
|
| 422 |
+ go func() {
|
|
| 423 |
+ defer writer.Close() |
|
| 424 |
+ c.backend.ContainerLogs(ctx, c.container.name(), apiOptions, chStarted) |
|
| 425 |
+ }() |
|
| 426 |
+ |
|
| 423 | 427 |
return reader, nil |
| 424 | 428 |
} |
| 425 | 429 |
|
| ... | ... |
@@ -4,6 +4,7 @@ package main |
| 4 | 4 |
|
| 5 | 5 |
import ( |
| 6 | 6 |
"bufio" |
| 7 |
+ "fmt" |
|
| 7 | 8 |
"io" |
| 8 | 9 |
"os/exec" |
| 9 | 10 |
"strings" |
| ... | ... |
@@ -24,7 +25,27 @@ func (s *DockerSwarmSuite) TestServiceLogs(c *check.C) {
|
| 24 | 24 |
|
| 25 | 25 |
name := "TestServiceLogs" |
| 26 | 26 |
|
| 27 |
- out, err := d.Cmd("service", "create", "--name", name, "busybox", "sh", "-c", "while true; do echo log test; sleep 1; done")
|
|
| 27 |
+ out, err := d.Cmd("service", "create", "--name", name, "--restart-condition", "none", "busybox", "sh", "-c", "echo hello world")
|
|
| 28 |
+ c.Assert(err, checker.IsNil) |
|
| 29 |
+ c.Assert(strings.TrimSpace(out), checker.Not(checker.Equals), "") |
|
| 30 |
+ |
|
| 31 |
+ // make sure task has been deployed. |
|
| 32 |
+ waitAndAssert(c, defaultReconciliationTimeout, d.checkActiveContainerCount, checker.Equals, 1) |
|
| 33 |
+ |
|
| 34 |
+ out, err = d.Cmd("service", "logs", name)
|
|
| 35 |
+ fmt.Println(out) |
|
| 36 |
+ c.Assert(err, checker.IsNil) |
|
| 37 |
+ c.Assert(out, checker.Contains, "hello world") |
|
| 38 |
+} |
|
| 39 |
+ |
|
| 40 |
+func (s *DockerSwarmSuite) TestServiceLogsFollow(c *check.C) {
|
|
| 41 |
+ testRequires(c, ExperimentalDaemon) |
|
| 42 |
+ |
|
| 43 |
+ d := s.AddDaemon(c, true, true) |
|
| 44 |
+ |
|
| 45 |
+ name := "TestServiceLogsFollow" |
|
| 46 |
+ |
|
| 47 |
+ out, err := d.Cmd("service", "create", "--name", name, "busybox", "sh", "-c", "while true; do echo log test; sleep 0.1; done")
|
|
| 28 | 48 |
c.Assert(err, checker.IsNil) |
| 29 | 49 |
c.Assert(strings.TrimSpace(out), checker.Not(checker.Equals), "") |
| 30 | 50 |
|
| ... | ... |
@@ -40,16 +61,26 @@ func (s *DockerSwarmSuite) TestServiceLogs(c *check.C) {
|
| 40 | 40 |
|
| 41 | 41 |
// Make sure pipe is written to |
| 42 | 42 |
ch := make(chan *logMessage) |
| 43 |
+ done := make(chan struct{})
|
|
| 43 | 44 |
go func() {
|
| 44 | 45 |
reader := bufio.NewReader(r) |
| 45 |
- msg := &logMessage{}
|
|
| 46 |
- msg.data, _, msg.err = reader.ReadLine() |
|
| 47 |
- ch <- msg |
|
| 46 |
+ for {
|
|
| 47 |
+ msg := &logMessage{}
|
|
| 48 |
+ msg.data, _, msg.err = reader.ReadLine() |
|
| 49 |
+ select {
|
|
| 50 |
+ case ch <- msg: |
|
| 51 |
+ case <-done: |
|
| 52 |
+ return |
|
| 53 |
+ } |
|
| 54 |
+ } |
|
| 48 | 55 |
}() |
| 49 | 56 |
|
| 50 |
- msg := <-ch |
|
| 51 |
- c.Assert(msg.err, checker.IsNil) |
|
| 52 |
- c.Assert(string(msg.data), checker.Contains, "log test") |
|
| 57 |
+ for i := 0; i < 3; i++ {
|
|
| 58 |
+ msg := <-ch |
|
| 59 |
+ c.Assert(msg.err, checker.IsNil) |
|
| 60 |
+ c.Assert(string(msg.data), checker.Contains, "log test") |
|
| 61 |
+ } |
|
| 62 |
+ close(done) |
|
| 53 | 63 |
|
| 54 | 64 |
c.Assert(cmd.Process.Kill(), checker.IsNil) |
| 55 | 65 |
} |