aboutsummaryrefslogtreecommitdiff
path: root/libpod/util.go
diff options
context:
space:
mode:
authorMatthew Heon <mheon@redhat.com>2020-04-07 16:52:47 -0400
committerMatthew Heon <mheon@redhat.com>2020-04-13 14:08:01 -0400
commit71f14bd7920e566e2968bcc85505c7a7980de58b (patch)
tree08dcdfe55f0f84be40accb26196f1978336f1a44 /libpod/util.go
parentc0e29b4a31e330927b7a980209b2aae192f9bafe (diff)
downloadpodman-71f14bd7920e566e2968bcc85505c7a7980de58b.tar.gz
podman-71f14bd7920e566e2968bcc85505c7a7980de58b.tar.bz2
podman-71f14bd7920e566e2968bcc85505c7a7980de58b.zip
Improve APIv2 support for Attach
A few major fixes here: - Support for attaching to Configured containers, to match Docker behavior. - Support for stream parameter has been improved (we now properly handle cases where it is not set). - Initial support for logs parameter has been added. - Setting attach streams when the container has a terminal is now supported. - Errors are properly reported once the hijack has begun. Signed-off-by: Matthew Heon <mheon@redhat.com>
Diffstat (limited to 'libpod/util.go')
-rw-r--r--libpod/util.go31
1 files changed, 27 insertions, 4 deletions
diff --git a/libpod/util.go b/libpod/util.go
index e9d234bbe..6457dac1c 100644
--- a/libpod/util.go
+++ b/libpod/util.go
@@ -2,6 +2,7 @@ package libpod
import (
"bufio"
+ "encoding/binary"
"fmt"
"io"
"os"
@@ -239,11 +240,22 @@ func checkDependencyContainer(depCtr, ctr *Container) error {
// hijackWriteErrorAndClose writes an error to a hijacked HTTP session and
// closes it. Intended to HTTPAttach function.
// If error is nil, it will not be written; we'll only close the connection.
-func hijackWriteErrorAndClose(toWrite error, cid string, httpCon io.Closer, httpBuf *bufio.ReadWriter) {
+func hijackWriteErrorAndClose(toWrite error, cid string, terminal bool, httpCon io.Closer, httpBuf *bufio.ReadWriter) {
if toWrite != nil {
- if _, err := httpBuf.Write([]byte(toWrite.Error())); err != nil {
- logrus.Errorf("Error writing error %q to container %s HTTP attach connection: %v", toWrite, cid, err)
- } else if err := httpBuf.Flush(); err != nil {
+ errString := []byte(fmt.Sprintf("%v\n", toWrite))
+ if !terminal {
+ // We need a header.
+ header := makeHTTPAttachHeader(2, uint32(len(errString)))
+ if _, err := httpBuf.Write(header); err != nil {
+ logrus.Errorf("Error writing header for container %s attach connection error: %v", cid, err)
+ }
+ // TODO: May want to return immediately here to avoid
+ // writing garbage to the socket?
+ }
+ if _, err := httpBuf.Write(errString); err != nil {
+ logrus.Errorf("Error writing error to container %s HTTP attach connection: %v", cid, err)
+ }
+ if err := httpBuf.Flush(); err != nil {
logrus.Errorf("Error flushing HTTP buffer for container %s HTTP attach connection: %v", cid, err)
}
}
@@ -252,3 +264,14 @@ func hijackWriteErrorAndClose(toWrite error, cid string, httpCon io.Closer, http
logrus.Errorf("Error closing container %s HTTP attach connection: %v", cid, err)
}
}
+
+// makeHTTPAttachHeader makes an 8-byte HTTP header for a buffer of the given
+// length and stream. Accepts an integer indicating which stream we are sending
+// to (STDIN = 0, STDOUT = 1, STDERR = 2).
+func makeHTTPAttachHeader(stream byte, length uint32) []byte {
+ headerBuf := []byte{stream, 0, 0, 0}
+ lenBuf := []byte{0, 0, 0, 0}
+ binary.BigEndian.PutUint32(lenBuf, length)
+ headerBuf = append(headerBuf, lenBuf...)
+ return headerBuf
+}