經過pyqt作了一個大數據最佳實踐檢查的gui界面node
一、首先是須要用到的模塊python
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
二、定義了一個類json
class check_hadoop_vm(QWidget):
三、重寫父類的init方法服務器
def __init__(self): super().__init__() self.initUI()
四、定義本身的初始化的方法app
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()
五、定義GUI居中的方法ssh
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)
六、定義上傳按鈕觸發的函數socket
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)
七、定義一個關閉窗口,點擊關閉按鈕彈出確認框ide
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): 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)
九、定義一個持久化輸出報告的函數工具
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)
十、定義一個檢查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)
十一、定義一個檢查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)
十二、定義一個檢查主機配置的函數
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配置檢查完成")
1三、定義一個檢查虛擬機外部配置的函數
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)
1四、啓動整個腳本的代碼
if __name__ == '__main__': app = QApplication(sys.argv) cw = check_hadoop_vm() sys.exit(app.exec_())