コード例 #1
0
ファイル: svnwatcher.py プロジェクト: sorinros/cxm
    def outReceived(self, data):
        log.debugd("Received:", data)

        for line in data.split('\n'):
            if len(line) <= 0:
                continue

            (path, action, file) = line.split()

            if file in self.blacklist:
                continue

            if action == "CREATE":
                if file in self.deleted:  # Usecase DELETE+CREATE
                    self.deleted.remove(file)
                    self.updated.append(file)
                else:
                    self.added.append(file)
            elif action == "DELETE":
                if file in self.added:  # Usecase CREATE+DELETE
                    self.added.remove(file)
                else:
                    self.deleted.append(file)
                if file in self.updated:  # Usecase MODIFY+DELETE
                    self.updated.remove(file)
            elif action == "MODIFY":
                self.updated.append(file)

            # Remove duplicate entries
            self.added = list(set(self.added))
            self.deleted = list(set(self.deleted))
            self.updated = list(set(self.updated))

        self.rescheduleCommit()
コード例 #2
0
ファイル: svnwatcher.py プロジェクト: nagius/cxm
	def outReceived(self, data):
		log.debugd("Received:", data)

		for line in data.split('\n'):
			if len(line) <= 0:
				continue

			(path, action, file)=line.split()

			if file in self.blacklist:
				continue

			if action == "CREATE":
				if file in self.deleted:		# Usecase DELETE+CREATE
					self.deleted.remove(file)
					self.updated.append(file)
				else:
					self.added.append(file)
			elif action == "DELETE":
				if file in self.added: 			# Usecase CREATE+DELETE
					self.added.remove(file)
				else:
					self.deleted.append(file)
				if file in self.updated:		# Usecase MODIFY+DELETE
					self.updated.remove(file)
			elif action == "MODIFY":
				self.updated.append(file)

			# Remove duplicate entries
			self.added=list(set(self.added))
			self.deleted=list(set(self.deleted))
			self.updated=list(set(self.updated))

		self.rescheduleCommit()
コード例 #3
0
ファイル: master.py プロジェクト: nagius/cxm
	def dispatchMessage(self, data, host):
		dispatcher = {
			"slavehb" : self.updateNodeStatus,
			"masterhb" : self.updateMasterStatus,
			"voterequest" : self.voteForNewMaster,
			"voteresponse" : self.recordVote,
		}

		try:
			msg=MessageHelper.get(data, host)
			log.debugd("Received", msg)
			dispatcher[msg.type()](msg)
		except (MessageError, KeyError), e:
			log.err("Bad message from %s : %s , %s" % (host,data,e))
コード例 #4
0
ファイル: master.py プロジェクト: sorinros/cxm
    def dispatchMessage(self, data, host):
        dispatcher = {
            "slavehb": self.updateNodeStatus,
            "masterhb": self.updateMasterStatus,
            "voterequest": self.voteForNewMaster,
            "voteresponse": self.recordVote,
        }

        try:
            msg = MessageHelper.get(data, host)
            log.debugd("Received", msg)
            dispatcher[msg.type()](msg)
        except (MessageError, KeyError), e:
            log.err("Bad message from %s : %s , %s" % (host, data, e))
コード例 #5
0
ファイル: svnwatcher.py プロジェクト: sorinros/cxm
    def doCommit(self):
        # Semi-global variables used by inner functions
        added = list()
        deleted = list()
        updated = list()

        def commit():
            if len(added) > 0:
                self.node.run(
                    "svn add " +
                    " ".join(map(lambda x: core.cfg['VMCONF_DIR'] + x, added)))
            if len(deleted) > 0:
                self.node.run("svn delete " + " ".join(
                    map(lambda x: core.cfg['VMCONF_DIR'] + x, deleted)))

            self.node.run(
                "svn --non-interactive commit -m 'svnwatcher autocommit' " +
                core.cfg['VMCONF_DIR'])

        def commitEnded(result):
            if self.agent:
                log.info("Cluster updated.")
            else:
                log.info("Local node updated.")

        def commitFailed(reason):
            log.err("SVN failed: %s" % reason.getErrorMessage())

        def releaseLock(result):
            self.commitRunning = False
            if self.agent:
                self.agent.releaseLock(self.LOCK)

        def checkLock(result):
            # If result is true, no commit running (lock successfully grabbed)
            if result:
                # Get a local copy for thread's work
                # Use .extend insted of = due to scope restriction (vars are in the parent function)
                added.extend(self.added)
                deleted.extend(self.deleted)
                updated.extend(self.updated)
                self.added = list()
                self.deleted = list()
                self.updated = list()

                log.info("Committing for " +
                         ", ".join(set(added + deleted + updated)))
                self.commitRunning = True

                d = threads.deferToThread(commit)
                d.addCallback(lambda _: self.doUpdate())
                d.addCallbacks(commitEnded, commitFailed)
                d.addCallback(releaseLock)
                return d
            else:
                log.info("Commit already running: rescheduling.")
                self.rescheduleCommit()
                return defer.succeed(None)

        # Get files versionned in svn
        versionned = [
            line.split()[-1].replace(core.cfg['VMCONF_DIR'], '')
            for line in self.node.run("svn status --verbose " +
                                      core.cfg['VMCONF_DIR']).readlines()
        ]

        # Keep the intersection: do not try to delete already deleted files
        self.deleted = list(set(self.deleted) & set(versionned))

        # Don't commit if there is no updates
        if len(self.added + self.deleted + self.updated) <= 0:
            log.debugd("Trigger commit: nothing to commit.")
            return defer.succeed(None)

        log.debugd("Trigger commit: ADD%s DEL%s UP%s" %
                   (self.added, self.deleted, self.updated))

        # Check for locks of a previous commit still running
        if self.agent:
            # Cluster mode
            d = self.agent.grabLock(self.LOCK)
            d.addCallback(checkLock)
        else:
            # Standalone mode
            d = checkLock(not self.commitRunning)

        d.addErrback(log.err)
        return d
コード例 #6
0
ファイル: svnwatcher.py プロジェクト: nagius/cxm
	def doCommit(self):
		# Semi-global variables used by inner functions
		added=list()
		deleted=list()
		updated=list()

		def commit():
			if len(added) > 0:
				self.node.run("svn add " + " ".join(map(lambda x: core.cfg['VMCONF_DIR']+x, added)))
			if len(deleted) > 0:
				self.node.run("svn delete " + " ".join(map(lambda x: core.cfg['VMCONF_DIR']+x, deleted)))

			self.node.run("svn --non-interactive commit -m 'svnwatcher autocommit' "+core.cfg['VMCONF_DIR'])

		def commitEnded(result):
			if self.agent:
				log.info("Cluster updated.")
			else:
				log.info("Local node updated.")
				
		def commitFailed(reason):
			log.err("SVN failed: %s" % reason.getErrorMessage())

		def releaseLock(result):
			self.commitRunning=False
			if self.agent:
				self.agent.releaseLock(self.LOCK)	

		def checkLock(result):
			# If result is true, no commit running (lock successfully grabbed)
			if result:
				# Get a local copy for thread's work
				# Use .extend insted of = due to scope restriction (vars are in the parent function)
				added.extend(self.added)
				deleted.extend(self.deleted)
				updated.extend(self.updated)
				self.added=list()
				self.deleted=list()
				self.updated=list()

				log.info("Committing for "+", ".join(set(added+deleted+updated)))
				self.commitRunning=True

				d=threads.deferToThread(commit)
				d.addCallback(lambda _: self.doUpdate())
				d.addCallbacks(commitEnded, commitFailed)
				d.addCallback(releaseLock)
				return d
			else:
				log.info("Commit already running: rescheduling.")
				self.rescheduleCommit()
				return defer.succeed(None)

		# Get files versionned in svn
		versionned=[
			line.split()[-1].replace(core.cfg['VMCONF_DIR'],'') 
			for line in self.node.run("svn status --verbose "+core.cfg['VMCONF_DIR']).readlines()
		]

		# Keep the intersection: do not try to delete already deleted files
		self.deleted=list(set(self.deleted) & set(versionned))

		# Don't commit if there is no updates
		if len(self.added+self.deleted+self.updated) <= 0:
			log.debugd("Trigger commit: nothing to commit.")
			return defer.succeed(None)

		log.debugd("Trigger commit: ADD%s DEL%s UP%s" % (self.added, self.deleted, self.updated))

		# Check for locks of a previous commit still running
		if self.agent:
			# Cluster mode 
			d=self.agent.grabLock(self.LOCK)
			d.addCallback(checkLock)
		else:
			# Standalone mode
			d=checkLock(not self.commitRunning)

		d.addErrback(log.err)
		return d
コード例 #7
0
ファイル: master.py プロジェクト: nagius/cxm
		# Get diskhearbeat timestamps
		try:
			tsDisk=self.disk.get_all_ts()
		except Exception, e:
			log.err("Diskheartbeat read failed: %s." % (e))
			raise
			
		# Compare node lists from net and disk hearbeat
		# Use Set's symmetric_difference
		if len(Set(tsDisk.keys()) ^ Set(self.status.keys())) != 0:
			log.err("Node list is inconsistent between net and disk heartbeats !")
			raise Exception("Inconsistent internal data")

		# Check disk heartbeat
		log.debugd("Diskhearbeat status:", tsDisk)
		diskFailed=Set()
		for name, timestamp in tsDisk.items():
			if timestamp == 0:
				# Do nothing if first heartbeat has not been received yet
				continue

			# Timestamp from diskheartbeat is taken from each node, not relative to the master's time
			# so we compute the absolute delta, with the time drift between nodes
			if abs(int(time.time()) - timestamp - self.status[name]['offset']) >= MasterService.TM_SLAVE:
				log.warn("Disk heartbeat lost for %s." % (name))
				diskFailed.add(name)

		# If we loose all heartbeats including master, there is a problem on localhost
		if len(diskFailed) >= len(self.status) or len(netFailed) >= len(self.status):
			log.err("Lost all heartbeats including me ! Maybe a clock screwed up ?")
コード例 #8
0
ファイル: master.py プロジェクト: sorinros/cxm
        # Get diskhearbeat timestamps
        try:
            tsDisk = self.disk.get_all_ts()
        except Exception, e:
            log.err("Diskheartbeat read failed: %s." % (e))
            raise

        # Compare node lists from net and disk hearbeat
        # Use Set's symmetric_difference
        if len(Set(tsDisk.keys()) ^ Set(self.status.keys())) != 0:
            log.err(
                "Node list is inconsistent between net and disk heartbeats !")
            raise Exception("Inconsistent internal data")

        # Check disk heartbeat
        log.debugd("Diskhearbeat status:", tsDisk)
        diskFailed = Set()
        for name, timestamp in tsDisk.items():
            if timestamp == 0:
                # Do nothing if first heartbeat has not been received yet
                continue

            # Timestamp from diskheartbeat is taken from each node, not relative to the master's time
            # so we compute the absolute delta, with the time drift between nodes
            if abs(int(time.time()) - timestamp -
                   self.status[name]['offset']) >= MasterService.TM_SLAVE:
                log.warn("Disk heartbeat lost for %s." % (name))
                diskFailed.add(name)

        # If we loose all heartbeats including master, there is a problem on localhost
        if len(diskFailed) >= len(self.status) or len(netFailed) >= len(