driver/docker: collect tty container logs

Fixes https://github.com/hashicorp/nomad/issues/5475

When container is a tty container, we need to get raw terminal output
without any additional processing.
This commit is contained in:
Mahmood Ali
2019-04-24 22:00:00 -04:00
parent 8d48b77bca
commit ce8a8a5326
7 changed files with 126 additions and 28 deletions

View File

@@ -18,6 +18,7 @@ func (c *dockerLoggerClient) Start(opts *StartOpts) error {
ContainerId: opts.ContainerID,
StdoutFifo: opts.Stdout,
StderrFifo: opts.Stderr,
Tty: opts.TTY,
TlsCert: opts.TLSCert,
TlsKey: opts.TLSKey,

View File

@@ -29,6 +29,7 @@ type StartOpts struct {
// ContainerID of the container to monitor logs for
ContainerID string
TTY bool
// Stdout path to fifo
Stdout string
@@ -97,6 +98,7 @@ func (d *dockerLogger) Start(opts *StartOpts) error {
Follow: true,
Stdout: true,
Stderr: true,
RawTerminal: opts.TTY,
}
err := client.Logs(logOpts)

View File

@@ -107,6 +107,89 @@ func TestDockerLogger_Success(t *testing.T) {
})
}
func TestDockerLogger_Success_TTY(t *testing.T) {
ctu.DockerCompatible(t)
t.Parallel()
require := require.New(t)
containerImage, containerImageName, containerImageTag := testContainerDetails()
client, err := docker.NewClientFromEnv()
if err != nil {
t.Skip("docker unavailable:", err)
}
if img, err := client.InspectImage(containerImage); err != nil || img == nil {
t.Log("image not found locally, downloading...")
err = client.PullImage(docker.PullImageOptions{
Repository: containerImageName,
Tag: containerImageTag,
}, docker.AuthConfiguration{})
require.NoError(err, "failed to pull image")
}
containerConf := docker.CreateContainerOptions{
Config: &docker.Config{
Cmd: []string{
"sh", "-c", "touch ~/docklog; tail -f ~/docklog",
},
Image: containerImage,
Tty: true,
},
Context: context.Background(),
}
container, err := client.CreateContainer(containerConf)
require.NoError(err)
defer client.RemoveContainer(docker.RemoveContainerOptions{
ID: container.ID,
Force: true,
})
err = client.StartContainer(container.ID, nil)
require.NoError(err)
testutil.WaitForResult(func() (bool, error) {
container, err = client.InspectContainer(container.ID)
if err != nil {
return false, err
}
if !container.State.Running {
return false, fmt.Errorf("container not running")
}
return true, nil
}, func(err error) {
require.NoError(err)
})
stdout := &noopCloser{bytes.NewBuffer(nil)}
stderr := &noopCloser{bytes.NewBuffer(nil)}
dl := NewDockerLogger(testlog.HCLogger(t)).(*dockerLogger)
dl.stdout = stdout
dl.stderr = stderr
require.NoError(dl.Start(&StartOpts{
ContainerID: container.ID,
TTY: true,
}))
echoToContainer(t, client, container.ID, "abc")
echoToContainer(t, client, container.ID, "123")
testutil.WaitForResult(func() (bool, error) {
act := stdout.String()
if "abc\r\n123\r\n" != act {
return false, fmt.Errorf("expected abc\\n123\\n for stdout but got %s", act)
}
return true, nil
}, func(err error) {
require.NoError(err)
})
}
func echoToContainer(t *testing.T, client *docker.Client, id string, line string) {
op := docker.CreateExecOptions{
Container: id,

View File

@@ -31,6 +31,7 @@ type StartRequest struct {
TlsCert string `protobuf:"bytes,5,opt,name=tls_cert,json=tlsCert,proto3" json:"tls_cert,omitempty"`
TlsKey string `protobuf:"bytes,6,opt,name=tls_key,json=tlsKey,proto3" json:"tls_key,omitempty"`
TlsCa string `protobuf:"bytes,7,opt,name=tls_ca,json=tlsCa,proto3" json:"tls_ca,omitempty"`
Tty bool `protobuf:"varint,8,opt,name=tty,proto3" json:"tty,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
@@ -40,7 +41,7 @@ func (m *StartRequest) Reset() { *m = StartRequest{} }
func (m *StartRequest) String() string { return proto.CompactTextString(m) }
func (*StartRequest) ProtoMessage() {}
func (*StartRequest) Descriptor() ([]byte, []int) {
return fileDescriptor_docker_logger_550e35425edc00c0, []int{0}
return fileDescriptor_docker_logger_5376107e0c9324a2, []int{0}
}
func (m *StartRequest) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_StartRequest.Unmarshal(m, b)
@@ -109,6 +110,13 @@ func (m *StartRequest) GetTlsCa() string {
return ""
}
func (m *StartRequest) GetTty() bool {
if m != nil {
return m.Tty
}
return false
}
type StartResponse struct {
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
@@ -119,7 +127,7 @@ func (m *StartResponse) Reset() { *m = StartResponse{} }
func (m *StartResponse) String() string { return proto.CompactTextString(m) }
func (*StartResponse) ProtoMessage() {}
func (*StartResponse) Descriptor() ([]byte, []int) {
return fileDescriptor_docker_logger_550e35425edc00c0, []int{1}
return fileDescriptor_docker_logger_5376107e0c9324a2, []int{1}
}
func (m *StartResponse) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_StartResponse.Unmarshal(m, b)
@@ -149,7 +157,7 @@ func (m *StopRequest) Reset() { *m = StopRequest{} }
func (m *StopRequest) String() string { return proto.CompactTextString(m) }
func (*StopRequest) ProtoMessage() {}
func (*StopRequest) Descriptor() ([]byte, []int) {
return fileDescriptor_docker_logger_550e35425edc00c0, []int{2}
return fileDescriptor_docker_logger_5376107e0c9324a2, []int{2}
}
func (m *StopRequest) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_StopRequest.Unmarshal(m, b)
@@ -179,7 +187,7 @@ func (m *StopResponse) Reset() { *m = StopResponse{} }
func (m *StopResponse) String() string { return proto.CompactTextString(m) }
func (*StopResponse) ProtoMessage() {}
func (*StopResponse) Descriptor() ([]byte, []int) {
return fileDescriptor_docker_logger_550e35425edc00c0, []int{3}
return fileDescriptor_docker_logger_5376107e0c9324a2, []int{3}
}
func (m *StopResponse) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_StopResponse.Unmarshal(m, b)
@@ -312,30 +320,31 @@ var _DockerLogger_serviceDesc = grpc.ServiceDesc{
}
func init() {
proto.RegisterFile("drivers/docker/docklog/proto/docker_logger.proto", fileDescriptor_docker_logger_550e35425edc00c0)
proto.RegisterFile("drivers/docker/docklog/proto/docker_logger.proto", fileDescriptor_docker_logger_5376107e0c9324a2)
}
var fileDescriptor_docker_logger_550e35425edc00c0 = []byte{
// 328 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x9c, 0x50, 0xb1, 0x4e, 0xeb, 0x40,
0x10, 0x7c, 0xce, 0x8b, 0x9d, 0x70, 0x49, 0x40, 0x3a, 0x09, 0x61, 0xd2, 0x00, 0xae, 0x28, 0x90,
0x83, 0xa0, 0x22, 0x74, 0x80, 0x90, 0x10, 0x54, 0x49, 0x47, 0x63, 0x19, 0x7b, 0x93, 0x58, 0x31,
0x5e, 0xb3, 0xb7, 0x41, 0x4a, 0x85, 0xc4, 0x37, 0xf0, 0x75, 0x7c, 0x0d, 0xf2, 0xfa, 0xb0, 0x68,
0x93, 0xea, 0x6e, 0x67, 0x67, 0x46, 0x3b, 0xa3, 0xce, 0x53, 0xca, 0xde, 0x81, 0xcc, 0x28, 0xc5,
0x64, 0x09, 0x24, 0x4f, 0x8e, 0xf3, 0x51, 0x49, 0xc8, 0x68, 0xc1, 0x28, 0xc7, 0xf9, 0x1c, 0x28,
0x14, 0x4c, 0x9f, 0x2d, 0x62, 0xb3, 0xc8, 0x12, 0xa4, 0x32, 0x2c, 0xf0, 0x35, 0x4e, 0x43, 0xeb,
0x10, 0xd6, 0xe4, 0xd0, 0x3a, 0xd4, 0xec, 0xe0, 0xdb, 0x51, 0xfd, 0x29, 0xc7, 0xc4, 0x13, 0x78,
0x5b, 0x81, 0x61, 0x3d, 0x54, 0x5d, 0x28, 0xd2, 0x12, 0xb3, 0x82, 0x7d, 0xe7, 0xd8, 0x39, 0xdd,
0x99, 0x34, 0xb3, 0x3e, 0x51, 0xfd, 0x04, 0x0b, 0x8e, 0xb3, 0x02, 0x28, 0xca, 0x52, 0xbf, 0x25,
0xfb, 0x5e, 0x83, 0x3d, 0xa4, 0xfa, 0x48, 0xf5, 0x0c, 0xa7, 0xb8, 0xe2, 0x68, 0x96, 0xcd, 0xd0,
0xff, 0x2f, 0x0c, 0x55, 0x43, 0xf7, 0xd9, 0x0c, 0x2d, 0x01, 0x88, 0x6a, 0x42, 0xbb, 0x21, 0x00,
0x91, 0x10, 0x0e, 0x55, 0x97, 0x73, 0x13, 0x25, 0x40, 0xec, 0xbb, 0xb2, 0xed, 0x70, 0x6e, 0x6e,
0x81, 0x58, 0x1f, 0xa8, 0xea, 0x1b, 0x2d, 0x61, 0xed, 0x7b, 0xb2, 0xf1, 0x38, 0x37, 0x8f, 0xb0,
0xd6, 0xfb, 0xca, 0x13, 0x4d, 0xec, 0x77, 0x04, 0x77, 0x2b, 0x45, 0x1c, 0xec, 0xa9, 0x81, 0xcd,
0x66, 0x4a, 0x2c, 0x0c, 0x04, 0x03, 0xd5, 0x9b, 0x32, 0x96, 0x36, 0x6b, 0xb0, 0x5b, 0x65, 0xaf,
0xc6, 0x7a, 0x7d, 0xf1, 0xd5, 0x52, 0xfd, 0x3b, 0x69, 0xe9, 0x49, 0x1a, 0xd5, 0x9f, 0x8e, 0x72,
0xc5, 0x41, 0x8f, 0xc3, 0x4d, 0x6a, 0x0d, 0xff, 0x56, 0x3a, 0xbc, 0xde, 0x4a, 0x6b, 0x4f, 0xfe,
0xa7, 0x3f, 0x54, 0xbb, 0xba, 0x52, 0x5f, 0x6d, 0x6a, 0xd3, 0x04, 0x1d, 0x8e, 0xb7, 0x91, 0xfe,
0x1e, 0x70, 0xd3, 0x79, 0x76, 0x05, 0x7f, 0xf1, 0xe4, 0xb9, 0xfc, 0x09, 0x00, 0x00, 0xff, 0xff,
0x43, 0xfe, 0x38, 0xd2, 0x95, 0x02, 0x00, 0x00,
var fileDescriptor_docker_logger_5376107e0c9324a2 = []byte{
// 341 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x9c, 0x50, 0x4f, 0x4f, 0xe2, 0x50,
0x10, 0xdf, 0x02, 0x2d, 0xdd, 0x01, 0x76, 0x37, 0x2f, 0xd9, 0x58, 0xb9, 0x88, 0x3d, 0x71, 0x30,
0xc5, 0xe8, 0x49, 0xbc, 0xa9, 0x31, 0x31, 0x7a, 0x82, 0x9b, 0x97, 0xa6, 0xb6, 0x0f, 0x68, 0xa8,
0x9d, 0x3a, 0x6f, 0x30, 0xe1, 0x64, 0xe2, 0x67, 0xf0, 0x63, 0xfa, 0x21, 0x4c, 0xa7, 0xb5, 0xf1,
0x0a, 0xa7, 0xf7, 0xe6, 0xf7, 0x2f, 0x33, 0x3f, 0x38, 0x4d, 0x28, 0x7d, 0xd5, 0x64, 0x26, 0x09,
0xc6, 0x6b, 0x4d, 0xf2, 0x64, 0xb8, 0x9c, 0x14, 0x84, 0x8c, 0x35, 0x18, 0x66, 0xb8, 0x5c, 0x6a,
0x0a, 0x04, 0x53, 0x27, 0xab, 0xc8, 0xac, 0xd2, 0x18, 0xa9, 0x08, 0x72, 0x7c, 0x8e, 0x92, 0xa0,
0x4e, 0x08, 0x2a, 0x71, 0x50, 0x27, 0x54, 0x6a, 0xff, 0xd3, 0x82, 0xfe, 0x9c, 0x23, 0xe2, 0x99,
0x7e, 0xd9, 0x68, 0xc3, 0x6a, 0x08, 0xae, 0xce, 0x93, 0x02, 0xd3, 0x9c, 0x3d, 0x6b, 0x64, 0x8d,
0x7f, 0xcf, 0x9a, 0x59, 0x1d, 0x43, 0x3f, 0xc6, 0x9c, 0xa3, 0x34, 0xd7, 0x14, 0xa6, 0x89, 0xd7,
0x12, 0xbe, 0xd7, 0x60, 0x77, 0x89, 0x3a, 0x82, 0x9e, 0xe1, 0x04, 0x37, 0x1c, 0x2e, 0xd2, 0x05,
0x7a, 0x6d, 0x51, 0x40, 0x05, 0xdd, 0xa6, 0x0b, 0xac, 0x05, 0x9a, 0xa8, 0x12, 0x74, 0x1a, 0x81,
0x26, 0x12, 0xc1, 0x21, 0xb8, 0x9c, 0x99, 0x30, 0xd6, 0xc4, 0x9e, 0x2d, 0x6c, 0x97, 0x33, 0x73,
0xad, 0x89, 0xd5, 0x01, 0x94, 0xdf, 0x70, 0xad, 0xb7, 0x9e, 0x23, 0x8c, 0xc3, 0x99, 0xb9, 0xd7,
0x5b, 0xf5, 0x1f, 0x1c, 0xf1, 0x44, 0x5e, 0x57, 0x70, 0xbb, 0x74, 0x44, 0xea, 0x1f, 0xb4, 0x99,
0xb7, 0x9e, 0x3b, 0xb2, 0xc6, 0xee, 0xac, 0xfc, 0xfa, 0x7f, 0x61, 0x50, 0x5f, 0x6b, 0x0a, 0xcc,
0x8d, 0xf6, 0x07, 0xd0, 0x9b, 0x33, 0x16, 0xf5, 0xf5, 0xfe, 0x9f, 0xb2, 0x8d, 0x72, 0xac, 0xe8,
0xb3, 0x8f, 0x16, 0xf4, 0x6f, 0xa4, 0xb7, 0x07, 0xe9, 0x58, 0xbd, 0x5b, 0x60, 0x4b, 0x82, 0x9a,
0x06, 0xbb, 0x14, 0x1d, 0xfc, 0x2c, 0x79, 0x78, 0xb9, 0x97, 0xb7, 0x5e, 0xf9, 0x97, 0x7a, 0x83,
0x4e, 0xb9, 0xa5, 0xba, 0xd8, 0x35, 0xa6, 0x39, 0x74, 0x38, 0xdd, 0xc7, 0xfa, 0xbd, 0xc0, 0x55,
0xf7, 0xd1, 0x16, 0xfc, 0xc9, 0x91, 0xe7, 0xfc, 0x2b, 0x00, 0x00, 0xff, 0xff, 0xe9, 0x09, 0x25,
0x99, 0xa7, 0x02, 0x00, 0x00,
}

View File

@@ -15,6 +15,7 @@ message StartRequest {
string tls_cert = 5;
string tls_key = 6;
string tls_ca = 7;
bool tty = 8;
}
message StartResponse {

View File

@@ -20,6 +20,7 @@ func (s *dockerLoggerServer) Start(ctx context.Context, req *proto.StartRequest)
ContainerID: req.ContainerId,
Stdout: req.StdoutFifo,
Stderr: req.StderrFifo,
TTY: req.Tty,
TLSCert: req.TlsCert,
TLSKey: req.TlsKey,

View File

@@ -144,6 +144,7 @@ func (d *Driver) setupNewDockerLogger(container *docker.Container, cfg *drivers.
if err := dlogger.Start(&docklog.StartOpts{
Endpoint: d.config.Endpoint,
ContainerID: container.ID,
TTY: container.Config.Tty,
Stdout: cfg.StdoutPath,
Stderr: cfg.StderrPath,
TLSCert: d.config.TLS.Cert,