diff --git a/backends/apiserver.go b/backends/apiserver.go index a163657753..4eabc25d81 100644 --- a/backends/apiserver.go +++ b/backends/apiserver.go @@ -82,6 +82,25 @@ func postContainersStart(out beam.Sender, version version.Version, w http.Respon return nil } +func postContainersStop(out beam.Sender, version version.Version, w http.ResponseWriter, r *http.Request, vars map[string]string) error { + if vars == nil { + return fmt.Errorf("Missing parameter") + } + + name := vars["name"] + _, containerOut, err := beam.Obj(out).Attach(name) + container := beam.Obj(containerOut) + if err != nil { + return err + } + if err := container.Stop(); err != nil { + return err + } + + w.WriteHeader(http.StatusNoContent) + return nil +} + func createRouter(out beam.Sender) (*mux.Router, error) { r := mux.NewRouter() m := map[string]map[string]HttpApiFunc{ @@ -91,6 +110,7 @@ func createRouter(out beam.Sender) (*mux.Router, error) { }, "POST": { "/containers/{name:.*}/start": postContainersStart, + "/containers/{name:.*}/stop": postContainersStop, }, "DELETE": {}, "OPTIONS": {}, diff --git a/backends/forward.go b/backends/forward.go index e808228b27..25ad42a184 100644 --- a/backends/forward.go +++ b/backends/forward.go @@ -119,6 +119,7 @@ func (f *forwarder) newContainer(id string) beam.Sender { instance := beam.NewServer() instance.OnAttach(beam.Handler(c.attach)) instance.OnStart(beam.Handler(c.start)) + instance.OnStop(beam.Handler(c.stop)) return instance } @@ -177,6 +178,25 @@ func (c *container) start(ctx *beam.Message) error { return nil } +func (c *container) stop(ctx *beam.Message) error { + path := fmt.Sprintf("/containers/%s/stop", c.id) + resp, err := c.forwarder.client.call("POST", path, "{}") + if err != nil { + return err + } + respBody, err := ioutil.ReadAll(resp.Body) + if err != nil { + return err + } + if resp.StatusCode != 204 { + return fmt.Errorf("expected status code 204, got %d:\n%s", resp.StatusCode, respBody) + } + if _, err := ctx.Ret.Send(&beam.Message{Verb: beam.Ack}); err != nil { + return err + } + return nil +} + type client struct { URL *url.URL proto string diff --git a/beam/object.go b/beam/object.go index 270eee17ad..7a0e44925d 100644 --- a/beam/object.go +++ b/beam/object.go @@ -187,3 +187,18 @@ func (o *Object) Start() error { } return fmt.Errorf("unexpected verb %v", msg.Verb) } + +func (o *Object) Stop() error { + ret, err := o.Send(&Message{Verb: Stop, Ret: RetPipe}) + msg, err := ret.Receive(0) + if err == io.EOF { + return fmt.Errorf("unexpected EOF") + } + if msg.Verb == Ack { + return nil + } + if msg.Verb == Error { + return fmt.Errorf(strings.Join(msg.Args[:1], "")) + } + return fmt.Errorf("unexpected verb %v", msg.Verb) +}