def validateExpansionSegs()

in automation/tinc/main/ext/qautils/gppylib/gparray.py [0:0]


    def validateExpansionSegs(self):
        """ Checks the segments added for various inconsistencies and errors.
        """
        dbids = []
        content = []
        expansion_seg_count = 0
        
        # make sure we have added at least one segment
        if len(self.expansionSegments) == 0:
            raise Exception('No expansion segments defined')
        
        # how many mirrors?
        mirrors_per_segment = len(self.segments[0].mirrorDBs)
            
        for seg in self.expansionSegments:
            # If a segment is 'None' that means we have a gap in the content ids
            if seg is None:
                raise Exception('Expansion segments do not have contiguous content ids.')
            
            expansion_seg_count += 1
            
            for segdb in seg.get_dbs():
                dbids.append(segdb.getSegmentDbId())
                if segdb.getSegmentRole() == ROLE_PRIMARY:
                    isprimary = True
                else:
                    isprimary = False
                content.append((segdb.getSegmentContentId(), isprimary))
            
            # mirror count correct for this content id?
            if mirrors_per_segment > 0:
                if len(seg.mirrorDBs) != mirrors_per_segment:
                    raise Exception('Expansion segment has incorrect number of mirrors defined.')
            else:
                #shouldn't have any mirrors
                if len(seg.mirrorDBs) != 0:
                    raise Exception('Expansion segment has a mirror segment defined but mirroring is not enabled.')
        
        # check that the dbids are what they should be
        dbids.sort()

        # KAS Is the following really true? dbids don't need to be continuous
        if dbids[0] != self.get_max_dbid() + 1:
            raise Exception('Expansion segments have incorrect dbids')
        for i in range(0, len(dbids) - 1):
            if dbids[i] != dbids[i + 1] - 1:
                raise Exception('Expansion segments have incorrect dbids')


        # check that content ids are ok
        valid_content = []
        for i in range(self.segments[-1].primaryDB.content + 1, 
                       self.segments[-1].primaryDB.content + 1 + len(self.expansionSegments)):
            valid_content.append((i, True))
            for j in range(0, mirrors_per_segment):
                valid_content.append((i, False))
        
        valid_content.sort(lambda x,y: cmp(x[0], y[0]) or cmp(x[1], y[1]))
        content.sort(lambda x,y: cmp(x[0], y[0]) or cmp(x[1], y[1]))
        
        if valid_content != content:
            raise Exception('Invalid content ids')
        
        # Check for redefinition data dirs and ports
        datadirs = {}
        used_ports = {}
        used_replication_ports = {}
        for db in self.getDbList(True):
            datadir = db.getSegmentDataDirectory()
            hostname = db.getSegmentHostName()
            port = db.getSegmentPort()
            replication_port = db.getSegmentReplicationPort()
            if datadirs.has_key(hostname):
                if datadir in datadirs[hostname]:
                    raise Exception('Data directory %s used multiple times on host %s' % (datadir, hostname))
                else:
                    datadirs[hostname].append(datadir)
            else:
                datadirs[hostname] = []
                datadirs[hostname].append(datadir)

            # Check ports
            if used_ports.has_key(hostname):
                if db.port in used_ports[hostname]:
                    raise Exception('Port %d is used multiple times on host %s' % (port, hostname))
                else:
                    used_ports[hostname].append(db.port)
            else:
                used_ports[hostname] = []
                used_ports[hostname].append(db.port)
    
            # Check replication ports
            if replication_port != None:
                if used_replication_ports.has_key(hostname):
                    if replication_port in used_replication_ports[hostname]:
                        raise Exception('Replication Port %d is used multiple times on host %s' % (replication_port, hostname))
                    else:
                        used_replication_ports[hostname].append(replication_port)
                else:
                    used_replication_ports[hostname] = []
                    used_replication_ports[hostname].append(replication_port)

        # Check for redefinition of filespace dirs
        dbList = self.getDbList(includeExpansionSegs = True)
        hostDict = GpArray.getSegmentsByHostName(dbList)
        for host in hostDict:
            segList = hostDict[host]
            dirList = []
            for seg in segList:
                dirDict = seg.getSegmentFilespaces()
                for oid in dirDict:
                    if dirDict[oid] in dirList:
                        raise Exception('Data directory %s used multiple times on host %s' % (datadir, hostname))
                    else:
                        dirList.append(dirDict[oid])