Ejemplo n.º 1
0
func updateContainerIP(containers []db.Container, privateIP string, store Store) {

	oldIPMap := map[string]string{}
	selfStore := path.Join(nodeStore, privateIP)
	etcdIPs, err := store.Get(path.Join(selfStore, minionIPStore))
	if err != nil {
		etcdErr, ok := err.(client.Error)
		if !ok || etcdErr.Code != client.ErrorCodeKeyNotFound {
			log.WithError(err).Error("Failed to load current IPs from Etcd")
			return
		}
	}
	json.Unmarshal([]byte(etcdIPs), &oldIPMap)

	newIPMap := map[string]string{}
	for _, c := range containers {
		newIPMap[strconv.Itoa(c.StitchID)] = c.IP
	}

	if util.StrStrMapEqual(oldIPMap, newIPMap) {
		return
	}

	jsonData, err := json.Marshal(newIPMap)
	if err != nil {
		log.WithError(err).Error("Failed to marshal minion container IP map")
		return
	}

	err = store.Set(path.Join(selfStore, minionIPStore), string(jsonData), 0)
	if err != nil {
		log.WithError(err).Error("Failed to update minion container IP map")
	}
}
Ejemplo n.º 2
0
func containerJoinScore(left, right storeContainer) int {
	if left.Minion != right.Minion ||
		left.Image != right.Image ||
		!util.StrSliceEqual(left.Command, right.Command) ||
		!util.StrStrMapEqual(left.Env, right.Env) {
		return -1
	}

	score := util.EditDistance(left.Labels, right.Labels)
	if left.StitchID != right.StitchID {
		score++
	}
	return score
}
Ejemplo n.º 3
0
func updateEtcdLabel(s Store, etcdData storeData, containers []db.Container) (storeData,
	error) {

	// Collect a map of labels to all of the containers that have that label.
	labelContainers := map[string][]db.Container{}
	for _, c := range containers {
		for _, l := range c.Labels {
			labelContainers[l] = append(labelContainers[l], c)
		}
	}

	newMultiHosts := map[string]string{}

	// Gather the multihost containers and set the IPs of non-multihost containers
	// at the same time. The single host IPs are retrieved from the map of container
	// IPs that updateEtcdDocker created.
	for label, cs := range labelContainers {
		if len(cs) > 1 {
			newMultiHosts[label] = ""
		}
	}

	// Etcd is the source of truth for IPs. If the label exists in both etcd and the
	// db and it is a multihost label, then assign it the IP that etcd has.
	// Otherwise, it stays unassigned and syncLabelIPs will take care of it.
	for id := range newMultiHosts {
		if ip, ok := etcdData.multiHost[id]; ok {
			newMultiHosts[id] = ip
		}
	}

	// No need to sync the SingleHost IPs, since they get their IPs from the dockerIP
	// map, which was already synced in updateEtcdDocker
	syncLabelIPs(newMultiHosts)

	if util.StrStrMapEqual(newMultiHosts, etcdData.multiHost) {
		return etcdData, nil
	}

	newLabelJSON, _ := json.Marshal(newMultiHosts)
	if err := s.Set(labelToIPStore, string(newLabelJSON), 0); err != nil {
		return etcdData, err
	}

	etcdData.multiHost = newMultiHosts
	return etcdData, nil
}
Ejemplo n.º 4
0
func updateContainers(view db.Database, spec stitch.Stitch) {
	score := func(l, r interface{}) int {
		left := l.(db.Container)
		right := r.(db.Container)

		if left.Image != right.Image ||
			!util.StrSliceEqual(left.Command, right.Command) ||
			!util.StrStrMapEqual(left.Env, right.Env) {
			return -1
		}

		score := util.EditDistance(left.Labels, right.Labels)
		if left.StitchID != right.StitchID {
			score++
		}
		return score
	}

	pairs, news, dbcs := join.Join(queryContainers(spec),
		view.SelectFromContainer(nil), score)

	for _, dbc := range dbcs {
		view.Remove(dbc.(db.Container))
	}

	for _, new := range news {
		pairs = append(pairs, join.Pair{L: new, R: view.InsertContainer()})
	}

	for _, pair := range pairs {
		newc := pair.L.(db.Container)
		dbc := pair.R.(db.Container)

		// By sorting the labels we prevent the database from getting confused
		// when their order is non deterministic.
		dbc.Labels = newc.Labels
		sort.Sort(sort.StringSlice(dbc.Labels))

		dbc.Command = newc.Command
		dbc.Image = newc.Image
		dbc.Env = newc.Env
		dbc.StitchID = newc.StitchID
		view.Commit(dbc)
	}
}