From efec4d4e427928911c3ec0421a6e75981b6253d0 Mon Sep 17 00:00:00 2001 From: Philip O'Toole Date: Wed, 21 Feb 2018 20:13:13 -0800 Subject: [PATCH] Return redirect if remove on follower Fixes issue #391. --- CHANGELOG.md | 1 + http/service.go | 12 ++++++++++++ store/store.go | 6 ++++++ 3 files changed, 19 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index ee3c40d2..60816a1a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,6 @@ ## 4.2.3 (unreleased) - [PR #389](https://github.com/rqlite/rqlite/pull/389): Log Store directory path on startup. +- [PR #392](https://github.com/rqlite/rqlite/pull/392): Return redirect if node removal attempted on follower. Fixes [issue #391](https://github.com/rqlite/rqlite/issues/391). ## 4.2.2 (December 7th 2017) - [PR #383](https://github.com/rqlite/rqlite/pull/383): Fix unit tests after underlying SQLite master table changes. diff --git a/http/service.go b/http/service.go index 6856748a..d497a675 100644 --- a/http/service.go +++ b/http/service.go @@ -355,6 +355,18 @@ func (s *Service) handleRemove(w http.ResponseWriter, r *http.Request) { } if err := s.store.Remove(remoteAddr); err != nil { + if err == store.ErrNotLeader { + leader := s.store.Peer(s.store.Leader()) + if leader == "" { + http.Error(w, err.Error(), http.StatusServiceUnavailable) + return + } + + redirect := s.FormRedirect(r, leader) + http.Redirect(w, r, redirect, http.StatusMovedPermanently) + return + } + w.WriteHeader(http.StatusInternalServerError) return } diff --git a/store/store.go b/store/store.go index da2a7e4e..377847d0 100644 --- a/store/store.go +++ b/store/store.go @@ -597,9 +597,15 @@ func (s *Store) Join(addr string) error { // Remove removes a node from the store, specified by addr. func (s *Store) Remove(addr string) error { s.logger.Printf("received request to remove node %s", addr) + if s.raft.State() != raft.Leader { + return ErrNotLeader + } f := s.raft.RemovePeer(addr) if f.Error() != nil { + if f.Error() == raft.ErrNotLeader { + return ErrNotLeader + } return f.Error() } s.logger.Printf("node %s removed successfully", addr)