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 }