From 8627f668f210bd1ba26914248bdb0e497b05eaf7 Mon Sep 17 00:00:00 2001 From: Tonis Tiigi Date: Sat, 25 Jul 2020 23:35:52 -0700 Subject: [PATCH 1/2] docker-container: show logs on bootstrap error Signed-off-by: Tonis Tiigi --- driver/docker-container/driver.go | 50 ++++++++++++++++++++++++++----- 1 file changed, 43 insertions(+), 7 deletions(-) diff --git a/driver/docker-container/driver.go b/driver/docker-container/driver.go index e9b24dde02c..cf11592cef8 100644 --- a/driver/docker-container/driver.go +++ b/driver/docker-container/driver.go @@ -44,7 +44,7 @@ func (d *Driver) Bootstrap(ctx context.Context, l progress.Logger) error { if err := d.start(ctx, sub); err != nil { return err } - if err := d.wait(ctx); err != nil { + if err := d.wait(ctx, sub); err != nil { return err } return nil @@ -106,7 +106,7 @@ func (d *Driver) create(ctx context.Context, l progress.SubLogger) error { if err := d.start(ctx, l); err != nil { return err } - if err := d.wait(ctx); err != nil { + if err := d.wait(ctx, l); err != nil { return err } return nil @@ -116,11 +116,22 @@ func (d *Driver) create(ctx context.Context, l progress.SubLogger) error { return nil } -func (d *Driver) wait(ctx context.Context) error { +func (d *Driver) wait(ctx context.Context, l progress.SubLogger) error { try := 0 for { - if err := d.run(ctx, []string{"buildctl", "debug", "workers"}); err != nil { + bufStdout := &bytes.Buffer{} + bufStderr := &bytes.Buffer{} + if err := d.run(ctx, []string{"buildctl", "debug", "workers"}, bufStdout, bufStderr); err != nil { if try > 10 { + if err != nil { + d.copyLogs(context.TODO(), l) + if bufStdout.Len() != 0 { + l.Log(1, bufStdout.Bytes()) + } + if bufStderr.Len() != 0 { + l.Log(2, bufStderr.Bytes()) + } + } return err } select { @@ -135,6 +146,21 @@ func (d *Driver) wait(ctx context.Context) error { } } +func (d *Driver) copyLogs(ctx context.Context, l progress.SubLogger) error { + rc, err := d.DockerAPI.ContainerLogs(ctx, d.Name, types.ContainerLogsOptions{ + ShowStdout: true, ShowStderr: true, + }) + if err != nil { + return err + } + stdout := &logWriter{logger: l, stream: 1} + stderr := &logWriter{logger: l, stream: 2} + if _, err := stdcopy.StdCopy(stdout, stderr, rc); err != nil { + return err + } + return rc.Close() +} + func (d *Driver) exec(ctx context.Context, cmd []string) (string, net.Conn, error) { execConfig := types.ExecConfig{ Cmd: cmd, @@ -159,12 +185,12 @@ func (d *Driver) exec(ctx context.Context, cmd []string) (string, net.Conn, erro return execID, resp.Conn, nil } -func (d *Driver) run(ctx context.Context, cmd []string) error { +func (d *Driver) run(ctx context.Context, cmd []string, stdout, stderr io.Writer) (err error) { id, conn, err := d.exec(ctx, cmd) if err != nil { return err } - if _, err := io.Copy(ioutil.Discard, conn); err != nil { + if _, err := stdcopy.StdCopy(stdout, stderr, conn); err != nil { return err } conn.Close() @@ -259,7 +285,7 @@ func (d *Driver) Features() map[driver.Feature]bool { func demuxConn(c net.Conn) net.Conn { pr, pw := io.Pipe() // TODO: rewrite parser with Reader() to avoid goroutine switch - go stdcopy.StdCopy(pw, os.Stdout, c) + go stdcopy.StdCopy(pw, os.Stderr, c) return &demux{ Conn: c, Reader: pr, @@ -297,3 +323,13 @@ func readFileToTar(fn string) (*bytes.Buffer, error) { } return buf, nil } + +type logWriter struct { + logger progress.SubLogger + stream int +} + +func (l *logWriter) Write(dt []byte) (int, error) { + l.logger.Log(l.stream, dt) + return len(dt), nil +} From 26570d05c1f80a76067f4708444e28d3464aef51 Mon Sep 17 00:00:00 2001 From: Tonis Tiigi Date: Sat, 25 Jul 2020 23:37:27 -0700 Subject: [PATCH 2/2] docker-container: increase bootstrap timeout Previous value was only 2 sec Signed-off-by: Tonis Tiigi --- driver/docker-container/driver.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/driver/docker-container/driver.go b/driver/docker-container/driver.go index cf11592cef8..0058aa5e4a5 100644 --- a/driver/docker-container/driver.go +++ b/driver/docker-container/driver.go @@ -117,12 +117,12 @@ func (d *Driver) create(ctx context.Context, l progress.SubLogger) error { } func (d *Driver) wait(ctx context.Context, l progress.SubLogger) error { - try := 0 + try := 1 for { bufStdout := &bytes.Buffer{} bufStderr := &bytes.Buffer{} if err := d.run(ctx, []string{"buildctl", "debug", "workers"}, bufStdout, bufStderr); err != nil { - if try > 10 { + if try > 15 { if err != nil { d.copyLogs(context.TODO(), l) if bufStdout.Len() != 0 { @@ -137,7 +137,7 @@ func (d *Driver) wait(ctx context.Context, l progress.SubLogger) error { select { case <-ctx.Done(): return ctx.Err() - case <-time.After(time.Duration(100+try*20) * time.Millisecond): + case <-time.After(time.Duration(try*120) * time.Millisecond): try++ continue }