Newer
Older
package csbi
import (
"bufio"
"context"
"encoding/json"
"errors"
"fmt"
"io"
"path/filepath"
"time"
spb "code.fbi.h-da.de/danet/gosdn/api/go/gosdn/southbound"
"github.com/docker/docker/api/types"
"github.com/docker/docker/client"
"github.com/docker/docker/pkg/archive"
"github.com/prometheus/client_golang/prometheus"
log "github.com/sirupsen/logrus"
)
// nolint
type ErrorLine struct {
Error string `json:"error"`
ErrorDetail ErrorDetail `json:"errorDetail"`
}
// nolint
type ErrorDetail struct {
Message string `json:"message"`
}
func buildImage(d Deployment, dockerClient *client.Client) (err error) {
labels := prometheus.Labels{"type": spb.Type_TYPE_CONTAINERISED.String()}
start := promStartHook(labels, buildsTotal)
ctx, cancel := context.WithTimeout(context.Background(), time.Second*300)
defer cancel()
p := filepath.Join(d.ID.String(), "/")
tar, err := archive.TarWithOptions(p, &archive.TarOptions{})
if err != nil {
return err
}
opts := types.ImageBuildOptions{
Dockerfile: "Dockerfile",
Tags: []string{d.Name},
Remove: true,
}
res, err := dockerClient.ImageBuild(ctx, tar, opts)
if err != nil {
return err
}
defer func() {
if ferr := res.Body.Close(); ferr != nil {
fErrString := ferr.Error()
err = fmt.Errorf("InternalError=%w DeferError=%+s", err, fErrString)
}
}()
err = printImageBody(res.Body)
if err != nil {
return err
}
promEndHook(labels, start, buildDurationSecondsTotal, buildDurationSeconds)
return nil
}
func printImageBody(rd io.Reader) error {
var lastLine string
scanner := bufio.NewScanner(rd)
for scanner.Scan() {
lastLine = scanner.Text()
fmt.Println(scanner.Text())
}
errLine := &ErrorLine{}
err := json.Unmarshal([]byte(lastLine), errLine)
if errLine.Error != "" {
return errors.New(errLine.Error)
} else if err != nil {
log.Error(err)
}
return scanner.Err()
}