diff options
author | Valentin Rothberg <rothberg@redhat.com> | 2021-07-26 11:55:33 +0200 |
---|---|---|
committer | Valentin Rothberg <rothberg@redhat.com> | 2021-07-28 14:46:15 +0200 |
commit | 4df6e31ccbad8dd7800e413a0377fa0d1a0774ce (patch) | |
tree | 4b81a37fa61e156d871d98f6874d2afe0ba1ab19 /pkg/api/handlers/compat | |
parent | a5de8314188d7376f645d8ac6c6f7a6f685b6a45 (diff) | |
download | podman-4df6e31ccbad8dd7800e413a0377fa0d1a0774ce.tar.gz podman-4df6e31ccbad8dd7800e413a0377fa0d1a0774ce.tar.bz2 podman-4df6e31ccbad8dd7800e413a0377fa0d1a0774ce.zip |
remote build: fix streaming and error handling
Address a number of issues in the streaming logic in remote build, most
importantly an error in using buffered channels on the server side.
The pattern below does not guarantee that the channel is entirely read
before the context fires.
for {
select {
case <- bufferedChannel:
...
case <- ctx.Done():
...
}
}
Fixes: #10154
Signed-off-by: Valentin Rothberg <rothberg@redhat.com>
Diffstat (limited to 'pkg/api/handlers/compat')
-rw-r--r-- | pkg/api/handlers/compat/images_build.go | 19 |
1 files changed, 10 insertions, 9 deletions
diff --git a/pkg/api/handlers/compat/images_build.go b/pkg/api/handlers/compat/images_build.go index 64805b7fa..2c98a5361 100644 --- a/pkg/api/handlers/compat/images_build.go +++ b/pkg/api/handlers/compat/images_build.go @@ -393,16 +393,16 @@ func BuildImage(w http.ResponseWriter, r *http.Request) { defer auth.RemoveAuthfile(authfile) // Channels all mux'ed in select{} below to follow API build protocol - stdout := channel.NewWriter(make(chan []byte, 1)) + stdout := channel.NewWriter(make(chan []byte)) defer stdout.Close() - auxout := channel.NewWriter(make(chan []byte, 1)) + auxout := channel.NewWriter(make(chan []byte)) defer auxout.Close() - stderr := channel.NewWriter(make(chan []byte, 1)) + stderr := channel.NewWriter(make(chan []byte)) defer stderr.Close() - reporter := channel.NewWriter(make(chan []byte, 1)) + reporter := channel.NewWriter(make(chan []byte)) defer reporter.Close() runtime := r.Context().Value("runtime").(*libpod.Runtime) @@ -529,7 +529,7 @@ func BuildImage(w http.ResponseWriter, r *http.Request) { enc := json.NewEncoder(body) enc.SetEscapeHTML(true) -loop: + for { m := struct { Stream string `json:"stream,omitempty"` @@ -543,13 +543,13 @@ loop: stderr.Write([]byte(err.Error())) } flush() - case e := <-auxout.Chan(): + case e := <-reporter.Chan(): m.Stream = string(e) if err := enc.Encode(m); err != nil { stderr.Write([]byte(err.Error())) } flush() - case e := <-reporter.Chan(): + case e := <-auxout.Chan(): m.Stream = string(e) if err := enc.Encode(m); err != nil { stderr.Write([]byte(err.Error())) @@ -561,8 +561,8 @@ loop: logrus.Warnf("Failed to json encode error %v", err) } flush() + return case <-runCtx.Done(): - flush() if success { if !utils.IsLibpodRequest(r) { m.Stream = fmt.Sprintf("Successfully built %12.12s\n", imageID) @@ -579,7 +579,8 @@ loop: } } } - break loop + flush() + return case <-r.Context().Done(): cancel() logrus.Infof("Client disconnect reported for build %q / %q.", registry, query.Dockerfile) |