From 2a474c88c9ffc7221b09513ad4db8720ca7661cb Mon Sep 17 00:00:00 2001 From: Peter Hunt Date: Tue, 25 Jun 2019 13:50:30 -0400 Subject: Finish up remote exec implementation Signed-off-by: Peter Hunt --- test/e2e/exec_test.go | 2 -- 1 file changed, 2 deletions(-) (limited to 'test/e2e/exec_test.go') diff --git a/test/e2e/exec_test.go b/test/e2e/exec_test.go index 76515cf3e..316575b0f 100644 --- a/test/e2e/exec_test.go +++ b/test/e2e/exec_test.go @@ -1,5 +1,3 @@ -// +build !remoteclient - package integration import ( -- cgit v1.2.3-54-g00ecf From 35ba77e0409036c455f85d9f8fcbe361f0693335 Mon Sep 17 00:00:00 2001 From: Peter Hunt Date: Fri, 19 Jul 2019 16:19:17 -0400 Subject: Update e2e tests for remote exec including changing -l to the container id and separating a case of setting the env that remote can't handle Signed-off-by: Peter Hunt --- pkg/adapter/containers_remote.go | 9 +++---- pkg/varlinkapi/containers.go | 43 +++++++++++++++------------------ pkg/varlinkapi/virtwriter/virtwriter.go | 11 ++++----- test/e2e/exec_test.go | 28 +++++++++++++++------ 4 files changed, 48 insertions(+), 43 deletions(-) (limited to 'test/e2e/exec_test.go') diff --git a/pkg/adapter/containers_remote.go b/pkg/adapter/containers_remote.go index 665821bb6..7a9cf94b7 100644 --- a/pkg/adapter/containers_remote.go +++ b/pkg/adapter/containers_remote.go @@ -1054,15 +1054,14 @@ func (r *LocalRuntime) ExecContainer(ctx context.Context, cli *cliconfig.ExecVal if err != nil { return ec, errors.Wrapf(err, "Exec operation failed for %s", cli.InputArgs) } - ecChan := make(chan int, 1) errChan := configureVarlinkAttachStdio(r.Conn.Reader, r.Conn.Writer, inputStream, os.Stdout, oldTermState, resize, ecChan) select { - case err = <-errChan: - break - case ec = <-ecChan: - break + case ec = <-ecChan: + break + case err = <-errChan: + break } return ec, err diff --git a/pkg/varlinkapi/containers.go b/pkg/varlinkapi/containers.go index 4714f3fa0..a70a87675 100644 --- a/pkg/varlinkapi/containers.go +++ b/pkg/varlinkapi/containers.go @@ -800,51 +800,46 @@ func (i *LibpodAPI) ExecContainer(call iopodman.VarlinkCall, opts iopodman.ExecO call.ReplyExecContainer() resizeChan := make(chan remotecommand.TerminalSize) - errChan := make(chan error) reader, writer, _, pipeWriter, streams := setupStreams(call) //reader, _, _, pipeWriter, streams := setupStreams(call) - ecChan := make(chan uint32, 1) + type ExitCodeError struct { + ExitCode uint32 + Error error + } + ecErrChan := make(chan ExitCodeError, 1) go func() { - fmt.Printf("ExecContainer Start Reader\n") if err := virtwriter.Reader(reader, nil, nil, pipeWriter, resizeChan, nil); err != nil { - //fmt.Printf("ExecContainer Reader err %s, %s\n", err.Error(), errors.Cause(err).Error()) - errChan <- errors.Wrapf(err, "error") + ecErrChan <- ExitCodeError{ + 125, //TODO FIXME magic number, define package? + err, + } } }() - 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 + // TODO FIXME detach keys go func() { ec, err := ctr.Exec(opts.Tty, opts.Privileged, envs, opts.Cmd, user, workDir, streams, 0, resizeChan, "") if err != nil { logrus.Errorf("ExecContainer Exec err %s, %s\n", err.Error(), errors.Cause(err).Error()) - errChan <-err } - ecChan <-uint32(ec) - + ecErrChan <- ExitCodeError{ + uint32(ec), + err, + } }() - ec := uint32(125) - var execErr error - select { - case execErr = <-errChan: - fmt.Println(execErr.Error()) - case ec = <-ecChan: - fmt.Println("found", ec) - } + ecErr := <-ecErrChan - // TODO FIXME prevent all of vthese conversions - if err = virtwriter.HangUp(writer, int(ec)); err != nil { + // TODO FIXME prevent all of these conversions + if err = virtwriter.HangUp(writer, int(ecErr.ExitCode)); err != nil { logrus.Errorf("ExecContainer failed to HANG-UP on %s: %s", ctr.ID(), err.Error()) } - defer fmt.Println("Succeeded in exec'ing") + if err := call.Writer.Flush(); err != nil { logrus.Errorf("Exec Container err: %s", err.Error()) } - return execErr + return ecErr.Error } diff --git a/pkg/varlinkapi/virtwriter/virtwriter.go b/pkg/varlinkapi/virtwriter/virtwriter.go index 23f945704..8cdedeed8 100644 --- a/pkg/varlinkapi/virtwriter/virtwriter.go +++ b/pkg/varlinkapi/virtwriter/virtwriter.go @@ -113,7 +113,7 @@ func Reader(r *bufio.Reader, output, errput, input io.Writer, resize chan remote if output != nil { _, err := io.CopyN(output, r, messageSize) if err != nil { - return errors.Wrapf(err, "issue stdout") + return errors.Wrapf(err, "issue stdout") } } case ToStderr: @@ -121,14 +121,14 @@ func Reader(r *bufio.Reader, output, errput, input io.Writer, resize chan remote _, err := io.CopyN(errput, r, messageSize) if err != nil { return err - return errors.Wrapf(err, "issue stderr") + return errors.Wrapf(err, "issue stderr") } } case ToStdin: if input != nil { _, err := io.CopyN(input, r, messageSize) if err != nil { - return errors.Wrapf(err, "issue stdin") + return errors.Wrapf(err, "issue stdin") } } case TerminalResize: @@ -159,7 +159,7 @@ func Reader(r *bufio.Reader, output, errput, input io.Writer, resize chan remote } if execEcChan != nil { ecInt := binary.BigEndian.Uint32(out) - execEcChan <-int(ecInt) + execEcChan <- int(ecInt) } return nil @@ -175,8 +175,7 @@ func HangUp(writer *bufio.Writer, ec int) (err error) { n := 0 msg := make([]byte, 4) - binary.LittleEndian.PutUint32(msg, uint32(ec)) - + binary.BigEndian.PutUint32(msg, uint32(ec)) writeQuit := NewVirtWriteCloser(writer, Quit) if n, err = writeQuit.Write(msg); err != nil { diff --git a/test/e2e/exec_test.go b/test/e2e/exec_test.go index 316575b0f..bd4fb7aad 100644 --- a/test/e2e/exec_test.go +++ b/test/e2e/exec_test.go @@ -65,6 +65,8 @@ var _ = Describe("Podman exec", func() { }) It("podman exec simple command using latest", func() { + // the remote client doesn't use latest + SkipIfRemote() setup := podmanTest.RunTopContainer("test1") setup.WaitWithDefaultTimeout() Expect(setup.ExitCode()).To(Equal(0)) @@ -75,27 +77,37 @@ var _ = Describe("Podman exec", func() { }) It("podman exec environment test", func() { + // passing environment variables is not supported in the remote client + SkipIfRemote() setup := podmanTest.RunTopContainer("test1") setup.WaitWithDefaultTimeout() Expect(setup.ExitCode()).To(Equal(0)) - session := podmanTest.Podman([]string{"exec", "-l", "--env", "FOO=BAR", "printenv", "FOO"}) + session := podmanTest.Podman([]string{"exec", "--env", "FOO=BAR", "test1", "printenv", "FOO"}) session.WaitWithDefaultTimeout() Expect(session.ExitCode()).To(Equal(0)) match, _ := session.GrepString("BAR") Expect(match).Should(BeTrue()) - session = podmanTest.Podman([]string{"exec", "-l", "--env", "PATH=/bin", "printenv", "PATH"}) + session = podmanTest.Podman([]string{"exec", "--env", "PATH=/bin", "test1", "printenv", "PATH"}) session.WaitWithDefaultTimeout() Expect(session.ExitCode()).To(Equal(0)) match, _ = session.GrepString("/bin") Expect(match).Should(BeTrue()) + }) + + It("podman exec os.Setenv env", func() { + // remote doesn't properly interpret os.Setenv + SkipIfRemote() + setup := podmanTest.RunTopContainer("test1") + setup.WaitWithDefaultTimeout() + Expect(setup.ExitCode()).To(Equal(0)) os.Setenv("FOO", "BAR") - session = podmanTest.Podman([]string{"exec", "-l", "--env", "FOO", "printenv", "FOO"}) + session := podmanTest.Podman([]string{"exec", "--env", "FOO", "test1", "printenv", "FOO"}) session.WaitWithDefaultTimeout() Expect(session.ExitCode()).To(Equal(0)) - match, _ = session.GrepString("BAR") + match, _ := session.GrepString("BAR") Expect(match).Should(BeTrue()) os.Unsetenv("FOO") @@ -141,13 +153,13 @@ var _ = Describe("Podman exec", func() { setup.WaitWithDefaultTimeout() Expect(setup.ExitCode()).To(Equal(0)) - session := podmanTest.Podman([]string{"exec", "-l", "--workdir", "/tmp", "pwd"}) + session := podmanTest.Podman([]string{"exec", "--workdir", "/tmp", "test1", "pwd"}) session.WaitWithDefaultTimeout() Expect(session.ExitCode()).To(Equal(0)) match, _ := session.GrepString("/tmp") Expect(match).Should(BeTrue()) - session = podmanTest.Podman([]string{"exec", "-l", "-w", "/tmp", "pwd"}) + session = podmanTest.Podman([]string{"exec", "-w", "/tmp", "test1", "pwd"}) session.WaitWithDefaultTimeout() Expect(session.ExitCode()).To(Equal(0)) match, _ = session.GrepString("/tmp") @@ -159,11 +171,11 @@ var _ = Describe("Podman exec", func() { setup.WaitWithDefaultTimeout() Expect(setup.ExitCode()).To(Equal(0)) - session := podmanTest.Podman([]string{"exec", "-l", "--workdir", "/missing", "pwd"}) + session := podmanTest.Podman([]string{"exec", "--workdir", "/missing", "test1", "pwd"}) session.WaitWithDefaultTimeout() Expect(session.ExitCode()).To(Equal(1)) - session = podmanTest.Podman([]string{"exec", "-l", "-w", "/missing", "pwd"}) + session = podmanTest.Podman([]string{"exec", "-w", "/missing", "test1", "pwd"}) session.WaitWithDefaultTimeout() Expect(session.ExitCode()).To(Equal(1)) }) -- cgit v1.2.3-54-g00ecf From 5bf99a82ff48cd5097182c55fe1347daf793324b Mon Sep 17 00:00:00 2001 From: Peter Hunt Date: Mon, 22 Jul 2019 15:56:58 -0400 Subject: add detach keys support for remote Signed-off-by: Peter Hunt --- API.md | 2 ++ cmd/podman/varlink/io.podman.varlink | 4 +++- pkg/adapter/containers_remote.go | 2 +- pkg/varlinkapi/containers.go | 15 ++++++++++----- test/e2e/exec_test.go | 4 +--- 5 files changed, 17 insertions(+), 10 deletions(-) (limited to 'test/e2e/exec_test.go') diff --git a/API.md b/API.md index 31bffeb16..71d09fed8 100755 --- a/API.md +++ b/API.md @@ -1591,6 +1591,8 @@ user [?string](#?string) workdir [?string](#?string) env [?[]string](#?[]string) + +detachKeys [?string](#?string) ### type Image diff --git a/cmd/podman/varlink/io.podman.varlink b/cmd/podman/varlink/io.podman.varlink index cc66e7df0..f5f3250f7 100644 --- a/cmd/podman/varlink/io.podman.varlink +++ b/cmd/podman/varlink/io.podman.varlink @@ -514,7 +514,9 @@ type ExecOpts( # workdir to run command in container workdir: ?string, # slice of keyword=value environment variables - env: ?[]string + env: ?[]string, + # string of detach keys + detachKeys: ?string ) # GetVersion returns version and build information of the podman service diff --git a/pkg/adapter/containers_remote.go b/pkg/adapter/containers_remote.go index 7fce30378..3b1b80315 100644 --- a/pkg/adapter/containers_remote.go +++ b/pkg/adapter/containers_remote.go @@ -1017,7 +1017,6 @@ func (r *LocalRuntime) ExecContainer(ctx context.Context, cli *cliconfig.ExecVal // Check if we are attached to a terminal. If we are, generate resize // events, and set the terminal to raw mode - // TODO FIXME tty if haveTerminal && cli.Tty { cancel, oldTermState, err := handleTerminalAttach(ctx, resize) if err != nil { @@ -1038,6 +1037,7 @@ func (r *LocalRuntime) ExecContainer(ctx context.Context, cli *cliconfig.ExecVal User: &cli.User, Workdir: &cli.Workdir, Env: &envs, + DetachKeys: &cli.DetachKeys, } inputStream := os.Stdin diff --git a/pkg/varlinkapi/containers.go b/pkg/varlinkapi/containers.go index fa17bed84..97eb36014 100644 --- a/pkg/varlinkapi/containers.go +++ b/pkg/varlinkapi/containers.go @@ -782,6 +782,9 @@ func (i *LibpodAPI) ExecContainer(call iopodman.VarlinkCall, opts iopodman.ExecO fmt.Sprintf("exec requires a running container, %s is %s", ctr.ID(), state.String())) } + // ACK the client upgrade request + call.ReplyExecContainer() + envs := []string{} if opts.Env != nil { envs = *opts.Env @@ -796,8 +799,11 @@ func (i *LibpodAPI) ExecContainer(call iopodman.VarlinkCall, opts iopodman.ExecO if opts.Workdir != nil { workDir = *opts.Workdir } - // ACK the client upgrade request - call.ReplyExecContainer() + + var detachKeys string + if opts.DetachKeys != nil { + detachKeys = *opts.DetachKeys + } resizeChan := make(chan remotecommand.TerminalSize) @@ -818,11 +824,10 @@ func (i *LibpodAPI) ExecContainer(call iopodman.VarlinkCall, opts iopodman.ExecO } }() - // TODO FIXME detach keys go func() { - ec, err := ctr.Exec(opts.Tty, opts.Privileged, envs, opts.Cmd, user, workDir, streams, 0, resizeChan, "") + ec, err := ctr.Exec(opts.Tty, opts.Privileged, envs, opts.Cmd, user, workDir, streams, 0, resizeChan, detachKeys) if err != nil { - logrus.Errorf("ExecContainer Exec err %s, %s\n", err.Error(), errors.Cause(err).Error()) + logrus.Errorf(err.Error()) } ecErrChan <- ExitCodeError{ uint32(ec), diff --git a/test/e2e/exec_test.go b/test/e2e/exec_test.go index bd4fb7aad..6cf78a25c 100644 --- a/test/e2e/exec_test.go +++ b/test/e2e/exec_test.go @@ -77,8 +77,6 @@ var _ = Describe("Podman exec", func() { }) It("podman exec environment test", func() { - // passing environment variables is not supported in the remote client - SkipIfRemote() setup := podmanTest.RunTopContainer("test1") setup.WaitWithDefaultTimeout() Expect(setup.ExitCode()).To(Equal(0)) @@ -110,8 +108,8 @@ var _ = Describe("Podman exec", func() { match, _ := session.GrepString("BAR") Expect(match).Should(BeTrue()) os.Unsetenv("FOO") - }) + It("podman exec exit code", func() { setup := podmanTest.RunTopContainer("test1") setup.WaitWithDefaultTimeout() -- cgit v1.2.3-54-g00ecf