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  }