mirror of
https://github.com/moby/moby.git
synced 2022-11-09 12:21:53 -05:00
79 lines
1.9 KiB
Go
79 lines
1.9 KiB
Go
|
package main
|
||
|
|
||
|
import (
|
||
|
"bufio"
|
||
|
"bytes"
|
||
|
"fmt"
|
||
|
"io"
|
||
|
"os/exec"
|
||
|
"strconv"
|
||
|
|
||
|
"github.com/go-check/check"
|
||
|
)
|
||
|
|
||
|
// eventMatcher is a function that tries to match an event input.
|
||
|
type eventMatcher func(text string)
|
||
|
|
||
|
// eventObserver runs an events commands and observes its output.
|
||
|
type eventObserver struct {
|
||
|
buffer *bytes.Buffer
|
||
|
command *exec.Cmd
|
||
|
stdout io.Reader
|
||
|
}
|
||
|
|
||
|
// newEventObserver creates the observer and initializes the command
|
||
|
// without running it. Users must call `eventObserver.Start` to start the command.
|
||
|
func newEventObserver(c *check.C, args ...string) (*eventObserver, error) {
|
||
|
since := daemonTime(c).Unix()
|
||
|
|
||
|
cmdArgs := []string{"events", "--since", strconv.FormatInt(since, 10)}
|
||
|
if len(args) > 0 {
|
||
|
cmdArgs = append(cmdArgs, args...)
|
||
|
}
|
||
|
eventsCmd := exec.Command(dockerBinary, cmdArgs...)
|
||
|
stdout, err := eventsCmd.StdoutPipe()
|
||
|
if err != nil {
|
||
|
return nil, err
|
||
|
}
|
||
|
|
||
|
return &eventObserver{
|
||
|
buffer: new(bytes.Buffer),
|
||
|
command: eventsCmd,
|
||
|
stdout: stdout,
|
||
|
}, nil
|
||
|
}
|
||
|
|
||
|
// Start starts the events command.
|
||
|
func (e *eventObserver) Start() error {
|
||
|
return e.command.Start()
|
||
|
}
|
||
|
|
||
|
// Stop stops the events command.
|
||
|
func (e *eventObserver) Stop() {
|
||
|
e.command.Process.Kill()
|
||
|
}
|
||
|
|
||
|
// Match tries to match the events output with a given matcher.
|
||
|
func (e *eventObserver) Match(match eventMatcher) {
|
||
|
scanner := bufio.NewScanner(e.stdout)
|
||
|
|
||
|
for scanner.Scan() {
|
||
|
text := scanner.Text()
|
||
|
e.buffer.WriteString(text)
|
||
|
e.buffer.WriteString("\n")
|
||
|
|
||
|
match(text)
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// TimeoutError generates an error for a given containerID and event type.
|
||
|
// It attaches the events command output to the error.
|
||
|
func (e *eventObserver) TimeoutError(id, event string) error {
|
||
|
return fmt.Errorf("failed to observe event `%s` for %s\n%v", event, id, e.output())
|
||
|
}
|
||
|
|
||
|
// output returns the events command output read until now by the Match goroutine.
|
||
|
func (e *eventObserver) output() string {
|
||
|
return e.buffer.String()
|
||
|
}
|