使用pyqt写了一个检查大数据环境的gui
通过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_())
使用pyqt写了一个检查大数据环境的gui的更多相关文章
- 有一个很大的整数list,需要求这个list中所有整数的和,写一个可以充分利用多核CPU的代码,来计算结果(转)
引用 前几天在网上看到一个淘宝的面试题:有一个很大的整数list,需要求这个list中所有整数的和,写一个可以充分利用多核CPU的代码,来计算结果.一:分析题目 从题中可以看到“很大的List”以及“ ...
- JS函数 编程练习 使用javascript代码写出一个函数:实现传入两个整数后弹出较大的整数。
编程练习 使用javascript代码写出一个函数:实现传入两个整数后弹出较大的整数. 任务 第一步: 编写代码完成一个函数的定义吧. 第二步: 我们来补充函数体中的控制语句,完成函数功能吧. 提示: ...
- python 写一个生成大乐透号码的程序
""" 写一个生成大乐透号码的程序 生成随机号码:大乐透分前区号码和后区号码, 前区号码是从01-35中无重复地取5个号码, 后区号码是从01-12中无重复地取2个号码, ...
- 写了一个hiero检查任务渲染结果的脚本
基本思路是写了一个时间判断函数(postSequence_check)来对比transcode任务提交时间和目标文件夹内文件的修改时间来确定渲染是否成功执行,然后通过Hiero提供的postSeque ...
- 独自handle一个数据库大程有感
这学期数据库课程,最后的大程是写一个MiniSQL的数据库实现,要求很简单,建删表,建删单值索引,支持主键和unique定义,支持最简单的select,只要支持3个类型:int,float,char( ...
- 闲来无事,用Java的软引用写了一个山寨的缓存
闲来无事,用Java的软引用写了一个山寨的缓存 博客分类: java基础 众所周知java中的引用分为 StrongReference.SoftReference.WeakReference.Phan ...
- XFS:大数据环境下Linux文件系统的未来?
XFS:大数据环境下Linux文件系统的未来? XFS开发者Dave Chinner近日声称,他认为更多的用户应当考虑XFS.XFS经常被认为是适合拥有海量数据的用户的文件系统,在空间分配方面的可 ...
- 使用Ambari快速部署Hadoop大数据环境
使用Ambari快速部署Hadoop大数据环境 发布于2013-5-24 前言 做大数据相关的后端开发工作一年多来,随着Hadoop社区的不断发展,也在不断尝试新的东西,本文着重来讲解下Amb ...
- python使用pyqt写带界面工具
上篇介绍的使用python自带tkinter包,来写带界面的工具. 此篇介绍使用pyqt来开发测试工具. tkinter的好处是python官方自带,上手容易(但手写控件复杂),布局和摆放都不直观和容 ...
随机推荐
- java序列化问题
今天无意中看到了 redistemplet封装的类中,出现了序列化的字眼 ,了解下序列化的知识 1.什么是序列化 我们把变量从内存中变成可存储或传输的过程称之为序列化,(java中一般是用来保 ...
- Oracle 学习总结 - 表和索引的性能优化
表的性能 表的性能取决于创建表之前所应用的数据库特性,数据库->表空间->表,创建数据库时确保为每个用户创建一个默认的永久表空间和临时表空间并使用本地管理,创建表空间设为本地管理并且自动段 ...
- ElasticSearch match, match_phrase, term区别
1.term结构化字段查询,匹配一个值,且输入的值不会被分词器分词. 比如查询条件是: { "query":{ "term":{ "foo" ...
- python 可迭代对象与迭代器
生成器函数的工作原理只要 Python 函数的定义体中有 yield 关键字, 该函数就是生成器函数. 调用生成器函数时, 会返回一个生成器对象. 也就是说, 生成器函数是生成器工厂. 调用生成器函数 ...
- while read line
# grep "请求报文:" application-20170822-*.log >> applog # cat applog|cut -d ":" ...
- Zabbix 3.0 LTS安装配置
关于Zabbix监控项类型的官网介绍: https://www.zabbix.com/documentation/3.4/zh/manual/config/items/itemtypes zabbix ...
- 21 week4 submit buidAndRun() node-rest-client
. 我们想实现一个提交代码的功能 这个功能有nodeserver 传到后边的server 验证 在返回给nodeserver 我们稍微修改一下ui ATOM修改文件权限不够 用下面命令 我们 Cont ...
- Logo tools
http://www.cilogo.com/LOGO/
- C++ vc中怎么使用SendMessage自定义消息函数
vc中怎么使用SendMessage自定义消息函数: SendMessage的基本结构如下:SendMessage( HWND hWnd, //消息传递的目标窗口或线程的句柄. UINT ...
- isPlainObject的解释
参考: http://www.365mini.com/page/jquery_isplainobject.htm 先来看下使用案例: //在当前页面内追加换行标签和指定的HTML内容 function ...