diff options
Diffstat (limited to 'pkg')
-rw-r--r-- | pkg/api/handlers/compat/images_build.go | 16 | ||||
-rw-r--r-- | pkg/bindings/images/build.go | 16 | ||||
-rw-r--r-- | pkg/domain/infra/abi/containers_runlabel.go | 25 |
3 files changed, 36 insertions, 21 deletions
diff --git a/pkg/api/handlers/compat/images_build.go b/pkg/api/handlers/compat/images_build.go index 700881926..ec40fdd2d 100644 --- a/pkg/api/handlers/compat/images_build.go +++ b/pkg/api/handlers/compat/images_build.go @@ -462,12 +462,18 @@ func BuildImage(w http.ResponseWriter, r *http.Request) { buildOptions.Timestamp = &ts } + var ( + imageID string + success bool + ) + runCtx, cancel := context.WithCancel(context.Background()) - var imageID string go func() { defer cancel() imageID, _, err = runtime.Build(r.Context(), buildOptions, query.Dockerfile) - if err != nil { + if err == nil { + success = true + } else { stderr.Write([]byte(err.Error() + "\n")) } }() @@ -483,8 +489,6 @@ func BuildImage(w http.ResponseWriter, r *http.Request) { w.Header().Add("Content-Type", "application/json") flush() - var failed bool - body := w.(io.Writer) if logrus.IsLevelEnabled(logrus.DebugLevel) { if v, found := os.LookupEnv("PODMAN_RETAIN_BUILD_ARTIFACT"); found { @@ -525,14 +529,14 @@ loop: } flush() case e := <-stderr.Chan(): - failed = true m.Error = string(e) if err := enc.Encode(m); err != nil { logrus.Warnf("Failed to json encode error %v", err) } flush() case <-runCtx.Done(): - if !failed { + flush() + if success { if !utils.IsLibpodRequest(r) { m.Stream = fmt.Sprintf("Successfully built %12.12s\n", imageID) if err := enc.Encode(m); err != nil { diff --git a/pkg/bindings/images/build.go b/pkg/bindings/images/build.go index 34d6cee05..c0e5706a5 100644 --- a/pkg/bindings/images/build.go +++ b/pkg/bindings/images/build.go @@ -340,6 +340,7 @@ func Build(ctx context.Context, containerFiles []string, options entities.BuildO re := regexp.MustCompile(`[0-9a-f]{12}`) var id string + var mErr error for { var s struct { Stream string `json:"stream,omitempty"` @@ -347,11 +348,21 @@ func Build(ctx context.Context, containerFiles []string, options entities.BuildO } if err := dec.Decode(&s); err != nil { if errors.Is(err, io.EOF) { - return &entities.BuildReport{ID: id}, nil + if mErr == nil && id == "" { + mErr = errors.New("stream dropped, unexpected failure") + } + break } s.Error = err.Error() + "\n" } + select { + case <-response.Request.Context().Done(): + return &entities.BuildReport{ID: id}, mErr + default: + // non-blocking select + } + switch { case s.Stream != "": stdout.Write([]byte(s.Stream)) @@ -359,11 +370,12 @@ func Build(ctx context.Context, containerFiles []string, options entities.BuildO id = strings.TrimSuffix(s.Stream, "\n") } case s.Error != "": - return nil, errors.New(s.Error) + mErr = errors.New(s.Error) default: return &entities.BuildReport{ID: id}, errors.New("failed to parse build results stream, unexpected input") } } + return &entities.BuildReport{ID: id}, mErr } func nTar(excludes []string, sources ...string) (io.ReadCloser, error) { diff --git a/pkg/domain/infra/abi/containers_runlabel.go b/pkg/domain/infra/abi/containers_runlabel.go index 8de383926..2cabab988 100644 --- a/pkg/domain/infra/abi/containers_runlabel.go +++ b/pkg/domain/infra/abi/containers_runlabel.go @@ -177,6 +177,16 @@ func generateRunlabelCommand(runlabel string, img *image.Image, args []string, o return cmd, env, nil } +func replaceName(arg, name string) string { + newarg := strings.ReplaceAll(arg, "$NAME", name) + return strings.ReplaceAll(newarg, "${NAME}", name) +} + +func replaceImage(arg, image string) string { + newarg := strings.ReplaceAll(arg, "$IMAGE", image) + return strings.ReplaceAll(newarg, "${IMAGE}", image) +} + // generateCommand takes a label (string) and converts it to an executable command func generateCommand(command, imageName, name, globalOpts string) ([]string, error) { if name == "" { @@ -196,26 +206,15 @@ func generateCommand(command, imageName, name, globalOpts string) ([]string, err for _, arg := range cmd[1:] { var newArg string switch arg { - case "IMAGE": - newArg = imageName - case "$IMAGE": - newArg = imageName case "IMAGE=IMAGE": newArg = fmt.Sprintf("IMAGE=%s", imageName) - case "IMAGE=$IMAGE": - newArg = fmt.Sprintf("IMAGE=%s", imageName) - case "NAME": - newArg = name case "NAME=NAME": newArg = fmt.Sprintf("NAME=%s", name) - case "NAME=$NAME": - newArg = fmt.Sprintf("NAME=%s", name) - case "$NAME": - newArg = name case "$GLOBAL_OPTS": newArg = globalOpts default: - newArg = arg + newArg = replaceName(arg, name) + newArg = replaceImage(newArg, imageName) } newCommand = append(newCommand, newArg) } |