Skip to content

Commit aee04d8

Browse files
authored
feat(server): add build log (#316)
Signed-off-by: Yaroslav Pershin <62902094+iapershin@users.noreply.github.com>
1 parent 73cc467 commit aee04d8

File tree

1 file changed

+22
-43
lines changed

1 file changed

+22
-43
lines changed

server/pkg/docker/build.go

Lines changed: 22 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,11 @@ package docker
33
import (
44
"archive/tar"
55
"bufio"
6-
"bytes"
76
"context"
87
"fmt"
8+
"io"
99
"os/exec"
1010
"path"
11-
"regexp"
1211

1312
"github.com/djherbis/buffer"
1413
"github.com/djherbis/nio/v3"
@@ -82,19 +81,20 @@ func BuildReleaseArtifacts(ctx context.Context, opts BuildReleaseArtifactsOpts,
8281
}
8382
}()
8483

85-
logboek.Context(ctx).Default().LogF("Building docker image with artifacts\n")
86-
logger.Debug("Building docker image with artifacts")
84+
logboek.Context(ctx).Default().LogLn("Building docker image with artifacts")
85+
logger.Info("Building docker image with artifacts")
8786

8887
args, err := setCliArgs(serviceDockerfilePathInContext, secrets)
8988
if err != nil {
9089
return fmt.Errorf("unable to set cli args: %w", err), nil
9190
}
9291

93-
if err := RunCliBuild(ctx, contextReader, opts.TarWriter, args...); err != nil {
92+
if err := RunCliBuild(ctx, logger, contextReader, opts.TarWriter, args...); err != nil {
9493
return fmt.Errorf("can't build artifacts: %w", err), nil
9594
}
9695

97-
logboek.Context(ctx).Default().LogF("Build is successful\n")
96+
logboek.Context(ctx).Default().LogLn("Build is successful")
97+
logger.Info("Build is successful")
9898

9999
cleanupFunc := func() error {
100100
cli, err := client.NewClientWithOpts(client.FromEnv, client.WithAPIVersionNegotiation())
@@ -107,21 +107,17 @@ func BuildReleaseArtifacts(ctx context.Context, opts BuildReleaseArtifactsOpts,
107107
return nil, cleanupFunc
108108
}
109109

110-
func RunCliBuild(ctx context.Context, contextReader *nio.PipeReader, tarWriter *nio.PipeWriter, args ...string) error {
110+
func RunCliBuild(ctx context.Context, logger hclog.Logger, contextReader *nio.PipeReader, tarWriter *nio.PipeWriter, args ...string) error {
111111
finalArgs := append([]string{"buildx", "build"}, args...)
112112
cmd := exec.CommandContext(ctx, "docker", finalArgs...)
113-
var stdErrBuf bytes.Buffer
113+
114114
cmd.Stdout = tarWriter
115115
cmd.Stdin = contextReader
116-
cmd.Stderr = &stdErrBuf
116+
117+
multiWriter := io.MultiWriter(logboek.Context(ctx).OutStream(), logWriter(logger))
118+
cmd.Stderr = multiWriter
117119

118120
if err := cmd.Run(); err != nil {
119-
if len := stdErrBuf.Len(); len > 0 {
120-
errSection, parseErr := extractRelevantLogs(&stdErrBuf)
121-
if parseErr == nil {
122-
return fmt.Errorf("build failed: %s %w", errSection.String(), err)
123-
}
124-
}
125121
return fmt.Errorf("build failed: %w", err)
126122
}
127123

@@ -132,37 +128,20 @@ func RunCliBuild(ctx context.Context, contextReader *nio.PipeReader, tarWriter *
132128
return nil
133129
}
134130

135-
// this needs for parsing buildx logs due to the fact that buildx writes all to stderr
136-
// it will look for the first error section of the logs that contains the error
137-
// or if not found just lines starts with "error:" or "ERROR:"
138-
func extractRelevantLogs(stderr *bytes.Buffer) (bytes.Buffer, error) {
139-
scanner := bufio.NewScanner(stderr)
140-
141-
var errSection bytes.Buffer
142-
var foundSection bool
143-
reSectionStart := regexp.MustCompile(`^------$`)
144-
reError := regexp.MustCompile(`(?i)^error:`)
145-
146-
for scanner.Scan() {
147-
line := scanner.Text()
148-
149-
if reSectionStart.MatchString(line) {
150-
if foundSection {
151-
break
152-
}
153-
foundSection = true
131+
func logWriter(logger hclog.Logger) *io.PipeWriter {
132+
pr, pw := io.Pipe()
133+
go func() {
134+
scanner := bufio.NewScanner(pr)
135+
for scanner.Scan() {
136+
line := scanner.Text()
137+
logger.Info(line)
154138
}
155-
156-
if foundSection || reError.MatchString(line) {
157-
errSection.WriteString(line + "\n")
139+
if err := scanner.Err(); err != nil {
140+
logger.Error("error reading stderr", "err", err)
158141
}
159-
}
160-
161-
if err := scanner.Err(); err != nil {
162-
return errSection, fmt.Errorf("error reading stderr: %w", err)
163-
}
142+
}()
164143

165-
return errSection, nil
144+
return pw
166145
}
167146

168147
func setCliArgs(serviceDockerfilePathInContext string, secrets []secrets.Secret) ([]string, error) {

0 commit comments

Comments
 (0)