Signed-off-by: Lei Jitang <leijitang@huawei.com>
| ... | ... |
@@ -41,6 +41,10 @@ func (cli *DockerCli) CmdAttach(args ...string) error {
|
| 41 | 41 |
return fmt.Errorf("You cannot attach to a stopped container, start it first")
|
| 42 | 42 |
} |
| 43 | 43 |
|
| 44 |
+ if c.State.Paused {
|
|
| 45 |
+ return fmt.Errorf("You cannot attach to a paused container, unpause it first")
|
|
| 46 |
+ } |
|
| 47 |
+ |
|
| 44 | 48 |
if err := cli.CheckTtyInput(!*noStdin, c.Config.Tty); err != nil {
|
| 45 | 49 |
return err |
| 46 | 50 |
} |
| ... | ... |
@@ -396,6 +396,10 @@ func (s *router) postContainersAttach(ctx context.Context, w http.ResponseWriter |
| 396 | 396 |
return derr.ErrorCodeNoSuchContainer.WithArgs(containerName) |
| 397 | 397 |
} |
| 398 | 398 |
|
| 399 |
+ if s.daemon.IsPaused(containerName) {
|
|
| 400 |
+ return derr.ErrorCodePausedContainer.WithArgs(containerName) |
|
| 401 |
+ } |
|
| 402 |
+ |
|
| 399 | 403 |
inStream, outStream, err := httputils.HijackConnection(w) |
| 400 | 404 |
if err != nil {
|
| 401 | 405 |
return err |
| ... | ... |
@@ -163,6 +163,12 @@ func (daemon *Daemon) Exists(id string) bool {
|
| 163 | 163 |
return c != nil |
| 164 | 164 |
} |
| 165 | 165 |
|
| 166 |
+// IsPaused returns a bool indicating if the specified container is paused. |
|
| 167 |
+func (daemon *Daemon) IsPaused(id string) bool {
|
|
| 168 |
+ c, _ := daemon.Get(id) |
|
| 169 |
+ return c.State.isPaused() |
|
| 170 |
+} |
|
| 171 |
+ |
|
| 166 | 172 |
func (daemon *Daemon) containerRoot(id string) string {
|
| 167 | 173 |
return filepath.Join(daemon.repository, id) |
| 168 | 174 |
} |
| ... | ... |
@@ -46,6 +46,14 @@ var ( |
| 46 | 46 |
HTTPStatusCode: http.StatusInternalServerError, |
| 47 | 47 |
}) |
| 48 | 48 |
|
| 49 |
+ // ErrorCodePausedContainer is generated when we attempt to attach a |
|
| 50 |
+ // container but its paused. |
|
| 51 |
+ ErrorCodePausedContainer = errcode.Register(errGroup, errcode.ErrorDescriptor{
|
|
| 52 |
+ Value: "CONTAINERPAUSED", |
|
| 53 |
+ Message: "Container %s is paused. Unpause the container before attach", |
|
| 54 |
+ Description: "The specified container is paused, unpause the container before attach", |
|
| 55 |
+ HTTPStatusCode: http.StatusConflict, |
|
| 56 |
+ }) |
|
| 49 | 57 |
// ErrorCodeAlreadyPaused is generated when we attempt to pause a |
| 50 | 58 |
// container when its already paused. |
| 51 | 59 |
ErrorCodeAlreadyPaused = errcode.Register(errGroup, errcode.ErrorDescriptor{
|
| ... | ... |
@@ -9,6 +9,7 @@ import ( |
| 9 | 9 |
"sync" |
| 10 | 10 |
"time" |
| 11 | 11 |
|
| 12 |
+ "github.com/docker/docker/pkg/integration/checker" |
|
| 12 | 13 |
"github.com/go-check/check" |
| 13 | 14 |
) |
| 14 | 15 |
|
| ... | ... |
@@ -150,3 +151,12 @@ func (s *DockerSuite) TestAttachDisconnect(c *check.C) {
|
| 150 | 150 |
c.Assert(err, check.IsNil) |
| 151 | 151 |
c.Assert(running, check.Equals, "true") |
| 152 | 152 |
} |
| 153 |
+ |
|
| 154 |
+func (s *DockerSuite) TestAttachPausedContainer(c *check.C) {
|
|
| 155 |
+ defer unpauseAllContainers() |
|
| 156 |
+ dockerCmd(c, "run", "-d", "--name=test", "busybox", "top") |
|
| 157 |
+ dockerCmd(c, "pause", "test") |
|
| 158 |
+ out, _, err := dockerCmdWithError("attach", "test")
|
|
| 159 |
+ c.Assert(err, checker.NotNil, check.Commentf(out)) |
|
| 160 |
+ c.Assert(out, checker.Contains, "You cannot attach to a paused container, unpause it first") |
|
| 161 |
+} |