зеркало из https://github.com/microsoft/docker.git
Remove `IsPaused` from backend interface.
Move connection hijacking logic to the daemon. Signed-off-by: David Calavera <david.calavera@gmail.com>
This commit is contained in:
Родитель
52fd30079a
Коммит
af94f941df
|
@ -44,7 +44,6 @@ type stateBackend interface {
|
|||
ContainerUnpause(name string) error
|
||||
ContainerWait(name string, timeout time.Duration) (int, error)
|
||||
Exists(id string) bool
|
||||
IsPaused(id string) bool
|
||||
}
|
||||
|
||||
// monitorBackend includes functions to implement to provide containers monitoring functionality.
|
||||
|
|
|
@ -400,29 +400,11 @@ func (s *containerRouter) postContainersAttach(ctx context.Context, w http.Respo
|
|||
}
|
||||
containerName := vars["name"]
|
||||
|
||||
if !s.backend.Exists(containerName) {
|
||||
return derr.ErrorCodeNoSuchContainer.WithArgs(containerName)
|
||||
}
|
||||
|
||||
if s.backend.IsPaused(containerName) {
|
||||
return derr.ErrorCodePausedContainer.WithArgs(containerName)
|
||||
}
|
||||
|
||||
inStream, outStream, err := httputils.HijackConnection(w)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer httputils.CloseStreams(inStream, outStream)
|
||||
|
||||
if _, ok := r.Header["Upgrade"]; ok {
|
||||
fmt.Fprintf(outStream, "HTTP/1.1 101 UPGRADED\r\nContent-Type: application/vnd.docker.raw-stream\r\nConnection: Upgrade\r\nUpgrade: tcp\r\n\r\n")
|
||||
} else {
|
||||
fmt.Fprintf(outStream, "HTTP/1.1 200 OK\r\nContent-Type: application/vnd.docker.raw-stream\r\n\r\n")
|
||||
}
|
||||
_, upgrade := r.Header["Upgrade"]
|
||||
|
||||
attachWithLogsConfig := &daemon.ContainerAttachWithLogsConfig{
|
||||
InStream: inStream,
|
||||
OutStream: outStream,
|
||||
Hijacker: w.(http.Hijacker),
|
||||
Upgrade: upgrade,
|
||||
UseStdin: httputils.BoolValue(r, "stdin"),
|
||||
UseStdout: httputils.BoolValue(r, "stdout"),
|
||||
UseStderr: httputils.BoolValue(r, "stderr"),
|
||||
|
@ -430,11 +412,7 @@ func (s *containerRouter) postContainersAttach(ctx context.Context, w http.Respo
|
|||
Stream: httputils.BoolValue(r, "stream"),
|
||||
}
|
||||
|
||||
if err := s.backend.ContainerAttachWithLogs(containerName, attachWithLogsConfig); err != nil {
|
||||
fmt.Fprintf(outStream, "Error attaching: %s\n", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
return s.backend.ContainerAttachWithLogs(containerName, attachWithLogsConfig)
|
||||
}
|
||||
|
||||
func (s *containerRouter) wsContainersAttach(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
|
||||
|
|
|
@ -1,53 +1,84 @@
|
|||
package daemon
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
"time"
|
||||
|
||||
"github.com/Sirupsen/logrus"
|
||||
"github.com/docker/docker/container"
|
||||
"github.com/docker/docker/daemon/logger"
|
||||
derr "github.com/docker/docker/errors"
|
||||
"github.com/docker/docker/pkg/stdcopy"
|
||||
)
|
||||
|
||||
// ContainerAttachWithLogsConfig holds the streams to use when connecting to a container to view logs.
|
||||
type ContainerAttachWithLogsConfig struct {
|
||||
InStream io.ReadCloser
|
||||
OutStream io.Writer
|
||||
UseStdin, UseStdout, UseStderr bool
|
||||
Logs, Stream bool
|
||||
Hijacker http.Hijacker
|
||||
Upgrade bool
|
||||
UseStdin bool
|
||||
UseStdout bool
|
||||
UseStderr bool
|
||||
Logs bool
|
||||
Stream bool
|
||||
}
|
||||
|
||||
// ContainerAttachWithLogs attaches to logs according to the config passed in. See ContainerAttachWithLogsConfig.
|
||||
func (daemon *Daemon) ContainerAttachWithLogs(prefixOrName string, c *ContainerAttachWithLogsConfig) error {
|
||||
if c.Hijacker == nil {
|
||||
return derr.ErrorCodeNoHijackConnection.WithArgs(prefixOrName)
|
||||
}
|
||||
container, err := daemon.GetContainer(prefixOrName)
|
||||
if err != nil {
|
||||
return derr.ErrorCodeNoSuchContainer.WithArgs(prefixOrName)
|
||||
}
|
||||
if container.IsPaused() {
|
||||
return derr.ErrorCodePausedContainer.WithArgs(prefixOrName)
|
||||
}
|
||||
|
||||
conn, _, err := c.Hijacker.Hijack()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer conn.Close()
|
||||
// Flush the options to make sure the client sets the raw mode
|
||||
conn.Write([]byte{})
|
||||
inStream := conn.(io.ReadCloser)
|
||||
outStream := conn.(io.Writer)
|
||||
|
||||
if c.Upgrade {
|
||||
fmt.Fprintf(outStream, "HTTP/1.1 101 UPGRADED\r\nContent-Type: application/vnd.docker.raw-stream\r\nConnection: Upgrade\r\nUpgrade: tcp\r\n\r\n")
|
||||
} else {
|
||||
fmt.Fprintf(outStream, "HTTP/1.1 200 OK\r\nContent-Type: application/vnd.docker.raw-stream\r\n\r\n")
|
||||
}
|
||||
|
||||
var errStream io.Writer
|
||||
|
||||
if !container.Config.Tty {
|
||||
errStream = stdcopy.NewStdWriter(c.OutStream, stdcopy.Stderr)
|
||||
c.OutStream = stdcopy.NewStdWriter(c.OutStream, stdcopy.Stdout)
|
||||
errStream = stdcopy.NewStdWriter(outStream, stdcopy.Stderr)
|
||||
outStream = stdcopy.NewStdWriter(outStream, stdcopy.Stdout)
|
||||
} else {
|
||||
errStream = c.OutStream
|
||||
errStream = outStream
|
||||
}
|
||||
|
||||
var stdin io.ReadCloser
|
||||
var stdout, stderr io.Writer
|
||||
|
||||
if c.UseStdin {
|
||||
stdin = c.InStream
|
||||
stdin = inStream
|
||||
}
|
||||
if c.UseStdout {
|
||||
stdout = c.OutStream
|
||||
stdout = outStream
|
||||
}
|
||||
if c.UseStderr {
|
||||
stderr = errStream
|
||||
}
|
||||
|
||||
return daemon.attachWithLogs(container, stdin, stdout, stderr, c.Logs, c.Stream)
|
||||
if err := daemon.attachWithLogs(container, stdin, stdout, stderr, c.Logs, c.Stream); err != nil {
|
||||
fmt.Fprintf(outStream, "Error attaching: %s\n", err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// ContainerWsAttachWithLogsConfig attach with websockets, since all
|
||||
|
|
|
@ -33,4 +33,13 @@ var (
|
|||
Description: "Docker's networking stack is disabled for this platform",
|
||||
HTTPStatusCode: http.StatusNotFound,
|
||||
})
|
||||
|
||||
// ErrorCodeNoHijackConnection is generated when a request tries to attach to a container
|
||||
// but the connection to hijack is not provided.
|
||||
ErrorCodeNoHijackConnection = errcode.Register(errGroup, errcode.ErrorDescriptor{
|
||||
Value: "HIJACK_CONNECTION_MISSING",
|
||||
Message: "error attaching to container %s, hijack connection missing",
|
||||
Description: "The caller didn't provide a connection to hijack",
|
||||
HTTPStatusCode: http.StatusBadRequest,
|
||||
})
|
||||
)
|
||||
|
|
Загрузка…
Ссылка в новой задаче