spiegel_podman/pkg/varlinkapi/attach.go
baude fbcda7772d Add the ability to attach remotely to a container
Also, you can now podman-remote run -it.  There are some bugs that need
to be ironed out but I would prefer to merge this so we can make both
progress on start and exec as well as the bugs.

* when doing podman-remote run -it foo /bin/bash, you have to press
enter to get the prompt to display. with the localized podman, we had to
teach it connect to the console first and then start the container so we
did not miss anything.

* when executing "exit" in the console, we get a hard lockup likely
because nobody knows what to do.

* custom detach keys are not supported

* podman-remote run -it alpine ls does not currently work.  only
dropping to a shell works.

Signed-off-by: baude <bbaude@redhat.com>
2019-04-10 08:59:28 -05:00

75 lines
1.8 KiB
Go

// +build varlink
package varlinkapi
import (
"io"
"github.com/containers/libpod/cmd/podman/varlink"
"github.com/containers/libpod/libpod"
"github.com/containers/libpod/pkg/varlinkapi/virtwriter"
"k8s.io/client-go/tools/remotecommand"
)
// Close is method to close the writer
// Attach ...
func (i *LibpodAPI) Attach(call iopodman.VarlinkCall, name string) error {
var finalErr error
resize := make(chan remotecommand.TerminalSize)
errChan := make(chan error)
if !call.WantsUpgrade() {
return call.ReplyErrorOccurred("client must use upgraded connection to attach")
}
ctr, err := i.Runtime.LookupContainer(name)
if err != nil {
return call.ReplyErrorOccurred(err.Error())
}
// These are the varlink sockets
reader := call.Call.Reader
writer := call.Call.Writer
// This pipe is used to pass stdin from the client to the input stream
// once the msg has been "decoded"
pr, pw := io.Pipe()
stdoutWriter := virtwriter.NewVirtWriteCloser(writer, virtwriter.ToStdout)
// TODO if runc ever starts passing stderr, we can too
//stderrWriter := NewVirtWriteCloser(writer, ToStderr)
streams := libpod.AttachStreams{
OutputStream: stdoutWriter,
InputStream: pr,
// Runc eats the error stream
ErrorStream: stdoutWriter,
AttachInput: true,
AttachOutput: true,
// Runc eats the error stream
AttachError: true,
}
go func() {
if err := virtwriter.Reader(reader, nil, nil, pw, resize); err != nil {
errChan <- err
}
}()
go func() {
// TODO allow for customizable detach keys
if err := ctr.Attach(&streams, "", resize); err != nil {
errChan <- err
}
}()
select {
// Blocking on an error
case finalErr = <-errChan:
// Need to close up shop
_ = finalErr
}
quitWriter := virtwriter.NewVirtWriteCloser(writer, virtwriter.Quit)
_, err = quitWriter.Write([]byte("HANG-UP"))
return call.Writer.Flush()
}