@@ -2,6 +2,7 @@ package term
22
33import (
44 "io"
5+ "time"
56
67 "github.com/acorn-io/acorn/pkg/streams"
78 "golang.org/x/sync/errgroup"
@@ -61,7 +62,22 @@ func copyIO(cIO *ExecIO, streams *streams.Streams) <-chan struct{} {
6162 result := make (chan struct {})
6263
6364 go func () {
64- _ , _ = io .Copy (cIO .Stdin , streams .In )
65+ c , err := io .Copy (cIO .Stdin , streams .In )
66+ if c == 0 && err == nil {
67+ // Very good chance the stdin was closed at start, so just wait
68+ // until stdout/stderr are done
69+ <- result
70+ } else {
71+ // This is an unfortunate hack. It does not seem possible to close the
72+ // stdin side of an exec session to kubernetes over a WebSocket. This
73+ // means that for a command like "echo hi | acorn exec container cat" we
74+ // can not reliably run it. For a command like that you have to finish
75+ // reading stdin, close it, and then fully read the response. If you
76+ // don't close stdin, the "cat" command will not exit. If you do
77+ // don't fully read the response you lose the output. So here we just
78+ // sleep one second hoping that is enough time to read the output
79+ time .Sleep (1 * time .Second )
80+ }
6581 _ = cIO .Stdin .Close ()
6682 }()
6783
@@ -76,7 +92,7 @@ func copyIO(cIO *ExecIO, streams *streams.Streams) <-chan struct{} {
7692 })
7793 go func () {
7894 _ = eg .Wait ()
79- result <- struct {}{}
95+ close ( result )
8096 }()
8197
8298 return result
0 commit comments