Exemple #1
0
    def __comparePackagesToString(self, comparePackages):
        stringUtil = StringUtil()
        rString = ""
        missingPackagesMap = comparePackages.getMissingPackagesMap()
        if (len(missingPackagesMap.keys()) > 0):
            description = "The following hosts did not have certain cluster packages installed(whereas other hosts did have the packages installed):"
            keys = missingPackagesMap.keys()
            keys.sort()
            missingPackagesTable = []
            for key in keys:
                reportNames = missingPackagesMap.get(key)
                reportNames.sort()
                if (len(reportNames) > 0):
                    currentHostnames = ""
                    for reportName in reportNames:
                        currentHostnames += "%s " % (reportName)
                    missingPackagesTable.append([key, currentHostnames])
            tableHeader = ["Package Name", "Hostname(s)"]
            tableOfStrings = stringUtil.toTableStringsList(
                missingPackagesTable, tableHeader)
            rString += StringUtil.formatBulletString(description, [],
                                                     tableOfStrings)

        differentPackagesVersionMap = comparePackages.getDiffernetPackagesVersionMap(
        )
        if (len(differentPackagesVersionMap.keys()) > 0):
            description = "The following hosts had a different package version installed:"
            keys = differentPackagesVersionMap.keys()
            keys.sort()
            differentPackageVersionsTable = []
            for key in keys:
                reportNames = differentPackagesVersionMap.get(key)
                reportNames.sort()
                if (len(reportNames) > 0):
                    currentHostnames = ""
                    for reportName in reportNames:
                        currentHostnames += "%s " % (reportName)
                    differentPackageVersionsTable.append(
                        [key, currentHostnames])
            tableHeader = ["Package Name", "Hostname(s)"]
            tableOfStrings = stringUtil.toTableStringsList(
                differentPackageVersionsTable, tableHeader)
            rString += StringUtil.formatBulletString(description, [],
                                                     tableOfStrings)
        if (len(rString) > 0):
            rString = "%s\n%s" % (comparePackages, rString)
        return rString
Exemple #2
0
    def __compareDataToString(self, compareData):
        stringUtil = StringUtil()
        rString = ""
        nonBaseCompareMap = compareData.getNonBaseCompareMap()
        if (not len(nonBaseCompareMap.keys()) > 0):
            return rString
        description = "The following hosts had similar compared values:"
        baseCompareMap = compareData.getBaseCompareMap()
        keys = baseCompareMap.keys()
        keys.sort()
        compareTable = []
        for key in keys:
            reportNames = baseCompareMap.get(key)
            reportNames.sort()
            currentHostnames = ""
            for reportName in reportNames:
                currentHostnames += "%s " % (reportName)
            compareTable.append([key, currentHostnames])
        tableHeader = ["Compared String", "Hostname(s)"]
        tableOfStrings = stringUtil.toTableStringsList(compareTable,
                                                       tableHeader)
        rString += StringUtil.formatBulletString(description, [],
                                                 tableOfStrings)

        description = "The following hosts had different compared values than the above compared values:"
        keys = nonBaseCompareMap.keys()
        keys.sort()
        compareTable = []
        for key in keys:
            reportNames = nonBaseCompareMap.get(key)
            reportNames.sort()
            currentHostnames = ""
            for reportName in reportNames:
                currentHostnames += "%s " % (reportName)
            compareTable.append([key, currentHostnames])
        tableHeader = ["Compared String", "Hostname(s)"]
        tableOfStrings = stringUtil.toTableStringsList(compareTable,
                                                       tableHeader)
        rString += StringUtil.formatBulletString(description, [],
                                                 tableOfStrings)

        if (len(rString) > 0):
            rString = "%s\n%s" % (compareData, rString)
        return rString
Exemple #3
0
    def evaluateClusteredFilesystems(self):
        # Is active/active nfs supported? Sorta
        # urls = ["https://access.redhat.com/solutions/59498"]

        rString = ""
        baseClusterNode = self.__cnc.getBaseClusterNode()
        if (baseClusterNode == None):
            return rString
        cca = ClusterHAConfAnalyzer(baseClusterNode.getPathToClusterConf())

        if ((cca.getTransportMode() == "broadcast") or (cca.getTransportMode() == "udpu")):
            for clusternode in self.__cnc.getClusterNodes():
                if (len(clusternode.getClusterStorageFilesystemList()) > 0):
                    description =  "There is known limitations for GFS2 filesystem when using the "
                    description += "following transports: \"%s\"." %(cca.getTransportMode())
                    urls = ["https://access.redhat.com/solutions/162193", "https://access.redhat.com/articles/146163", "https://access.redhat.com/solutions/459243"]
                    rString += "%s\n" %(StringUtil.formatBulletString(description, urls))
                    break;
        for clusternode in self.__cnc.getClusterNodes():
            stringUtil = StringUtil()
            clusterNodeEvalString = ""
            # ###################################################################
            # Distro Specific evaluations
            # ###################################################################
            # The distro release of this node
            distroRelease = clusternode.getDistroRelease()
            if ((distroRelease.getDistroName() == "RHEL") and (distroRelease.getMajorVersion() == 5)):
                # Check if GFS2 module should be removed on RH5 nodes
                if (self.__doesGFS2ModuleNeedRemoval(clusternode.getUnameA(), clusternode.getClusterModulePackagesVersion())) :
                    description = "The kmod-gfs2 is installed on a running kernel >= 2.6.18-128. This module should be removed since the module is included in the kernel."
                    urls = ["https://access.redhat.com/solutions/17832"]
                    clusterNodeEvalString += StringUtil.formatBulletString(description, urls)

            # ###################################################################
            # Analyze the Clustered Storage
            # ###################################################################
            listOfClusterStorageFilesystems = clusternode.getClusterStorageFilesystemList()

            # ###################################################################
            # Verify that GFS/GFS2 filesystem is using lvm with cluster bit set
            # ###################################################################
            fsTable = []
            # Verify the locking_type is set to 3 cause built-in cluster locking is required.
            if (len(listOfClusterStorageFilesystems) > 0):
                devicemapperCommandsMap =  self.__cnc.getStorageData(clusternode.getClusterNodeName()).getDMCommandsMap()
                lvm = LVM(DeviceMapperParser.parseVGSVData(devicemapperCommandsMap.get("vgs_-v")),
                          DeviceMapperParser.parseLVSAODevicesData(devicemapperCommandsMap.get("lvs_-a_-o_devices")),
                          self.__cnc.getStorageData(clusternode.getClusterNodeName()).getLVMConfData())
                if (not lvm.isLockingTypeClustering()):
                    description =  "The locking_type is not set to type 3 for built-in cluster locking. A GFS/GFS2 filesystem requires the filesystem be on a "
                    description += "clustered LVM volume with locking_type 3 enabled in the /etc/lvm/lvm.conf."
                    urls = ["https://access.redhat.com/solutions/46637"]
                    clusterNodeEvalString += StringUtil.formatBulletString(description, urls)

            # Disabling this check for now cause still working on how to do it.
            """
            # Verify that the clustered filesystem has clusterbit set on the vg.
            # Verify the locking_type is set to 3 cause built-in cluster locking is required.
            fsTable = []
            if (len(listOfClusterStorageFilesystems) > 0):
                devicemapperCommandsMap =  self.__cnc.getStorageData(clusternode.getClusterNodeName()).getDMCommandsMap()
                lvm = LVM(DeviceMapperParser.parseVGSVData(devicemapperCommandsMap.get("vgs_-v")),
                          DeviceMapperParser.parseLVSAODevicesData(devicemapperCommandsMap.get("lvs_-a_-o_devices")),
                          self.__cnc.getStorageData(clusternode.getClusterNodeName()).getLVMConfData())
                for csFilesystem in listOfClusterStorageFilesystems:
                   pathToDevice = str(csFilesystem.getDeviceName().strip().rstrip())
                   if (not lvm.isClusteredLVMDevice(pathToDevice)):
                       currentFS = [pathToDevice, csFilesystem.getMountPoint(), csFilesystem.getFSType()]
                       if (not currentFS in fsTable):
                           fsTable.append(currentFS)
            if (len(fsTable) > 0):
                stringUtil = StringUtil()
                description = "The following filesystems appears not to be on a clustered LVM volume. A clustered LVM volume is required for GFS/GFS2 fileystems."
                tableHeader = ["device_name", "mount_point", "fs_type"]
                tableOfStrings = stringUtil.toTableStringsList(fsTable, tableHeader)
                urls = ["https://access.redhat.com/solutions/46637"]
                clusterNodeEvalString += StringUtil.formatBulletString(description, urls, tableOfStrings)
            """
            # ###################################################################
            # Verify they are exporting a gfs/gfs2 fs via samba and nfs correctly
            # ###################################################################
            tableHeader = ["device_name", "mount_point", "nfs_mp", "smb_mp"]
            fsTable = []
            for csFilesystem in listOfClusterStorageFilesystems:
                # There are 4 ways of mounting gfs via nfs/smb at same time that
                # needs to be checked:

                # 1) nfs mount via /etc/exports  and smb mount via /etc/samba/smb.conf
                # 2) nfs mount via /etc/cluster/cluster.conf and smb mount via /etc/cluster/cluster.conf
                # 3) nfs mount via /etc/cluster/cluster.conf and smb mount via /etc/samba/smb.conf.
                # 4) nfs mount via /etc/exports and smb mount via /etc/cluster/cluster.conf
                if (csFilesystem.isEtcExportMount() and csFilesystem.isSMBSectionMount()):
                    # 1) nfs mount via /etc/exports  and smb mount via /etc/samba/smb.conf
                    #print "1: %s" %(csFilesystem.getMountPoint())
                    nfsMP = csFilesystem.getEtcExportMount().getMountPoint()
                    smbSectionList = csFilesystem.getSMBSectionMountList()
                    if (len(smbSectionList) > 0):
                        smbMP = smbSectionList.pop().getOptionValue("path").strip()
                        fsTable.append([csFilesystem.getDeviceName(), csFilesystem.getMountPoint(), "%s(EN)" %(nfsMP), "%s(ES)" %(smbMP)])
                        for smbSection in smbSectionList:
                            smbMP = smbSection.getOptionValue("path").strip()
                            fsTable.append(["", "", "", "%s(ES)" %(smbMP)])
                elif ((not csFilesystem.isEtcExportMount()) and (not csFilesystem.isSMBSectionMount())):
                    # 2) nfs mount via /etc/cluster/cluster.conf and smb mount via /etc/cluster/cluster.conf
                    #print "2: %s" %(csFilesystem.getMountPoint())
                    if((self.__isNFSChildOfClusterStorageResource(cca, csFilesystem)) and
                       (len(csFilesystem.getClusteredSMBNames()) > 0)):
                        nfsMP = csFilesystem.getMountPoint()
                        smbPaths = []
                        for name in csFilesystem.getClusteredSMBNames():
                            for smbSection in csFilesystem.getClusteredSMBSectionList(name):
                                currentPath = smbSection.getOptionValue("path").strip()
                                if (len(currentPath) > 0):
                                    smbPaths.append(currentPath)
                        if ((len(nfsMP) > 0) and (len(smbPaths) > 0)):
                            # Pop the first one off the list.
                            smbMP = smbPaths.pop()
                            fsTable.append([csFilesystem.getDeviceName(), csFilesystem.getMountPoint(), "%s(CN)" %(nfsMP), "%s(CS)" %(smbMP)])
                            # IF there any left add those with some blanks.
                            for smbMP in smbPaths:
                                fsTable.append(["", "", "", "%s(CS)" %(smbMP)])
                elif ((csFilesystem.isSMBSectionMount()) and (self.__isNFSChildOfClusterStorageResource(cca, csFilesystem))):
                    # 3) nfs mount via /etc/cluster/cluster.conf and smb mount via /etc/samba/smb.conf.
                    #print "3: %s" %(csFilesystem.getMountPoint())
                    nfsMP = csFilesystem.getMountPoint()
                    smbSectionList = csFilesystem.getSMBSectionMountList()
                    if (len(smbSectionList) > 0):
                        smbMP = smbSectionList.pop().getOptionValue("path").strip()
                        fsTable.append([csFilesystem.getDeviceName(), csFilesystem.getMountPoint(), "%s(CN)" %(nfsMP), "%s(ES)" %(smbMP)])
                        for smbSection in smbSectionList:
                            smbMP = smbSection.getOptionValue("path").strip()
                            fsTable.append(["", "", "", "%s(ES)" %(smbMP)])
                elif ((csFilesystem.isEtcExportMount()) and (len(csFilesystem.getClusteredSMBNames()) > 0)):
                    # 4) nfs mount via /etc/exports and smb mount via /etc/cluster/cluster.conf
                    # print "4: %s" %(csFilesystem.getMountPoint())
                    smbSectionList = []
                    for name in csFilesystem.getClusteredSMBNames():
                        smbSectionList += csFilesystem.getClusteredSMBSectionList(name)
                    if (len(smbSectionList) > 0):
                        smbMP = smbSectionList.pop().getOptionValue("path").strip()
                        fsTable.append([csFilesystem.getDeviceName(), csFilesystem.getMountPoint(), "%s(EN)" %(nfsMP), "%s(CS)" %(smbMP)])
                        for smbSection in smbSectionList:
                            smbMP = smbSection.getOptionValue("path").strip()
                            fsTable.append(["", "", "", "%s(CS)" %(smbMP)])
            # Write the table if it is not empty.
            if (len(fsTable) > 0):
                description =  "The following GFS/GFS2 filesystem(s) are being exported by NFS and SMB(samba) which is unsupported. "
                description += "The mount point(s) that were found will be noted with these symbols below:                          "
                description += "nfs export via /etc/exports (EN)                                                                    "
                description += "nfs export via /etc/cluster/cluster.conf (CN)                                                       "
                description += "samba export via /etc/exports for samba (ES)                                                        "
                description += "samba export via /etc/cluster/cluster.conf for samba (CS)"
                urls = ["https://access.redhat.com/solutions/39855"]
                tableOfStrings = stringUtil.toTableStringsList(fsTable, tableHeader)
                clusterNodeEvalString += StringUtil.formatBulletString(description, urls, tableOfStrings)

            # ###################################################################
            # Check for localflocks if they are exporting nfs.
            # ###################################################################
            fsTable = []
            for csFilesystem in listOfClusterStorageFilesystems:
                # If a GFS or GFS2 fs is in /etc/exports or has a child that is
                # nfsexport then localflocks required.
                if ((csFilesystem.isEtcExportMount()) or (self.__isNFSChildOfClusterStorageResource(cca, csFilesystem))):
                    csFilesystemOptions = csFilesystem.getAllMountOptions()
                    if (not csFilesystemOptions.find("localflocks") >= 0):
                        fsTable.append([csFilesystem.getDeviceName(), csFilesystem.getMountPoint()])
            # Write the table if it is not empty.
            if (len(fsTable) > 0):
                tableHeader = ["device_name", "mount_point"]
                description = "Any GFS/GFS2 filesystem that is exported with NFS should have the option \"localflocks\" set."
                description += "The following GFS/GFS2 filesystem do not have the option set."
                tableOfStrings = stringUtil.toTableStringsList(fsTable, tableHeader)
                urls = ["https://access.redhat.com/solutions/20327", "http://docs.redhat.com/docs/en-US/Red_Hat_Enterprise_Linux/5/html-single/Configuration_Example_-_NFS_Over_GFS/index.html#locking_considerations"]
                clusterNodeEvalString += StringUtil.formatBulletString(description, urls, tableOfStrings)

            # ###################################################################
            # Check to see if the GFS/GFS2 fs has certain mount options enabled.
            # ###################################################################
            fsTable = []
            for csFilesystem in listOfClusterStorageFilesystems:
                csFilesystemOptions = csFilesystem.getAllMountOptions()
                if (not csFilesystemOptions.find("noatime") >= 0):
                    fsTable.append([csFilesystem.getDeviceName(), csFilesystem.getMountPoint()])
            if (len(fsTable) > 0):
                # Verified that noatime implies nodiratime, so nodiratime check
                # does not need to be done.
                description =  "There were GFS/GFS2 file-systems that did not have the mount option \"noatime\"(no \"nodiratime\" is implied. "
                description += "when noatime is set) enabled. Unless atime support is essential, Red Hat recommends setting the mount option "
                description += "\"noatime\" on every GFS/GFS2 mount point. This will significantly improve performance since it prevents "
                description += "reads from turning into writes because the access time attribute will not be updated."
                urls = ["https://access.redhat.com/articles/628093#slowdown_due_to_system_configuration_issues"]
                clusterNodeEvalString += StringUtil.formatBulletString(description, urls)

            # ###################################################################
            # Make sure GFS/GFS2 filesystems dont have fsck option enable
            # ###################################################################

            for csFilesystem in listOfClusterStorageFilesystems:
                if (csFilesystem.isEtcFstabMount()):
                    if (not csFilesystem.getEtcFstabMount().getFSFsck() == "0"):
                        description =  "There were GFS/GFS2 file-systems that had the fsck option enabled in the /etc/fstab file. This option "
                        description += "should be disabled(set value to 0) or corruption will occur eventually."
                        urls = ["https://access.redhat.com/solutions/766393"]
                        clusterNodeEvalString += StringUtil.formatBulletString(description, urls)

            # ###################################################################
            # Add to string with the hostname and header if needed.
            # ###################################################################
            if (len(clusterNodeEvalString) > 0):
                rString += "%s(Cluster Node ID: %s):\n%s\n\n" %(clusternode.getClusterNodeName(), clusternode.getClusterNodeID(), clusterNodeEvalString.rstrip())
        # Return the string
        if (len(rString) > 0):
            sectionHeader = "%s\nCluster Storage Configuration Known Issues\n%s" %(self.__seperator, self.__seperator)
            rString = "%s\n%s" %(sectionHeader, rString)
        return rString