summaryrefslogtreecommitdiff
path: root/pkg/varlinkapi/containers.go
diff options
context:
space:
mode:
authorPeter Hunt <pehunt@redhat.com>2019-07-01 13:55:03 -0400
committerPeter Hunt <pehunt@redhat.com>2019-07-22 15:57:23 -0400
commita1a79c08b72793cf2f75490d8ffc844c3d16bd4a (patch)
tree0ba4dd73229399a4c57e9d073327886fa3640707 /pkg/varlinkapi/containers.go
parentcf9efa90e5dcf89e10408eae5229c4ce904d9fc7 (diff)
downloadpodman-a1a79c08b72793cf2f75490d8ffc844c3d16bd4a.tar.gz
podman-a1a79c08b72793cf2f75490d8ffc844c3d16bd4a.tar.bz2
podman-a1a79c08b72793cf2f75490d8ffc844c3d16bd4a.zip
Implement conmon exec
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>
Diffstat (limited to 'pkg/varlinkapi/containers.go')
-rw-r--r--pkg/varlinkapi/containers.go82
1 files changed, 82 insertions, 0 deletions
diff --git a/pkg/varlinkapi/containers.go b/pkg/varlinkapi/containers.go
index 6f6909fac..19a8bfd2e 100644
--- a/pkg/varlinkapi/containers.go
+++ b/pkg/varlinkapi/containers.go
@@ -19,8 +19,11 @@ import (
"github.com/containers/libpod/libpod/define"
"github.com/containers/libpod/libpod/logs"
"github.com/containers/libpod/pkg/adapter/shortcuts"
+ "github.com/containers/libpod/pkg/varlinkapi/virtwriter"
"github.com/containers/storage/pkg/archive"
"github.com/pkg/errors"
+ "github.com/sirupsen/logrus"
+ "k8s.io/client-go/tools/remotecommand"
)
// ListContainers ...
@@ -756,3 +759,82 @@ func (i *LibpodAPI) Top(call iopodman.VarlinkCall, nameOrID string, descriptors
}
return call.ReplyTop(topInfo)
}
+
+// ExecContainer is the varlink endpoint to execute a command in a container
+func (i *LibpodAPI) ExecContainer(call iopodman.VarlinkCall, opts iopodman.ExecOpts) error {
+ if !call.WantsUpgrade() {
+ return call.ReplyErrorOccurred("client must use upgraded connection to exec")
+ }
+
+ ctr, err := i.Runtime.LookupContainer(opts.Name)
+ if err != nil {
+ return call.ReplyContainerNotFound(opts.Name, err.Error())
+ }
+
+ state, err := ctr.State()
+ if err != nil {
+ return call.ReplyErrorOccurred(
+ fmt.Sprintf("exec failed to obtain container %s state: %s", ctr.ID(), err.Error()))
+ }
+
+ if state != define.ContainerStateRunning {
+ return call.ReplyErrorOccurred(
+ fmt.Sprintf("exec requires a running container, %s is %s", ctr.ID(), state.String()))
+ }
+
+ envs := []string{}
+ if opts.Env != nil {
+ envs = *opts.Env
+ }
+
+ var user string
+ if opts.User != nil {
+ user = *opts.User
+ }
+
+ var workDir string
+ if opts.Workdir != nil {
+ workDir = *opts.Workdir
+ }
+
+ resizeChan := make(chan remotecommand.TerminalSize)
+ errChan := make(chan error)
+
+ reader, writer, _, pipeWriter, streams := setupStreams(call)
+
+ go func() {
+ fmt.Printf("ExecContainer Start Reader\n")
+ if err := virtwriter.Reader(reader, nil, nil, pipeWriter, resizeChan); err != nil {
+ fmt.Printf("ExecContainer Reader err %s, %s\n", err.Error(), errors.Cause(err).Error())
+ errChan <- err
+ }
+ }()
+
+ // Debugging...
+ time.Sleep(5 * time.Second)
+
+ go func() {
+ fmt.Printf("ExecContainer Start ctr.Exec\n")
+ // TODO detach keys and resize
+ // TODO add handling for exit code
+ // TODO capture exit code and return to main thread
+ _, err := ctr.Exec(opts.Tty, opts.Privileged, envs, opts.Cmd, user, workDir, streams, 0, nil, "")
+ if err != nil {
+ fmt.Printf("ExecContainer Exec err %s, %s\n", err.Error(), errors.Cause(err).Error())
+ errChan <- errors.Wrapf(err, "ExecContainer failed for container %s", ctr.ID())
+ }
+ }()
+
+ execErr := <-errChan
+
+ if execErr != nil && errors.Cause(execErr) != io.EOF {
+ fmt.Printf("ExecContainer err: %s\n", execErr.Error())
+ return call.ReplyErrorOccurred(execErr.Error())
+ }
+
+ if err = virtwriter.HangUp(writer); err != nil {
+ fmt.Printf("ExecContainer hangup err: %s\n", err.Error())
+ logrus.Errorf("ExecContainer failed to HANG-UP on %s: %s", ctr.ID(), err.Error())
+ }
+ return call.Writer.Flush()
+}