1. 程式人生 > >使用pyqt寫了一個檢查大資料環境的gui

使用pyqt寫了一個檢查大資料環境的gui

背景:在xx公司上班,該公司有款超融合的產品,當前已經梳理出來在超融合平臺部署大資料軟體的最佳實踐,該指令碼主要是為了檢查當前部署的大資料環境是否符合最佳實踐的部署

使用方法:輸入超融合的主控的ip地址和密碼,輸入ambari節點的主控和密碼,然後上傳大資料虛擬機器的vmid資訊,點選檢查即可觸發檢查

 

from PyQt5.QtWidgets import QApplication
from PyQt5.QtWidgets import QMainWindow
from PyQt5.QtWidgets import QWidget
from PyQt5.QtWidgets import QMessageBox
from PyQt5.QtGui import QIcon
from PyQt5.QtWidgets import QToolTip
from PyQt5.QtGui import QFont
from PyQt5.QtWidgets import QPushButton
from PyQt5.QtCore import QCoreApplication

from PyQt5.QtWidgets import QHBoxLayout
from PyQt5.QtWidgets import QVBoxLayout

from PyQt5.QtWidgets import QLineEdit
from PyQt5.QtWidgets import QTextEdit
from PyQt5.QtWidgets import QLabel

from PyQt5.QtWidgets import QGridLayout
import sys
from PyQt5.QtWidgets import QProgressBar
from PyQt5.QtWidgets import QMainWindow
from PyQt5.QtWidgets import QFileDialog
from PyQt5 import QtGui
import paramiko
import re
import json
from sshtunnel import SSHTunnelForwarder
import socket
import configparser
class check_hadoop_vm(QWidget):
    def __init__(self):
        super().__init__()
        self.initUI()

    def initUI(self):
        self.error_info = {"主機檢查之記憶體檢查":{},
                           "主機檢查之vxlan檢查":{},
                           "主機檢查之Cpu核心數檢查":{},
                           "主機檢查之Cpu型號檢查":{},
                           "主機檢查之Cpu型別檢查":{},
                           "主機檢查之numa檢查":{}}
        self.error_info_vm = {"虛擬機器檢查之記憶體大小檢查":{},
                              "虛擬機器檢查之記憶體配置檢查":{},
                              "虛擬機器檢查之Cpu個數檢查":{},
                              "虛擬機器檢查之Cpu配置檢查":{},
                              "虛擬機器檢查之重要虛擬機器配置檢查":{},
                              "虛擬機器檢查之記憶體回收配置檢查":{},
                              "虛擬機器檢查之FastIO磁碟檢查":{},
                              "虛擬機器檢查之裸盤檢查":{},
                              "虛擬機器檢查之透明大頁檢查":{}
                              }
        self.valid_cputype = ["2630","2650","2680"]
        self.config_list = []
        self.mn_list = []
        self.dn_list = []
        self.host_list = []
        self.vm_ip_list = []
        self.resize(400, 180)
        self.hostip = QLabel("*acloud地址:")
        self.hostpwd = QLabel("*acloud密碼:")
        self.vmip = QLabel("*ambari地址:")
        self.vmpwd = QLabel("*ambari密碼:")
        # self.output = QLabel("上傳配置檔案:")

        self.btn_chooseFile = QPushButton(self)
        self.btn_chooseFile.setObjectName("btn_chooseFile")
        self.btn_chooseFile.setText("上傳配置檔案")
        s = """
        該檔案需要輸入所有大資料虛擬機器的vmid資訊,格式如下:{"mn":["mn1_vmid","mn2_vmid",....],"dn":["dn1_vmid","dn2_vmid,dn3_vmid",....]}
        """
        self.btn_chooseFile.setToolTip(s)


        self.hostipedit = QLineEdit()
        self.hostpwdedit = QLineEdit()
        self.hostpwdedit.setEchoMode(QLineEdit.Password)
        self.vmipedit = QLineEdit()
        self.vmpwdedit = QLineEdit()
        self.vmpwdedit.setEchoMode(QLineEdit.Password)
        # self.outputedit =  QLineEdit()

        self.grid = QGridLayout()
        # 建立單元格之間的距離
        self.grid.setSpacing(0)
        # 新增到第二行的第一列
        self.grid.addWidget(self.hostip, 1, 0)
        # 新增到第二行的第二列
        self.grid.addWidget(self.hostipedit,1,1)
        # 新增到第三行第一列
        self.grid.addWidget(self.hostpwd, 2, 0)
        # 新增到第三行第二列
        self.grid.addWidget(self.hostpwdedit,2,1)
        self.grid.addWidget(self.vmip,3,0)
        self.grid.addWidget(self.vmipedit,3,1)
        self.grid.addWidget(self.vmpwd,4,0)
        self.grid.addWidget(self.vmpwdedit,4,1)
        # self.grid.addWidget(self.output, 5, 0)

        self.grid.addWidget(self.btn_chooseFile,6,0)

        self.checkbtn = QPushButton("開始檢查")
        self.grid.addWidget(self.checkbtn,6,2)

        self.checkbtn.clicked[bool].connect(self.check)
        self.btn_chooseFile.clicked.connect(self.slot_btn_chooseFile)
        self.setLayout(self.grid)
        self.icon = QtGui.QIcon()
        self.icon.addPixmap(QtGui.QPixmap("title.jpg"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
        self.setWindowTitle("大傻逼大資料環境檢查工具")
        # self.setWindowIcon(QIcon("title.jpg"))
        self.setWindowIcon(self.icon)
        self.center()
   
    def center(self):
        desktop = app.desktop()
        # print(dir(desktop))

        # 獲取整個螢幕的高度
        print(desktop.height())

        # 獲取整個螢幕的寬度
        print(desktop.width())

        # 獲取視窗的寬度
        print(self.width())

        # 獲取視窗的高度
        print(self.height())
        self.move((desktop.width() - self.width()) / 2, (desktop.height() - self.height()) / 2)

    def slot_btn_chooseFile(self):
        try:
            fileName_choose, filetype = QFileDialog.getOpenFileName(self,
                                                                    "選取檔案",
                                                                    self.cwd,  # 起始路徑
                                                                    "All Files (*);;Text Files (*.txt)")

            if bool(fileName_choose) is True:
                with open(fileName_choose,"r",encoding="utf-8") as f:
                    # for line in f:
                    s = json.loads(f.read())
                    self.mn_list = s["mn"]
                    self.dn_list = s["dn"]
            else:
                pass
        except Exception as e:
            reply = QMessageBox.question(self, "上傳檔案格式錯誤", """該檔案需要輸入所有大資料虛擬機器的vmid資訊,格式如下:{"mn":["mn1_vmid","mn2_vmid",....],"dn":["dn1_vmid","dn2_vmid,dn3_vmid",....]}""", QMessageBox.Yes)

    def closeEvent(self, event):
        # 顯示詢問的對話方塊,這裡會阻塞

        # 顯示兩個框,一個是YES 一個NO,預設選中no
        reply = QMessageBox.question(self, "訊息", "確定要退出?", QMessageBox.Yes | QMessageBox.No, QMessageBox.No)

        if reply == QMessageBox.Yes:

            # 接受事件
            event.accept()
        else:
            # 忽略事件
            event.ignore()

    def check(self,presssed):
        hostip = self.hostipedit.text()
        hostpwd = self.hostpwdedit.text()
        vmip = self.vmipedit.text()
        vmpwd = self.vmpwdedit.text()
        if bool(hostip) is False:
            reply = QMessageBox.question(self, "錯誤", "acloud地址不允許為空,請重新輸入", QMessageBox.Yes)
        elif bool(hostpwd) is False:
            reply = QMessageBox.question(self, "錯誤", "acloud密碼不允許為空,請重新輸入", QMessageBox.Yes)
        elif bool(vmip) is False:
            reply = QMessageBox.question(self, "錯誤", "ambari地址不允許為空,請重新輸入", QMessageBox.Yes)
        elif bool(vmpwd) is False:
            reply = QMessageBox.question(self, "錯誤", "ambari密碼不允許為空,請重新輸入", QMessageBox.Yes)
        else:
            self.config_list.append(hostip)
            self.config_list.append(hostpwd)
            self.config_list.append(vmip)
            self.config_list.append(vmpwd)


            print("開始檢查",self.config_list)
            self.check_host_config()
            self.check_mn_config()
            self.check_dn_config()
            self.check_vm_config()
            self.output_error_file()


 def output_error_file(self):
        import configparser
        import os
        import time
        config = configparser.ConfigParser()
        output_file =os.getcwd() + "\\" + "大傻逼大資料環境檢查_" + time.strftime("%Y-%h-%d_%H-%M-%S") + "." + "ini"
        self.error_info.update(self.error_info_vm)
        for k, v in self.error_info.items():
            config[k] = v

        config.write(open(output_file, "w"))
        reply = QMessageBox.question(self, "檢查成功", "檢查結果見{file},請自行查閱".format(file=output_file), QMessageBox.Yes)

   def check_mn_config(self):
        for vmid in self.mn_list:
            ssh = paramiko.SSHClient()
            # 允許連線不在know_hosts檔案中的主機
            ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())

            # 通過使用者名稱和密碼去連線伺服器
            ssh.connect(hostname=self.config_list[0], port=22, username="root",
                        password="{pwd}sangfornetwork".format(pwd=self.config_list[1]))

            # 獲取虛擬機器的名稱
            stdin, stdout, stderr = ssh.exec_command(
                """cat `find /cfs -name "{vmid}.conf"` |grep -w name |cut -d ":" -f 2""".format(vmid=vmid))

            vm_name = stdout.read().decode().strip(" ").strip("\n")
            print("虛擬機器名稱為",vm_name)
            # 檢查mn節點的記憶體大小
            stdin, stdout, stderr = ssh.exec_command("""cat `find /cfs -name "{vmid}.conf"` |grep -w memory |cut -d ":" -f 2""".format(vmid=vmid))
            mem = stdout.read().decode().strip(" ").strip("\n")

            print("虛擬機器記憶體為",mem)
            if int(mem)//1024 >= 24:
                pass
            else:
                self.error_info_vm["虛擬機器檢查之記憶體大小檢查"][vm_name] = "虛擬機器{vm_name}為管理節點,當前記憶體為{mem},記憶體建議配置大於24G".format(vm_name=vm_name,mem=int(mem)//1024)

            # 檢查mn節點是否啟用大頁
            stdin, stdout, stderr = ssh.exec_command(
                """cat `find /cfs -name "{vmid}.conf"` |grep "hugepage" |cut -d ":" -f 2""".format(vmid=vmid))
            hug = stdout.read().decode().strip(" ").strip("\n")
            print("虛擬機器的大頁未",hug)
            if hug == "2":
                pass
            else:
                # print(hug)
                self.error_info_vm["虛擬機器檢查之記憶體配置檢查"][vm_name] = "虛擬機器{vm_name}未開啟大頁記憶體,建議編輯虛擬機器記憶體處勾選使用大頁記憶體".format(vm_name=vm_name)

            # 檢查mn節點的cpu個數

            stdin, stdout, stderr = ssh.exec_command(
                """cat `find /cfs -name "{vmid}.conf"` |grep sockets |cut -d ":" -f 2""".format(vmid=vmid))
            socket = stdout.read().decode().strip(" ").strip("\n")

            stdin, stdout, stderr = ssh.exec_command(
                """cat `find /cfs -name "{vmid}.conf"` |grep cores |cut -d ":" -f 2""".format(vmid=vmid))
            cores = stdout.read().decode().strip(" ").strip("\n")
            print("虛擬機器的cpu為",socket,cores)
            if int(socket) == 2 and int(cores) == 4:
                pass

            else:
                self.error_info_vm["虛擬機器檢查之Cpu個數檢查"][vm_name] = "虛擬機器的cpu建議配置為2*4"


            # 檢查mn節點的cpu配置
            stdin, stdout, stderr = ssh.exec_command(
                """cat `find /cfs -name "{vmid}.conf"` |grep cpu |cut -d ":" -f 2""".format(vmid=vmid))
            host = stdout.read().decode().strip(" ").strip("\n")

            stdin, stdout, stderr = ssh.exec_command(
                """cat `find /cfs -name "{vmid}.conf"` |grep numa |cut -d ":" -f 2""".format(vmid=vmid))
            numa = stdout.read().decode().strip(" ").strip("\n")
            print("虛擬機器的cpu配置為",host,numa)
            if host == "host" and numa == "1":
                pass
            elif host != "host" and numa == "1":
                self.error_info_vm["虛擬機器檢查之Cpu配置檢查"][vm_name] = "虛擬機器{vmname}未使用Host cpu設定,建議開啟".format(vmname=vm_name)

            elif host == "host" and numa != "1":
                self.error_info_vm["虛擬機器檢查之Cpu配置檢查"][vm_name] = "虛擬機器{vmname}未啟用使用NUMA排程,建議開啟".format(vmname=vm_name)
            else:
                self.error_info_vm["虛擬機器檢查之Cpu配置檢查"][vm_name] = "虛擬機器{vmname}未啟用使用NUMA排程和Host cpu設定,建議開啟".format(vmname=vm_name)




 # 重要虛擬機器檢查
            stdin, stdout, stderr = ssh.exec_command(
                """cat `find /cfs -name "{vmid}.conf"` |grep schedopt |cut -d ":" -f 2""".format(vmid=vmid))
            schedopt = stdout.read().decode().strip(" ").strip("\n")
            print("重要虛擬機器配置為",schedopt)
            if schedopt == "0":
                pass
            else:
                self.error_info_vm["虛擬機器檢查之重要虛擬機器配置檢查"][vm_name] = "虛擬機器{vmname}未啟用重要虛擬機器選項,建議開啟".format(vmname = vm_name)

            # 記憶體回收檢查
            stdin, stdout, stderr = ssh.exec_command(
                """cat `find /cfs -name "{vmid}.conf"` |grep balloon_memory |cut -d ":" -f 2""".format(vmid=vmid))
            balloon_memory = stdout.read().decode().strip(" ").strip("\n")
            print("虛擬機器的記憶體回收為",balloon_memory)

            if balloon_memory == "1":
                pass
            else:
                self.error_info_vm["虛擬機器檢查之記憶體回收配置檢查"][vm_name] = "虛擬機器{vmname}啟用記憶體回收選項,建議關閉".format(vmname = vm_name)

            # fastio磁碟檢查
            stdin, stdout, stderr = ssh.exec_command(
                """cat `find /cfs -name "{vmid}.conf"` |grep -w use_vblk |cut -d ":" -f 2""".format(vmid=vmid))
            use_vblk = stdout.read().decode().strip(" ").strip("\n")
            print("虛擬機器的磁碟為",use_vblk)
            if use_vblk == "no":
                pass
            else:
                self.error_info_vm["虛擬機器檢查之FastIO磁碟檢查"][vm_name] = "虛擬機器{vmname}未啟用Fast IO磁碟,建議關閉".format(vmname=vm_name)


        print(self.error_info_vm)
        print("mn節點檢查完成")

    def check_dn_config(self):
        print(self.config_list)
        for vmid in self.dn_list:
            ssh = paramiko.SSHClient()
            # 允許連線不在know_hosts檔案中的主機
            ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())

            # 通過使用者名稱和密碼去連線伺服器
            ssh.connect(hostname=self.config_list[0], port=22, username="root",
                        password="{pwd}sangfornetwork".format(pwd=self.config_list[1]))

            # 獲取虛擬機器的名稱
            stdin, stdout, stderr = ssh.exec_command(
                """cat `find /cfs -name "{vmid}.conf"` |grep -w name |cut -d ":" -f 2""".format(vmid=vmid))

            vm_name = stdout.read().decode().strip(" ").strip("\n")
            print("虛擬機器的名稱為",vm_name)
            # 檢查mn節點的記憶體大小
            stdin, stdout, stderr = ssh.exec_command("""cat `find /cfs -name "{vmid}.conf"` |grep -w memory |cut -d ":" -f 2""".format(vmid=vmid))
            mem = stdout.read().decode().strip(" ").strip("\n")
            print("虛擬機器記憶體", mem)
            if int(mem)//1024 >= 48:
                pass
            else:
                self.error_info_vm["虛擬機器檢查之記憶體大小檢查"][vm_name] = "虛擬機器{vm_name}為管理節點,當前記憶體為{mem},記憶體建議配置大於32G".format(vm_name=vm_name,mem=int(mem)//1024)

            # 檢查mn節點是否啟用大頁
            stdin, stdout, stderr = ssh.exec_command(
                """cat `find /cfs -name "{vmid}.conf"` |grep "hugepage" |cut -d ":" -f 2""".format(vmid=vmid))
            hug = stdout.read().decode().strip(" ").strip("\n")
            if hug == "1":
                pass
            else:
                print(hug)
                self.error_info_vm["虛擬機器檢查之記憶體配置檢查"][vm_name] = "虛擬機器{vm_name}未開啟大頁記憶體,建議編輯虛擬機器記憶體處勾選使用大頁記憶體".format(vm_name=vm_name)
            print("虛擬機器的大頁", hug)
            # 檢查mn節點的cpu個數
            stdin, stdout, stderr = ssh.exec_command(
                """cat `find /cfs -name "{vmid}.conf"` |grep sockets |cut -d ":" -f 2""".format(vmid=vmid))
            socket = stdout.read().decode().strip(" ").strip("\n")
            stdin, stdout, stderr = ssh.exec_command(
                """cat `find /cfs -name "{vmid}.conf"` |grep cores |cut -d ":" -f 2""".format(vmid=vmid))
            cores = stdout.read().decode().strip(" ").strip("\n")

            if int(socket) == 2 and int(cores) == 8:
                pass

            else:
                self.error_info_vm["虛擬機器檢查之Cpu個數檢查"][vm_name] = "虛擬機器的cpu建議配置為2*4"

            print("虛擬機器的cpu為",socket,cores)
            # 檢查mn節點的cpu配置
            stdin, stdout, stderr = ssh.exec_command(
                """cat `find /cfs -name "{vmid}.conf"` |grep cpu |cut -d ":" -f 2""".format(vmid=vmid))
            host = stdout.read().decode().strip(" ").strip("\n")

            stdin, stdout, stderr = ssh.exec_command(
                """cat `find /cfs -name "{vmid}.conf"` |grep numa |cut -d ":" -f 2""".format(vmid=vmid))
            numa = stdout.read().decode().strip(" ").strip("\n")
            if host == "host" and numa == "2":
                pass
            elif host != "host" and numa == "1":
                self.error_info_vm["虛擬機器檢查之Cpu配置檢查"][vm_name] = "虛擬機器{vmname}為使用Host cpu設定,建議開啟".format(vmname=vm_name)

            elif host == "host" and numa != "1":
                self.error_info_vm["虛擬機器檢查之Cpu配置檢查"][vm_name] = "虛擬機器{vmname}為啟用使用NUMA排程,建議開啟".format(vmname=vm_name)

            else:
                self.error_info_vm["虛擬機器檢查之Cpu配置檢查"][vm_name] = "虛擬機器{vmname}為啟用使用NUMA排程和Host cpu設定,建議開啟".format(vmname=vm_name)

            print("虛擬機器的cpu為未",host,numa)
            # 重要虛擬機器檢查
            stdin, stdout, stderr = ssh.exec_command(
                """cat `find /cfs -name "{vmid}.conf"` |grep schedopt |cut -d ":" -f 2""".format(vmid=vmid))
            schedopt = stdout.read().decode().strip(" ").strip("\n")
            if schedopt == "2":
                pass

            else:
                self.error_info_vm["虛擬機器檢查之重要虛擬機器配置檢查"][vm_name] = "虛擬機器{vmname}未啟用重要虛擬機器選項,建議開啟".format(vmname = vm_name)

            print("虛擬機器的重要配置為",schedopt)
            # 記憶體回收檢查

            stdin, stdout, stderr = ssh.exec_command(
                """cat `find /cfs -name "{vmid}.conf"` |grep balloon_memory |cut -d ":" -f 2""".format(vmid=vmid))
            balloon_memory = stdout.read().decode().strip(" ").strip("\n")
            if balloon_memory == "1":
                pass
            else:
                self.error_info_vm["虛擬機器檢查之記憶體回收配置檢查"][vm_name] = "虛擬機器{vmname}啟用記憶體回收選項,建議關閉".format(vmname = vm_name)

            # fastio磁碟檢查

            print("虛擬機器的汽包記憶體為",balloon_memory)
            stdin, stdout, stderr = ssh.exec_command(
                """cat `find /cfs -name "{vmid}.conf"` |grep -w use_vblk |cut -d ":" -f 2""".format(vmid=vmid))
            use_vblk = stdout.read().decode().strip(" ").strip("\n")
            if use_vblk == "yes":
                pass
            else:
                self.error_info_vm["虛擬機器檢查之FastIO磁碟檢查"][vm_name] = "虛擬機器{vmname}未啟用Fast IO磁碟,建議關閉".format(vmname=vm_name)
            print("虛擬機器的裸盤配置為", use_vblk)
            # 虛擬機器裸盤檢查
            stdin, stdout, stderr = ssh.exec_command(
                """cat `find /cfs -name "{vmid}.conf"` |grep scsi[0-9]: |wc -l""".format(vmid=vmid))
            use_vblk = int(stdout.read().decode().strip(" ").strip("\n"))
            if use_vblk >= 1 and use_vblk <=3:
                pass
            elif use_vblk == 0:
                self.error_info_vm["虛擬機器檢查之裸盤檢查"][vm_name] = "虛擬機器{vmname}未使用裸盤,建議使用裸盤跑大資料業務".format(vmname=vm_name)
            else:
                self.error_info_vm["虛擬機器檢查之裸盤檢查"][vm_name] = "虛擬機器{vmname}掛載超過3個裸盤,建議一個虛擬機器掛載低於3個裸盤".format(vmname=vm_name)

            print("虛擬機器的裸盤個數", use_vblk)


            # 虛擬機器裸盤個數檢查
        print(self.error_info_vm)
        print("dn檢查完成")

  def check_host_config(self):
        ssh = paramiko.SSHClient()
        # 允許連線不在know_hosts檔案中的主機
        ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())


        # 通過使用者名稱和密碼去連線伺服器
        ssh.connect(hostname=self.config_list[0], port=22, username="root", password="{pwd}sangfornetwork".format(pwd=self.config_list[1]))

        # 先獲取叢集中所有主機的ip地址
        stdin, stdout, stderr = ssh.exec_command("cat /cfs/.members")

        d = json.loads(stdout.read().decode(), encoding="utf-8")
        for i in d["nodelist"].values():
            self.host_list.append(i["ip"])

        for host in self.host_list:

            # 檢查主機的記憶體
            ssh.connect(hostname=host, port=22, username="root",
                        password="{pwd}sangfornetwork".format(pwd=self.config_list[1]))
            stdin, stdout, stderr = ssh.exec_command("cat /proc/meminfo |grep MemTotal")

            res = stdout.read().decode()
            r = re.findall("\d+",res)

            g = int(r[0]) // 1024 // 1024
            if g >= 150:
                continue
            else:
                self.error_info["主機檢查之記憶體檢查"][host] = "主機{host}記憶體為{mem},不適合跑大資料場景,如該節點不跑大資料虛擬機器,可忽略".format(mem = g,host =  host)


            # vxlan的檢查
            stdin, stdout, stderr = ssh.exec_command(
                """ethtool `cat /sf/cfg/if.d/comif.ini |grep ifname | cut -d "=" -f 2` |grep Speed""")

            speed = int(re.findall("\d+",stdout.read().decode())[0])
            if speed == 100000:
                continue
            else:
                self.error_info["主機檢查之vxlan檢查"][host] = "主機{host}的vxlan口建議使用萬兆網絡卡".format(host=host)

            # 主機cpu核心數檢查
            stdin, stdout, stderr = ssh.exec_command(
                """cat /proc/cpuinfo |grep "physical id" |cut -d ":" -f 2 |sort -u |wc -l""")
            if int(stdout.read().decode()) >= 3:
                pass
            else:
                self.error_info["主機檢查之Cpu核心數檢查"][host] = "主機{host}的cpu非標配核數,請檢查".format(host=host)

            # 主機cpu的型號檢查
            stdin, stdout, stderr = ssh.exec_command(
                """cat /proc/cpuinfo |grep "model name" |uniq |cut -d ":" -f 2 |cut -d " " -f 5 |cut -d "-" -f 2""")
            s = stdout.read().decode()
            if s in self.valid_cputype:
                pass
            else:
                self.error_info["主機檢查之Cpu型號檢查"][host] = "主機{host}的cpu的型別為{type}非標配型別,請檢查".format(host=host,type=s.strip("\n"))

            # 主機cpu的型別檢查
            stdin, stdout, stderr = ssh.exec_command(
                """cat /proc/cpuinfo |grep "model name" |uniq |cut -d ":" -f 2 |cut -d " " -f 6""")
            s = stdout.read().decode()
            if s == "v4":
                pass

            else:
                self.error_info["主機檢查之Cpu型別檢查"][host] = "主機{host}的cpu型別為{type},非v4 cpu,請檢查".format(host=host,type=s.strip("\n"))


        # 叢集numa檢查
        ssh.connect(hostname=self.config_list[0], port=22, username="root",
                    password="{pwd}sangfornetwork".format(pwd=self.config_list[1]))

        stdin, stdout, stderr = ssh.exec_command("cat /cfs/system_config.ini |grep if_numa_on")
        res = stdout.read().decode()
        print(res)
        res = re.findall("\d+", res)
        if res[0] == "2":
            pass
        else:
            self.error_info["主機檢查之numa檢查"][self.config_list[0]] = "請在【管理】--【高可用(HA)與資源排程配置】--【系統引數】中開啟NUMA排程"
        print(self.error_info)
        print("host配置檢查完成")
  def check_vm_config(self):
        print("虛擬機器內部配置檢查")
        # 獲取所有節點的ip地址
        ssh = paramiko.SSHClient()
        # 允許連線不在know_hosts檔案中的主機
        ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
        ssh.connect(hostname=self.config_list[2], port=22, username="root",password=self.config_list[3])

        stdin, stdout, stderr = ssh.exec_command("""cat /etc/hosts |grep -v '#'""")
        res = stdout.read().decode().strip(" ").strip("\n")
        l = res.split("\n")
        print(l)
        for i in l:
            self.vm_ip_list.append(i.split(" ")[0])


        # 獲取本機的ip地址
        localip = socket.gethostbyname(socket.gethostname())
        # 檢查每個節點的透明大頁是否關閉
        re_obj = re.compile("\[.*\]")
        for dn in self.vm_ip_list:

            with SSHTunnelForwarder(
                    ssh_address_or_host=(self.config_list[2], 22),
                    ssh_username="root",
                    ssh_password=self.config_list[3],
                    remote_bind_address=(dn, 22),
                    local_bind_address=(localip, 50002)
            ) as server:
                client = paramiko.SSHClient()
                client.load_system_host_keys()
                client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
                client.connect(localip, 50002, username="root", password=self.config_list[3])

                stdin, stdout, stderr = client.exec_command("cat /sys/kernel/mm/transparent_hugepage/defrag")
                s = stdout.read().decode()
                defrag_state = re.findall(re_obj, s)[0]


                stdin, stdout, stderr = client.exec_command("cat /sys/kernel/mm/transparent_hugepage/enabled")
                s = stdout.read().decode()
                enabled_state = re.findall(re_obj, s)[0]

                if defrag_state == "never" and enabled_state == "never":
                    pass
                elif defrag_state != "never" and enabled_state == "never":
                    self.error_info_vm["虛擬機器檢查之透明大頁檢查"][dn] = "虛擬機器{vmip}的defrag未關閉透明大頁,請修改/sys/kernel/mm/transparent_hugepage/defrag中的欄位為never,如果該節點為ambari節點,可忽略".format(vmip=dn)
                elif defrag_state == "never" and enabled_state != "never":
                    self.error_info_vm["虛擬機器檢查之透明大頁檢查"][dn] = "虛擬機器{vmip}的enable未關閉透明大頁,請修改/sys/kernel/mm/transparent_hugepage/enable中的欄位為never,如果該節點為ambari節點,可忽略".format(vmip=dn)
                else:
                    self.error_info_vm["虛擬機器檢查之透明大頁檢查"][dn] = "虛擬機器{vmip}的defrag和enable未關閉透明大頁,請修改/sys/kernel/mm/transparent_hugepage/enable和/sys/kernel/mm/transparent_hugepage/enable中的欄位為never,如果該節點為ambari節點,可忽略".format(vmip=dn)
                client.close()

if __name__ == '__main__':
    app = QApplication(sys.argv)
    cw = check_hadoop_vm()
    sys.exit(app.exec_())
    sys.exit(app.exec_())