コード例 #1
0
ファイル: cluster.go プロジェクト: qianzhangxa/swarm
// validatePendingEngine connects to the engine,
func (c *Cluster) validatePendingEngine(engine *cluster.Engine) bool {
	// Attempt a connection to the engine. Since this is slow, don't get a hold
	// of the lock yet.
	if err := engine.Connect(c.TLSConfig); err != nil {
		log.WithFields(log.Fields{"Addr": engine.Addr}).Debugf("Failed to validate pending node: %s", err)
		return false
	}

	// The following is critical and fast. Grab a lock.
	c.Lock()
	defer c.Unlock()

	// Only validate engines from pendingEngines list
	if _, exists := c.pendingEngines[engine.Addr]; !exists {
		return false
	}

	// Make sure the engine ID is unique.
	if old, exists := c.engines[engine.ID]; exists {
		if old.Addr != engine.Addr {
			log.Errorf("ID duplicated. %s shared by %s and %s", engine.ID, old.Addr, engine.Addr)
			// Keep this engine in pendingEngines table and show its error.
			// If it's ID duplication from VM clone, user see this message and can fix it.
			// If the engine is rebooted and get new IP from DHCP, previous address will be removed
			// from discovery after a while.
			// In both cases, retry may fix the problem.
			engine.HandleIDConflict(old.Addr)
		} else {
			log.Debugf("node %q (name: %q) with address %q is already registered", engine.ID, engine.Name, engine.Addr)
			engine.Disconnect()
			// Remove it from pendingEngines table
			delete(c.pendingEngines, engine.Addr)
		}
		return false
	}

	// Engine validated, move from pendingEngines table to engines table
	delete(c.pendingEngines, engine.Addr)
	// set engine state to healthy, and start refresh loop
	engine.ValidationComplete()
	c.engines[engine.ID] = engine

	log.Infof("Registered Engine %s at %s", engine.Name, engine.Addr)
	return true
}