From 70ad664e92da04f487c20a185a3ad659828d15e9 Mon Sep 17 00:00:00 2001 From: Ewout Prangsma Date: Fri, 17 Aug 2018 11:56:37 +0200 Subject: [PATCH 1/2] Fixed version-check when running in docker --- service/runner_docker.go | 51 ++++++++++++++++++++++++++++++---------- service/version_check.go | 13 ++++++---- 2 files changed, 47 insertions(+), 17 deletions(-) diff --git a/service/runner_docker.go b/service/runner_docker.go index 1baf6628..3a889e5b 100644 --- a/service/runner_docker.go +++ b/service/runner_docker.go @@ -90,9 +90,10 @@ type dockerRunner struct { } type dockerContainer struct { + log zerolog.Logger client *docker.Client container *docker.Container - output io.Writer + waiter docker.CloseWaiter } func (r *dockerRunner) GetContainerDir(hostDir, defaultContainerDir string) string { @@ -215,6 +216,8 @@ func (r *dockerRunner) start(image string, command string, args []string, volume Entrypoint: []string{command}, Cmd: args, Tty: r.tty, + AttachStdout: output != nil, + AttachStderr: output != nil, User: r.user, ExposedPorts: make(map[docker.Port]struct{}), Labels: map[string]string{ @@ -259,7 +262,30 @@ func (r *dockerRunner) start(image string, command string, args []string, volume r.log.Error().Err(err).Interface("options", opts).Msg("Creating container failed") return nil, maskAny(err) } - r.recordContainerID(c.ID) // Record ID so we can clean it up later + //r.recordContainerID(c.ID) // Record ID so we can clean it up later + + var waiter docker.CloseWaiter + if output != nil { + // Attach output to container + r.log.Debug().Msgf("Attaching to output of container %s", containerName) + success := make(chan struct{}) + defer close(success) + waiter, err = r.client.AttachToContainerNonBlocking(docker.AttachToContainerOptions{ + Container: c.ID, + OutputStream: output, + Logs: true, + Stdout: true, + Stderr: true, + Success: success, + Stream: true, + RawTerminal: true, + }) + if err != nil { + r.log.Error().Err(err).Msgf("Failed to attach to output of container %s", c.ID) + return nil, maskAny(err) + } + <-success + } r.log.Debug().Msgf("Starting container %s", containerName) if err := r.client.StartContainer(c.ID, opts.HostConfig); err != nil { return nil, maskAny(err) @@ -276,9 +302,10 @@ func (r *dockerRunner) start(image string, command string, args []string, volume return nil, maskAny(err) } return &dockerContainer{ + log: r.log.With().Str("container", c.ID).Logger(), client: r.client, container: c, - output: output, + waiter: waiter, }, nil } @@ -486,16 +513,14 @@ func (p *dockerContainer) HostPort(containerPort int) (int, error) { } func (p *dockerContainer) Wait() { - p.client.WaitContainer(p.container.ID) - if p.output != nil { - // Fetch logs - if err := p.client.Logs(docker.LogsOptions{ - Container: p.container.ID, - OutputStream: p.output, - Stdout: true, - }); err != nil { - p.output.Write([]byte(err.Error())) - } + if p.waiter != nil { + p.waiter.Wait() + } + exitCode, err := p.client.WaitContainer(p.container.ID) + if err != nil { + p.log.Error().Err(err).Msg("WaitContainer failed") + } else if exitCode != 0 { + p.log.Debug().Int("exitcode", exitCode).Msg("Container terminated with non-zero exit code") } } diff --git a/service/version_check.go b/service/version_check.go index 362e7461..1213995e 100644 --- a/service/version_check.go +++ b/service/version_check.go @@ -29,6 +29,7 @@ import ( "strings" driver "github.com/arangodb/go-driver" + "github.com/dchest/uniuri" ) // DatabaseVersion returns the version of the `arangod` binary that is being @@ -36,7 +37,8 @@ import ( func (s *Service) DatabaseVersion(ctx context.Context) (driver.Version, error) { // Start process to print version info output := &bytes.Buffer{} - p, err := s.runner.Start(ctx, ProcessTypeArangod, s.cfg.ArangodPath, []string{"--version"}, nil, nil, "", ".", output) + containerName := "arangodb-versioncheck-" + strings.ToLower(uniuri.NewLen(6)) + p, err := s.runner.Start(ctx, ProcessTypeArangod, s.cfg.ArangodPath, []string{"--version"}, nil, nil, containerName, ".", output) if err != nil { return "", maskAny(err) } @@ -44,7 +46,8 @@ func (s *Service) DatabaseVersion(ctx context.Context) (driver.Version, error) { p.Wait() // Parse output - lines := strings.Split(output.String(), "\n") + stdout := output.String() + lines := strings.Split(stdout, "\n") for _, l := range lines { parts := strings.Split(l, ":") if len(parts) != 2 { @@ -53,7 +56,9 @@ func (s *Service) DatabaseVersion(ctx context.Context) (driver.Version, error) { if strings.TrimSpace(parts[0]) != "server-version" { continue } - return driver.Version(strings.TrimSpace(parts[1])), nil + v := driver.Version(strings.TrimSpace(parts[1])) + s.log.Debug().Msgf("Found server version '%s'", v) + return v, nil } - return "", fmt.Errorf("No server-version found") + return "", fmt.Errorf("No server-version found in '%s'", stdout) } From 83e4a79350d9b5d58d9e817f9862dc37e000e86f Mon Sep 17 00:00:00 2001 From: Ewout Prangsma Date: Fri, 17 Aug 2018 12:47:50 +0200 Subject: [PATCH 2/2] Do record container ID --- service/runner_docker.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/service/runner_docker.go b/service/runner_docker.go index 3a889e5b..9f339f55 100644 --- a/service/runner_docker.go +++ b/service/runner_docker.go @@ -262,7 +262,7 @@ func (r *dockerRunner) start(image string, command string, args []string, volume r.log.Error().Err(err).Interface("options", opts).Msg("Creating container failed") return nil, maskAny(err) } - //r.recordContainerID(c.ID) // Record ID so we can clean it up later + r.recordContainerID(c.ID) // Record ID so we can clean it up later var waiter docker.CloseWaiter if output != nil {