github.com/yasker/longhorn-engine@v0.0.0-20160621014712-6ed6cfca0729/agent/status/replica.go (about) 1 package status 2 3 import ( 4 "fmt" 5 "net/http" 6 7 md "github.com/rancher/go-rancher-metadata/metadata" 8 "github.com/rancher/longhorn/controller/client" 9 replicaClient "github.com/rancher/longhorn/replica/client" 10 11 "github.com/Sirupsen/logrus" 12 "github.com/rancher/longhorn/agent/controller" 13 ) 14 15 type ReplicaStatus struct { 16 controller *client.ControllerClient 17 replica *replicaClient.ReplicaClient 18 metadata *md.Client 19 address string 20 controllerLastError string 21 } 22 23 func NewReplicaStatus() (*ReplicaStatus, error) { 24 metadata, err := md.NewClientAndWait(controller.MetadataURL) 25 if err != nil { 26 return nil, err 27 } 28 self, err := metadata.GetSelfContainer() 29 if err != nil { 30 return nil, err 31 } 32 addr := controller.ReplicaAddress(self.PrimaryIp, 9502) 33 34 controllerClient := client.NewControllerClient("http://controller:9501/v1") 35 replicaClient, err := replicaClient.NewReplicaClient("http://localhost:9502/v1") 36 if err != nil { 37 return nil, err 38 } 39 40 return &ReplicaStatus{ 41 controller: controllerClient, 42 replica: replicaClient, 43 address: addr, 44 }, nil 45 } 46 47 func (s *ReplicaStatus) ServeHTTP(rw http.ResponseWriter, r *http.Request) { 48 // Checking against the replica is easy: just ensure that the API is responding. 49 _, err := s.replica.GetReplica() 50 if err != nil { 51 writeError(rw, err) 52 return 53 } 54 55 if ok, msg := s.checkReplicaStatusInController(rw); !ok { 56 writeErrorString(rw, msg) 57 return 58 } 59 60 writeOK(rw) 61 } 62 63 func (s *ReplicaStatus) checkReplicaStatusInController(rw http.ResponseWriter) (bool, string) { 64 replicas, err := s.controller.ListReplicas() 65 if err != nil { 66 logrus.Warnf("Couldn't get replicas from controller. Reporting cached status.") 67 return s.reportCacheControllerResponse() 68 } 69 for _, replica := range replicas { 70 if replica.Address == s.address { 71 if replica.Mode == "ERR" { 72 return s.cacheControllerResponse(false, fmt.Sprintf("Replica %v is in error mode.", s.address)) 73 } 74 } 75 } 76 77 return s.cacheControllerResponse(true, "") 78 } 79 80 func (s *ReplicaStatus) reportCacheControllerResponse() (bool, string) { 81 healthy := len(s.controllerLastError) == 0 82 return healthy, s.controllerLastError 83 } 84 85 func (s *ReplicaStatus) cacheControllerResponse(ok bool, msg string) (bool, string) { 86 if ok { 87 s.controllerLastError = "" 88 } else { 89 s.controllerLastError = msg + " (cached response)" 90 } 91 return ok, msg 92 }