Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
49 changes: 37 additions & 12 deletions service/runner_docker.go
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down Expand Up @@ -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{
Expand Down Expand Up @@ -260,6 +263,29 @@ func (r *dockerRunner) start(image string, command string, args []string, volume
return nil, maskAny(err)
}
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)
Expand All @@ -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
}

Expand Down Expand Up @@ -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")
}
}

Expand Down
13 changes: 9 additions & 4 deletions service/version_check.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,22 +29,25 @@ import (
"strings"

driver "github.com/arangodb/go-driver"
"github.com/dchest/uniuri"
)

// DatabaseVersion returns the version of the `arangod` binary that is being
// used by this starter.
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)
}
defer p.Cleanup()
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 {
Expand All @@ -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)
}