summaryrefslogtreecommitdiff
path: root/pkg/bindings
diff options
context:
space:
mode:
Diffstat (limited to 'pkg/bindings')
-rw-r--r--pkg/bindings/containers/attach.go52
-rw-r--r--pkg/bindings/containers/containers.go6
-rw-r--r--pkg/bindings/test/containers_test.go12
3 files changed, 51 insertions, 19 deletions
diff --git a/pkg/bindings/containers/attach.go b/pkg/bindings/containers/attach.go
index 3bd85fbae..7b321af93 100644
--- a/pkg/bindings/containers/attach.go
+++ b/pkg/bindings/containers/attach.go
@@ -19,6 +19,7 @@ import (
"github.com/containers/podman/v2/pkg/bindings"
sig "github.com/containers/podman/v2/pkg/signal"
"github.com/containers/podman/v2/utils"
+ "github.com/moby/term"
"github.com/pkg/errors"
"github.com/sirupsen/logrus"
"golang.org/x/crypto/ssh/terminal"
@@ -60,8 +61,14 @@ func Attach(ctx context.Context, nameOrID string, detachKeys *string, logs, stre
}
params := url.Values{}
+ detachKeysInBytes := []byte{}
if detachKeys != nil {
params.Add("detachKeys", *detachKeys)
+
+ detachKeysInBytes, err = term.ToBytes(*detachKeys)
+ if err != nil {
+ return errors.Wrapf(err, "invalid detach keys")
+ }
}
if logs != nil {
params.Add("logs", fmt.Sprintf("%t", *logs))
@@ -141,27 +148,51 @@ func Attach(ctx context.Context, nameOrID string, detachKeys *string, logs, stre
attachReady <- true
}
+ stdoutChan := make(chan error)
+ stdinChan := make(chan error)
+
if isSet.stdin {
go func() {
logrus.Debugf("Copying STDIN to socket")
- _, err := utils.CopyDetachable(socket, stdin, []byte{})
- if err != nil {
+
+ _, err := utils.CopyDetachable(socket, stdin, detachKeysInBytes)
+
+ if err != nil && err != define.ErrDetach {
logrus.Error("failed to write input to service: " + err.Error())
}
+ stdinChan <- err
}()
}
buffer := make([]byte, 1024)
if ctnr.Config.Tty {
- logrus.Debugf("Copying STDOUT of container in terminal mode")
+ go func() {
+ logrus.Debugf("Copying STDOUT of container in terminal mode")
- if !isSet.stdout {
- return fmt.Errorf("container %q requires stdout to be set", ctnr.ID)
- }
- // If not multiplex'ed, read from server and write to stdout
- _, err := io.Copy(stdout, socket)
- if err != nil {
- return err
+ if !isSet.stdout {
+ stdoutChan <- fmt.Errorf("container %q requires stdout to be set", ctnr.ID)
+ }
+ // If not multiplex'ed, read from server and write to stdout
+ _, err := io.Copy(stdout, socket)
+
+ stdoutChan <- err
+ }()
+
+ for {
+ select {
+ case err := <-stdoutChan:
+ if err != nil {
+ return err
+ }
+
+ return nil
+ case err := <-stdinChan:
+ if err != nil {
+ return err
+ }
+
+ return nil
+ }
}
} else {
logrus.Debugf("Copying standard streams of container in non-terminal mode")
@@ -205,7 +236,6 @@ func Attach(ctx context.Context, nameOrID string, detachKeys *string, logs, stre
}
}
}
- return nil
}
// DemuxHeader reads header for stream from server multiplexed stdin/stdout/stderr/2nd error channel
diff --git a/pkg/bindings/containers/containers.go b/pkg/bindings/containers/containers.go
index 708ad06cb..b5cd2128b 100644
--- a/pkg/bindings/containers/containers.go
+++ b/pkg/bindings/containers/containers.go
@@ -322,12 +322,14 @@ func Wait(ctx context.Context, nameOrID string, condition *define.ContainerStatu
// Exists is a quick, light-weight way to determine if a given container
// exists in local storage. The nameOrID can be a container name
// or a partial/full ID.
-func Exists(ctx context.Context, nameOrID string) (bool, error) {
+func Exists(ctx context.Context, nameOrID string, external bool) (bool, error) {
conn, err := bindings.GetClient(ctx)
if err != nil {
return false, err
}
- response, err := conn.DoRequest(nil, http.MethodGet, "/containers/%s/exists", nil, nil, nameOrID)
+ params := url.Values{}
+ params.Set("external", strconv.FormatBool(external))
+ response, err := conn.DoRequest(nil, http.MethodGet, "/containers/%s/exists", params, nil, nameOrID)
if err != nil {
return false, err
}
diff --git a/pkg/bindings/test/containers_test.go b/pkg/bindings/test/containers_test.go
index 408b4769d..0fb677768 100644
--- a/pkg/bindings/test/containers_test.go
+++ b/pkg/bindings/test/containers_test.go
@@ -405,7 +405,7 @@ var _ = Describe("Podman containers ", func() {
It("podman bogus container does not exist in local storage", func() {
// Bogus container existence check should fail
- containerExists, err := containers.Exists(bt.conn, "foobar")
+ containerExists, err := containers.Exists(bt.conn, "foobar", false)
Expect(err).To(BeNil())
Expect(containerExists).To(BeFalse())
})
@@ -415,7 +415,7 @@ var _ = Describe("Podman containers ", func() {
var name = "top"
_, err := bt.RunTopContainer(&name, bindings.PFalse, nil)
Expect(err).To(BeNil())
- containerExists, err := containers.Exists(bt.conn, name)
+ containerExists, err := containers.Exists(bt.conn, name, false)
Expect(err).To(BeNil())
Expect(containerExists).To(BeTrue())
})
@@ -425,7 +425,7 @@ var _ = Describe("Podman containers ", func() {
var name = "top"
cid, err := bt.RunTopContainer(&name, bindings.PFalse, nil)
Expect(err).To(BeNil())
- containerExists, err := containers.Exists(bt.conn, cid)
+ containerExists, err := containers.Exists(bt.conn, cid, false)
Expect(err).To(BeNil())
Expect(containerExists).To(BeTrue())
})
@@ -435,7 +435,7 @@ var _ = Describe("Podman containers ", func() {
var name = "top"
cid, err := bt.RunTopContainer(&name, bindings.PFalse, nil)
Expect(err).To(BeNil())
- containerExists, err := containers.Exists(bt.conn, cid[0:12])
+ containerExists, err := containers.Exists(bt.conn, cid[0:12], false)
Expect(err).To(BeNil())
Expect(containerExists).To(BeTrue())
})
@@ -455,7 +455,7 @@ var _ = Describe("Podman containers ", func() {
Expect(err).To(BeNil())
err = containers.Kill(bt.conn, name, "SIGINT")
Expect(err).To(BeNil())
- _, err = containers.Exists(bt.conn, name)
+ _, err = containers.Exists(bt.conn, name, false)
Expect(err).To(BeNil())
})
@@ -466,7 +466,7 @@ var _ = Describe("Podman containers ", func() {
Expect(err).To(BeNil())
err = containers.Kill(bt.conn, cid, "SIGTERM")
Expect(err).To(BeNil())
- _, err = containers.Exists(bt.conn, cid)
+ _, err = containers.Exists(bt.conn, cid, false)
Expect(err).To(BeNil())
})