func callEvent(event *docker.APIEvents) tree_lib.TreeError { var err tree_lib.TreeError err.From = tree_lib.FROM_CALL_EVENT switch event.Status { case "start", "unpouse": { var ( dock_inspect *docker.Container ) dock_inspect, err.Err = DockerClient.InspectContainer(event.ID) if !err.IsNull() { return err } ci := ContainerInfo{InspectContainer: dock_inspect, ID: event.ID, Image: dock_inspect.Config.Image} tree_event.Trigger(&tree_event.Event{Name: tree_event.ON_DOCKER_CONTAINER_START, LocalVar: &ci}) } case "die", "kill", "pause": { // Sending only Container ID if it stopped // Sometimes Docker API not giving all info about container after stopping it tree_event.Trigger(&tree_event.Event{Name: tree_event.ON_DOCKER_CONTAINER_STOP, LocalVar: event.ID}) } case "pull", "tag": { var ( inspect *docker.Image ) inspect, err.Err = DockerClient.InspectImage(event.ID) if !err.IsNull() { return err } im := ImageInfo{ID: inspect.ID, Name: event.ID, Inspect: inspect} tree_event.Trigger(&tree_event.Event{Name: tree_event.ON_DOCKER_IMAGE_CREATE, LocalVar: &im}) } case "untag", "delete": { var ( inspect *docker.Image ) inspect, err.Err = DockerClient.InspectImage(event.ID) if !err.IsNull() { return err } im := ImageInfo{ID: inspect.ID, Name: event.ID, Inspect: inspect} tree_event.Trigger(&tree_event.Event{Name: tree_event.ON_DOCKER_IMAGE_DELETE, LocalVar: &im}) } } return err }
func StartEventListener() (err tree_lib.TreeError) { err.From = tree_lib.FROM_START_EVENT_LISTENER err = InitDockerClient() if !err.IsNull() { return } err = triggerInitEvent() if !err.IsNull() { return } // When function will be returned local event for ending docker client will be triggered defer tree_event.Trigger(&tree_event.Event{Name: tree_event.ON_DOCKER_END, LocalVar: nil}) ev := make(chan *docker.APIEvents) err.Err = DockerClient.AddEventListener(ev) if !err.IsNull() { return } for { err = callEvent(<-ev) if !err.IsNull() { break } } return }
func (bs *BalancingService) CheckForStopEvent() (err tree_lib.TreeError) { // If our balancer don't have any destination we need to stop it and call global callback about it if len(bs.destinations) > 0 { return } tree_event.Trigger(&tree_event.Event{Name: tree_event.ON_BALANCER_SERVICE_STOP, LocalVar: &bs.BalancerConfig}) // Deleting service from LVS // err = bs.DropService() // We don't need to delete service from here return }
func triggerInitEvent() tree_lib.TreeError { var ( err tree_lib.TreeError dock_containers []docker.APIContainers ) err.From = tree_lib.FROM_TRIGGER_INIT_EVENT dock_containers, err.Err = DockerClient.ListContainers(docker.ListContainersOptions{All: false}) if !err.IsNull() { return err } // Triggering event with currently running Docker containers inside tree_event.Trigger(&tree_event.Event{Name: tree_event.ON_DOCKER_INIT, LocalVar: dock_containers}) return err }
func UpdateNodeChange(info node_info.NodeInfo) { var ( ev = &tree_event.Event{} err tree_lib.TreeError ) err.From = tree_lib.FROM_UPDATE_NODE_CHANGE ev.Data, err.Err = ffjson.Marshal(info) if !err.IsNull() { tree_log.Error(err.From, err.Error()) return } path := &tree_graph.Path{From: node_info.CurrentNodeInfo.Name, Nodes: []string{"*"}} ev.Name = tree_event.ON_UPDATE_NODE_INFO tree_event.Trigger(ev) tree_event.Emit(ev, path) }
func NewBalancerFromConfig(bc BalancerConfig) (bs BalancingService, err error) { var bs_addr Address bs_addr = Address{IP: bc.IP, Port: bc.Port} bs, err = NewBalancer(bs_addr, bc.Algorithm) if err != nil { return } for _, im := range bc.Images { im = strings.Replace(im, " ", "", -1) // Deleting spaces im_split := strings.Split(im, "|") // splitting image name and port bs.DockerImages[im_split[0]], err = strconv.Atoi(im_split[1]) if err != nil { return } } bs.BalancerConfig = bc bs.SubscribeEvents() tree_event.Trigger(&tree_event.Event{Name: tree_event.ON_BALANCER_SERVICE_START, LocalVar: &bs.BalancerConfig}) return }
func init() { var err tree_lib.TreeError err.From = tree_lib.FROM_INIT tree_db, err.Err = bolt.Open(DB_DIR, 0600, nil) if !err.IsNull() { tree_log.Error(log_from_db, " unable to open database", err.Error()) tree_db = nil os.Exit(1) // Without database we can't keep and share configurations, so program should be exited } // creating Buckets in database tree_db.Update(func(tx *bolt.Tx) (err error) { // Setting databases for _, d := range [][]byte{DB_NODE, DB_BALANCER, DB_RANDOM, DB_GROUP, DB_TAG, DB_RELATIONS, DB_REGISTRY, DB_EVENT} { _, err = tx.CreateBucketIfNotExists(d) if err != nil { return err } } return nil }) // Handling node change event tree_event.ON(tree_event.ON_UPDATE_NODE_INFO, func(e *tree_event.Event) { var ( info node_info.NodeInfo ev_info node_info.NodeInfo names []string data []byte mark bool ) err.Err = ffjson.Unmarshal(e.Data, &ev_info) if !err.IsNull() { tree_log.Error(err.From, err.Error()) return } info, err = GetNodeInfo(ev_info.Name) if !err.IsNull() { tree_log.Error(err.From, err.Error()) return } if len(info.Name) > 0 { err = DeleteNodeFromHisGroups(info.Name) if !err.IsNull() { tree_log.Error(err.From, err.Error()) return } err = DeleteNodeFromHisTags(info.Name) if !err.IsNull() { tree_log.Error(err.From, err.Error()) return } if len(ev_info.TreeIp) > 0 { info.TreeIp = ev_info.TreeIp mark = true } if ev_info.TreePort != -1 { info.TreePort = ev_info.TreePort mark = true } if len(ev_info.Childs[0]) > 0 { info.Childs = append(info.Childs, ev_info.Childs[0]) } if len(ev_info.Childs[1]) > 0 { if g, ok := tree_lib.ArrayContains(info.Childs, ev_info.Childs[1]); ok { info.Childs = info.Childs[:g+copy(info.Childs[g:], info.Childs[g+1:])] } } if len(ev_info.Groups[0]) > 0 { info.Groups = append(info.Groups, ev_info.Groups[0]) } if len(ev_info.Groups[1]) > 0 { if g, ok := tree_lib.ArrayContains(info.Groups, ev_info.Groups[1]); ok { info.Groups = info.Groups[:g+copy(info.Groups[g:], info.Groups[g+1:])] } } if len(ev_info.Tags[0]) > 0 { info.Tags = append(info.Tags, ev_info.Tags[0]) } if len(ev_info.Tags[1]) > 0 { if g, ok := tree_lib.ArrayContains(info.Tags, ev_info.Tags[1]); ok { info.Tags = info.Tags[:g+copy(info.Tags[g:], info.Tags[g+1:])] } } data, err.Err = ffjson.Marshal(info) if !err.IsNull() { tree_log.Error(err.From, err.Error()) return } err = Set(DB_NODE, []byte(ev_info.Name), data) if !err.IsNull() { tree_log.Error(err.From, err.Error()) return } names, err = ListNodeNames() if !err.IsNull() { tree_log.Error(err.From, err.Error()) return } err = AddNodeToHisGroups(info.Name) if !err.IsNull() { tree_log.Error(err.From, err.Error()) return } err = AddNodeToHisTags(info.Name) if !err.IsNull() { tree_log.Error(err.From, err.Error()) return } for _, n := range names { err = SetRelations(n) if !err.IsNull() { tree_log.Error(err.From, err.Error()) return } } if node_info.CurrentNodeInfo.Name == ev_info.Name && mark { var e1 tree_event.Event e1.Name = tree_event.ON_RESTART_NODE tree_event.Trigger(&e1) } } else { err = Set(DB_NODE, []byte(ev_info.Name), e.Data) if !err.IsNull() { tree_log.Error(err.From, err.Error()) return } names, err = ListNodeNames() if !err.IsNull() { tree_log.Error(err.From, err.Error()) return } err = AddNodeToHisGroups(ev_info.Name) if !err.IsNull() { tree_log.Error(err.From, err.Error()) return } err = AddNodeToHisTags(ev_info.Name) if !err.IsNull() { tree_log.Error(err.From, err.Error()) return } for _, n := range names { err = SetRelations(n) if !err.IsNull() { tree_log.Error(err.From, err.Error()) return } } if node_info.CurrentNodeInfo.Name == ev_info.Name { var e1 *tree_event.Event e1.Name = tree_event.ON_RESTART_NODE tree_event.Trigger(e1) } } }) // Closing database before program will be exited // Just in case if program exiting force or we don't want to make dead lock tree_event.ON(tree_event.ON_PROGRAM_EXIT, func(e *tree_event.Event) { CloseDB() }) }