diff --git a/api/handlers.go b/api/handlers.go index e676194f60..8a051f6ee1 100644 --- a/api/handlers.go +++ b/api/handlers.go @@ -751,7 +751,27 @@ func postContainersStart(c *context, w http.ResponseWriter, r *http.Request) { return } - if err := c.cluster.StartContainer(container); err != nil { + hostConfig := &dockerclient.HostConfig{ + MemorySwappiness: -1, + } + + buf, err := ioutil.ReadAll(r.Body) + if err != nil { + httpError(w, err.Error(), http.StatusBadRequest) + return + } + r.Body.Close() + + if len(buf) <= 2 { + hostConfig = nil + } else { + if err := json.Unmarshal(buf, hostConfig); err != nil { + httpError(w, err.Error(), http.StatusBadRequest) + return + } + } + + if err := c.cluster.StartContainer(container, hostConfig); err != nil { httpError(w, err.Error(), http.StatusInternalServerError) return } diff --git a/cluster/cluster.go b/cluster/cluster.go index 2d3bcd5627..1f1b1896ff 100644 --- a/cluster/cluster.go +++ b/cluster/cluster.go @@ -27,7 +27,7 @@ type Cluster interface { Containers() Containers // Start a container - StartContainer(container *Container) error + StartContainer(container *Container, hostConfig *dockerclient.HostConfig) error // Return container the matching `IDOrName` // TODO: remove this method from the interface as we can use diff --git a/cluster/engine.go b/cluster/engine.go index 6e72273100..6a130cf0e1 100644 --- a/cluster/engine.go +++ b/cluster/engine.go @@ -1083,8 +1083,8 @@ func (e *Engine) cleanupContainers() { } // StartContainer starts a container -func (e *Engine) StartContainer(id string) error { - err := e.client.StartContainer(id, nil) +func (e *Engine) StartContainer(id string, hostConfig *dockerclient.HostConfig) error { + err := e.client.StartContainer(id, hostConfig) e.CheckConnectionErr(err) if err != nil { return err diff --git a/cluster/mesos/cluster.go b/cluster/mesos/cluster.go index 004fceb5c6..d1aeaf1e28 100644 --- a/cluster/mesos/cluster.go +++ b/cluster/mesos/cluster.go @@ -179,10 +179,10 @@ func (c *Cluster) UnregisterEventHandler(h cluster.EventHandler) { } // StartContainer starts a container -func (c *Cluster) StartContainer(container *cluster.Container) error { +func (c *Cluster) StartContainer(container *cluster.Container, hostConfig *dockerclient.HostConfig) error { // if the container was started less than a second ago in detach mode, do not start it if time.Now().Unix()-container.Created > 1 || container.Config.Labels[cluster.SwarmLabelNamespace+".mesos.detach"] != "true" { - return container.Engine.StartContainer(container.Id) + return container.Engine.StartContainer(container.Id, hostConfig) } return nil } diff --git a/cluster/swarm/cluster.go b/cluster/swarm/cluster.go index ebd336d824..1e6789672f 100644 --- a/cluster/swarm/cluster.go +++ b/cluster/swarm/cluster.go @@ -125,8 +125,8 @@ func (c *Cluster) generateUniqueID() string { } // StartContainer starts a container -func (c *Cluster) StartContainer(container *cluster.Container) error { - return container.Engine.StartContainer(container.Id) +func (c *Cluster) StartContainer(container *cluster.Container, hostConfig *dockerclient.HostConfig) error { + return container.Engine.StartContainer(container.Id, hostConfig) } // CreateContainer aka schedule a brand new container into the cluster. diff --git a/cluster/watchdog.go b/cluster/watchdog.go index 25efd7b3df..3ef52d7811 100644 --- a/cluster/watchdog.go +++ b/cluster/watchdog.go @@ -83,7 +83,7 @@ func (w *Watchdog) rescheduleContainers(e *Engine) { log.Infof("Rescheduled container %s from %s to %s as %s", c.Id, c.Engine.Name, newContainer.Engine.Name, newContainer.Id) if c.Info.State.Running { log.Infof("Container %s was running, starting container %s", c.Id, newContainer.Id) - if err := w.cluster.StartContainer(newContainer); err != nil { + if err := w.cluster.StartContainer(newContainer, nil); err != nil { log.Errorf("Failed to start rescheduled container %s", newContainer.Id) } } diff --git a/test/integration/api/start.bats b/test/integration/api/start.bats index 4f46ad2737..859065542a 100644 --- a/test/integration/api/start.bats +++ b/test/integration/api/start.bats @@ -25,3 +25,26 @@ function teardown() { # Verify [ -n $(docker_swarm ps -q --filter=name=test_container --filter=status=running) ] } + +@test "docker start with hostConfig" { + start_docker_with_busybox 2 + swarm_manage + # create + docker_swarm create --name test_container busybox sleep 1000 + + # make sure created container exists + # new created container has no status + run docker_swarm ps -l + [ "${#lines[@]}" -eq 2 ] + [[ "${lines[1]}" == *"test_container"* ]] + + # start + curl -s -H "Content-Type: application/json" -X POST -d '{"PublishAllPorts": true}' ${SWARM_HOSTS[0]}/v1.23/containers/test_container/start + + # Verify + [ -n $(docker_swarm ps -q --filter=name=test_container --filter=status=running) ] + + # Inspect HostConfig of container, should have PublishAllPorts set to true + run docker_swarm inspect test_container + [[ "${output}" == *'"PublishAllPorts": true'* ]] +} \ No newline at end of file