Пример #1
0
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
}
Пример #2
0
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
}
Пример #3
0
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
}
Пример #4
0
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
}
Пример #5
0
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)
}
Пример #6
0
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
}
Пример #7
0
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()
	})
}