소스 검색

Update docs + fix endian issue

Guillaume J. Charmes 11 년 전
부모
커밋
cb18a6e1b9
6개의 변경된 파일63개의 추가작업 그리고 95개의 파일을 삭제
  1. 2 2
      api_test.go
  2. 0 52
      docs/sources/api/attach_api_1.6.rst
  3. 3 3
      docs/sources/api/docker_remote_api.rst
  4. 44 1
      docs/sources/api/docker_remote_api_v1.6.rst
  5. 7 3
      server.go
  6. 7 34
      utils/stdcopy.go

+ 2 - 2
api_test.go

@@ -951,7 +951,7 @@ func TestPostContainersAttach(t *testing.T) {
 	})
 
 	setTimeout(t, "read/write assertion timed out", 2*time.Second, func() {
-		if err := assertPipe("hello\n", string([]byte{1, 0, 0, 0, 6, 0, 0, 0})+"hello", stdout, stdinPipe, 15); err != nil {
+		if err := assertPipe("hello\n", string([]byte{1, 0, 0, 0, 0, 0, 0, 6})+"hello", stdout, stdinPipe, 15); err != nil {
 			t.Fatal(err)
 		}
 	})
@@ -1040,7 +1040,7 @@ func TestPostContainersAttachStderr(t *testing.T) {
 	})
 
 	setTimeout(t, "read/write assertion timed out", 2*time.Second, func() {
-		if err := assertPipe("hello\n", string([]byte{2, 0, 0, 0, 6, 0, 0, 0})+"hello", stdout, stdinPipe, 15); err != nil {
+		if err := assertPipe("hello\n", string([]byte{2, 0, 0, 0, 0, 0, 0, 6})+"hello", stdout, stdinPipe, 15); err != nil {
 			t.Fatal(err)
 		}
 	})

+ 0 - 52
docs/sources/api/attach_api_1.6.rst

@@ -1,52 +0,0 @@
-:title: Attach stream API
-:description: API Documentation for the Attach command in Docker
-:keywords: API, Docker, Attach, Stream, REST, documentation
-
-=================
-Docker Attach stream API
-=================
-
-.. contents:: Table of Contents
-
-1. Brief introduction
-=====================
-
-- This is the Attach stream API for Docker
-
-2. Format
-=========
-
-The attach format is a Header and a Payload (frame).
-
-2.1 Header
-^^^^^^^^^^
-
-The header will contain the information on which stream write
-the stream (stdout or stderr).
-It also contain the size of the associated frame encoded on the last 4 bytes (uint32).
-
-It is encoded on the first 8 bytes like this:
-header := [8]byte{STREAM_TYPE, 0, 0, 0, SIZE1, SIZE2, SIZE3, SIZE4}
-
-STREAM_TYPE can be:
-- 0: stdin (will be writen on stdout)
-- 1: stdout
-- 2: stderr
-
-SIZE1, SIZE2, SIZE3, SIZE4 are the 4 bytes of the uint32 size.
-
-2.1 Payload (frame)
-^^^^^^^^^^^^^^^^^^^
-
-The payload is the raw stream.
-
-3. Implementation
-=================
-
-The simplest way to implement the Attach protocol is the following:
-
-1) Read 8 bytes
-2) chose stdout or stderr depending on the first byte
-3) Extract the frame size from the last 4 byets
-4) Read the extracted size and output it on the correct output
-5) Goto 1)

+ 3 - 3
docs/sources/api/docker_remote_api.rst

@@ -44,10 +44,10 @@ What's new
 .. http:post:: /containers/(id)/attach
 
    **New!** You can now split stderr from stdout. This is done by prefixing
-   a header to each transmition. See :doc:`attach_api_1.6`.
+   a header to each transmition. See :http:post:`/containers/(id)/attach`.
    The WebSocket attach is unchanged.
-   Note that attach calls on previous API version didn't change. Stdout and
-   stderr are merge.
+   Note that attach calls on the previous API version didn't change. Stdout and
+   stderr are merged.
 
 
 :doc:`docker_remote_api_v1.5`

+ 44 - 1
docs/sources/api/docker_remote_api_v1.6.rst

@@ -468,7 +468,7 @@ Attach to a container
 	   HTTP/1.1 200 OK
 	   Content-Type: application/vnd.docker.raw-stream
 
-	   {{ PREFIXED STREAM }} See :doc:`attach_api_1.6`
+	   {{ STREAM }}
 	   	
 	:query logs: 1/True/true or 0/False/false, return logs. Default false
 	:query stream: 1/True/true or 0/False/false, return stream. Default false
@@ -480,6 +480,49 @@ Attach to a container
 	:statuscode 404: no such container
 	:statuscode 500: server error
 
+	**Stream details**:
+
+	When using the TTY setting is enabled in
+	:http:post:`/containers/create`, the stream is the raw data
+	from the process PTY and client's stdin.  When the TTY is
+	disabled, then the stream is multiplexed to separate stdout
+	and stderr.
+
+	The format is a **Header** and a **Payload** (frame).
+
+	**HEADER**
+
+	The header will contain the information on which stream write
+	the stream (stdout or stderr). It also contain the size of
+	the associated frame encoded on the last 4 bytes (uint32).
+
+	It is encoded on the first 8 bytes like this::
+
+	    header := [8]byte{STREAM_TYPE, 0, 0, 0, SIZE1, SIZE2, SIZE3, SIZE4}
+
+	``STREAM_TYPE`` can be:
+
+	- 0: stdin (will be writen on stdout)
+	- 1: stdout
+	- 2: stderr
+
+	``SIZE1, SIZE2, SIZE3, SIZE4`` are the 4 bytes of the uint32 size encoded as big endian.
+
+	**PAYLOAD**
+
+	The payload is the raw stream.
+
+	**IMPLEMENTATION**
+
+	The simplest way to implement the Attach protocol is the following:
+
+	1) Read 8 bytes
+	2) chose stdout or stderr depending on the first byte
+	3) Extract the frame size from the last 4 byets
+	4) Read the extracted size and output it on the correct output
+	5) Goto 1)
+
+
 
 Wait a container
 ****************

+ 7 - 3
server.go

@@ -1208,16 +1208,20 @@ func (srv *Server) ContainerAttach(name string, logs, stream, stdin, stdout, std
 		} else {
 			dec := json.NewDecoder(cLog)
 			for {
-				var l utils.JSONLog
-				if err := dec.Decode(&l); err == io.EOF {
+				l := &utils.JSONLog{}
+
+				if err := dec.Decode(l); err == io.EOF {
 					break
 				} else if err != nil {
 					utils.Debugf("Error streaming logs: %s", err)
 					break
 				}
-				if (l.Stream == "stdout" && stdout) || (l.Stream == "stderr" && stderr) {
+				if l.Stream == "stdout" && stdout {
 					fmt.Fprintf(outStream, "%s", l.Log)
 				}
+				if l.Stream == "stderr" && stderr {
+					fmt.Fprintf(errStream, "%s", l.Log)
+				}
 			}
 		}
 	}

+ 7 - 34
utils/stdcopy.go

@@ -4,18 +4,8 @@ import (
 	"encoding/binary"
 	"errors"
 	"io"
-	"unsafe"
 )
 
-func CheckBigEndian() bool {
-	var x uint32 = 0x01020304
-
-	if *(*byte)(unsafe.Pointer(&x)) == 0x01 {
-		return true
-	}
-	return false
-}
-
 const (
 	StdWriterPrefixLen = 8
 	StdWriterFdIndex   = 0
@@ -32,16 +22,15 @@ var (
 
 type StdWriter struct {
 	io.Writer
-	prefix    StdType
-	sizeBuf   []byte
-	byteOrder binary.ByteOrder
+	prefix  StdType
+	sizeBuf []byte
 }
 
 func (w *StdWriter) Write(buf []byte) (n int, err error) {
 	if w == nil || w.Writer == nil {
 		return 0, errors.New("Writer not instanciated")
 	}
-	w.byteOrder.PutUint32(w.prefix[4:], uint32(len(buf)))
+	binary.BigEndian.PutUint32(w.prefix[4:], uint32(len(buf)))
 	buf = append(w.prefix[:], buf...)
 
 	n, err = w.Writer.Write(buf)
@@ -55,18 +44,10 @@ func NewStdWriter(w io.Writer, t StdType) *StdWriter {
 		return nil
 	}
 
-	var bo binary.ByteOrder
-
-	if CheckBigEndian() {
-		bo = binary.BigEndian
-	} else {
-		bo = binary.LittleEndian
-	}
 	return &StdWriter{
-		Writer:    w,
-		prefix:    t,
-		sizeBuf:   make([]byte, 4),
-		byteOrder: bo,
+		Writer:  w,
+		prefix:  t,
+		sizeBuf: make([]byte, 4),
 	}
 }
 
@@ -91,17 +72,9 @@ func StdCopy(dstout, dsterr io.Writer, src io.Reader) (written int64, err error)
 		nr, nw    int
 		er, ew    error
 		out       io.Writer
-		byteOrder binary.ByteOrder
 		frameSize int
 	)
 
-	// Check the machine's endianness
-	if CheckBigEndian() {
-		byteOrder = binary.BigEndian
-	} else {
-		byteOrder = binary.LittleEndian
-	}
-
 	for {
 		// Make sure we have at least a full header
 		for nr < StdWriterPrefixLen {
@@ -132,7 +105,7 @@ func StdCopy(dstout, dsterr io.Writer, src io.Reader) (written int64, err error)
 		}
 
 		// Retrieve the size of the frame
-		frameSize = int(byteOrder.Uint32(buf[StdWriterSizeIndex : StdWriterSizeIndex+4]))
+		frameSize = int(binary.BigEndian.Uint32(buf[StdWriterSizeIndex : StdWriterSizeIndex+4]))
 
 		// Check if the buffer is big enough to read the frame.
 		// Extend it if necessary.