diff options
author | Peter Hunt <pehunt@redhat.com> | 2019-07-01 13:55:03 -0400 |
---|---|---|
committer | Peter Hunt <pehunt@redhat.com> | 2019-07-22 15:57:23 -0400 |
commit | a1a79c08b72793cf2f75490d8ffc844c3d16bd4a (patch) | |
tree | 0ba4dd73229399a4c57e9d073327886fa3640707 /pkg/varlinkapi/containers.go | |
parent | cf9efa90e5dcf89e10408eae5229c4ce904d9fc7 (diff) | |
download | podman-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.go | 82 |
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() +} |