diff --git a/api/server/server.go b/api/server/server.go index 2aabcb5227..6cb9fc8723 100644 --- a/api/server/server.go +++ b/api/server/server.go @@ -693,8 +693,11 @@ func postContainersStart(eng *engine.Engine, version version.Version, w http.Res if vars == nil { return fmt.Errorf("Missing parameter") } - name := vars["name"] - job := eng.Job("start", name) + var ( + name = vars["name"] + job = eng.Job("start", name) + ) + // allow a nil body for backwards compatibility if r.Body != nil { if api.MatchesContentType(r.Header.Get("Content-Type"), "application/json") { @@ -704,6 +707,10 @@ func postContainersStart(eng *engine.Engine, version version.Version, w http.Res } } if err := job.Run(); err != nil { + if err.Error() == "Container already started" { + w.WriteHeader(http.StatusNotModified) + return nil + } return err } w.WriteHeader(http.StatusNoContent) @@ -720,6 +727,10 @@ func postContainersStop(eng *engine.Engine, version version.Version, w http.Resp job := eng.Job("stop", vars["name"]) job.Setenv("t", r.Form.Get("t")) if err := job.Run(); err != nil { + if err.Error() == "Container already stopped" { + w.WriteHeader(http.StatusNotModified) + return nil + } return err } w.WriteHeader(http.StatusNoContent) diff --git a/docs/sources/reference/api/docker_remote_api.md b/docs/sources/reference/api/docker_remote_api.md index b623167c4a..6e0b7e000e 100644 --- a/docs/sources/reference/api/docker_remote_api.md +++ b/docs/sources/reference/api/docker_remote_api.md @@ -21,7 +21,7 @@ page_keywords: API, Docker, rcli, REST, documentation The current version of the API is v1.13 Calling `/images//insert` is the same as calling -`/v1.12/images//insert`. +`/v1.13/images//insert`. You can still call an old version of the API using `/v1.12/images//insert`. @@ -38,6 +38,12 @@ You can still call an old version of the API using `Sockets` parameter added to the `/info` endpoint listing all the sockets the daemon is configured to listen on. +`POST /containers/(name)/start` +`POST /containers/(name)/stop` + +**New!** +`start` and `stop` will now return 304 if the container's status is not modified + ## v1.12 ### Full Documentation diff --git a/docs/sources/reference/api/docker_remote_api_v1.13.md b/docs/sources/reference/api/docker_remote_api_v1.13.md index 95856af472..9f54be944f 100644 --- a/docs/sources/reference/api/docker_remote_api_v1.13.md +++ b/docs/sources/reference/api/docker_remote_api_v1.13.md @@ -429,6 +429,7 @@ Start the container `id` Status Codes: - **204** – no error + - **304** – container already started - **404** – no such container - **500** – server error @@ -455,6 +456,7 @@ Stop the container `id` Status Codes: - **204** – no error + - **304** – container already stopped - **404** – no such container - **500** – server error diff --git a/server/server.go b/server/server.go index 6d5975e6e7..fa695adfe2 100644 --- a/server/server.go +++ b/server/server.go @@ -2046,6 +2046,11 @@ func (srv *Server) ContainerStart(job *engine.Job) engine.Status { if container == nil { return job.Errorf("No such container: %s", name) } + + if container.State.IsRunning() { + return job.Errorf("Container already started") + } + // If no environment was set, then no hostconfig was passed. if len(job.Environ()) > 0 { hostConfig := runconfig.ContainerHostConfigFromJob(job) @@ -2099,6 +2104,9 @@ func (srv *Server) ContainerStop(job *engine.Job) engine.Status { t = job.GetenvInt("t") } if container := srv.daemon.Get(name); container != nil { + if !container.State.IsRunning() { + return job.Errorf("Container already stopped") + } if err := container.Stop(int(t)); err != nil { return job.Errorf("Cannot stop container %s: %s\n", name, err) }