import libvirt
import tkinter as tk
import os
import subprocess
import xml.etree.ElementTree as ET
import uuid
import paramiko
def close_connection(): # 关闭连接
try:
conn.close()
except:
print("--关闭连接失败--")
return 1
print('--成功关闭连接--')
def list_connection(): # 主机信息
set = tk.Tk()
set.title('主机信息')
nodeinfo = conn.getInfo() # 获取虚拟化主机信息
labelNew = tk.Label(set, fg='#000000', font='Helvetica -18 bold', text="node1主机信息:")
labelNew.grid(row=0, column=0, padx=2, pady=6, sticky='W')
labelNew = tk.Label(set, fg='#000000', font='Helvetica -18 bold', text="模型: {}".format(str(nodeinfo[0])))
labelNew.grid(row=1, column=0, padx=2, pady=6, sticky='W')
labelNew = tk.Label(set, fg='#000000', font='Helvetica -18 bold', text="内存大小: {}MB".format(str(nodeinfo[1])))
labelNew.grid(row=2, column=0, padx=2, pady=6, sticky='W')
labelNew = tk.Label(set, fg='#000000', font='Helvetica -18 bold', text="CPU数量: {}".format(str(nodeinfo[2])))
labelNew.grid(row=3, column=0, padx=2, pady=6, sticky='W')
labelNew = tk.Label(set, fg='#000000', font='Helvetica -18 bold', text="虚拟类型: {}".format(conn.getType()))
labelNew.grid(row=4, column=0, padx=2, pady=6, sticky='W')
labelNew = tk.Label(set, fg='#000000', font='Helvetica -18 bold', text="连接URI: {}".format(conn.getURI()))
labelNew.grid(row=5, column=0, padx=2, pady=6, sticky='W')
labelNew = tk.Label(set, fg='#000000', font='Helvetica -18 bold', text="空闲内存: {}bytes".format(conn.getFreeMemory()))
labelNew.grid(row=6, column=0, padx=2, pady=6, sticky='W')
nodeinfo = conn1.getInfo()
labelNew = tk.Label(set, fg='#000000', font='Helvetica -18 bold', text="node2主机信息:")
labelNew.grid(row=0, column=1, padx=2, pady=6, sticky='W')
labelNew = tk.Label(set, fg='#000000', font='Helvetica -18 bold', text="模型: {}".format(str(nodeinfo[0])))
labelNew.grid(row=1, column=1, padx=2, pady=6, sticky='W')
labelNew = tk.Label(set, fg='#000000', font='Helvetica -18 bold', text="内存大小: {}MB".format(str(nodeinfo[1])))
labelNew.grid(row=2, column=1, padx=2, pady=6, sticky='W')
labelNew = tk.Label(set, fg='#000000', font='Helvetica -18 bold', text="CPU数量: {}".format(str(nodeinfo[2])))
labelNew.grid(row=3, column=1, padx=2, pady=6, sticky='W')
labelNew = tk.Label(set, fg='#000000', font='Helvetica -18 bold', text="虚拟类型: {}".format(conn1.getType()))
labelNew.grid(row=4, column=1, padx=2, pady=6, sticky='W')
labelNew = tk.Label(set, fg='#000000', font='Helvetica -18 bold', text="连接URI: {}".format(conn1.getURI()))
labelNew.grid(row=5, column=1, padx=2, pady=6, sticky='W')
labelNew = tk.Label(set, fg='#000000', font='Helvetica -18 bold',
text="空闲内存: {}bytes".format(conn1.getFreeMemory()))
labelNew.grid(row=6, column=1, padx=2, pady=6, sticky='W')
def show_machine(): # 显示虚拟机状态
# node1开启的域
vms_dict = {}
domain_list = conn.listDomainsID()
openID = []
openNAME = []
shutNAME = []
# node2开启的域
vms_dict1 = {}
domain_list1 = conn1.listDomainsID()
openID1 = []
openNAME1 = []
shutNAME1 = []
for vm in domain_list:
vms_dict[str(vm)] = conn.lookupByID(vm).name()
for vm in domain_list1:
vms_dict1[str(vm)] = conn1.lookupByID(vm).name()
if vms_dict:
for id_part, name_part in vms_dict.items():
openID.append(id_part)
openNAME.append(name_part)
if vms_dict1:
for id_part, name_part in vms_dict1.items():
openID1.append(id_part)
openNAME1.append(name_part)
# 关闭的域
global vmd_list
vmd_list = []
for i in conn.listDefinedDomains():
vmd_list.append(i)
global vmd_list1
vmd_list1 = []
for i in conn1.listDefinedDomains():
vmd_list1.append(i)
if vmd_list:
for name_part in vmd_list:
shutNAME.append(name_part)
if vmd_list1:
for name_part in vmd_list1:
shutNAME1.append(name_part)
set = tk.Tk()
set.title('虚拟机状态')
labelNew = tk.Label(set, fg='#000000', font='Helvetica -18 bold', text="node1虚拟机信息:")
labelNew.grid(row=0, column=0, padx=2, pady=6, sticky='W')
labelNew = tk.Label(set, fg='#000000', font='Helvetica -18 bold', text="处于开启状态的虚拟机:")
labelNew.grid(row=1, column=0, padx=2, pady=6, sticky='W')
labelNew = tk.Label(set, fg='#000000', font='Helvetica -18 bold', text="ID\tName")
labelNew.grid(row=2, column=0, padx=2, pady=6, sticky='W')
for i in range(len(openID)):
labelNew = tk.Label(set, fg='#000000', font='Helvetica -18 bold', text="{}\t{}"
.format(openID[i], openNAME[i]))
labelNew.grid(row=i + 3, column=0, padx=2, pady=6, sticky='W')
if len(openID) == 0:
labelNew = tk.Label(set, fg='#000000', font='Helvetica -18 bold', text="None")
labelNew.grid(row=3, column=0, padx=2, pady=6, sticky='W')
r = 4 if len(openID) == 0 else 2 + len(openID)
labelNew = tk.Label(set, fg='#000000', font='Helvetica -18 bold', text="处于关机状态的虚拟机:")
labelNew.grid(row=r + len(openID), column=0, padx=2, pady=6, sticky='W')
labelNew = tk.Label(set, fg='#000000', font='Helvetica -18 bold', text="Name")
labelNew.grid(row=r + 1 + len(openID), column=0, padx=2, pady=6, sticky='W')
for i in range(len(shutNAME)):
labelNew = tk.Label(set, fg='#000000', font='Helvetica -18 bold', text="{}"
.format(shutNAME[i]))
labelNew.grid(row=i + r + 2 + len(openID), column=0, padx=2, pady=6, sticky='W')
if len(shutNAME) == 0:
labelNew = tk.Label(set, fg='#000000', font='Helvetica -18 bold', text="None")
labelNew.grid(row=r + 2 + len(openID), column=0, padx=2, pady=6, sticky='W')
# node2虚拟机信息
labelNew = tk.Label(set, fg='#000000', font='Helvetica -18 bold', text="node2虚拟机信息:")
labelNew.grid(row=0, column=1, padx=2, pady=6, sticky='W')
labelNew = tk.Label(set, fg='#000000', font='Helvetica -18 bold', text="处于开启状态的虚拟机:")
labelNew.grid(row=1, column=1, padx=2, pady=6, sticky='W')
labelNew = tk.Label(set, fg='#000000', font='Helvetica -18 bold', text="ID\tName")
labelNew.grid(row=2, column=1, padx=2, pady=6, sticky='W')
for i in range(len(openID1)):
labelNew = tk.Label(set, fg='#000000', font='Helvetica -18 bold', text="{}\t{}"
.format(openID1[i], openNAME1[i]))
labelNew.grid(row=i + 3, column=1, padx=2, pady=6, sticky='W')
if len(openID1) == 0:
labelNew = tk.Label(set, fg='#000000', font='Helvetica -18 bold', text="None")
labelNew.grid(row=3, column=1, padx=2, pady=6, sticky='W')
r = 4 if len(openID1) == 0 else 2 + len(openID1)
labelNew = tk.Label(set, fg='#000000', font='Helvetica -18 bold', text="处于关机状态的虚拟机:")
labelNew.grid(row=r + len(openID1), column=1, padx=2, pady=6, sticky='W')
labelNew = tk.Label(set, fg='#000000', font='Helvetica -18 bold', text="Name")
labelNew.grid(row=r + 1 + len(openID1), column=1, padx=2, pady=6, sticky='W')
for i in range(len(shutNAME1)):
labelNew = tk.Label(set, fg='#000000', font='Helvetica -18 bold', text="{}"
.format(shutNAME1[i]))
labelNew.grid(row=i + r + 2 + len(openID1), column=1, padx=2, pady=6, sticky='W')
if len(shutNAME1) == 0:
labelNew = tk.Label(set, fg='#000000', font='Helvetica -18 bold', text="None")
labelNew.grid(row=r + 2 + len(openID1), column=1, padx=2, pady=6, sticky='W')
# def clone():
# name = entryName.get()
# # lableInit.config(text="请在virt-manager中完成虚拟机 {} 的创建".format(name))
# print('start!!')
# subprocess.call(["sh", "-c", 'cd /etc/libvirt/qemu/;virsh dumpxml centos7.0 > {}.xml'.format(name)])
# path = '/etc/libvirt/qemu/{}.xml'.format(name)
# doc = ET.parse(path)
# root = doc.getroot()
# sub1 = root.find('name') # 找到filename标签,
# sub2 = root.find('uuid')
# sub1.text = name # 修改标签内容
# sub2.text = str(uuid.uuid1())
# for cc in root:
# for bb in cc:
# for aa in bb:
# if aa.tag == 'source':
# aa.set('file', '/var/lib/libvirt/images/{}.qcow2'.format(name))
# doc.write(path) # 保存修改
# print('clone!!')
# subprocess.call(["sh", "-c", 'cd /var/lib/libvirt/images;cp centos7.0.qcow2 {}.qcow2'.format(name)])
# print('define beginning!!')
# subprocess.call(["sh", "-c", 'cd /etc/libvirt/qemu/; sudo virsh define {}.xml'.format(name)])
# print('finished!')
# os.system('virt-manager')
def deleter():
name = entryName.get()
subprocess.call(["sh", "-c", 'cd /etc/libvirt/qemu/; virsh undefine {}'.format(name)])
# subprocess.call('rm -f /var/lib/libvirt/images/{}.qcow2'.format(name))
lableInit.config(text="delete successfully!!".format(name))
os.system('virt-manager')
def suspand():
dom = conn.lookupByName(entryName.get())
dom.suspend()
print("虚拟机 {} 暂停成功".format(entryName.get()))
lableInit.config(text="虚拟机 {} 已暂停".format(entryName.get()))
def resume():
dom = conn.lookupByName(entryName.get())
dom.resume()
print("虚拟机 {} 运行成功".format(entryName.get()))
lableInit.config(text="虚拟机 {} 继续运行".format(entryName.get()))
def start():
dom = conn.lookupByName(entryName.get())
dom.create()
print("虚拟机 {} 启动成功".format(entryName.get()))
lableInit.config(text="虚拟机 {} 已启动".format(entryName.get()))
def start1():
dom = conn1.lookupByName(entryName.get())
dom.create()
print("虚拟机 {} 启动成功".format(entryName.get()))
lableInit.config(text="虚拟机 {} 已启动".format(entryName.get()))
def shutdown():
dom = conn.lookupByName(entryName.get())
dom.shutdown()
print("虚拟机 {} 关闭成功".format(entryName.get()))
lableInit.config(text="虚拟机 {} 已关闭".format(entryName.get()))
def run():
# judge ping
# read servers file to count nodes
ll = os.popen('cat /home/mpiuser/mpich/servers').readlines()
all_nodes = []
for i in range(0, len(ll)):
all_nodes.append(ll[i][4])
alive_nodes = []
dead_nodes = []
for i in range(0, len(all_nodes)):
cmd = 'ping node' + str(all_nodes[i]) + ' -c 2'
ss = os.popen(cmd).readlines()
print('ss:', ss)
target = '100% packet loss'
search = ss[-2].find(target)
if search != -1:
print('cannot ping node{}'.format(all_nodes[i]))
dead_nodes.append(all_nodes[i])
else:
alive_nodes.append(all_nodes[i])
print('alive_nodes:', alive_nodes)
print('dead_nodes:', dead_nodes)
# modify servers file
ssh1 = paramiko.SSHClient()
ssh1.set_missing_host_key_policy(paramiko.AutoAddPolicy()) # 指定当对方主机没有本机公钥的情况时应该怎么办,AutoAddPolicy表示自动在对方主机保存下本机的秘钥
ssh1.connect('node1', 22, 'root', '123456') # SSH端口默认22,可改
print('finish connect')
for i in range(0, len(dead_nodes)):
ssh1.exec_command("sed -i '/node{}/d' /home/mpiuser/mpich/servers".format(dead_nodes[i]))
for j in range(0, len(alive_nodes)):
ssh1.exec_command("scp /home/mpiuser/mpich/servers node{}:/home/mpiuser/mpich/".format(alive_nodes[j]))
print('finish modify')
# run MPI
ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) # 指定当对方主机没有本机公钥的情况时应该怎么办,AutoAddPolicy表示自动在对方主机保存下本机的秘钥
ssh.connect('node1', 22, 'mpiuser', 'mpiuser') # SSH端口默认22,可改
stdin, stdout, stderr = ssh.exec_command('mpirun -n 20 -f /home/mpiuser/mpich/servers /home/mpiuser/floyd_file')
outmsg, errmsg = stdout.read(), stderr.read() # 读一次之后,stdout和stderr里就没有内容了,所以一定要用变量把它们带的信息给保存下来,否则read一次之后就没有了
print(outmsg.decode())
print(errmsg)
if errmsg == "":
print(outmsg)
ssh.close()
print('成功运行MPI程序')
lableInit.config(text="成功运行MPI程序")
def connect(node='node2', passwd='123456'):
ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) # 指定当对方主机没有本机公钥的情况时应该怎么办,AutoAddPolicy表示自动在对方主机保存下本机的秘钥
ssh.connect(node, 22, 'root', passwd) # SSH端口默认22,可改
ssh.exec_command('echo node4:4 >> /home/mpiuser/mpich/servers')
def add_node():
os.system('echo node4:4 >> /home/mpiuser/mpich/servers ')
connect()
connect('node3')
def add(): # 主机信息
print(entryName.get())
set = tk.Tk()
title = '确认将{}加入mpi结点?'.format(entryName.get())
set.title(title)
flag = False
if entryName.get() in conn1.listDefinedDomains():
labelNew = tk.Label(set, fg='#c71585', font='Helvetica -18 bold', text="{}的状态是关机".format(entryName.get()))
labelNew.grid(row=1, column=0, padx=2, pady=6, sticky='E')
else:
labelNew = tk.Label(set, fg='#c71585', font='Helvetica -18 bold', text="{}的状态是开启".format(entryName.get()))
labelNew.grid(row=1, column=0, padx=2, pady=6, sticky='E')
flag = True
if not flag:
buttonOK = tk.Button(set, bg='#00DDDD', fg='white', width=18, height=2, font='Helvetica -15 bold', text="确认"
, command=start1)
buttonOK.grid(row=5, column=1, padx=4, pady=4, sticky='W')
add_node()
else:
buttonOK = tk.Button(set, bg='#00DDDD', fg='white', width=18, height=2, font='Helvetica -15 bold', text="确认"
, command=add_node)
buttonOK.grid(row=5, column=1, padx=4, pady=4, sticky='W')
def showDisk():
str = os.popen('df -hl /opt').read()
str = ' '.join(str.split())
str = str.replace(' ', '')
result = str.split('G')
diskInfo = result[2]
return diskInfo
def showAnotherDisk():
ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh.connect('node2', 22, 'root', '123456') # SSH端口默认22,可改
stdin, stdout, stderr = ssh.exec_command("df -hl /opt") # 这三个得到的都是类文件对象
outmsg, errmsg = stdout.read(), stderr.read() # 读一次之后,stdout和stderr里就没有内容了,所以一定要用变量把它们带的信息给保存下来,否则read一次之后就没有了
str = outmsg.decode()
str = ' '.join(str.split())
str = str.replace(' ', '')
result = str.split('G')
diskInfo = result[2]
print(errmsg)
ssh.close()
return diskInfo
def create():
set = tk.Tk()
set.title('设置虚拟机参数')
labelNew = tk.Label(set, fg='#000000', font='Helvetica -18 bold', text="请输入虚拟机的名称:")
labelNew.grid(row=1, column=0, padx=2, pady=6, sticky='E')
entryNew = tk.Entry(set, width=24)
entryNew.grid(row=1, column=1, padx=2, sticky='W')
labelMemory = tk.Label(set, fg='#000000', font='Helvetica -18 bold', text="请输入内存大小(以MB为单位):")
labelMemory.grid(row=2, column=0, padx=2, pady=6, sticky='E')
entryMemory = tk.Entry(set, width=24)
entryMemory.grid(row=2, column=1, padx=2, sticky='W')
labelCPU = tk.Label(set, fg='#000000', font='Helvetica -18 bold', text="请输入CPU个数(上限为8):")
labelCPU.grid(row=3, column=0, padx=2, pady=6, sticky='E')
entryCPU = tk.Entry(set, width=24)
entryCPU.grid(row=3, column=1, padx=2, sticky='W')
labelDisk = tk.Label(set, fg='#000000', font='Helvetica -18 bold', text="请输入硬盘大小(以GB为单位):")
labelDisk.grid(row=4, column=0, padx=2, pady=6, sticky='E')
entryDisk = tk.Entry(set, width=24)
entryDisk.grid(row=4, column=1, padx=2, sticky='W')
def another_create(newname, memorysize, cpusize, disksize):
diskpath = '/opt/imgs/{}.qcow2'.format(newname)
isopath = '/opt/CentOS-7-x86_64-DVD-2003.iso'
os.system('cd /opt')
os.system('qemu-img create -f qcow2 {}.qcow2 {}G'.format(newname, disksize))
os.system(
'virt-install --connect qemu+ssh://node2/system --virt-type kvm --name {} --ram {} --vcpus {} --network network=br0 --disk path={},size={},format=qcow2 --cdrom {} --noautoconsole'
.format(newname, memorysize, cpusize,
diskpath, disksize, isopath))
def cur_create(newname, memorysize, cpusize, disksize):
diskpath = '/home/mpiuser/imgs/{}.qcow2'.format(newname)
isopath = '/home/mpiuser/imgs/CentOS-7.4-x86_64-DVD-1708.iso'
os.system('cd /home/mpiuser')
os.system('qemu-img create -f qcow2 {}.qcow2 {}G'.format(newname, disksize))
os.system(
'virt-install --connect qemu:///system --virt-type kvm --name {} --ram {} --vcpus {} --network network=br0 --disk path={},size={},format=qcow2 --cdrom {} --noautoconsole'
.format(newname, memorysize, cpusize,
diskpath, disksize, isopath))
def confirm():
newname = entryNew.get()
memorysize = int(entryMemory.get())
cpusize = int(entryCPU.get())
disksize = int(entryDisk.get())
cur_diskInfo = showDisk()
another_diskInfo = showAnotherDisk()
if float(cur_diskInfo) < disksize < float(another_diskInfo):
warn = tk.Tk()
warn.title('提示')
content1 = tk.Label(warn, fg='#c71585', font='Helvetica -18 bold',
text="所创建的虚拟机硬盘大小{}G超过当前主机可用容量{}G".format(disksize, cur_diskInfo))
content1.grid(row=1, column=0, padx=2, pady=6, sticky='E')
content2 = tk.Label(warn, fg='#c71585', font='Helvetica -18 bold',
text="另一台主机可用容量为{}G".format(another_diskInfo))
content2.grid(row=2, column=0, padx=2, pady=6, sticky='E')
content3 = tk.Label(warn, fg='#c71585', font='Helvetica -18 bold',
text="因此新虚拟机{}创建在另一台主机上".format(newname))
content3.grid(row=3, column=0, padx=2, pady=6, sticky='E')
sure = tk.Button(warn, bg='#00DDDD', fg='white', width=18, height=2, font='Helvetica -15 bold',
text="确认",
command=another_create(newname, memorysize, cpusize, disksize))
sure.grid(row=4, column=1, padx=4, pady=4, sticky='W')
warn.mainloop()
elif disksize < float(cur_diskInfo):
cur_create(newname, memorysize, cpusize, disksize)
else:
warn = tk.Tk()
warn.title('提示')
content1 = tk.Label(warn, fg='#c71585', font='Helvetica -18 bold',
text="所创建的虚拟机硬盘大小{}G超过当前主机可用容量{}G".format(disksize, cur_diskInfo))
content1.grid(row=1, column=0, padx=2, pady=6, sticky='E')
content2 = tk.Label(warn, fg='#c71585', font='Helvetica -18 bold',
text="另一台主机可用容量为{}G".format(another_diskInfo))
content2.grid(row=2, column=0, padx=2, pady=6, sticky='E')
content3 = tk.Label(warn, fg='#c71585', font='Helvetica -18 bold',
text="因此新虚拟机{}硬盘大小应该小于{}G".format(newname, max(cur_diskInfo, another_diskInfo)))
content3.grid(row=3, column=0, padx=2, pady=6, sticky='E')
sure = tk.Button(warn, bg='#00DDDD', fg='white', width=18, height=2, font='Helvetica -15 bold',
text="确认",
command=another_create(newname, memorysize, cpusize, disksize))
sure.grid(row=4, column=1, padx=4, pady=4, sticky='W')
warn.mainloop()
buttonConfirm = tk.Button(set, bg='#00DDDD', fg='white', width=18, height=2, font='Helvetica -15 bold', text="确认"
, command=confirm)
buttonConfirm.grid(row=5, column=1, padx=4, pady=4, sticky='W')
set.mainloop()
# ------------菜单控制-------------
def test():
name = str(entryName.get())
print(name)
# --------------------------------
conn = libvirt.open("qemu:///system") # 链接
conn1 = libvirt.open('qemu+ssh://node2/system')
top = tk.Tk()
top.title("虚拟机管理平台")
# top.geometry('602x')#窗体大小
lableTitle = tk.Label(top, bg='#00DDDD', fg="#EEE8AA", font='Helvetica -24 bold', text="虚 拟 机 管 理 平 台",
width=50)
lableTitle.grid(row=0, column=0, columnspan=2, ipady=10)
# -------------------------------
labelHello = tk.Label(top, fg='#000000', font='Helvetica -18 bold', text="请输入虚拟机的名称:")
labelHello.grid(row=1, column=0, padx=2, pady=6, sticky='E')
entryName = tk.Entry(top, width=24)
entryName.grid(row=1, column=1, padx=2, sticky='W')
# -------操作------
showHost = tk.Button(top, bg='#00DDDD', fg='white', width=18, height=2, font='Helvetica -15 bold', text="显示主机信息",
command=list_connection)
showHost.grid(row=2, column=0, padx=4, pady=4, sticky='E')
showVM = tk.Button(top, bg='#00DDDD', fg='white', width=18, height=2, font='Helvetica -15 bold', text="显示虚拟机状态",
command=show_machine)
showVM.grid(row=2, column=1, padx=4, pady=4, sticky='W')
startVM = tk.Button(top, bg='#00DDDD', fg='white', width=18, height=2, font='Helvetica -15 bold', text="开启虚拟机",
command=start)
startVM.grid(row=4, column=0, padx=4, pady=4, sticky='E')
shutdownVM = tk.Button(top, bg='#00DDDD', fg='white', width=18, height=2, font='Helvetica -15 bold', text="关闭虚拟机",
command=shutdown)
shutdownVM.grid(row=4, column=1, padx=4, pady=4, sticky='W')
suspandVM = tk.Button(top, bg='#00DDDD', fg='white', width=18, height=2, font='Helvetica -15 bold', text="暂停虚拟机",
command=suspand)
suspandVM.grid(row=5, column=0, padx=4, pady=4, sticky='E')
resumeVM = tk.Button(top, bg='#00DDDD', fg='white', width=18, height=2, font='Helvetica -15 bold', text="运行虚拟机",
command=resume)
resumeVM.grid(row=5, column=1, padx=4, pady=4, sticky='W')
# cloneVM = tk.Button(top, bg='#00BFFF', fg='white', width=18, height=2, font='Helvetica -15 bold', text="克隆虚拟机"
# , command=clone)
# cloneVM.grid(row=6, column=0, padx=4, pady=4, sticky='E')
createVM = tk.Button(top, bg='#00DDDD', fg='white', width=18, height=2, font='Helvetica -15 bold', text="创建虚拟机"
, command=create)
createVM.grid(row=6, column=0, padx=4, pady=4, sticky='E')
undefineVM = tk.Button(top, bg='#00DDDD', fg='white', width=18, height=2, font='Helvetica -15 bold', text="删除虚拟机"
, command=deleter)
undefineVM.grid(row=6, column=1, padx=4, pady=4, sticky='W')
runMPI = tk.Button(top, bg='#00DDDD', fg='white', width=18, height=2, font='Helvetica -15 bold', text="运行MPI程序"
, command=run)
runMPI.grid(row=7, column=0, padx=4, pady=4, sticky='E')
addNode = tk.Button(top, bg='#00DDDD', fg='white', width=18, height=2, font='Helvetica -15 bold', text="增加mpi结点",
command=add)
addNode.grid(row=7, column=1, padx=4, pady=4, sticky='W')
lableInitTitle = tk.Label(top, bg='black', font='Helvetica -13 bold', text="* * * 系 统 反 馈 信 息 * * *", width=85,
fg="blue")
lableInitTitle.grid(row=9, column=0, columnspan=2, ipady=10)
lableInit = tk.Label(top, bg='black', font='Helvetica -13 bold', text="NULL", width=85, fg="white")
lableInit.grid(row=9, column=0, columnspan=2, ipady=10)
# quitVM = tk.Button(top,text="退出管理系统",command=close_connection())
# quitVM.pack()
top.mainloop()