通过pyqt做了一个大数据最佳实践检查的gui界面

1、首先是需要用到的模块

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

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
import sys
from sshtunnel import SSHTunnelForwarder
import socket
import configparser
import os
import time

  

 

2、定义了一个类

class check_hadoop_vm(QWidget):

  

3、重写父类的init方法

    def __init__(self):
        super().__init__()
        self.initUI()

  

4、定义自己的初始化的方法

 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, 200)
        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.uploadfile = QLineEdit()
        # 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.grid.addWidget(self.uploadfile,6,1)

        self.checkbtn = QPushButton("开始检查")
        self.grid.addWidget(self.checkbtn,7,2)
        self.pbar = QProgressBar(self)
        self.grid.addWidget(self.pbar,7,1)

        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(self.icon)
        self.center()
        self.show()
        import os
        self.cwd = os.getcwd()

  

5、定义GUI居中的方法

 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)

  

6、定义上传按钮触发的函数

    def slot_btn_chooseFile(self):
        self.uploadfile.setText("")
        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"]
                self.uploadfile.setText(fileName_choose)
            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)

  

7、定义一个关闭窗口,点击关闭按钮弹出确认框

    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()

  

8、定义一个检查函数,这个函数会对输入框做合法性的判断,和调用其他的检查虚拟机,检查主机的函数

  

 def check(self,presssed):
        pat = "^(([1-2][0-5][0-5])|([1-9][0-9])|([1-9]))\.(([1-2][0-5][0-5])|([1-9][0-9])|([1-9]))\.(([1-2][0-5][0-5])|([1-9][0-9])|([1-9]))\.(([1-2][0-5][0-5])|([1-9][0-9])|([1-9]))$"
        re_com = re.compile(pat)
        hostip = self.hostipedit.text()
        hostpwd = self.hostpwdedit.text()
        vmip = self.vmipedit.text()
        vmpwd = self.vmpwdedit.text()
        vmid_file = self.uploadfile.text()
        print(hostip,"hostIP地址")
        print(vmip,"vmIP地址")
        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)

        elif bool(vmid_file) is False:
            reply = QMessageBox.question(self, "错误", "配置文件必须上传,请上传文件后再执行检查操作", QMessageBox.Yes)

        else:
            ret_host = re_com.match(hostip)
            ret_vm = re_com.match(vmip)
            print(ret_host,"校验hostip")
            print(ret_vm,"校验vmip")
            if bool(ret_host) and bool(ret_vm):
                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.pbar.setValue(10)
                self.check_host_config()
                self.check_mn_config()
                self.check_dn_config()
                self.check_vm_config()
                self.output_error_file()
            elif bool(ret_host) is False:
                reply = QMessageBox.question(self, "错误", "acloud的{ip}不是一个正常的ip地址,请输入正常的ip地址".format(ip=hostip),
                                             QMessageBox.Yes)
            else:
                reply = QMessageBox.question(self, "错误", "ambari的{ip}不是一个正常的ip地址,请输入正常的ip地址".format(ip=vmip),
                                             QMessageBox.Yes)

  

9、定义一个持久化输出报告的函数

   def output_error_file(self):
        config = configparser.ConfigParser()
        import time
        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"),space_around_delimiters=4)

        import time
        time.sleep(1)

        reply = QMessageBox.question(self, "检查成功","检查结果:\n{file}".format(file=output_file), QMessageBox.Yes)
        self.pbar.setValue(100)

  

10、定义一个检查mn节点的函数

    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}G,内存建议配置大于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)

            # 系统盘预分配检查
            stdin, stdout, stderr = ssh.exec_command(
                """cat `find /cfs -name "{vmid}.conf"` |grep -w ide0: |cut -d "," -f 3 |cut -d "=" -f 2""".format(vmid=vmid))
            preallocate = stdout.read().decode().strip(" ").strip("\n")
            print("虚拟机的磁盘为", use_vblk)
            if preallocate == "full":
                pass
            else:
                self.error_info_vm["虚拟机检查之系统盘预分配检查"][vm_name] = "虚拟机{vmname}的系统盘未采用预分配格式,建议开启".format(vmname=vm_name)
        print(self.error_info_vm)
        print("mn节点检查完成")
        self.pbar.setValue(20)

  

11、定义一个检查dn的函数

  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}G,内存建议配置大于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)

            # 系统盘预分配检查
            stdin, stdout, stderr = ssh.exec_command(
                """cat `find /cfs -name "{vmid}.conf"` |grep -w ide0: |cut -d "," -f 3 |cut -d "=" -f 2""".format(
                    vmid=vmid))
            preallocate = stdout.read().decode().strip(" ").strip("\n")
            print("虚拟机的磁盘为", use_vblk)
            if preallocate == "full":
                pass
            else:
                self.error_info_vm["虚拟机检查之系统盘预分配检查"][vm_name] = "虚拟机{vmname}的系统盘未采用预分配格式,建议开启".format(vmname=vm_name)
        print(self.error_info_vm)
        print("dn检查完成")
        self.pbar.setValue(40)

  

12、定义一个检查主机配置的函数

 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}G,不适合跑大数据场景,如该节点不跑大数据虚拟机,可忽略".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口为{speed}口,建议使用万兆网卡".format(host=host,speed=speed)

            # 主机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的核数为{socket}非标配核数,请检查".format(host=host,socket=int(stdout.read().decode()))

            # 主机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配置检查完成")

  

13、定义一个检查虚拟机外部配置的函数

 def check_vm_config(self):
        try:
            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("\[.*\]")
            print(self.vm_ip_list)

            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]
                    print(dn,enabled_state,defrag_state)
                    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()
            self.pbar.setValue(80)
        except Exception as e:
            print(e)
            # reply = QMessageBox.question(self, "出错",str(e), QMessageBox.Yes)

  

14、启动整个脚本的代码

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

  

 

posted on 2018-11-22 20:36  bainianminguo  阅读(453)  评论(0编辑  收藏  举报