mirror of https://github.com/knative/func.git
feat: improve docker build and push output (#1364)
Signed-off-by: Matej Vasek <mvasek@redhat.com> Signed-off-by: Matej Vasek <mvasek@redhat.com>
This commit is contained in:
parent
fe81e235d3
commit
cc063f79fc
|
@ -17,11 +17,13 @@ import (
|
|||
|
||||
"github.com/docker/docker/api/types"
|
||||
"github.com/docker/docker/client"
|
||||
"github.com/docker/docker/pkg/jsonmessage"
|
||||
"github.com/google/go-containerregistry/pkg/authn"
|
||||
"github.com/google/go-containerregistry/pkg/name"
|
||||
v1 "github.com/google/go-containerregistry/pkg/v1"
|
||||
"github.com/google/go-containerregistry/pkg/v1/daemon"
|
||||
"github.com/google/go-containerregistry/pkg/v1/remote"
|
||||
"golang.org/x/term"
|
||||
)
|
||||
|
||||
type Opt func(*Pusher)
|
||||
|
@ -176,34 +178,19 @@ func (n *Pusher) daemonPush(ctx context.Context, f fn.Function, credentials Cred
|
|||
var outBuff bytes.Buffer
|
||||
output = io.MultiWriter(&outBuff, output)
|
||||
|
||||
decoder := json.NewDecoder(r)
|
||||
li := logItem{}
|
||||
for {
|
||||
err = decoder.Decode(&li)
|
||||
if err != nil {
|
||||
if errors.Is(err, io.EOF) {
|
||||
err = nil
|
||||
}
|
||||
break
|
||||
}
|
||||
if li.Error != "" {
|
||||
return "", errors.New(li.ErrorDetail.Message)
|
||||
}
|
||||
if li.Id != "" {
|
||||
fmt.Fprintf(output, "%s: ", li.Id)
|
||||
}
|
||||
var percent int
|
||||
if li.ProgressDetail.Total == 0 {
|
||||
percent = 100
|
||||
} else {
|
||||
percent = (li.ProgressDetail.Current * 100) / li.ProgressDetail.Total
|
||||
}
|
||||
fmt.Fprintf(output, "%s (%d%%)\n", li.Status, percent)
|
||||
var isTerminal bool
|
||||
var fd uintptr
|
||||
if outF, ok := output.(*os.File); ok {
|
||||
fd = outF.Fd()
|
||||
isTerminal = term.IsTerminal(int(outF.Fd()))
|
||||
}
|
||||
|
||||
digest = ParseDigest(outBuff.String())
|
||||
err = jsonmessage.DisplayJSONMessagesStream(r, output, fd, isTerminal, nil)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
return digest, nil
|
||||
return ParseDigest(outBuff.String()), nil
|
||||
}
|
||||
|
||||
var digestRE = regexp.MustCompile(`digest:\s+(sha256:\w{64})`)
|
||||
|
@ -219,24 +206,6 @@ func ParseDigest(output string) string {
|
|||
return ""
|
||||
}
|
||||
|
||||
type errorDetail struct {
|
||||
Message string `json:"message"`
|
||||
}
|
||||
|
||||
type progressDetail struct {
|
||||
Current int `json:"current"`
|
||||
Total int `json:"total"`
|
||||
}
|
||||
|
||||
type logItem struct {
|
||||
Id string `json:"id"`
|
||||
Status string `json:"status"`
|
||||
Error string `json:"error"`
|
||||
ErrorDetail errorDetail `json:"errorDetail"`
|
||||
Progress string `json:"progress"`
|
||||
ProgressDetail progressDetail `json:"progressDetail"`
|
||||
}
|
||||
|
||||
func (n *Pusher) push(ctx context.Context, f fn.Function, credentials Credentials, output io.Writer) (digest string, err error) {
|
||||
auth := &authn.Basic{
|
||||
Username: credentials.Username,
|
||||
|
|
|
@ -3,7 +3,6 @@ package s2i
|
|||
import (
|
||||
"archive/tar"
|
||||
"context"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
|
@ -15,6 +14,7 @@ import (
|
|||
|
||||
"github.com/docker/docker/api/types"
|
||||
dockerClient "github.com/docker/docker/client"
|
||||
"github.com/docker/docker/pkg/jsonmessage"
|
||||
"github.com/google/go-containerregistry/pkg/name"
|
||||
v1 "github.com/google/go-containerregistry/pkg/v1"
|
||||
"github.com/google/go-containerregistry/pkg/v1/remote"
|
||||
|
@ -24,6 +24,7 @@ import (
|
|||
"github.com/openshift/source-to-image/pkg/build/strategies"
|
||||
s2idocker "github.com/openshift/source-to-image/pkg/docker"
|
||||
"github.com/openshift/source-to-image/pkg/scm/git"
|
||||
"golang.org/x/term"
|
||||
|
||||
fn "knative.dev/func"
|
||||
"knative.dev/func/builders"
|
||||
|
@ -281,45 +282,14 @@ func (b *Builder) Build(ctx context.Context, f fn.Function) (err error) {
|
|||
out = os.Stderr
|
||||
}
|
||||
|
||||
errMsg, err := parseBuildResponse(resp.Body, out)
|
||||
if err != nil {
|
||||
return fmt.Errorf("cannot parse response body: %w", err)
|
||||
}
|
||||
if errMsg != "" {
|
||||
return fmt.Errorf("cannot build the app: %s", errMsg)
|
||||
var isTerminal bool
|
||||
var fd uintptr
|
||||
if outF, ok := out.(*os.File); ok {
|
||||
fd = outF.Fd()
|
||||
isTerminal = term.IsTerminal(int(outF.Fd()))
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func parseBuildResponse(r io.Reader, w io.Writer) (errorMessage string, err error) {
|
||||
obj := struct {
|
||||
ErrorDetail struct {
|
||||
Message string `json:"message"`
|
||||
} `json:"errorDetail"`
|
||||
Stream string `json:"stream"`
|
||||
}{}
|
||||
d := json.NewDecoder(r)
|
||||
for {
|
||||
err = d.Decode(&obj)
|
||||
if err != nil {
|
||||
if errors.Is(err, io.EOF) {
|
||||
break
|
||||
}
|
||||
return "", err
|
||||
}
|
||||
if obj.ErrorDetail.Message != "" {
|
||||
errorMessage = obj.ErrorDetail.Message
|
||||
return errorMessage, nil
|
||||
}
|
||||
if obj.Stream != "" {
|
||||
_, err = w.Write([]byte(obj.Stream))
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
}
|
||||
}
|
||||
return "", nil
|
||||
return jsonmessage.DisplayJSONMessagesStream(resp.Body, out, fd, isTerminal, nil)
|
||||
}
|
||||
|
||||
func s2iScriptURL(ctx context.Context, cli DockerClient, image string) (string, error) {
|
||||
|
|
Loading…
Reference in New Issue