// 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 AddResourcePool(conn client.Connection, pool *pool.ResourcePool) error { var node PoolNode if err := conn.Create(poolpath(pool.ID), &node); err != nil { return err } node.ResourcePool = pool return conn.Set(poolpath(pool.ID), &node) }
func AddVirtualIP(conn client.Connection, virtualIP *pool.VirtualIP) error { var node VirtualIPNode path := vippath(virtualIP.IP) glog.V(1).Infof("Adding virtual ip to zookeeper: %s", path) if err := conn.Create(path, &node); err != nil { return err } node.VirtualIP = virtualIP return conn.Set(path, &node) }
// SendAction sends an action request to a particular host func SendAction(conn client.Connection, action *Action) (string, error) { uuid, err := utils.NewUUID() if err != nil { return "", err } node := actionPath(action.HostID, uuid) if err := conn.Create(node, action); err != nil { return "", err } else if err := conn.Set(node, action); err != nil { return "", err } return uuid, nil }
// UpdateService updates a service node if it exists, otherwise creates it func UpdateService(conn client.Connection, svc *service.Service) error { var node ServiceNode spath := servicepath(svc.ID) // For some reason you can't just create the node with the service data // already set. Trust me, I tried. It was very aggravating. if err := conn.Get(spath, &node); err != nil { if err := conn.Create(spath, &node); err != nil { glog.Errorf("Error trying to create node at %s: %s", spath, err) } } node.Service = svc return conn.Set(spath, &node) }
// UpdateServiceVhost updates a service vhost node if it exists, otherwise creates it func UpdateServiceVhost(conn client.Connection, serviceID, vhostname string) error { glog.V(2).Infof("UpdateServiceVhost serviceID:%s vhostname:%s", serviceID, vhostname) var node ServiceVhostNode spath := servicevhostpath(serviceID, vhostname) // For some reason you can't just create the node with the service data // already set. Trust me, I tried. It was very aggravating. if err := conn.Get(spath, &node); err != nil { if err := conn.Create(spath, &node); err != nil { glog.Errorf("Error trying to create node at %s: %s", spath, err) } } node.ServiceID = serviceID node.Vhost = vhostname glog.V(2).Infof("Adding service vhost at path:%s %+v", spath, node) return conn.Set(spath, &node) }
//EnsureKey ensures key path to the registry. Returns the path of the key in the registry func (r *registryType) EnsureKey(conn client.Connection, key string) (string, error) { path := r.getPath(key) glog.Infof("EnsureKey key:%s path:%s", key, path) exists, err := zzk.PathExists(conn, path) if err != nil { return "", err } if !exists { key := &KeyNode{ID: key} if err := conn.Create(path, key); err != nil { return "", err } } glog.Infof("EnsureKey returning path:%s", path) return path, nil }
func (r *registryType) ensureKey(conn client.Connection, key string) error { node := &KeyNode{ID: key, IsRemote: false} timeout := time.After(time.Second * 60) var err error path := r.getPath(key) for { err = conn.Create(path, node) if err == client.ErrNodeExists || err == nil { return nil } select { case <-timeout: break default: } } return fmt.Errorf("could not create key: %s", key, err) }
//Add node to the key in registry. Returns the path of the node in the registry func (r *registryType) addItem(conn client.Connection, key string, nodeID string, node client.Node) (string, error) { if err := r.ensureKey(conn, key); err != nil { glog.Errorf("error with addItem.ensureKey(%s): %+v", r.getPath(key), err) return "", err } //TODO: make ephemeral path := r.getPath(key, nodeID) glog.V(3).Infof("Adding to %s: %#v", path, node) if r.ephemeral { var err error if path, err = conn.CreateEphemeral(path, node); err != nil { glog.Errorf("error with addItem.CreateEphemeral(%s) %+v", path, err) return "", err } } else { if err := conn.Create(path, node); err != nil { glog.Errorf("error with addItem.Create(%s) %+v", path, err) return "", err } } return path, nil }