Initial YakPanel commit
This commit is contained in:
459
class_v2/btdockerModelV2/dkgroupModel_.py
Normal file
459
class_v2/btdockerModelV2/dkgroupModel_.py
Normal file
@@ -0,0 +1,459 @@
|
||||
# coding: utf-8
|
||||
# -------------------------------------------------------------------
|
||||
# YakPanel
|
||||
# -------------------------------------------------------------------
|
||||
# Copyright (c) 2015-2099 YakPanel(www.yakpanel.com) All rights reserved.
|
||||
# -------------------------------------------------------------------
|
||||
# Author: zhengweibiao
|
||||
# -------------------------------------------------------------------
|
||||
|
||||
# ------------------------------
|
||||
# 容器项目编排
|
||||
# ------------------------------
|
||||
import os, sys, re, json, shutil, psutil, time
|
||||
import datetime
|
||||
import public
|
||||
from btdockerModelV2.containerModel import main as docker
|
||||
import subprocess
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
class main():
|
||||
|
||||
next_id = 1 # 将 next_id 设为类变量,而不是实例变量
|
||||
def __init__(self):
|
||||
# self.next_id = 1
|
||||
pass
|
||||
|
||||
def load_project_data(self):
|
||||
json_file = "/www/server/panel/class_v2/btdockerModelV2/docker_project_groups.json"
|
||||
try:
|
||||
with open(json_file, 'r') as f:
|
||||
return json.load(f)
|
||||
except FileNotFoundError:
|
||||
data = []
|
||||
with open(json_file, 'w') as f:
|
||||
json.dump(data, f)
|
||||
|
||||
return data
|
||||
except Exception as e:
|
||||
return None
|
||||
|
||||
def write_to_json(self, data):
|
||||
json_file = "/www/server/panel/class_v2/btdockerModelV2/docker_project_groups.json"
|
||||
try:
|
||||
with open(json_file, 'w') as f:
|
||||
json.dump(data, f)
|
||||
return True
|
||||
except Exception as e:
|
||||
print("写入失败!{}".format(e))
|
||||
return False
|
||||
|
||||
def get_project_groups(self, get):
|
||||
|
||||
data = self.load_project_data()
|
||||
if data is None:
|
||||
return public.returnMsg(False, "获取配置文件失败")
|
||||
|
||||
# 获取项目列表
|
||||
project_list = docker().get_list(get)
|
||||
|
||||
# 更新每个项目组的状态
|
||||
for group in data:
|
||||
# 检查项目排序是否为空
|
||||
if not group['order']:
|
||||
group['status'] = 0 # 如果项目排序为空,状态为停止
|
||||
continue
|
||||
|
||||
all_running = True # 假设所有的项目都在运行
|
||||
for project in group['projects']:
|
||||
for p in project_list['container_list']:
|
||||
if p['name'] == project['project_name']:
|
||||
if p['status']!="running": # 如果项目没有运行
|
||||
all_running = False
|
||||
break
|
||||
if not all_running:
|
||||
break
|
||||
|
||||
if all_running:
|
||||
group['status'] = 1 # 如果所有的项目都在运行,状态为启动
|
||||
else:
|
||||
group['status'] = 0
|
||||
|
||||
return public.returnMsg(True, data)
|
||||
|
||||
def get_group_data(self, get):
|
||||
try:
|
||||
data = self.load_project_data()
|
||||
if data is None:
|
||||
return None, public.returnMsg(False, "获取配置文件失败!")
|
||||
|
||||
project_list = docker().get_list(get)
|
||||
for group in data:
|
||||
if group['id'] == int(get.id):
|
||||
for project in group['projects']:
|
||||
|
||||
print(project)
|
||||
# print(project_list['container_list'])
|
||||
for p in project_list['container_list']:
|
||||
if p['name'] == project['project_name']:
|
||||
print(3333)
|
||||
print(p)
|
||||
project['status'] = p['status']
|
||||
return group, None
|
||||
return None, public.ReturnMsg(False, "项目不存在!")
|
||||
|
||||
except Exception as e:
|
||||
return None, public.returnMsg(False, "获取失败!" + str(e))
|
||||
|
||||
def get_project_details(self, get):
|
||||
print(33333)
|
||||
group, error_msg = self.get_group_data(get)
|
||||
if error_msg:
|
||||
return error_msg
|
||||
|
||||
group['projects'].sort(
|
||||
key=lambda x: group['order'].index(x['project_name']))
|
||||
return public.returnMsg(True, group['projects'])
|
||||
|
||||
def get_project_group_details(self, get):
|
||||
group, error_msg = self.get_group_data(get)
|
||||
if error_msg:
|
||||
return error_msg
|
||||
return public.returnMsg(True, group)
|
||||
|
||||
def add_project_group(self, get):
|
||||
|
||||
try:
|
||||
data = self.load_project_data()
|
||||
if data is None:
|
||||
return public.returnMsg(False, "获取配置文件失败")
|
||||
|
||||
# 检查是否已存在
|
||||
for group in data:
|
||||
if group['group_name'] == get.group_name:
|
||||
return public.returnMsg(False, "项目已存在!")
|
||||
|
||||
# 添加新的项目
|
||||
new_group = {
|
||||
"id": self.next_id, # 使用 next_id 作为新的 id
|
||||
"group_name": get.group_name,
|
||||
# "status": 0,
|
||||
"interval": 30,
|
||||
"projects": [],
|
||||
"order": [],
|
||||
}
|
||||
data.append(new_group)
|
||||
|
||||
# 更新 next_id
|
||||
|
||||
main.next_id += 1
|
||||
if not self.write_to_json(data):
|
||||
return public.returnMsg(False, "写入失败!")
|
||||
|
||||
return public.returnMsg(True, "项目添加成功!")
|
||||
|
||||
except Exception as e:
|
||||
|
||||
return public.returnMsg(False, "添加失败!" + str(e))
|
||||
|
||||
def edit_project_order(self, get):
|
||||
|
||||
try:
|
||||
data = self.load_project_data()
|
||||
if data is None:
|
||||
return public.returnMsg(False, "获取配置文件失败")
|
||||
# 找到指定的项目组
|
||||
for group in data:
|
||||
if group['id']==int(get.id):
|
||||
new_order=get.order.split(',')
|
||||
if sorted(new_order) != sorted(group['order']):
|
||||
return public.returnMsg(False, "无效的容器顺序!")
|
||||
group['order']=new_order
|
||||
if not self.write_to_json(data):
|
||||
return public.returnMsg(False, "写入失败!")
|
||||
return public.returnMsg(True,"容器顺序修改成功!")
|
||||
return public.returnMsg(False,"项目不存在!")
|
||||
except Exception as e:
|
||||
return public.returnMsg(False,"修改失败:"+str(e))
|
||||
|
||||
def edit_group_interval(self, get):
|
||||
try:
|
||||
data = self.load_project_data()
|
||||
if data is None:
|
||||
return public.returnMsg(False, "获取配置文件失败")
|
||||
|
||||
|
||||
# 找到指定的项目
|
||||
for group in data:
|
||||
if group['id'] == int(get.id):
|
||||
# 检查新的项目顺序是否有效
|
||||
group['interval'] = get.interval
|
||||
break
|
||||
else:
|
||||
return public.returnMsg(False, "项目不存在!")
|
||||
|
||||
if not self.write_to_json(data):
|
||||
return public.returnMsg(False, "写入失败!")
|
||||
|
||||
return public.returnMsg(True, "项目时间间隔修改成功!")
|
||||
except Exception as e:
|
||||
return public.returnMsg(False, "修改失败!" + str(e))
|
||||
|
||||
def start_projects_in_order(self, get):
|
||||
|
||||
try:
|
||||
data = self.load_project_data()
|
||||
if data is None:
|
||||
return public.returnMsg(False, "获取配置文件失败")
|
||||
project_list=docker().get_list(get)['container_list']
|
||||
|
||||
for group in data:
|
||||
if group['id']==int(get.id):
|
||||
# 如果pid存在并且进程仍在运行,那么就不允许用户再次启动项目
|
||||
if 'start_pid' in group and self.is_process_running(group['start_pid']):
|
||||
return public.returnMsg(False,"正在依次启动容器中!")
|
||||
|
||||
project_order=group['order']
|
||||
|
||||
running_projects=[project for project in project_order if self.is_project_running(project,project_list)]
|
||||
|
||||
if running_projects and not get.get("force_stop",False):
|
||||
return public.returnMsg(False,"以下容器正在运行:{}。是否允许先强制停止再启动?您也可以选择自己手动停止运行中的容器!".format(",".join(running_projects)))
|
||||
|
||||
with open('/dev/null','w') as devnull:
|
||||
process=subprocess.Popen(['btpython','/www/server/panel/script/set_docker_project_groups.py','--id',str(group['id']),"--action","start"],stdout=devnull,stderr=devnull)
|
||||
|
||||
|
||||
|
||||
pid=process.pid
|
||||
group['start_pid']=pid
|
||||
if not self.write_to_json(data):
|
||||
return public.returnMsg(False, "写入失败!")
|
||||
|
||||
return public.returnMsg(True, "开始依次启动容器!")
|
||||
except Exception as e:
|
||||
return public.returnMsg(False, "启动失败!"+str(e))
|
||||
|
||||
def is_process_running(self,pid):
|
||||
try:
|
||||
os.kill(pid,0)
|
||||
except OSError:
|
||||
return False
|
||||
else:
|
||||
return True
|
||||
|
||||
|
||||
def is_project_running(self,project_name,project_list):
|
||||
for project in project_list:
|
||||
if project['name']==project_name and project['status']=="running":
|
||||
return True
|
||||
return False
|
||||
|
||||
def stop_projects_in_order(self, get):
|
||||
try:
|
||||
data = self.load_project_data()
|
||||
if data is None:
|
||||
return public.returnMsg(False, "获取配置文件失败")
|
||||
for group in data:
|
||||
if group['id']==int(get.id):
|
||||
# 如果pid存在并且进程仍在运行,那么就不允许用户再次停stop_pid止项目
|
||||
if 'stop_pid' in group and self.is_process_running(group['stop_pid']):
|
||||
return public.returnMsg(False,"正在依次停止容器中!")
|
||||
with open("/dev/null","w") as devnull:
|
||||
process=subprocess.Popen(['btpython','/www/server/panel/script/set_docker_project_groups.py','--id',str(group['id']),"--action","stop"],stdout=devnull,stderr=devnull)
|
||||
|
||||
pid=process.pid
|
||||
group['stop_pid']=pid
|
||||
if not self.write_to_json(data):
|
||||
return public.returnMsg(False, "写入失败!")
|
||||
return public.returnMsg(True,"容器开始按顺序停止")
|
||||
|
||||
except Exception as e:
|
||||
return public.returnMsg(False, "停止失败!" + str(e))
|
||||
|
||||
|
||||
def start_group(self, args_id):
|
||||
|
||||
try:
|
||||
get = public.dict_obj()
|
||||
data = self.load_project_data()
|
||||
if data is None:
|
||||
return public.returnMsg(False, "获取配置文件失败")
|
||||
# 找到指定的项目
|
||||
for group in data:
|
||||
if group['id'] == int(args_id):
|
||||
# 获取项目排序
|
||||
project_order = group['order']
|
||||
|
||||
# 停止所有项目
|
||||
for project_name in project_order:
|
||||
container_id = None
|
||||
for project in group['projects']:
|
||||
if project['project_name'] == project_name:
|
||||
container_id = project['project_id']
|
||||
break
|
||||
if container_id:
|
||||
# print()
|
||||
# docker().set_container_status(public.dict_obj({
|
||||
# "id": container_id,
|
||||
# "status": "stop"
|
||||
# }))
|
||||
print(33333333333333)
|
||||
get.status = "stop"
|
||||
get.id = container_id
|
||||
docker().set_container_status(get)
|
||||
# time.sleep(30)
|
||||
# 依次启动项目
|
||||
for project_name in project_order:
|
||||
container_id = None
|
||||
for project in group['projects']:
|
||||
if project['project_name'] == project_name:
|
||||
container_id = project['project_id']
|
||||
break
|
||||
if container_id:
|
||||
# print()
|
||||
# docker().set_container_status(public.dict_obj({
|
||||
# "id": container_id,
|
||||
# "status": "stop"
|
||||
# }))
|
||||
get.status = "start"
|
||||
get.id = container_id
|
||||
start_result=docker().set_container_status(get)
|
||||
|
||||
if not start_result['status']:
|
||||
return start_result # 如果启动失败,立即返回错误信息
|
||||
|
||||
# 暂停指定的时间间隔
|
||||
time.sleep(int(group['interval']))
|
||||
if not self.is_process_running(group['pid']):
|
||||
# 删除pid
|
||||
del group['pid']
|
||||
if not self.write_to_json(data):
|
||||
return public.returnMsg(False, "写入失败!")
|
||||
except Exception as e:
|
||||
print("启动失败!" + str(e))
|
||||
|
||||
|
||||
def stop_group(self, args_id):
|
||||
|
||||
|
||||
try:
|
||||
get = public.dict_obj()
|
||||
data = self.load_project_data()
|
||||
if data is None:
|
||||
return public.returnMsg(False, "获取配置文件失败")
|
||||
# 找到指定的项目
|
||||
for group in data:
|
||||
if group['id'] == int(args_id):
|
||||
# 获取项目排序
|
||||
project_order = group['order']
|
||||
|
||||
# 停止所有项目
|
||||
for project_name in project_order:
|
||||
container_id = None
|
||||
for project in group['projects']:
|
||||
if project['project_name'] == project_name:
|
||||
container_id = project['project_id']
|
||||
break
|
||||
if container_id:
|
||||
get.status = "stop"
|
||||
get.id = container_id
|
||||
docker().set_container_status(get)
|
||||
except Exception as e:
|
||||
print("启动失败!" + str(e))
|
||||
|
||||
def modify_group_status(self, get):
|
||||
group_ids=[int(id) for id in get.id.split(",")]
|
||||
|
||||
for group_id in group_ids:
|
||||
get.id=group_id
|
||||
if get.status=="1":
|
||||
return self.start_projects_in_order(get)
|
||||
elif get.status=="0":
|
||||
return self.stop_projects_in_order(get)
|
||||
else:
|
||||
return public.returnMsg(False,"无效的状态!")
|
||||
|
||||
|
||||
|
||||
def add_project_to_group(self, get):
|
||||
|
||||
try:
|
||||
|
||||
data = self.load_project_data()
|
||||
if data is None:
|
||||
return public.returnMsg(False, "获取配置文件失败")
|
||||
# 检查项目是否已被其他项目组添加
|
||||
for group in data:
|
||||
for project in group['projects']:
|
||||
if project['project_name']==get.project_name:
|
||||
return public.returnMsg(False,"容器 {} 已经被项目组 {} 添加了!".format(get.project_name,group['group_name']))
|
||||
for group in data:
|
||||
if group['id']==int(get.id):
|
||||
new_project={
|
||||
"project_id":get.project_id,
|
||||
"project_name":get.project_name,
|
||||
|
||||
|
||||
}
|
||||
group['projects'].append(new_project)
|
||||
group['order'].append(get.project_name)
|
||||
break
|
||||
|
||||
|
||||
if not self.write_to_json(data):
|
||||
return public.returnMsg(False, "写入失败!")
|
||||
|
||||
return public.returnMsg(True, "容器添加成功!")
|
||||
except Exception as e:
|
||||
return public.returnMsg(False, "添加失败!" + str(e))
|
||||
|
||||
def remove_project_from_group(self, get):
|
||||
try:
|
||||
data = self.load_project_data()
|
||||
if data is None:
|
||||
return public.returnMsg(False, "获取配置文件失败")
|
||||
|
||||
# 将 get.project_name 分割成一个列表
|
||||
project_names=get.project_name.split(",")
|
||||
|
||||
# 找到指定的项目
|
||||
for group in data:
|
||||
if group['id']==int(get.id):
|
||||
# 删除指定的项目组
|
||||
group['projects']=[project for project in group['projects'] if project['project_name'] not in project_names]
|
||||
# 同时更新order列表,移除已删除的项目名称
|
||||
group['order'] = [project_name for project_name in group['order'] if project_name not in project_names]
|
||||
break
|
||||
else:
|
||||
return public.returnMsg(False,"项目不存在!")
|
||||
|
||||
# 将更新后的数据写回文件
|
||||
if not self.write_to_json(data):
|
||||
return public.returnMsg(False, "写入失败!")
|
||||
|
||||
return public.returnMsg(True, "容器删除成功!")
|
||||
except Exception as e:
|
||||
return public.returnMsg(False, "删除失败!" + str(e))
|
||||
|
||||
def delete_project_group(self, get):
|
||||
|
||||
try:
|
||||
data = self.load_project_data()
|
||||
if data is None:
|
||||
return public.returnMsg(False, "获取配置文件失败")
|
||||
|
||||
# 将 get.id 分割成一个列表
|
||||
group_ids=[int(id) for id in get.id.split(",")]
|
||||
# 找到并删除指定的项目
|
||||
data=[group for group in data if group['id'] not in group_ids]
|
||||
# 将更新后的数据写回文件
|
||||
if not self.write_to_json(data):
|
||||
return public.returnMsg(False, "写入失败!")
|
||||
|
||||
return public.returnMsg(True, "项目删除成功!")
|
||||
except Exception as e:
|
||||
return public.returnMsg(False, "删除失败!" + str(e))
|
||||
Reference in New Issue
Block a user