mirror of
https://github.com/podman-container-tools/podman.git
synced 2026-10-16 10:57:49 +00:00
This includes: Implement exec -i and fix some typos in description of -i docs pass failed runtime status to caller Add resize handling for a terminal connection Customize exec systemd-cgroup slice fix healthcheck fix top add --detach-keys Implement podman-remote exec (jhonce) * Cleanup some orphaned code (jhonce) adapt remote exec for conmon exec (pehunt) Fix healthcheck and exec to match docs Introduce two new OCIRuntime errors to more comprehensively describe situations in which the runtime can error Use these different errors in branching for exit code in healthcheck and exec Set conmon to use new api version Signed-off-by: Jhon Honce <jhonce@redhat.com> Signed-off-by: Peter Hunt <pehunt@redhat.com>
115 lines
3.2 KiB
Go
115 lines
3.2 KiB
Go
// +build varlink
|
|
|
|
package varlinkapi
|
|
|
|
import (
|
|
"bufio"
|
|
"io"
|
|
|
|
"github.com/containers/libpod/cmd/podman/varlink"
|
|
"github.com/containers/libpod/libpod"
|
|
"github.com/containers/libpod/libpod/define"
|
|
"github.com/containers/libpod/pkg/varlinkapi/virtwriter"
|
|
"github.com/sirupsen/logrus"
|
|
"k8s.io/client-go/tools/remotecommand"
|
|
)
|
|
|
|
func setupStreams(call iopodman.VarlinkCall) (*bufio.Reader, *bufio.Writer, *io.PipeReader, *io.PipeWriter, *libpod.AttachStreams) {
|
|
|
|
// 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,
|
|
}
|
|
return reader, writer, pr, pw, &streams
|
|
}
|
|
|
|
// Attach connects to a containers console
|
|
func (i *LibpodAPI) Attach(call iopodman.VarlinkCall, name string, detachKeys string, start bool) 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())
|
|
}
|
|
state, err := ctr.State()
|
|
if err != nil {
|
|
return call.ReplyErrorOccurred(err.Error())
|
|
}
|
|
if !start && state != define.ContainerStateRunning {
|
|
return call.ReplyErrorOccurred("container must be running to attach")
|
|
}
|
|
|
|
// ACK the client upgrade request
|
|
call.ReplyAttach()
|
|
|
|
reader, writer, _, pw, streams := setupStreams(call)
|
|
|
|
go func() {
|
|
if err := virtwriter.Reader(reader, nil, nil, pw, resize); err != nil {
|
|
errChan <- err
|
|
}
|
|
}()
|
|
|
|
if state == define.ContainerStateRunning {
|
|
finalErr = attach(ctr, streams, detachKeys, resize, errChan)
|
|
} else {
|
|
finalErr = startAndAttach(ctr, streams, detachKeys, resize, errChan)
|
|
}
|
|
|
|
if finalErr != define.ErrDetach && finalErr != nil {
|
|
logrus.Error(finalErr)
|
|
}
|
|
|
|
if err = virtwriter.HangUp(writer); err != nil {
|
|
logrus.Errorf("Failed to HANG-UP attach to %s: %s", ctr.ID(), err.Error())
|
|
}
|
|
return call.Writer.Flush()
|
|
}
|
|
|
|
func attach(ctr *libpod.Container, streams *libpod.AttachStreams, detachKeys string, resize chan remotecommand.TerminalSize, errChan chan error) error {
|
|
go func() {
|
|
if err := ctr.Attach(streams, detachKeys, resize); err != nil {
|
|
errChan <- err
|
|
}
|
|
}()
|
|
attachError := <-errChan
|
|
return attachError
|
|
}
|
|
|
|
func startAndAttach(ctr *libpod.Container, streams *libpod.AttachStreams, detachKeys string, resize chan remotecommand.TerminalSize, errChan chan error) error {
|
|
var finalErr error
|
|
attachChan, err := ctr.StartAndAttach(getContext(), streams, detachKeys, resize, false)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
select {
|
|
case attachChanErr := <-attachChan:
|
|
finalErr = attachChanErr
|
|
case chanError := <-errChan:
|
|
finalErr = chanError
|
|
}
|
|
return finalErr
|
|
}
|