github.com/dustinrc/deis@v1.10.1-0.20150917223407-0894a5fb979e/mesos/pkg/boot/zookeeper/zookeeper_map.go (about)

     1  package zookeeper
     2  
     3  import (
     4  	"strconv"
     5  
     6  	"github.com/deis/deis/mesos/pkg/etcd"
     7  	"github.com/deis/deis/mesos/pkg/fleet"
     8  	logger "github.com/deis/deis/mesos/pkg/log"
     9  )
    10  
    11  const (
    12  	etcdLock = "/zookeeper/setupLock"
    13  )
    14  
    15  var (
    16  	log = logger.New()
    17  )
    18  
    19  // CheckZkMappingInFleet verifies if there is a mapping for each node in
    20  // the CoreOS cluster using the metadata zookeeper=true to filter wich
    21  // nodes zookeeper should run
    22  func CheckZkMappingInFleet(etcdPath string, etcdClient *etcd.Client, etcdURL []string) {
    23  	// check if the nodes with the required role already have the an id.
    24  	// If not get fleet nodes with the required role and preassing the
    25  	// ids for every node in the cluster
    26  	err := etcd.AcquireLock(etcdClient, etcdLock, 10)
    27  	if err != nil {
    28  		panic(err)
    29  	}
    30  
    31  	zkNodes := etcd.GetList(etcdClient, etcdPath)
    32  	log.Debugf("zookeeper nodes %v", zkNodes)
    33  
    34  	machines, err := getMachines(etcdURL)
    35  	if err != nil {
    36  		panic(err)
    37  	}
    38  	log.Debugf("machines %v", machines)
    39  
    40  	if len(machines) == 0 {
    41  		log.Warning("")
    42  		log.Warning("there is no machine using metadata zookeeper=true in the cluster to run zookeeper")
    43  		log.Warning("we will create the mapping with for all the nodes")
    44  		log.Warning("")
    45  		machines = fleet.GetNodesInCluster(etcdURL)
    46  	}
    47  
    48  	if len(zkNodes) == 0 {
    49  		log.Debug("initializing zookeeper cluster")
    50  		for index, newZkNode := range machines {
    51  			log.Debug("adding node %v to zookeeper cluster", newZkNode)
    52  			etcd.Set(etcdClient, etcdPath+"/"+newZkNode+"/id", strconv.Itoa(index+1), 0)
    53  		}
    54  	} else {
    55  		// we check if some machine in the fleet cluster with the
    56  		// required role is not initialized (no zookeeper node id).
    57  		machinesNotInitialized := difference(machines, zkNodes)
    58  		if len(machinesNotInitialized) > 0 {
    59  			nextNodeID := getNextNodeID(etcdPath, etcdClient, zkNodes)
    60  			for _, zkNode := range machinesNotInitialized {
    61  				etcd.Set(etcdClient, etcdPath+"/"+zkNode+"/id", strconv.Itoa(nextNodeID), 0)
    62  				nextNodeID++
    63  			}
    64  		}
    65  	}
    66  
    67  	// release the etcd lock
    68  	etcd.ReleaseLock(etcdClient)
    69  }
    70  
    71  // getMachines return the list of machines that can run zookeeper or an empty list
    72  func getMachines(etcdURL []string) ([]string, error) {
    73  	metadata, err := fleet.ParseMetadata("zookeeper=true")
    74  	if err != nil {
    75  		panic(err)
    76  	}
    77  
    78  	return fleet.GetNodesWithMetadata(etcdURL, metadata)
    79  }
    80  
    81  // getNextNodeID returns the next id to use as zookeeper node index
    82  func getNextNodeID(etcdPath string, etcdClient *etcd.Client, nodes []string) int {
    83  	result := 0
    84  	for _, node := range nodes {
    85  		id := etcd.Get(etcdClient, etcdPath+"/"+node+"/id")
    86  		numericID, err := strconv.Atoi(id)
    87  		if id != "" && err == nil && numericID > result {
    88  			result = numericID
    89  		}
    90  	}
    91  
    92  	return result + 1
    93  }
    94  
    95  // difference get the elements present in the first slice and not in
    96  // the second one returning those elemenets in a new string slice.
    97  func difference(slice1 []string, slice2 []string) []string {
    98  	diffStr := []string{}
    99  	m := map[string]int{}
   100  
   101  	for _, s1Val := range slice1 {
   102  		m[s1Val] = 1
   103  	}
   104  	for _, s2Val := range slice2 {
   105  		m[s2Val] = m[s2Val] + 1
   106  	}
   107  
   108  	for mKey, mVal := range m {
   109  		if mVal == 1 {
   110  			diffStr = append(diffStr, mKey)
   111  		}
   112  	}
   113  
   114  	return diffStr
   115  }