diff --git a/pkg/docker/build.go b/pkg/docker/build.go index 483efcb..7efa606 100644 --- a/pkg/docker/build.go +++ b/pkg/docker/build.go @@ -2,8 +2,10 @@ package docker import ( "archive/tar" + "bufio" "bytes" "context" + "encoding/json" "errors" "io" "os" @@ -16,6 +18,15 @@ import ( "github.com/robolaunch/cosmodrome/pkg/api" ) +type ErrorLine struct { + Error string `json:"error"` + ErrorDetail ErrorDetail `json:"errorDetail"` +} + +type ErrorDetail struct { + Message string `json:"message"` +} + func Build(ctx context.Context, dfName, dfPath, buildContext string, step api.Step, lc api.LaunchConfig) error { cli, err := client.NewClientWithOpts(client.FromEnv) if err != nil { @@ -60,7 +71,7 @@ func Build(ctx context.Context, dfName, dfPath, buildContext string, step api.St defer imageBuildResponse.Body.Close() if lc.Verbose { - _, err = io.Copy(os.Stdout, imageBuildResponse.Body) + err = printBuildLogs(os.Stdout, imageBuildResponse.Body) if err != nil { return err } @@ -82,7 +93,7 @@ func Build(ctx context.Context, dfName, dfPath, buildContext string, step api.St } } - _, err = io.Copy(f, imageBuildResponse.Body) + err = printBuildLogs(f, imageBuildResponse.Body) if err != nil { return err } @@ -91,6 +102,28 @@ func Build(ctx context.Context, dfName, dfPath, buildContext string, step api.St return nil } +func printBuildLogs(dst io.Writer, rd io.Reader) error { + var lastLine string + + scanner := bufio.NewScanner(rd) + for scanner.Scan() { + lastLine = scanner.Text() + io.Copy(dst, rd) + } + + errLine := &ErrorLine{} + json.Unmarshal([]byte(lastLine), errLine) + if errLine.Error != "" { + return errors.New(errLine.Error) + } + + if err := scanner.Err(); err != nil { + return err + } + + return nil +} + func BuildMultiplatform(ctx context.Context, dfName, dfPath, buildContext, baseImage string, step api.Step, lc api.LaunchConfig) error { // docker buildx rm multiarch_builder || true