// addInstance creates a new service state and host instance func addInstance(conn client.Connection, state ss.ServiceState) error { glog.V(2).Infof("Adding instance %+v", state) // check the object if err := state.ValidEntity(); err != nil { glog.Errorf("Could not validate service state %+v: %s", state, err) return err } // CC-1050: we need to trigger the scheduler in case we only have a // partial create. svclock := newStateLock(conn, state.ServiceID) if err := svclock.Lock(); err != nil { glog.Errorf("Could not set lock on service %s: %s", state.ServiceID, err) return err } defer svclock.Unlock() lock := newInstanceLock(conn, state.ID) if err := lock.Lock(); err != nil { glog.Errorf("Could not set lock for service instance %s for service %s on host %s: %s", state.ID, state.ServiceID, state.HostID, err) return err } glog.V(2).Infof("Acquired lock for instance %s", state.ID) defer lock.Unlock() var err error defer func() { if err != nil { conn.Delete(hostpath(state.HostID, state.ID)) conn.Delete(servicepath(state.ServiceID, state.ID)) rmInstanceLock(conn, state.ID) } }() // Create node on the service spath := servicepath(state.ServiceID, state.ID) snode := &ServiceStateNode{ServiceState: &state} if err = conn.Create(spath, snode); err != nil { glog.Errorf("Could not create service state %s for service %s: %s", state.ID, state.ServiceID, err) return err } else if err = conn.Set(spath, snode); err != nil { glog.Errorf("Could not set service state %s for node %+v: %s", state.ID, snode, err) return err } // Create node on the host hpath := hostpath(state.HostID, state.ID) hnode := NewHostState(&state) glog.V(2).Infof("Host node: %+v", hnode) if err = conn.Create(hpath, hnode); err != nil { glog.Errorf("Could not create host state %s for host %s: %s", state.ID, state.HostID, err) return err } else if err = conn.Set(hpath, hnode); err != nil { glog.Errorf("Could not set host state %s for node %+v: %s", state.ID, hnode, err) return err } glog.V(2).Infof("Releasing lock for instance %s", state.ID) return nil }
func RemoveVirtualIP(conn client.Connection, ip string) error { glog.V(1).Infof("Removing virtual ip from zookeeper: %s", vippath(ip)) err := conn.Delete(vippath(ip)) if err == nil || err == client.ErrNoNode { return nil } return err }
// RemoveServiceVhost deletes a service vhost func RemoveServiceVhost(conn client.Connection, serviceID, vhostname string) error { glog.V(2).Infof("RemoveServiceVhost serviceID:%s vhostname:%s", serviceID, vhostname) // Check if the path exists spath := servicevhostpath(serviceID, vhostname) if exists, err := zzk.PathExists(conn, spath); err != nil { glog.Errorf("unable to determine whether removal path exists %s %s", spath, err) return err } else if !exists { glog.Errorf("service vhost removal path does not exist %s", spath) return nil } // Delete the service vhost glog.V(2).Infof("Deleting service vhost at path:%s", spath) return conn.Delete(spath) }
func removeNode(conn client.Connection, path string) error { exists, err := zzk.PathExists(conn, path) if err != nil { return err } if !exists { return nil } if err := conn.Delete(path); err != nil { glog.Errorf("Unable to delete path:%s error:%v", path, err) return err } return 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)) }
// removeInstance removes the service state and host instances func removeInstance(conn client.Connection, serviceID, hostID, stateID string) error { glog.V(2).Infof("Removing instance %s", stateID) // CC-1050: we need to trigger the scheduler in case we only have a // partial delete. svclock := newStateLock(conn, serviceID) if err := svclock.Lock(); err != nil { glog.Errorf("Could not set lock on service %s: %s", serviceID, err) return err } defer svclock.Unlock() lock := newInstanceLock(conn, stateID) if err := lock.Lock(); err != nil { glog.Errorf("Could not set lock for service instance %s for service %s on host %s: %s", stateID, serviceID, hostID, err) return err } defer lock.Unlock() defer rmInstanceLock(conn, stateID) glog.V(2).Infof("Acquired lock for instance %s", stateID) // Remove the node on the service spath := servicepath(serviceID, stateID) if err := conn.Delete(spath); err != nil { if err != client.ErrNoNode { glog.Errorf("Could not delete service state node %s for service %s on host %s: %s", stateID, serviceID, hostID, err) return err } } // Remove the node on the host hpath := hostpath(hostID, stateID) if err := conn.Delete(hpath); err != nil { if err != client.ErrNoNode { glog.Errorf("Could not delete host state node %s for host %s: %s", stateID, hostID, err) return err } } glog.V(2).Infof("Releasing lock for instance %s", stateID) return 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 }
// rmInstanceLock removes a zk instance lock parent func rmInstanceLock(conn client.Connection, stateID string) error { return conn.Delete(path.Join(zkInstanceLock, stateID)) }
// rmStateLock removes a zk state lock parent func rmStateLock(conn client.Connection, serviceID string) error { return conn.Delete(path.Join(zkStateLock, serviceID)) }
func RemoveResourcePool(conn client.Connection, poolID string) error { return conn.Delete(poolpath(poolID)) }