Esempio n. 1
0
    def __getMirrorsToBuildFromConfigFile(self, gpArray):

        # create fileData object from config file
        #
        filename = self.__options.mirrorConfigFile
        rows = []
        with open(filename) as f:
            for lineno, line in line_reader(f):
                fixed, flexible = parse_gpaddmirrors_line(filename, lineno, line)
                rows.append(ParsedConfigFileRow(fixed, flexible, line))
        fileData = ParsedConfigFile([], rows)

        # validate fileData
        #
        allAddresses = [row.getFixedValuesMap()["address"] for row in fileData.getRows()]
        allNoneArr = [None for a in allAddresses]
        interfaceLookup = GpInterfaceToHostNameCache(self.__pool, allAddresses, allNoneArr)

        #
        # build up the output now
        #
        toBuild = []
        primaries = [seg for seg in gpArray.getDbList() if seg.isSegmentPrimary(current_role=False)]
        segsByContentId = GpArray.getSegmentsByContentId(primaries)

        # note: passed port offset in this call should not matter
        calc = GpMirrorBuildCalculator(gpArray, [], self.__options)

        for row in fileData.getRows():
            fixedValues = row.getFixedValuesMap()
            flexibleValues = row.getFlexibleValuesMap()

            contentId = int(fixedValues['contentId'])
            address = fixedValues['address']
            #
            # read the rest and add the mirror
            #
            port = int(fixedValues['port'])
            dataDir = normalizeAndValidateInputPath(fixedValues['dataDirectory'], "in config file", row.getLine())
            hostName = interfaceLookup.getHostName(address)
            if hostName is None:
                raise Exception("Segment Host Address %s is unreachable" % address)

            primary = segsByContentId[contentId]
            if primary is None:
                raise Exception("Invalid content %d specified in input file" % contentId)
            primary = primary[0]

            calc.addMirror(toBuild, primary, hostName, address, port, dataDir)

        if len(toBuild) != len(primaries):
            raise Exception("Wrong number of mirrors specified (specified %s mirror(s) for %s primarie(s))" % \
                            (len(toBuild), len(primaries)))

        return GpMirrorListToBuild(toBuild, self.__pool, self.__options.quiet, self.__options.parallelDegree)
    def getRecoveryActionsFromConfigFile(self, gpArray):
        """
        getRecoveryActionsFromConfigFile

        returns: a tuple (segments in change tracking disabled mode which are unable to recover, GpMirrorListToBuild object
                 containing information of segments which are able to recover)
        """

        # create fileData object from config file
        #
        filename = self.__options.recoveryConfigFile
        rows = []
        with open(filename) as f:
            for lineno, line in line_reader(f):
                fixed, flexible = parse_gprecoverseg_line(
                    filename, lineno, line)
                rows.append(ParsedConfigFileRow(fixed, flexible, line))
        fileData = ParsedConfigFile(rows)

        allAddresses = [
            row.getFixedValuesMap()["newAddress"]
            for row in fileData.getRows()
            if "newAddress" in row.getFixedValuesMap()
        ]
        allNoneArr = [None] * len(allAddresses)
        interfaceLookup = GpInterfaceToHostNameCache(self.__pool, allAddresses,
                                                     allNoneArr)

        failedSegments = []
        failoverSegments = []
        for row in fileData.getRows():
            fixedValues = row.getFixedValuesMap()
            flexibleValues = row.getFlexibleValuesMap()

            # find the failed segment
            failedAddress = fixedValues['failedAddress']
            failedPort = fixedValues['failedPort']
            failedDataDirectory = normalizeAndValidateInputPath(
                fixedValues['failedDataDirectory'], "config file",
                row.getLine())
            failedSegment = None
            for segment in gpArray.getDbList():
                if segment.getSegmentAddress() == failedAddress and \
                                str(segment.getSegmentPort()) == failedPort and \
                                segment.getSegmentDataDirectory() == failedDataDirectory:

                    if failedSegment is not None:
                        #
                        # this could be an assertion -- configuration should not allow multiple entries!
                        #
                        raise Exception((
                            "A segment to recover was found twice in configuration.  "
                            "This segment is described by address:port:directory '%s:%s:%s' "
                            "on the input line: %s") %
                                        (failedAddress, failedPort,
                                         failedDataDirectory, row.getLine()))
                    failedSegment = segment

            if failedSegment is None:
                raise Exception("A segment to recover was not found in configuration.  " \
                                "This segment is described by address:port:directory '%s:%s:%s' on the input line: %s" %
                                (failedAddress, failedPort, failedDataDirectory, row.getLine()))

            failoverSegment = None
            if "newAddress" in fixedValues:
                """
                When the second set was passed, the caller is going to tell us to where we need to failover, so
                  build a failover segment
                """
                # these two lines make it so that failoverSegment points to the object that is registered in gparray
                failoverSegment = failedSegment
                failedSegment = failoverSegment.copy()

                address = fixedValues["newAddress"]
                try:
                    port = int(fixedValues["newPort"])
                except ValueError:
                    raise Exception(
                        'Config file format error, invalid number value in line: %s'
                        % (row.getLine()))

                dataDirectory = normalizeAndValidateInputPath(
                    fixedValues["newDataDirectory"], "config file",
                    row.getLine())

                hostName = interfaceLookup.getHostName(address)
                if hostName is None:
                    raise Exception(
                        'Unable to find host name for address %s from line:%s'
                        % (address, row.getLine()))

                # now update values in failover segment
                failoverSegment.setSegmentAddress(address)
                failoverSegment.setSegmentHostName(hostName)
                failoverSegment.setSegmentPort(port)
                failoverSegment.setSegmentDataDirectory(dataDirectory)

            # this must come AFTER the if check above because failedSegment can be adjusted to
            #   point to a different object
            failedSegments.append(failedSegment)
            failoverSegments.append(failoverSegment)

        peersForFailedSegments = self.findAndValidatePeersForFailedSegments(
            gpArray, failedSegments)

        segs = []
        segs_with_persistent_mirroring_disabled = []
        for index, failedSegment in enumerate(failedSegments):
            peerForFailedSegment = peersForFailedSegments[index]

            peerForFailedSegmentDbId = peerForFailedSegment.getSegmentDbId()
            segs.append(
                GpMirrorToBuild(failedSegment, peerForFailedSegment,
                                failoverSegments[index],
                                self.__options.forceFullResynchronization))

        self._output_segments_with_persistent_mirroring_disabled(
            segs_with_persistent_mirroring_disabled)

        return GpMirrorListToBuild(segs, self.__pool, self.__options.quiet,
                                   self.__options.parallelDegree)