示例#1
0
    def computeNodeInitialize(self, computeNodeResources,
                              versionInformationLogOnly, updateOSHarddrives):
        logger = logging.getLogger(self.loggerName)
        resultDict = {'updateNeeded': False, 'errorMessages': []}
        command = 'dmidecode -s system-product-name'
        result = subprocess.Popen(command,
                                  stdout=subprocess.PIPE,
                                  stderr=subprocess.PIPE,
                                  shell=True)
        out, err = result.communicate()
        out = out.strip()
        logger.debug('The output of the command (' + command +
                     ") used to get the system's model was: " + out)
        if result.returncode != 0:
            logger.error("Unable to get the system's model information.\n" +
                         err)
            resultDict['errorMessages'].append(
                "Unable to get the system's model information.")
            return resultDict
        else:
            try:
                systemModel = re.match('[a-z,0-9]+\\s+(.*)', out,
                                       re.IGNORECASE).group(1).replace(
                                           ' ', '')
            except AttributeError as err:
                logger.error(
                    "There was a system model match error when trying to match against '"
                    + out + "':\n" + str(err) + '.')
                resultDict['errorMessages'].append(
                    'There was a system model match error.')
                return resultDict

            try:
                if systemModel not in self.healthResourceDict[
                        'supportedComputeNodeModels']:
                    logger.error("The system's model (" + systemModel +
                                 ') is not supported by this CSUR bundle.')
                    resultDict['errorMessages'].append(
                        "The system's model is not supported by this CSUR bundle."
                    )
                    return resultDict
            except KeyError as err:
                logger.error(
                    'The resource key (' + str(err) +
                    ") was not present in the application's esource file.")
                resultDict['errorMessages'].append(
                    'A resource key error was encountered.')
                return resultDict

            logger.debug("The system's model was determined to be: " +
                         systemModel + '.')
            self.computeNodeDict['systemModel'] = systemModel
            if systemModel == 'DL580Gen9':
                command = 'dmidecode -s processor-version'
                result = subprocess.Popen(command,
                                          stdout=subprocess.PIPE,
                                          stderr=subprocess.PIPE,
                                          shell=True)
                out, err = result.communicate()
                out = out.strip()
                logger.debug('The output of the command (' + command +
                             ') used to get the processor version was: ' + out)
                if result.returncode != 0:
                    logger.error('Unable to get the processor version.\n' +
                                 err)
                    resultDict['errorMessages'].append(
                        'Unable to get the processor version information.')
                    return resultDict
                try:
                    processorVersion = re.search(
                        'CPU (E\\d-\\s*\\d{4}\\w* v\\d)',
                        out).group(1).replace(' ', '')
                except AttributeError as err:
                    logger.error(
                        "There was a processor match error when trying to match against '"
                        + out + "':\n" + str(err) + '.')
                    resultDict['errorMessages'].append(
                        'There was a processor match error.')
                    return resultDict

                logger.debug("The processor's version was determined to be: " +
                             processorVersion + '.')
            else:
                processorVersion = ''
            self.computeNodeDict['processorVersion'] = processorVersion
            command = 'cat /proc/version'
            result = subprocess.Popen(command,
                                      stdout=subprocess.PIPE,
                                      stderr=subprocess.PIPE,
                                      shell=True)
            out, err = result.communicate()
            logger.debug(
                'The output of the command (' + command +
                ') used to get the OS distribution information was: ' +
                out.strip())
            if result.returncode != 0:
                logger.error(
                    "Unable to get the system's OS distribution version information.\n"
                    + err)
                resultDict['errorMessages'].append(
                    "Unable to get the system's OS distribution version information."
                )
                return resultDict
            versionInfo = out.lower()
            if 'suse' in versionInfo:
                OSDist = 'SLES'
                command = 'cat /etc/SuSE-release'
            else:
                OSDist = 'RHEL'
                command = 'cat /etc/redhat-release'
            result = subprocess.Popen(command,
                                      stdout=subprocess.PIPE,
                                      stderr=subprocess.PIPE,
                                      shell=True)
            out, err = result.communicate()
            if result.returncode != 0:
                logger.error(
                    "Unable to get the system's OS distribution level.\n" +
                    err)
                resultDict['errorMessages'].append(
                    "Unable to get the system's OS distribution level.")
                return resultDict
            releaseInfo = out.replace('\n', ' ')
            if OSDist == 'SLES':
                try:
                    slesVersion = re.match('.*version\\s*=\\s*([1-4]{2})',
                                           releaseInfo, re.IGNORECASE).group(1)
                except AttributeError as err:
                    logger.error(
                        "There was SLES OS version match error when trying to match against '"
                        + releaseInfo + "':\n" + str(err) + '.')
                    resultDict['errorMessages'].append(
                        'There was a SLES OS version match error.')
                    return resultDict

                try:
                    slesPatchLevel = re.match(
                        '.*patchlevel\\s*=\\s*([1-4]{1})', releaseInfo,
                        re.IGNORECASE).group(1)
                except AttributeError as err:
                    logger.error(
                        "There was SLES patch level match error when trying to match against '"
                        + releaseInfo + "':\n" + str(err) + '.')
                    resultDict['errorMessages'].append(
                        'There was a SLES patch level match error.')
                    return resultDict

                osDistLevel = OSDist + slesVersion + '.' + slesPatchLevel
            else:
                try:
                    rhelVersion = re.match(
                        '.*release\\s+([6-7]{1}.[0-9]{1}).*', releaseInfo,
                        re.IGNORECASE).group(1)
                except AttributeError as err:
                    logger.error(
                        "There was RHEL OS version match error when trying to match against '"
                        + releaseInfo + "':\n" + str(err) + '.')
                    resultDict['errorMessages'].append(
                        'There was a RHEL OS version match error.')
                    return resultDict

                osDistLevel = OSDist + rhelVersion
            try:
                if osDistLevel not in self.healthResourceDict[
                        'supportedDistributionLevels']:
                    if osDistLevel not in self.healthResourceDict[
                            'unsupportedUpgradableDistLevels']:
                        logger.error("The system's OS distribution level (" +
                                     osDistLevel +
                                     ') is not supported by this CSUR bundle.')
                        resultDict['errorMessages'].append(
                            "The system's OS distribution level is not supported by this CSUR bundle."
                        )
                        return resultDict
            except KeyError as err:
                logger.error('The resource key (' + str(err) +
                             ') was not present in the resource file.')
                resultDict['errorMessages'].append(
                    'A resource key error was encountered.')
                return resultDict

            logger.debug(
                "The system's OS distribution level was determined to be: " +
                osDistLevel + '.')
            self.computeNodeDict['osDistLevel'] = osDistLevel
            if not versionInformationLogOnly:
                if 'DL380' in systemModel:
                    command = '/opt/cmcluster/bin/cmviewcl -f line'
                    result = subprocess.Popen(command,
                                              stdout=subprocess.PIPE,
                                              stderr=subprocess.PIPE,
                                              shell=True)
                    out, err = result.communicate()
                    logger.debug(
                        'The output of the command (' + command +
                        ') used to check if the cluster is running was: ' +
                        out.strip())
                    if result.returncode != 0:
                        logger.warn(
                            'Unable to check if the cluster is running.\n' +
                            err)
                        resultDict['errorMessages'].append(
                            'Unable to check if the cluster is running.')
                    clusterView = out.splitlines()
                    for line in clusterView:
                        if re.search('^status=', line):
                            if re.match('status=up', line):
                                logger.warn(
                                    'It appears that the cluster is still running.\n'
                                    + out)
                                resultDict['errorMessages'].append(
                                    'It appears that the cluster is still running.'
                                )

                if not 'DL380' in systemModel:
                    if not 'DL320' in systemModel:
                        command = 'ps -C hdbnameserver,hdbcompileserver,hdbindexserver,hdbpreprocessor,hdbxsengine,hdbwebdispatcher'
                        result = subprocess.Popen(command,
                                                  stdout=subprocess.PIPE,
                                                  stderr=subprocess.PIPE,
                                                  shell=True)
                        out, err = result.communicate()
                        logger.debug(
                            'The output of the command (' + command +
                            ') used to check if SAP is running was: ' +
                            out.strip())
                        if result.returncode == 0:
                            logger.warn(
                                'It appears that SAP HANA is still running.\n'
                                + out)
                            resultDict['errorMessages'].append(
                                'It appears that SAP HANA is still running.')
                    if systemModel == 'DL580G7' or systemModel == 'DL980G7':
                        command = 'mount'
                        result = subprocess.Popen(command,
                                                  stdout=subprocess.PIPE,
                                                  stderr=subprocess.PIPE,
                                                  shell=True)
                        out, err = result.communicate()
                        logger.debug(
                            'The output of the command (' + command +
                            ') used to check if the log partition is mounted was: '
                            + out.strip())
                        if result.returncode != 0:
                            logger.error(
                                'Unable to check if the log partition is mounted.\n'
                                + err)
                            resultDict['errorMessages'].append(
                                'Unable to check if the log partition is mounted.'
                            )
                            return resultDict
                        if re.search('/hana/log|/HANA/IMDB-log', out,
                                     re.MULTILINE | re.DOTALL) != None:
                            logger.error('The log partition is still mounted.')
                            resultDict['errorMessages'].append(
                                'The log partition needs to be unmounted before the system is updated.'
                            )
                            return resultDict
                        command = 'uname -r'
                        result = subprocess.Popen(command,
                                                  stdout=subprocess.PIPE,
                                                  stderr=subprocess.PIPE,
                                                  shell=True)
                        out, err = result.communicate()
                        kernel = out.strip()
                        logger.debug(
                            'The output of the command (' + command +
                            ') used to get the currently used kernel was: ' +
                            kernel)
                        if result.returncode != 0:
                            logger.error(
                                "Unable to get the system's current kernel information.\n"
                                + err)
                            resultDict['errorMessages'].append(
                                "Unable to get the system's current kernel information."
                            )
                            return resultDict
                        logger.debug(
                            'The currently used kernel was determined to be: '
                            + kernel + '.')
                        self.computeNodeDict['kernel'] = kernel
                        command = 'uname -p'
                        result = subprocess.Popen(command,
                                                  stdout=subprocess.PIPE,
                                                  stderr=subprocess.PIPE,
                                                  shell=True)
                        out, err = result.communicate()
                        processorType = out.strip()
                        logger.debug(
                            'The output of the command (' + command +
                            ") used to get the compute node's processor type was: "
                            + processorType)
                        if result.returncode != 0:
                            logger.error(
                                "Unable to get the system's processor type.\n"
                                + err)
                            resultDict['errorMessages'].append(
                                "Unable to get the system's processor type.")
                            return resultDict
                        logger.debug(
                            "The compute node's processor type was determined to be: "
                            + processorType + '.')
                        self.computeNodeDict['processorType'] = processorType
                        try:
                            if not checkFusionIOFirmwareUpgradeSupport(
                                    self.healthResourceDict[
                                        'fusionIOFirmwareVersionList'],
                                    self.loggerName):
                                resultDict['errorMessages'].append(
                                    'The fusionIO firmware is not at a supported version for an automatic upgrade.'
                                )
                                return resultDict
                        except KeyError as err:
                            logger.error(
                                'The resource key (' + str(err) +
                                ') was not present in the resource file.')
                            resultDict['errorMessages'].append(
                                'A resource key error was encountered.')
                            return resultDict

                if not updateOSHarddrives:
                    result = self.__checkDrivers(computeNodeResources,
                                                 systemModel, osDistLevel)
                    if result != '':
                        resultDict['errorMessages'].append(result)
                        return resultDict
                try:
                    if systemModel == 'DL580G7' or systemModel == 'DL980G7':
                        computeNodeInventory = Gen1ScaleUpComputeNodeInventory(
                            self.computeNodeDict.copy(), self.
                            healthResourceDict['noPMCFirmwareUpdateModels'],
                            computeNodeResources,
                            self.healthResourceDict.copy())
                    else:
                        computeNodeInventory = ComputeNodeInventory(
                            self.computeNodeDict.copy(), self.
                            healthResourceDict['noPMCFirmwareUpdateModels'],
                            computeNodeResources,
                            self.healthResourceDict.copy())
                except KeyError as err:
                    logger.error('The resource key (' + str(err) +
                                 ') was not present in the resource file.')
                    resultDict['errorMessages'].append(
                        'A resource key error was encountered.')
                    return resultDict

                if not updateOSHarddrives:
                    computeNodeInventory.getComponentUpdateInventory()
                else:
                    computeNodeInventory.getLocalHardDriveFirmwareInventory()
                if computeNodeInventory.getInventoryStatus():
                    resultDict['errorMessages'].append(
                        "Errors were encountered during the compute node's inventory."
                    )
                    return resultDict
                if versionInformationLogOnly:
                    if os.path.isfile(self.versionInformationLog):
                        try:
                            shutil.copy(self.versionInformationLog,
                                        self.healthBasePath)
                        except IOError as err:
                            self.logger.error('I/O Error while copy of ' +
                                              self.versionInformationLog +
                                              ' to ' + self.healthBasePath)

                    return resultDict
                componentUpdateDict = computeNodeInventory.getComponentUpdateDict(
                )
                if updateOSHarddrives:
                    self.computeNodeDict['componentUpdateDict'] = len(
                        componentUpdateDict['Firmware']
                    ) != 0 and componentUpdateDict
                    resultDict['updateNeeded'] = True
            else:
                componentDictSizes = [
                    len(dict) for dict in componentUpdateDict.values()
                ]
                if any((x != 0 for x in componentDictSizes)):
                    self.computeNodeDict[
                        'componentUpdateDict'] = componentUpdateDict
                    resultDict['updateNeeded'] = True
                    if 'FusionIO' in componentUpdateDict['Firmware']:
                        self.computeNodeDict[
                            'busList'] = computeNodeInventory.getFusionIOBusList(
                            )
                    self.computeNodeDict[
                        'externalStoragePresent'] = computeNodeInventory.isExternalStoragePresent(
                        )
            return resultDict
示例#2
0
    def computeNodeInitialize(self, computeNodeResources,
                              versionInformationLogOnly, updateOSHarddrives):
        logger = logging.getLogger(self.loggerName)
        '''
		This is returned with any error messages that are encountered along with whether or not the 
		compute node needs to be updated.
		'''
        resultDict = {'updateNeeded': False, 'errorMessages': []}

        #Get system model.
        command = "dmidecode -s system-product-name"
        result = subprocess.Popen(command,
                                  stdout=subprocess.PIPE,
                                  stderr=subprocess.PIPE,
                                  shell=True)
        out, err = result.communicate()
        out = out.strip()

        logger.debug("The output of the command (" + command +
                     ") used to get the system's model was: " + out)

        if result.returncode != 0:
            logger.error("Unable to get the system's model information.\n" +
                         err)
            resultDict['errorMessages'].append(
                "Unable to get the system's model information.")
            return resultDict

        try:
            systemModel = (re.match('[a-z,0-9]+\s+(.*)', out,
                                    re.IGNORECASE).group(1)).replace(' ', '')
        except AttributeError as err:
            logger.error(
                "There was a system model match error when trying to match against '"
                + out + "':\n" + str(err) + ".")
            resultDict['errorMessages'].append(
                "There was a system model match error.")
            return resultDict

        try:
            if systemModel not in self.csurResourceDict[
                    'supportedComputeNodeModels']:
                logger.error("The system's model (" + systemModel +
                             ") is not supported by this CSUR bundle.")
                resultDict['errorMessages'].append(
                    "The system's model is not supported by this CSUR bundle.")
                return resultDict
        except KeyError as err:
            logger.error(
                "The resource key (" + str(err) +
                ") was not present in the application's esource file.")
            resultDict['errorMessages'].append(
                "A resource key error was encountered.")
            return resultDict

        logger.debug("The system's model was determined to be: " +
                     systemModel + ".")

        self.computeNodeDict['systemModel'] = systemModel

        #Get the system's OS distribution version information.
        command = "cat /proc/version"
        result = subprocess.Popen(command,
                                  stdout=subprocess.PIPE,
                                  stderr=subprocess.PIPE,
                                  shell=True)
        out, err = result.communicate()

        logger.debug("The output of the command (" + command +
                     ") used to get the OS distribution information was: " +
                     out.strip())

        if result.returncode != 0:
            logger.error(
                "Unable to get the system's OS distribution version information.\n"
                + err)
            resultDict['errorMessages'].append(
                "Unable to get the system's OS distribution version information."
            )
            return resultDict

        #Change version information to lowercase before checking for OS type.
        versionInfo = out.lower()

        if 'suse' in versionInfo:
            OSDist = 'SLES'
            command = "cat /etc/SuSE-release"
        else:
            OSDist = 'RHEL'
            command = "cat /etc/redhat-release"

        result = subprocess.Popen(command,
                                  stdout=subprocess.PIPE,
                                  stderr=subprocess.PIPE,
                                  shell=True)
        out, err = result.communicate()

        if result.returncode != 0:
            logger.error(
                "Unable to get the system's OS distribution level.\n" + err)
            resultDict['errorMessages'].append(
                "Unable to get the system's OS distribution level.")
            return resultDict
        else:
            releaseInfo = out.replace('\n', ' ')

            if OSDist == 'SLES':
                try:
                    slesVersion = re.match('.*version\s*=\s*([1-4]{2})',
                                           releaseInfo, re.IGNORECASE).group(1)
                except AttributeError as err:
                    logger.error(
                        "There was SLES OS version match error when trying to match against '"
                        + releaseInfo + "':\n" + str(err) + ".")
                    resultDict['errorMessages'].append(
                        "There was a SLES OS version match error.")
                    return resultDict

                try:
                    slesPatchLevel = re.match('.*patchlevel\s*=\s*([1-4]{1})',
                                              releaseInfo,
                                              re.IGNORECASE).group(1)
                except AttributeError as err:
                    logger.error(
                        "There was SLES patch level match error when trying to match against '"
                        + releaseInfo + "':\n" + str(err) + ".")
                    resultDict['errorMessages'].append(
                        "There was a SLES patch level match error.")
                    return resultDict

                osDistLevel = OSDist + slesVersion + '.' + slesPatchLevel
            else:
                try:
                    rhelVersion = re.match('.*release\s+([6-7]{1}.[0-9]{1}).*',
                                           releaseInfo, re.IGNORECASE).group(1)
                except AttributeError as err:
                    logger.error(
                        "There was RHEL OS version match error when trying to match against '"
                        + releaseInfo + "':\n" + str(err) + ".")
                    resultDict['errorMessages'].append(
                        "There was a RHEL OS version match error.")
                    return resultDict

                osDistLevel = OSDist + rhelVersion

        try:
            if osDistLevel not in self.csurResourceDict[
                    'supportedDistributionLevels']:
                logger.error("The system's OS distribution level (" +
                             osDistLevel +
                             ") is not supported by this CSUR bundle.")
                resultDict['errorMessages'].append(
                    "The system's OS distribution level is not supported by this CSUR bundle."
                )
                return resultDict
        except KeyError as err:
            logger.error("The resource key (" + str(err) +
                         ") was not present in the resource file.")
            resultDict['errorMessages'].append(
                "A resource key error was encountered.")
            return resultDict

        logger.debug(
            "The system's OS distribution level was determined to be: " +
            osDistLevel + ".")

        self.computeNodeDict['osDistLevel'] = osDistLevel
        '''
		Whenever any type of update is being performed we ensure certain prerequisites are met, e.g. the HANA application
		is not running.
		'''
        if not versionInformationLogOnly:
            #On NFS servers we want to check and notify if the cluster is still running.
            if 'DL380' in systemModel:
                command = '/opt/cmcluster/bin/cmviewcl -f line'
                result = subprocess.Popen(command,
                                          stdout=subprocess.PIPE,
                                          stderr=subprocess.PIPE,
                                          shell=True)
                out, err = result.communicate()

                logger.debug(
                    "The output of the command (" + command +
                    ") used to check if the cluster is running was: " +
                    out.strip())

                if result.returncode != 0:
                    logger.warn(
                        "Unable to check if the cluster is running.\n" + err)
                    resultDict['errorMessages'].append(
                        "Unable to check if the cluster is running.")

                clusterView = out.splitlines()

                for line in clusterView:
                    if re.search('^status=', line):
                        if re.match('status=up', line):
                            logger.warn(
                                "It appears that the cluster is still running.\n"
                                + out)
                            resultDict['errorMessages'].append(
                                "It appears that the cluster is still running."
                            )
            '''
			On servers that are not Serviceguard we check if SAP HANA is running and notify if it is running.
			We can assume that processes are not running is we get a return code of 1.
			'''
            if not ('DL380' in systemModel or 'DL320' in systemModel):
                command = 'ps -C hdbnameserver,hdbcompileserver,hdbindexserver,hdbpreprocessor,hdbxsengine,hdbwebdispatcher'
                result = subprocess.Popen(command,
                                          stdout=subprocess.PIPE,
                                          stderr=subprocess.PIPE,
                                          shell=True)
                out, err = result.communicate()

                logger.debug("The output of the command (" + command +
                             ") used to check if SAP is running was: " +
                             out.strip())

                if result.returncode == 0:
                    logger.warn(
                        "It appears that SAP HANA is still running.\n" + out)
                    resultDict['errorMessages'].append(
                        "It appears that SAP HANA is still running.")
            '''
			Additional kernel version and processorType is needed for FusionIO systems when the driver is rebuilt.	
			Also, need to confirm the system is already at a supported firmware version for automatic upgrades.
			'''
            if systemModel == 'DL580G7' or systemModel == 'DL980G7':
                #Check if /hana/log or /HANA/IMDB-log is mounted.
                command = 'mount'
                result = subprocess.Popen(command,
                                          stdout=subprocess.PIPE,
                                          stderr=subprocess.PIPE,
                                          shell=True)
                out, err = result.communicate()

                logger.debug(
                    "The output of the command (" + command +
                    ") used to check if the log partition is mounted was: " +
                    out.strip())

                if result.returncode != 0:
                    logger.error(
                        "Unable to check if the log partition is mounted.\n" +
                        err)
                    resultDict['errorMessages'].append(
                        "Unable to check if the log partition is mounted.")
                    return resultDict

                if re.search('/hana/log|/HANA/IMDB-log', out,
                             re.MULTILINE | re.DOTALL) != None:
                    logger.error("The log partition is still mounted.")
                    resultDict['errorMessages'].append(
                        "The log partition needs to be unmounted before the system is updated."
                    )
                    return resultDict

                #Get the currently used kernel and processor type, which is used as part of the FusionIO driver RPM name.
                command = 'uname -r'
                result = subprocess.Popen(command,
                                          stdout=subprocess.PIPE,
                                          stderr=subprocess.PIPE,
                                          shell=True)
                out, err = result.communicate()
                kernel = out.strip()

                logger.debug("The output of the command (" + command +
                             ") used to get the currently used kernel was: " +
                             kernel)

                if result.returncode != 0:
                    logger.error(
                        "Unable to get the system's current kernel information.\n"
                        + err)
                    resultDict['errorMessages'].append(
                        "Unable to get the system's current kernel information."
                    )
                    return resultDict

                logger.debug(
                    "The currently used kernel was determined to be: " +
                    kernel + ".")

                self.computeNodeDict['kernel'] = kernel

                command = 'uname -p'
                result = subprocess.Popen(command,
                                          stdout=subprocess.PIPE,
                                          stderr=subprocess.PIPE,
                                          shell=True)
                out, err = result.communicate()
                processorType = out.strip()

                logger.debug(
                    "The output of the command (" + command +
                    ") used to get the compute node's processor type was: " +
                    processorType)

                if result.returncode != 0:
                    logger.error(
                        "Unable to get the system's processor type.\n" + err)
                    resultDict['errorMessages'].append(
                        "Unable to get the system's processor type.")
                    return resultDict

                logger.debug(
                    "The compute node's processor type was determined to be: "
                    + processorType + ".")

                self.computeNodeDict['processorType'] = processorType

                try:
                    if not checkFusionIOFirmwareUpgradeSupport(
                            self.
                            csurResourceDict['fusionIOFirmwareVersionList'],
                            self.loggerName):
                        resultDict['errorMessages'].append(
                            "The fusionIO firmware is not at a supported version for an automatic upgrade."
                        )
                        return resultDict
                except KeyError as err:
                    logger.error("The resource key (" + str(err) +
                                 ") was not present in the resource file.")
                    resultDict['errorMessages'].append(
                        "A resource key error was encountered.")
                    return resultDict

        #Don't need to check drivers if only doing an OS hard drive firmware update.
        if not updateOSHarddrives:
            #Confirm that the drivers for the system being updated are loaded.
            result = self.__checkDrivers(computeNodeResources, systemModel,
                                         osDistLevel)

            if result != '':
                resultDict['errorMessages'].append(result)
                return resultDict

        #Instantiate the compute node inventory class which is used to get a list of compute node components that need to be updated.
        try:
            if (systemModel == 'DL580G7' or systemModel == 'DL980G7'):
                computeNodeInventory = Gen1ScaleUpComputeNodeInventory(
                    self.computeNodeDict.copy(),
                    self.csurResourceDict['noPMCFirmwareUpdateModels'],
                    computeNodeResources, self.
                    csurResourceDict['fusionIOSoftwareInstallPackageList'])
            elif systemModel == 'DL380pGen8' and 'systemGeneration' in self.csurResourceDict and self.csurResourceDict[
                    'systemGeneration'] == 'Gen1.x':
                computeNodeInventory = ComputeNodeInventory(
                    self.computeNodeDict.copy(),
                    self.csurResourceDict['noPMCFirmwareUpdateModels'],
                    computeNodeResources,
                    systemGeneration='Gen1.x')
            else:
                computeNodeInventory = ComputeNodeInventory(
                    self.computeNodeDict.copy(),
                    self.csurResourceDict['noPMCFirmwareUpdateModels'],
                    computeNodeResources)
        except KeyError as err:
            logger.error("The resource key (" + str(err) +
                         ") was not present in the resource file.")
            resultDict['errorMessages'].append(
                "A resource key error was encountered.")
            return resultDict

        #Inventory the compute node to determine which components need to be updated.
        if not updateOSHarddrives:
            computeNodeInventory.getComponentUpdateInventory()
        else:
            hardDrivesLocal = computeNodeInventory.getLocalHardDriveFirmwareInventory(
            )

            if hardDrivesLocal != None and not hardDrivesLocal:
                resultDict['errorMessages'].append(
                    "There are no local hard drives to update, since there were no controllers detected."
                )
                return resultDict

        if computeNodeInventory.getInventoryStatus():
            resultDict['errorMessages'].append(
                "Errors were encountered during the compute node's inventory.")
            return resultDict

        #The resultDict will not be used, but the inventory is done which generated the version report.
        if versionInformationLogOnly:
            return resultDict

        componentUpdateDict = computeNodeInventory.getComponentUpdateDict()
        '''
                This gets a list of the dictionary sizes (Software, Drivers, Firmwware) so that
                it can be determined whether or not an update is needed.
                '''
        if updateOSHarddrives:
            if len(componentUpdateDict['Firmware']) != 0:
                self.computeNodeDict[
                    'componentUpdateDict'] = componentUpdateDict
                resultDict['updateNeeded'] = True
        else:
            componentDictSizes = [
                len(dict) for dict in componentUpdateDict.values()
            ]

            if any(x != 0 for x in componentDictSizes):
                self.computeNodeDict[
                    'componentUpdateDict'] = componentUpdateDict
                resultDict['updateNeeded'] = True

                if 'FusionIO' in componentUpdateDict['Firmware']:
                    self.computeNodeDict[
                        'busList'] = computeNodeInventory.getFusionIOBusList()

                self.computeNodeDict[
                    'externalStoragePresent'] = computeNodeInventory.isExternalStoragePresent(
                    )

        return resultDict
示例#3
0
    def computeNodeInitialize(self, computeNodeResources,
                              versionInformationLogOnly, updateOSHarddrives):
        logger = logging.getLogger(self.loggerName)
        resultDict = {
            'updateNeeded': False,
            'errorMessages': [],
            'hardDrivesMissingFirmware': ''
        }
        command = 'dmidecode -s system-product-name'
        result = subprocess.Popen(command,
                                  stdout=subprocess.PIPE,
                                  stderr=subprocess.PIPE,
                                  shell=True)
        out, err = result.communicate()
        out = out.strip()
        logger.info('The output of the command (' + command +
                    ") used to get the system's model was: " + out)
        if result.returncode != 0:
            logger.error("Unable to get the system's model information.\n" +
                         err)
            resultDict['errorMessages'].append(
                "Unable to get the system's model information.")
            return resultDict
        else:
            try:
                systemModel = re.match('[a-z,0-9]+\\s+(.*)', out,
                                       re.IGNORECASE).group(1).replace(
                                           ' ', '')
            except AttributeError as err:
                logger.error(
                    "There was a system model match error when trying to match against '"
                    + out + "':\n" + str(err) + '.')
                resultDict['errorMessages'].append(
                    'There was a system model match error.')
                return resultDict

            try:
                if systemModel not in self.csurResourceDict[
                        'supportedComputeNodeModels']:
                    logger.error("The system's model (" + systemModel +
                                 ') is not supported by this CSUR bundle.')
                    resultDict['errorMessages'].append(
                        "The system's model is not supported by this CSUR bundle."
                    )
                    return resultDict
            except KeyError as err:
                logger.error(
                    'The resource key (' + str(err) +
                    ") was not present in the application's resource file.")
                resultDict['errorMessages'].append(
                    'A resource key error was encountered.')
                return resultDict

            logger.info("The system's model was determined to be: " +
                        systemModel + '.')
            if '16s' in systemModel:
                logger.info(
                    'The system was determined to be a Superdome2 compute node. Checking its CPU model.'
                )
                processorDict = {
                    '62': 'ivybridge',
                    '63': 'haswell',
                    '79': 'broadwell'
                }
                command = 'cat /proc/cpuinfo'
                result = subprocess.Popen(command,
                                          stdout=subprocess.PIPE,
                                          stderr=subprocess.PIPE,
                                          shell=True)
                out, err = result.communicate()
                logger.info('The output of the command (' + command +
                            ") used to get the system's CPU model was: " +
                            out.strip())
                if result.returncode != 0:
                    logger.error(
                        'There was a problem getting the cpu information.\n' +
                        err + '\n' + out)
                    resultDict['errorMessages'].append(
                        'Unable to get the cpu information.')
                cpudata = out.splitlines()
                for line in cpudata:
                    if re.match('\\s*model\\s+:\\s+[2-9]{2}', line) != None:
                        try:
                            processor = processorDict[re.match(
                                '\\s*model\\s+:\\s+([2-9]{2})', line).group(1)]
                        except AttributeError as err:
                            logger.error(
                                "There was a match error when trying to match against '"
                                + line + "'.\n" + str(err))
                            resultDict['errorMessages'].append(
                                'There was a CPU model match error.')

                        break

                logger.info(
                    "The server's processor type was determined to be: " +
                    processor + '.')
                if processor == 'ivybridge':
                    systemModel = systemModel + 'Gen8'
                elif processor == 'haswell' or processor == 'broadwell':
                    systemModel = systemModel + 'Gen9'
                logger.info("The system's generation was determined to be: " +
                            systemModel + '.')
            self.computeNodeDict['systemModel'] = systemModel
            command = 'cat /proc/version'
            result = subprocess.Popen(command,
                                      stdout=subprocess.PIPE,
                                      stderr=subprocess.PIPE,
                                      shell=True)
            out, err = result.communicate()
            logger.info('The output of the command (' + command +
                        ') used to get the OS distribution information was: ' +
                        out.strip())
            if result.returncode != 0:
                logger.error(
                    "Unable to get the system's OS distribution version information.\n"
                    + err)
                resultDict['errorMessages'].append(
                    "Unable to get the system's OS distribution version information."
                )
                return resultDict
            versionInfo = out.lower()
            if 'suse' in versionInfo:
                OSDist = 'SLES'
                command = 'cat /etc/SuSE-release'
            else:
                OSDist = 'RHEL'
                command = 'cat /etc/redhat-release'
            result = subprocess.Popen(command,
                                      stdout=subprocess.PIPE,
                                      stderr=subprocess.PIPE,
                                      shell=True)
            out, err = result.communicate()
            if result.returncode != 0:
                logger.error(
                    "Unable to get the system's OS distribution level.\n" +
                    err)
                resultDict['errorMessages'].append(
                    "Unable to get the system's OS distribution level.")
                return resultDict
            releaseInfo = out.replace('\n', ' ')
            if OSDist == 'SLES':
                try:
                    slesVersion = re.match('.*version\\s*=\\s*([1-4]{2})',
                                           releaseInfo, re.IGNORECASE).group(1)
                except AttributeError as err:
                    logger.error(
                        "There was SLES OS version match error when trying to match against '"
                        + releaseInfo + "':\n" + str(err) + '.')
                    resultDict['errorMessages'].append(
                        'There was a SLES OS version match error.')
                    return resultDict

                try:
                    slesPatchLevel = re.match(
                        '.*patchlevel\\s*=\\s*([1-4]{1})', releaseInfo,
                        re.IGNORECASE).group(1)
                except AttributeError as err:
                    logger.error(
                        "There was SLES patch level match error when trying to match against '"
                        + releaseInfo + "':\n" + str(err) + '.')
                    resultDict['errorMessages'].append(
                        'There was a SLES patch level match error.')
                    return resultDict

                osDistLevel = OSDist + slesVersion + '.' + slesPatchLevel
            else:
                try:
                    rhelVersion = re.match(
                        '.*release\\s+([6-7]{1}.[0-9]{1}).*', releaseInfo,
                        re.IGNORECASE).group(1)
                except AttributeError as err:
                    logger.error(
                        "There was RHEL OS version match error when trying to match against '"
                        + releaseInfo + "':\n" + str(err) + '.')
                    resultDict['errorMessages'].append(
                        'There was a RHEL OS version match error.')
                    return resultDict

                osDistLevel = OSDist + rhelVersion
            try:
                if osDistLevel not in self.csurResourceDict[
                        'supportedDistributionLevels']:
                    logger.error("The system's OS distribution level (" +
                                 osDistLevel +
                                 ') is not supported by this CSUR bundle.')
                    resultDict['errorMessages'].append(
                        "The system's OS distribution level is not supported by this CSUR bundle."
                    )
                    return resultDict
            except KeyError as err:
                logger.error('The resource key (' + str(err) +
                             ') was not present in the resource file.')
                resultDict['errorMessages'].append(
                    'A resource key error was encountered.')
                return resultDict

            logger.info(
                "The system's OS distribution level was determined to be: " +
                osDistLevel + '.')
            self.computeNodeDict['osDistLevel'] = osDistLevel
            if not versionInformationLogOnly:
                if 'DL380' in systemModel or 'DL360' in systemModel:
                    if 'SLES' in osDistLevel:
                        sgBinPath = '/opt/cmcluster/bin'
                    else:
                        sgBinPath = '/usr/local/cmcluster/bin'
                    command = sgBinPath + '/cmviewcl -f line -l cluster'
                    result = subprocess.Popen(command,
                                              stdout=subprocess.PIPE,
                                              stderr=subprocess.PIPE,
                                              shell=True)
                    out, err = result.communicate()
                    logger.info(
                        'The output of the command (' + command +
                        ') used to check if the cluster is running was: ' +
                        out.strip())
                    if result.returncode != 0:
                        logger.error(
                            'Unable to check if the cluster is running.\n' +
                            err)
                        resultDict['errorMessages'].append(
                            'Unable to check if the cluster is running.')
                        return resultDict
                    clusterView = out.splitlines()
                    for line in clusterView:
                        if re.search('^status=', line):
                            if re.match('status=up', line):
                                logger.error(
                                    'It appears that the cluster is still running.\n'
                                    + out.strip())
                                resultDict['errorMessages'].append(
                                    'It appears that the cluster is still running.'
                                )
                                return resultDict

                    command = sgBinPath + '/cmversion'
                    result = subprocess.Popen(command,
                                              stdout=subprocess.PIPE,
                                              stderr=subprocess.PIPE,
                                              shell=True)
                    out, err = result.communicate()
                    out = out.strip()
                    logger.info('The output of the command (' + command +
                                ") used to get Serviceguard's version was: " +
                                out)
                    if result.returncode != 0:
                        logger.error(
                            "Unable to get Serviceguard's version.\n" + err)
                        resultDict['errorMessages'].append(
                            "Unable to get Serviceguard's version.")
                        return resultDict
                    sgVersion = out[0:7]
                    try:
                        if sgVersion not in self.csurResourceDict[
                                'supportedServiceguardLevels']:
                            logger.error(
                                'The current version of Serviceguard ' + out +
                                ' is not supported for an upgrade.')
                            resultDict['errorMessages'].append(
                                'The current version of Serviceguard is not supported.'
                            )
                            return resultDict
                    except KeyError as err:
                        logger.error('The resource key (' + str(err) +
                                     ') was not present in the resource file.')
                        resultDict['errorMessages'].append(
                            'A resource key error was encountered.')
                        return resultDict

                if not 'DL380' in systemModel:
                    if not 'DL320' in systemModel:
                        if not 'DL360' in systemModel:
                            command = 'ps -C hdbnameserver,hdbcompileserver,hdbindexserver,hdbpreprocessor,hdbxsengine,hdbwebdispatcher'
                            result = subprocess.Popen(command,
                                                      stdout=subprocess.PIPE,
                                                      stderr=subprocess.PIPE,
                                                      shell=True)
                            out, err = result.communicate()
                            logger.info(
                                'The output of the command (' + command +
                                ') used to check if SAP is running was: ' +
                                out.strip())
                            if result.returncode == 0:
                                logger.warn(
                                    'It appears that SAP HANA is still running.\n'
                                    + out)
                                resultDict['errorMessages'].append(
                                    'It appears that SAP HANA is still running.'
                                )
                                return resultDict
                        if systemModel == 'DL580G7' or systemModel == 'DL980G7':
                            command = 'mount'
                            result = subprocess.Popen(command,
                                                      stdout=subprocess.PIPE,
                                                      stderr=subprocess.PIPE,
                                                      shell=True)
                            out, err = result.communicate()
                            logger.info(
                                'The output of the command (' + command +
                                ') used to check if the log partition is mounted was: '
                                + out.strip())
                            if result.returncode != 0:
                                logger.error(
                                    'Unable to check if the log partition is mounted.\n'
                                    + err)
                                resultDict['errorMessages'].append(
                                    'Unable to check if the log partition is mounted.'
                                )
                                return resultDict
                            if re.search('/hana/log|/HANA/IMDB-log', out,
                                         re.MULTILINE | re.DOTALL) != None:
                                logger.error(
                                    'The log partition is still mounted.')
                                resultDict['errorMessages'].append(
                                    'The log partition needs to be unmounted before the system is updated.'
                                )
                                return resultDict
                            command = 'uname -r'
                            result = subprocess.Popen(command,
                                                      stdout=subprocess.PIPE,
                                                      stderr=subprocess.PIPE,
                                                      shell=True)
                            out, err = result.communicate()
                            kernel = out.strip()
                            logger.info(
                                'The output of the command (' + command +
                                ') used to get the currently used kernel was: '
                                + kernel)
                            if result.returncode != 0:
                                logger.error(
                                    "Unable to get the system's current kernel information.\n"
                                    + err)
                                resultDict['errorMessages'].append(
                                    "Unable to get the system's current kernel information."
                                )
                                return resultDict
                            logger.info(
                                'The currently used kernel was determined to be: '
                                + kernel + '.')
                            self.computeNodeDict['kernel'] = kernel
                            command = 'uname -p'
                            result = subprocess.Popen(command,
                                                      stdout=subprocess.PIPE,
                                                      stderr=subprocess.PIPE,
                                                      shell=True)
                            out, err = result.communicate()
                            processorType = out.strip()
                            logger.info(
                                'The output of the command (' + command +
                                ") used to get the compute node's processor type was: "
                                + processorType)
                            if result.returncode != 0:
                                logger.error(
                                    "Unable to get the system's processor type.\n"
                                    + err)
                                resultDict['errorMessages'].append(
                                    "Unable to get the system's processor type."
                                )
                                return resultDict
                            logger.info(
                                "The compute node's processor type was determined to be: "
                                + processorType + '.')
                            self.computeNodeDict[
                                'processorType'] = processorType
                            try:
                                if not checkFusionIOFirmwareUpgradeSupport(
                                        self.csurResourceDict[
                                            'fusionIOFirmwareVersionList'],
                                        self.loggerName):
                                    resultDict['errorMessages'].append(
                                        'The fusionIO firmware is not at a supported version for an automatic upgrade.'
                                    )
                                    return resultDict
                            except KeyError as err:
                                logger.error(
                                    'The resource key (' + str(err) +
                                    ') was not present in the resource file.')
                                resultDict['errorMessages'].append(
                                    'A resource key error was encountered.')
                                return resultDict

                    if not updateOSHarddrives and '16s' not in systemModel:
                        result = self.__checkDrivers(computeNodeResources,
                                                     systemModel, osDistLevel)
                        if result != '':
                            resultDict['errorMessages'].append(result)
                            return resultDict
                    try:
                        if systemModel == 'DL580G7' or systemModel == 'DL980G7':
                            computeNodeInventory = Gen1ScaleUpComputeNodeInventory(
                                self.computeNodeDict.copy(), self.
                                csurResourceDict['noPMCFirmwareUpdateModels'],
                                computeNodeResources)
                        elif systemModel == 'DL380pGen8' and 'systemGeneration' in self.csurResourceDict and self.csurResourceDict[
                                'systemGeneration'] == 'Gen1.x':
                            computeNodeInventory = ComputeNodeInventory(
                                self.computeNodeDict.copy(),
                                self.
                                csurResourceDict['noPMCFirmwareUpdateModels'],
                                computeNodeResources,
                                systemGeneration='Gen1.x')
                        else:
                            computeNodeInventory = ComputeNodeInventory(
                                self.computeNodeDict.copy(), self.
                                csurResourceDict['noPMCFirmwareUpdateModels'],
                                computeNodeResources)
                    except KeyError as err:
                        logger.error('The resource key (' + str(err) +
                                     ') was not present in the resource file.')
                        resultDict['errorMessages'].append(
                            'A resource key error was encountered.')
                        return resultDict

                    if not updateOSHarddrives:
                        computeNodeInventory.getComponentUpdateInventory(
                            self.csurResourceDict.copy())
                    else:
                        hardDrivesLocal = computeNodeInventory.getLocalHardDriveFirmwareInventory(
                        )
                        if hardDrivesLocal != None and not hardDrivesLocal:
                            resultDict['errorMessages'].append(
                                'There are no local hard drives to update, since there were no controllers detected.'
                            )
                            return resultDict
                    if computeNodeInventory.getInventoryStatus():
                        resultDict['errorMessages'].append(
                            "Errors were encountered during the compute node's inventory."
                        )
                        return resultDict
                    if computeNodeInventory.getHardDriveFirmwareStatus():
                        resultDict[
                            'hardDrivesMissingFirmware'] = computeNodeInventory.getHardDrivesMissingFirmware(
                            )
                    if versionInformationLogOnly:
                        return resultDict
                    componentUpdateDict = computeNodeInventory.getComponentUpdateDict(
                    )
                    self.computeNodeDict[
                        'componentUpdateDict'] = updateOSHarddrives and len(
                            componentUpdateDict['Firmware']) != 0 and len(
                                resultDict['hardDrivesMissingFirmware']
                            ) == 0 and componentUpdateDict
                    resultDict['updateNeeded'] = True
                else:
                    logger.error(
                        'The local hard drives are not being updated, since firmware was missing for the following hard drives: '
                        + resultDict['hardDrivesMissingFirmware'] + '.')
            else:
                componentDictSizes = [
                    len(dict) for dict in componentUpdateDict.values()
                ]
                if any((x != 0 for x in componentDictSizes)):
                    self.computeNodeDict[
                        'componentUpdateDict'] = componentUpdateDict
                    resultDict['updateNeeded'] = True
                    self.computeNodeDict[
                        'mellanoxBusList'] = computeNodeInventory.getMellanoxBusList(
                        )
                    if 'FusionIO' in componentUpdateDict['Firmware']:
                        self.computeNodeDict[
                            'busList'] = computeNodeInventory.getFusionIOBusList(
                            )
                    self.computeNodeDict[
                        'externalStoragePresent'] = computeNodeInventory.isExternalStoragePresent(
                        )
            return resultDict