// IsServiceLocked verifies whether services are locked func IsServiceLocked(conn client.Connection) (bool, error) { locks, err := conn.Children(zkServiceLock) if err == client.ErrNoNode { return false, nil } return len(locks) > 0, err }
// LoadRunningServicesByHost returns a slice of RunningServices given a host(s) func LoadRunningServicesByHost(conn client.Connection, hostIDs ...string) ([]dao.RunningService, error) { var rss []dao.RunningService = make([]dao.RunningService, 0) for _, hostID := range hostIDs { if exists, err := zzk.PathExists(conn, hostpath(hostID)); err != nil { return nil, err } else if !exists { continue } stateIDs, err := conn.Children(hostpath(hostID)) if err != nil { return nil, err } for _, ssID := range stateIDs { var hs HostState if err := conn.Get(hostpath(hostID, ssID), &hs); err != nil { return nil, err } rs, err := LoadRunningService(conn, hs.ServiceID, hs.ServiceStateID) if err != nil { return nil, err } rss = append(rss, *rs) } } return rss, nil }
// getAllRemoteHostsFromZookeeper retrieves a list of remote storage clients from zookeeper func getAllRemoteHostsFromZookeeper(conn client.Connection, storageClientsPath string) ([]string, error) { clients, err := conn.Children(storageClientsPath) if err != nil { glog.Errorf("unable to retrieve list of DFS remote hosts: %s", err) return []string{}, err } glog.V(4).Infof("DFS remote IPs: %+v", clients) return clients, nil }
// getChildren gets all child paths for the given nodeID func (r *registryType) getChildren(conn client.Connection, nodeID string) ([]string, error) { path := r.getPath(nodeID) glog.V(4).Infof("Getting children for %v", path) names, err := conn.Children(path) if err != nil { return []string{}, err } result := []string{} for _, name := range names { result = append(result, r.getPath(nodeID, name)) } return result, nil }
// monitor checks for changes in a path-based connection func (zconn *zconn) monitor(path string) { var ( connC chan<- client.Connection conn client.Connection err error ) defer func() { if conn != nil { conn.Close() } }() for { // wait for someone to request a connection, or shutdown select { case connC = <-zconn.connC: case <-zconn.shutdownC: return } retry: // create a connection if it doesn't exist or ping the existing connection if conn == nil { conn, err = zconn.client.GetCustomConnection(path) if err != nil { glog.Warningf("Could not obtain a connection to %s: %s", path, err) } } else if _, err := conn.Children("/"); err == client.ErrConnectionClosed { glog.Warningf("Could not ping connection to %s: %s", path, err) conn = nil } // send the connection back if conn != nil { connC <- conn continue } // if conn is nil, try to create a new connection select { case <-time.After(time.Second): glog.Infof("Refreshing connection to zookeeper") goto retry case <-zconn.shutdownC: return } } }
// GetServiceStates gets all service states for a particular service func GetServiceStates(conn client.Connection, serviceIDs ...string) (states []servicestate.ServiceState, err error) { for _, serviceID := range serviceIDs { stateIDs, err := conn.Children(servicepath(serviceID)) if err != nil { return nil, err } for _, stateID := range stateIDs { var state servicestate.ServiceState if err := GetServiceState(conn, &state, serviceID, stateID); err != nil { return nil, err } states = append(states, state) } } return states, nil }
// RemoveService deletes a service func RemoveService(conn client.Connection, serviceID string) error { // Check if the path exists if exists, err := zzk.PathExists(conn, servicepath(serviceID)); err != nil { return err } else if !exists { return nil } // If the service has any children, do not delete if states, err := conn.Children(servicepath(serviceID)); err != nil { return err } else if instances := len(states); instances > 0 { return fmt.Errorf("service %s has %d running instances", serviceID, instances) } // Delete the service return conn.Delete(servicepath(serviceID)) }
// GetVHostKeyChildren gets the ephemeral nodes of a vhost key (example of a key is 'hbase') func (vr *VhostRegistry) GetVHostKeyChildren(conn client.Connection, vhostKey string) ([]VhostEndpoint, error) { var vhostEphemeralNodes []VhostEndpoint vhostChildren, err := conn.Children(vhostPath(vhostKey)) if err == client.ErrNoNode { return vhostEphemeralNodes, nil } if err != nil { return vhostEphemeralNodes, err } for _, vhostChild := range vhostChildren { var vep VhostEndpoint if err := conn.Get(vhostPath(vhostKey, vhostChild), &vep); err != nil { return vhostEphemeralNodes, err } vhostEphemeralNodes = append(vhostEphemeralNodes, vep) } return vhostEphemeralNodes, nil }
// Sync synchronizes zookeeper data with what is in elastic or any other storage facility func Sync(conn client.Connection, data []Node, zkpath string) error { var current []string if exists, err := PathExists(conn, zkpath); err != nil { return err } else if !exists { // pass } else if current, err = conn.Children(zkpath); err != nil { return err } datamap := make(map[string]Node) for i, node := range data { datamap[node.GetID()] = data[i] } for _, id := range current { if node, ok := datamap[id]; ok { glog.V(2).Infof("Updating id:'%s' at zkpath:%s with: %+v", id, zkpath, node) if err := node.Update(conn); err != nil { return err } delete(datamap, id) } else { glog.V(2).Infof("Deleting id:'%s' at zkpath:%s not found in elastic\nzk current children: %v", id, zkpath, current) if err := conn.Delete(path.Join(zkpath, id)); err != nil { return err } } } for id, node := range datamap { glog.V(2).Infof("Creating id:'%s' at zkpath:%s with: %+v", id, zkpath, node) if err := node.Create(conn); err != nil { return err } } return nil }
// LoadRunningServicesByService returns a slice of RunningServices per service id(s) func LoadRunningServicesByService(conn client.Connection, serviceIDs ...string) ([]dao.RunningService, error) { var rss []dao.RunningService for _, serviceID := range serviceIDs { if exists, err := zzk.PathExists(conn, servicepath(serviceID)); err != nil { return nil, err } else if !exists { continue } stateIDs, err := conn.Children(servicepath(serviceID)) if err != nil { return nil, err } for _, ssID := range stateIDs { rs, err := LoadRunningService(conn, serviceID, ssID) if err != nil { return nil, err } rss = append(rss, *rs) } } return rss, nil }
// RemoveServiceVhosts removes vhosts of a service func RemoveServiceVhosts(conn client.Connection, svc *service.Service) error { glog.V(2).Infof("RemoveServiceVhosts for ID:%s Name:%s", svc.ID, svc.Name) // generate map of current vhosts if svcvhosts, err := conn.Children(zkServiceVhosts); err == client.ErrNoNode { } else if err != nil { glog.Errorf("UpdateServiceVhosts unable to retrieve vhost children at path %s %s", zkServiceVhosts, err) return err } else { glog.V(2).Infof("RemoveServiceVhosts for svc.ID:%s from children:%+v", svc.ID, svcvhosts) for _, svcvhost := range svcvhosts { parts := strings.SplitN(svcvhost, "_", 2) svcID := parts[0] vhostname := parts[1] if svcID == svc.ID { if err := RemoveServiceVhost(conn, svc.ID, vhostname); err != nil { return err } } } } return nil }
// LoadRunningServices gets all RunningServices func LoadRunningServices(conn client.Connection) ([]dao.RunningService, error) { if exists, err := zzk.PathExists(conn, servicepath()); err != nil { return nil, err } else if !exists { return []dao.RunningService{}, nil } serviceIDs, err := conn.Children(servicepath()) if err != nil { return nil, err } // filter non-unique service ids unique := make(map[string]interface{}) ids := make([]string, 0) for _, serviceID := range serviceIDs { if _, ok := unique[serviceID]; !ok { unique[serviceID] = nil ids = append(ids, serviceID) } } return LoadRunningServicesByService(conn, ids...) }
// UpdateServiceVhosts updates vhosts of a service func UpdateServiceVhosts(conn client.Connection, svc *service.Service) error { glog.V(2).Infof("UpdateServiceVhosts for ID:%s Name:%s", svc.ID, svc.Name) // generate map of current vhosts currentvhosts := map[string]string{} if svcvhosts, err := conn.Children(zkServiceVhosts); err == client.ErrNoNode { /* // do not do this, otherwise, nodes aren't deleted when calling RemoveServiceVhost if exists, err := zzk.PathExists(conn, zkServiceVhosts); err != nil { return err } else if !exists { err := conn.CreateDir(zkServiceVhosts) if err != client.ErrNodeExists && err != nil { return err } } */ } else if err != nil { glog.Errorf("UpdateServiceVhosts unable to retrieve vhost children at path %s %s", zkServiceVhosts, err) return err } else { for _, svcvhost := range svcvhosts { parts := strings.SplitN(svcvhost, "_", 2) vhostname := parts[1] currentvhosts[svcvhost] = vhostname } } glog.V(2).Infof(" currentvhosts %+v", currentvhosts) // generate map of vhosts in the service svcvhosts := map[string]string{} for _, ep := range svc.GetServiceVHosts() { for _, vhostname := range ep.VHosts { svcvhosts[fmt.Sprintf("%s_%s", svc.ID, vhostname)] = vhostname } } glog.V(2).Infof(" svcvhosts %+v", svcvhosts) // remove vhosts in current not in svc that match serviceid for sv, vhostname := range currentvhosts { svcID := strings.SplitN(sv, "_", 2)[0] if svcID != svc.ID { continue } if _, ok := svcvhosts[sv]; !ok { if err := RemoveServiceVhost(conn, svc.ID, vhostname); err != nil { return err } } } // add vhosts from svc not in current for sv, vhostname := range svcvhosts { if _, ok := currentvhosts[sv]; !ok { if err := UpdateServiceVhost(conn, svc.ID, vhostname); err != nil { return err } } } return nil }