可视化窗口、容错机制

import docker
import sys
import tkinter
import tkinter.messagebox
import random
import paramiko
import tkinter.font as tkFont
from PIL import Image, ImageTk
from tkinter import ttk
import os
import re
import datetime
import threading
import time
import subprocess

host_share = '/mpi_config/'
docker_file = '/mpi_config'
volumes = {}
temp_volumes = {}
temp_volumes['bind'] = docker_file
temp_volumes['mode'] = 'rw'
volumes[host_share] = temp_volumes


ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh.connect(hostname="192.168.43.122", port=22, username="ares", password="123456")

ip1 = '192.168.43.237'
ip2 = '192.168.43.122'
docker_images = '06ab69e711f4'
connect1 = ip1 + ':2375'
connect2 = ip2 + ':2375'

client1 = docker.DockerClient(base_url=connect1,use_ssh_client=True)
client2 = docker.DockerClient(base_url=connect2,use_ssh_client=True)
network = client1.networks.get('multihost')
CPU_yang = 4
CPU_zhang = 4


def write_config():
    file_address = host_share + '/mpi_config'
    containers1 = client1.containers.list()
    containers2 = client2.containers.list()
    containers_ip = network.attrs['Containers']
    print(containers2)
    print(containers1)
    print(containers_ip)
    print(network)
    ips = []
    with open(file_address, mode='w', encoding='utf-8') as file_obj:
        for container in containers1:
            # stats = container.stats(decode=True)
            # stats_value = next(stats)
            # pids_num = stats_value['pids_stats']['current']
            for container_ip in containers_ip:
                key = container_ip
                value = containers_ip[key]
                if value['Name'] == container.name:
                    ip = value['IPv4Address'][:-3]
                    if value['Name'] == 'master_yang':
                        file_obj.write(ip + ':' + str(1) + '\n')
                    else:
                        ips.append(ip)
        for container in containers2:
            # stats = container.stats(decode=True)
            # stats_value = next(stats)
            # pids_num = stats_value['pids_stats']['current']
            for container_ip in containers_ip:
                key = container_ip
                value = containers_ip[key]
                if value['Name'] == container.name:
                    ip = value['IPv4Address'][:-3]
                    if value['Name'] == 'master_zhang':
                        file_obj.write(ip + ':' + str(1) + '\n')
                    else:
                        ips.append(ip)
        for i in range(len(ips)):
            file_obj.write(ips[i] + ':' + str(1) + '\n')
    print(ips)


def create():
    create_one = tkinter.Toplevel()
    frame_main = tkinter.Frame(create_one, bg="whitesmoke")
    frame_main.propagate(False)
    frame_main.pack(expand=tkinter.YES, fill=tkinter.BOTH)
    create_one.title('创建虚拟机')
    create_one.geometry('800x600')  # 窗体大小
    global memory, CPU_number, docker_name, docker_place

    number3 = tkinter.StringVar()
    memory = ttk.Combobox(create_one, width=12, textvariable=number3)
    memory['values'] = ('1', '2', '3', '4', '5', '6', '7', '8')
    memory.place(width=250, x=500, y=20, height=20)
    memory.current(0)
    memory_label = tkinter.Label(create_one, text='请输入最大内存(单位GB)(范围1-8)',bg='whitesmoke')
    memory_label.place(x=20, y=20, width=400, height=20)

    number1 = tkinter.StringVar()
    CPU_number = ttk.Combobox(create_one, width=12, textvariable=number1)
    CPU_number['values'] = ('0')
    CPU_number.place(width=250, x=500, y=70, height=20)
    CPU_number.current(0)
    CPU_number_label = tkinter.Label(create_one, text='请输入CPU核数目',bg='whitesmoke')
    CPU_number_label.place(x=20, y=70, width=400, height=20)

    docker_name = tkinter.Entry(create_one)
    docker_name.place(width=250, x=500, y=120, height=20)
    docker_name_label = tkinter.Label(create_one, text='请输入虚拟机名字', width=80,bg='whitesmoke')
    docker_name_label.place(x=20, y=120, width=400, height=20)

    number2 = tkinter.StringVar()
    docker_place = ttk.Combobox(create_one, width=12, textvariable=number2)
    docker_place['values'] = ('0', '1')
    docker_place.place(width=250, x=500, y=170, height=20)
    docker_place.current(0)
    docker_place_label = tkinter.Label(create_one, text='请选择在那一台物理机上创建docker(0在杨嘉禧主机, 1在张铭宇主机):',bg='whitesmoke')
    docker_place_label.place(x=20, y=170, width=400, height=20)

    button2 = tkinter.Button(create_one, text='创建虚拟机', command=docker_create, font=('Arial', 12), width=50, height=2)
    button2.place(x=170, y=300)


def docker_check_status(container, flag):
    result = {}
    result['name'] = container.name
    containers_ip = network.attrs['Containers']
    ip = '----'
    result['ipv4'] = ip
    for container_ip in containers_ip:
        key = container_ip
        value = containers_ip[key]
        if value['Name'] == container.name:
            ip = value['IPv4Address'][:-3]
            result['ipv4'] = ip
            break

    stats = container.stats(decode=True)
    stats_value = next(stats)
    short_id = container.short_id
    status = container.status
    result['status'] = status
    result['id'] = short_id
    # view_time = stats_value['read'][:-11]
    # view_time = view_time[0:11] + str((int(view_time[11:13]) + 8) % 24) + view_time[13:]
    # result['view_time'] = view_time
    try:
        pids_num = stats_value['pids_stats']['current']
    except:
        pids_num = 0
    result['pid_num'] = pids_num
    if flag == 0:
        out = subprocess.Popen('docker stats {}'.format(container.name), shell=True, stdout=subprocess.PIPE)
        for n, v in enumerate(out.stdout):
            if n == 1:
                value = bytes.decode(v.strip()).split(' ')
                valuelist = [j for j in value if j != '' and j != '/']
                result['cpu_percentage'] = valuelist[2]
                result['memory_use'] = valuelist[3]
                result['memory_total'] = valuelist[4]
                result['memory_percentage'] = valuelist[5]
                out.terminate()
                break
    if flag == 1:
        command = "docker stats --no-stream " + container.name
        stdin, stdout, stderr = ssh.exec_command(command)
        a = (stdout.read().decode()).split('\n')[1]
        b = a.split(' ')
        list1 = []
        for i in range(len(b)):
            if len(b[i]) > 1:
                list1.append(b[i])
        result['cpu_percentage'] = list1[2]
        result['memory_use'] = list1[3]
        result['memory_total'] = list1[4]
        result['memory_percentage'] = list1[5]

    return result


def check():
    create_two = tkinter.Toplevel()
    frame_main = tkinter.Frame(create_two, bg="whitesmoke")
    frame_main.propagate(False)
    frame_main.pack(expand=tkinter.YES, fill=tkinter.BOTH)
    create_two.title('查看虚拟机状态')
    create_two.geometry('1100x700')  # 窗体大小
    write_config()
    cmd = 'tar czf - /mpi_config/mpi_config | ssh hadoop@'+'192.168.43.237'+' tar xzf - -C /'
    os.system(cmd)
    containers1 = client1.containers.list(all=True)
    result1 = {}
    for container in containers1:
        result1[container.name] = docker_check_status(container, 0)
    containers2 = client2.containers.list(all=True)
    result2 = {}
    for container in containers2:
        result2[container.name] = docker_check_status(container, 1)

    label1 = tkinter.Label(create_two, text='机器yang', font=('Arial', 15),bg="whitesmoke")
    label1.place(x=500, y=0, width=100, height=50)
    for i, k in enumerate(result1):
        data = result1[k]
        label = tkinter.Label(create_two, font=tkFont.Font(family="微软雅黑", size=10),bg="whitesmoke",text='name:{}   status:{}   ip:{}   pid_num:{}   cpu_percentage:{}   memory_use:{}   memory_total:{}   memory_percentage:{}'.format(data['name'], data['status'], data['ipv4'], data['pid_num'], data['cpu_percentage'], data['memory_use'], data['memory_total'], data['memory_percentage']))
        label.place(x=0, y=i*45+70, height=30)
    label2 = tkinter.Label(create_two, text='机器zhang', font=('Arial', 15),bg="whitesmoke")
    label2.place(x=500, y=320, width=100, height=50)
    for i, k in enumerate(result2):
        data = result2[k]
        label = tkinter.Label(create_two, font=tkFont.Font(family="微软雅黑", size=10),bg="whitesmoke",text='name:{}   status:{}   ip:{}   pid_num:{}   cpu_percentage:{}   memory_use:{}   memory_total:{}   memory_percentage:{}'.format(data['name'], data['status'], data['ipv4'], data['pid_num'], data['cpu_percentage'], data['memory_use'], data['memory_total'], data['memory_percentage']))
        label.place(x=0, y=i*45+390, height=30)


def start():
    create_three = tkinter.Toplevel()
    frame_main = tkinter.Frame(create_three, bg="whitesmoke")
    frame_main.propagate(False)
    frame_main.pack(expand=tkinter.YES, fill=tkinter.BOTH)
    create_three.title('开启虚拟机')
    create_three.geometry('800x600')  # 窗体大小
    global name2, docker_place2

    number2 = tkinter.StringVar()
    name2 = ttk.Combobox(create_three, width=12, textvariable=number2)
    containers1 = client1.containers.list(all=True)
    containers2 = client2.containers.list(all=True)
    containers1_run = client1.containers.list()
    containers2_run = client2.containers.list()
    list_temp = []
    for container in containers1:
        if container not in containers1_run:
            list_temp.append(container.name)
    for container in containers2:
        if container not in containers2_run:
            list_temp.append(container.name)
    if len(list_temp) == 0:
        list_temp.append('所有的docker容器都已经开启')
    name2['values'] = tuple(list_temp)
    name2.place(width=250, x=500, y=70, height=20)
    name2.current(0)
    # name2 = tkinter.Entry(create_three)
    # name2.place(width=250, x=500, y=70, height=20)
    name2_label = tkinter.Label(create_three, text='请输入要开启的虚拟机名字',bg='whitesmoke')
    name2_label.place(x=20, y=70, width=400, height=20)

    number1 = tkinter.StringVar()
    docker_place2 = ttk.Combobox(create_three, width=12, textvariable=number1)
    docker_place2['values'] = ('0', '1')
    docker_place2.place(width=250, x=500, y=170, height=20)
    docker_place2.current(0)
    docker_place2_label1 = tkinter.Label(create_three, text='请选择在那一台物理机上开启docker(0在杨嘉主机, 1在张铭宇主机):',bg='whitesmoke')
    docker_place2_label1.place(x=20, y=170, width=400, height=20)

    button1 = tkinter.Button(create_three, text='开启虚拟机', command=start_container, font=('Arial', 12), width=50,
                             height=2)
    button1.place(x=170, y=300)


def remove():
    create_four = tkinter.Toplevel()
    frame_main = tkinter.Frame(create_four, bg="whitesmoke")
    frame_main.propagate(False)
    frame_main.pack(expand=tkinter.YES, fill=tkinter.BOTH)
    create_four.title('删除虚拟机')
    create_four.geometry('800x600')  # 窗体大小
    global name1, docker_place1

    number1 = tkinter.StringVar()
    name1 = ttk.Combobox(create_four, width=12, textvariable=number1)
    containers1 = client1.containers.list(all=True)
    containers2 = client2.containers.list(all=True)
    list_temp = []
    for container in containers1:
        list_temp.append(container.name)
    for container in containers2:
        list_temp.append(container.name)
    name1['values'] = tuple(list_temp)
    name1.place(width=250, x=500, y=70, height=20)
    name1.current(0)
    name1_label = tkinter.Label(create_four, text='请输入要删除的虚拟机名字',bg='whitesmoke')
    name1_label.place(x=20, y=70, width=400, height=20)

    number2 = tkinter.StringVar()
    docker_place1 = ttk.Combobox(create_four, width=12, textvariable=number2)
    docker_place1['values'] = ('0', '1')
    docker_place1.place(width=250, x=500, y=170, height=20)
    docker_place1.current(0)
    docker_place_label1 = tkinter.Label(create_four, text='请选择在那一台物理机上删除docker(0在杨嘉禧主机, 1在张铭宇主机):',bg='whitesmoke')
    docker_place_label1.place(x=20, y=170, width=400, height=20)

    button1 = tkinter.Button(create_four, text='删除虚拟机', command=remove_container, font=('Arial', 12), width=50, height=2)
    button1.place(x=170, y=300)


def stop():
    create_five = tkinter.Toplevel()
    frame_main = tkinter.Frame(create_five, bg="whitesmoke")
    frame_main.propagate(False)
    frame_main.pack(expand=tkinter.YES, fill=tkinter.BOTH)
    create_five.title('停止虚拟机')
    create_five.geometry('800x600')  # 窗体大小
    global name3, docker_place3

    number1 = tkinter.StringVar()
    name3 = ttk.Combobox(create_five, width=12, textvariable=number1)
    containers1 = client1.containers.list()
    containers2 = client2.containers.list()
    list_temp = []
    for container in containers1:
        list_temp.append(container.name)
    for container in containers2:
        list_temp.append(container.name)
    name3['values'] = tuple(list_temp)
    name3.place(width=250, x=500, y=70, height=20)
    name3.current(0)
    name3_label = tkinter.Label(create_five, text='请输入要停止的虚拟机名字',bg='whitesmoke')
    name3_label.place(x=20, y=70, width=400, height=20)

    number2 = tkinter.StringVar()
    docker_place3 = ttk.Combobox(create_five, width=12, textvariable=number2)
    docker_place3['values'] = ('0', '1')
    docker_place3.place(width=250, x=500, y=170, height=20)
    docker_place3.current(0)
    docker_place_label3 = tkinter.Label(create_five, text='请选择在哪一台物理机上停止docker(0在杨嘉禧主机, 1在张铭宇主机):',bg='whitesmoke')
    docker_place_label3.place(x=20, y=170, width=400, height=20)

    button3 = tkinter.Button(create_five, text='停止虚拟机', command=stop_container, font=('Arial', 12), width=50, height=2)
    button3.place(x=170, y=300)


def remove_container():
    position = docker_place1.get()
    name = name1.get()
    if position == "0":
        client = client1
    elif position == '1':
        client = client2
    if position!='0' and position!='1':
        tkinter.messagebox.showwarning("提示", '虚拟机参数输入错误')
        return
    name_list = []
    containers = client.containers.list(all=True)
    for container in containers:
        name_list.append(container.name)
    if name not in name_list:
        tkinter.messagebox.showwarning("提示", '要删除的虚拟机不存在')
        return
    container = client.containers.get(name)
    container.stop()
    container.remove()
    tkinter.messagebox.showwarning("提示", '成功删除虚拟机')


def start_container():
    position = docker_place2.get()
    name = name2.get()
    if position == "0":
        client = client1
    elif position == '1':
        client = client2
    if position != '0' and position != '1':
        tkinter.messagebox.showwarning("提示", '虚拟机参数输入错误')
        return
    name_list = []
    containers = client.containers.list(all = True)
    for container in containers:
        name_list.append(container.name)
    if name not in name_list:
        tkinter.messagebox.showwarning("提示", '要开启的虚拟机不存在')
        return
    container = client.containers.get(name)
    container.start()
    container.exec_run('/etc/init.d/ssh start')
    tkinter.messagebox.showwarning("提示", '成功开启虚拟机')


def stop_container():
    position = docker_place3.get()
    name = name3.get()
    if position == "0":
        client = client1
    elif position == '1':
        client = client2
    if position != '0' and position != '1':
        tkinter.messagebox.showwarning("提示", '虚拟机参数输入错误')
        return
    name_list = []
    containers = client.containers.list()
    for container in containers:
        name_list.append(container.name)
    if name not in name_list:
        tkinter.messagebox.showwarning("提示", '要停止的虚拟机不存在')
        return
    container = client.containers.get(name)
    container.stop()
    tkinter.messagebox.showwarning("提示", '成功停止虚拟机')



def docker_create():
    position = docker_place.get()
    if position == "0":
        client = client1
        CPU_number_limit = CPU_yang
    elif position == '1':
        client = client2
        CPU_number_limit = CPU_zhang
    if position!= '0' and position!='1':
        tkinter.messagebox.showwarning("提示", '虚拟机参数输入错误')
        return
    name = docker_name.get()
    memory_number = int(eval(memory.get()))
    if memory_number>8:
        tkinter.messagebox.showwarning("提示", '虚拟机超过主机最大内存容量')
        return
    mem_limit = memory.get() + 'g'
    number = int(eval(CPU_number.get()))
    if number>CPU_number_limit:
        tkinter.messagebox.showwarning("提示", '虚拟机超过最大CPU核数目')
        return
    CPU_list = []
    CPU_str = ''
    while len(CPU_list) < number:
        i = random.randint(0,7)
        if i not in CPU_list:
            CPU_list.append(i)
            CPU_str += str(i)
            CPU_str += ','
    CPU_str = CPU_str[:-1]
    container1 = client.containers.run(image=docker_images, name=name, mem_limit=mem_limit, tty=True, privileged=True, detach=True,stdin_open=True,network='multihost',cpuset_cpus=CPU_str, volumes =volumes)
    container1.exec_run('/etc/init.d/ssh start')
    tkinter.messagebox.showwarning("提示", '虚拟机创建成功')
    client1.close()
    client2.close()

# write_config()
def run(): # 定时器回调
    global timer
    ping = os.popen('ping 192.168.43.122 -c 1').read()
    if 'Destination Host Unreachable' in ping:
        # print(ping)
        print('访问失败')
        tkinter.messagebox.showwarning("提示", '主机连接出现错误')
        sys.exit(0)
    else:
        print('访问成功')
    timer = threading.Timer(2, run)
    timer.start()

timer = threading.Timer(2,run) # 1代表1秒后执行
timer.start()  # 启动定时器

time.sleep(3)   ## 等待6s
print('====')
time.sleep(3)   ## 等待6s
print('====')
time.sleep(3)   ## 等待6s
print('====')
root = tkinter.Tk()
root.title('docker虚拟管理')  # 标题
root.geometry('800x700')  #窗体大小

frame_top = tkinter.Frame(root, bg="grey")
frame_top.pack(fill=tkinter.X)


lbl_image = tkinter.Label(frame_top, width=100, height=80)
lbl_image.pack(side=tkinter.LEFT)
imgtop = Image.open(r'docker.jpg')
img1 = imgtop.resize((100, 80), Image.ANTIALIAS)
tk_img = ImageTk.PhotoImage(img1)
lbl_image.image = tk_img
lbl_image.config(image=tk_img)


tkinter.Label(frame_top, text="制作成员:张铭宇 杨嘉禧",bg = 'Green',font=tkFont.Font(family="微软雅黑", size=12, weight=tkFont.NORMAL)).pack(side=tkinter.LEFT, padx=20)
tkinter.Label(frame_top, text="云计算课程设计", bg="Green", height=2, font=tkFont.Font(family="微软雅黑", size=12, weight=tkFont.NORMAL)).pack(side=tkinter.RIGHT, padx=100)


frame_main = tkinter.Frame(root, bg="whitesmoke")
frame_main.propagate(False)
frame_main.pack(expand=tkinter.YES, fill=tkinter.BOTH)

frame_maintop = tkinter.Frame(frame_main, bg="white", height=40)
frame_maintop.pack(fill=tkinter.X, padx=20, pady=10)
imagetop = tkinter.Label(frame_maintop, width=180, height=40)
tkinter.Label(frame_maintop, text="虚拟机管理器", bg="white", fg='black', height=2, font=tkFont.Font(family="微软雅黑", size=19, weight=tkFont.BOLD)).pack(side=tkinter.LEFT, padx=300)

frame_mainleft=tkinter.Frame(frame_main, width=800, bg="white")
frame_mainleft.pack(side=tkinter.RIGHT, fill=tkinter.Y, padx=30)
tkinter.Label(frame_mainleft, text="  主要功能", bg="white", fg='black', height=2, font=tkFont.Font(family="微软雅黑", size=18,weight=tkFont.BOLD)).pack(anchor=tkinter.W, padx=300, pady=5)
frame_mainleft.propagate(False)
button1 = tkinter.Button(frame_mainleft, text='创建虚拟机', command=create, font=tkFont.Font(family="微软雅黑", size=11), width=50, height=2, bg='white').pack(padx=10,pady=5)
button2 = tkinter.Button(frame_mainleft, text='查看虚拟机状态', command=check, font=tkFont.Font(family="微软雅黑", size=11), width=50, height=2, bg='white').pack(padx=10,pady=5)
button3 = tkinter.Button(frame_mainleft, text='开启虚拟机', command=start, font=tkFont.Font(family="微软雅黑", size=11), width=50, height=2, bg='white').pack(padx=10,pady=5)
button5 = tkinter.Button(frame_mainleft, text='停止虚拟机', command=stop, font=tkFont.Font(family="微软雅黑", size=11), width=50, height=2, bg='white').pack(padx=10,pady=5)
button4 = tkinter.Button(frame_mainleft, text='删除虚拟机', command=remove, font=tkFont.Font(family="微软雅黑", size=11), width=50, height=2, bg='white').pack(padx=10,pady=5)


root.mainloop()
ssh.close()

Logo

华为开发者空间,是为全球开发者打造的专属开发空间,汇聚了华为优质开发资源及工具,致力于让每一位开发者拥有一台云主机,基于华为根生态开发、创新。

更多推荐