From f36d55f062eb30e06db104852d00f9e19e49f000 Mon Sep 17 00:00:00 2001 From: Xiang Li Date: Wed, 21 Jan 2015 22:59:58 -0800 Subject: [PATCH] next-version-handler --- server/peer_server.go | 1 + server/peer_server_handlers.go | 43 ++++++++++++++++++++++++++++++++++ 2 files changed, 44 insertions(+) diff --git a/server/peer_server.go b/server/peer_server.go index eda20fc3d..9b2190544 100644 --- a/server/peer_server.go +++ b/server/peer_server.go @@ -370,6 +370,7 @@ func (s *PeerServer) HTTPHandler() http.Handler { router.HandleFunc("/v2/admin/machines", s.getMachinesHttpHandler).Methods("GET") router.HandleFunc("/v2/admin/machines/{name}", s.getMachineHttpHandler).Methods("GET") router.HandleFunc("/v2/admin/machines/{name}", s.RemoveHttpHandler).Methods("DELETE") + router.HandleFunc("/v2/admin/next-internal-version", s.NextInternalVersionHandler).Methods("GET") return router } diff --git a/server/peer_server_handlers.go b/server/peer_server_handlers.go index 2696956de..2d561d279 100644 --- a/server/peer_server_handlers.go +++ b/server/peer_server_handlers.go @@ -3,6 +3,7 @@ package server import ( "encoding/json" "net/http" + "path" "strconv" "time" @@ -309,6 +310,48 @@ func (ps *PeerServer) UpgradeHttpHandler(w http.ResponseWriter, req *http.Reques w.WriteHeader(http.StatusOK) } +func (ps *PeerServer) NextInternalVersionHandler(w http.ResponseWriter, req *http.Request) { + for i := 0; i < 50; i++ { + if ps.raftServer.State() != raft.Leader { + l := ps.raftServer.Leader() + if l == "" { + time.Sleep(5 * time.Second) + continue + } + url, _ := ps.registry.PeerURL(l) + uhttp.Redirect(url, w, req) + return + } + resp, err := ps.store.Get("/_etcd/available-internal-versions/2", true, true) + if err != nil { + time.Sleep(5 * time.Second) + continue + } + available := make(map[string]bool) + for _, n := range resp.Node.Nodes { + available[path.Base(n.Key)] = true + } + + notfound := false + for _, n := range ps.registry.Names() { + if !available[n] { + notfound = true + break + } + } + if notfound { + time.Sleep(5 * time.Second) + continue + } + c := ps.store.CommandFactory().CreateSetCommand("/_etcd/next-internal-version", false, "2", store.Permanent) + _, err = ps.raftServer.Do(c) + if err == nil { + return + } + } + w.WriteHeader(http.StatusServiceUnavailable) +} + // machineMessage represents information about a peer or standby in the registry. type machineMessage struct { Name string `json:"name"`