|
|
@ -15,6 +15,7 @@ from mycode.WebSocketManager import g_WSM |
|
|
|
from mycode.CommandVerify import g_CV |
|
|
|
from mycode.PythonTManager import PythonTManager |
|
|
|
from mycode.DataFilterManager import DataFilterManager |
|
|
|
from myutils.ReadWriteLock import ReadWriteLock |
|
|
|
import asyncio |
|
|
|
import queue |
|
|
|
import time |
|
|
@ -46,31 +47,72 @@ class TaskObject: |
|
|
|
self.task_status = 0 #0-暂停,1-执行中,2-已完成 3-未启动,2025-4-27为配合批量添加任务增加“未启动”状态 |
|
|
|
self.local_ip = local_ip |
|
|
|
self.attack_tree = None #任务节点树 |
|
|
|
self.attack_tree_lock = None #把节点的Lock外置 |
|
|
|
self.safe_rank = safe_rank #安全级别 0-9 #?暂时还没实现更新逻辑 |
|
|
|
self.is_had_work = False |
|
|
|
self.is_had_work_lock = threading.Lock() |
|
|
|
|
|
|
|
#读写锁 |
|
|
|
self.rwlock = ReadWriteLock() |
|
|
|
#指令执行相关------- |
|
|
|
self.max_thread_num = num_threads #指令执行线程数量 |
|
|
|
self.workth_list = [None] * num_threads #线程句柄list |
|
|
|
self.workth_node_list = [None] * num_threads # 线程句柄list |
|
|
|
self.doing_instr_list= [""] * num_threads |
|
|
|
self.instr_node_queue = queue.Queue() #待执行指令的节点队列 |
|
|
|
self.node_num = 0 #在处理Node线程的处理 |
|
|
|
#llm执行相关-------- |
|
|
|
self.llm_max_nums = myCongif.get_data("LLM_max_threads") # 控制最大并发指令数量 --- 多线程的话节点树需要加锁 |
|
|
|
self.llmth_list = [None] * self.llm_max_nums # llm线程list |
|
|
|
self.llmth_node_list = [None] * self.llm_max_nums # llm线程--node |
|
|
|
self.doing_llm_list = [""] * self.llm_max_nums |
|
|
|
self.llm_node_queue = queue.Queue() #待提交LLM的节点队列 |
|
|
|
#自检线程----------- |
|
|
|
self.check_th = None #自检线程句柄 |
|
|
|
#单步执行控制------- |
|
|
|
self.one_step_num = 0 #单步执行任务次数,默认1 |
|
|
|
#-----四队列------- |
|
|
|
self.run_instr_lock = threading.Lock() # 线程锁 |
|
|
|
self.runing_instr = {} #执行中指令记录 |
|
|
|
|
|
|
|
#---------------三个线程------------ |
|
|
|
#测试指令执行线程 |
|
|
|
|
|
|
|
#读取待办指令节点 |
|
|
|
def get_instr_node(self,index): |
|
|
|
self.rwlock.acquire_read() |
|
|
|
try: |
|
|
|
self.workth_node_list[index] = self.instr_node_queue.get(block=False) |
|
|
|
except queue.Empty: |
|
|
|
self.workth_node_list[index] = None |
|
|
|
finally: |
|
|
|
self.rwlock.release_read() |
|
|
|
|
|
|
|
def put_instr_node(self,node): |
|
|
|
#self.instr_node_queue.put(node) |
|
|
|
self.rwlock.acquire_read() |
|
|
|
try: |
|
|
|
self.instr_node_queue.put(node) |
|
|
|
finally: |
|
|
|
self.rwlock.release_read() |
|
|
|
|
|
|
|
#读取待办llm节点 |
|
|
|
def get_llm_node(self,index): |
|
|
|
self.rwlock.acquire_read() |
|
|
|
try: |
|
|
|
self.llmth_node_list[index] = self.llm_node_queue.get(block=False) |
|
|
|
except queue.Empty: |
|
|
|
self.llmth_node_list[index] = None |
|
|
|
finally: |
|
|
|
self.rwlock.release_read() |
|
|
|
|
|
|
|
def put_llm_node(self,node): |
|
|
|
# self.llm_node_queue.put(node) |
|
|
|
self.rwlock.acquire_read() |
|
|
|
try: |
|
|
|
self.llm_node_queue.put(node) |
|
|
|
finally: |
|
|
|
self.rwlock.release_read() |
|
|
|
|
|
|
|
|
|
|
|
def mill_instr_preprocess(self,instructions,str_split): |
|
|
|
new_instr = [] |
|
|
|
instrs = instructions.split(str_split) |
|
|
@ -129,13 +171,14 @@ class TaskObject: |
|
|
|
bnode_work = False |
|
|
|
while self.brun: |
|
|
|
if self.task_status == 1: |
|
|
|
try: |
|
|
|
self.get_instr_node(th_index) #获取一个待办节点 |
|
|
|
if self.workth_node_list[th_index]: |
|
|
|
work_node = self.workth_node_list[th_index] |
|
|
|
llm_type = 1 |
|
|
|
work_node = self.instr_node_queue.get(block=False)#正常一个队列中一个节点只会出现一次,进而也就只有一个线程在处理 |
|
|
|
# 开始执行指令 |
|
|
|
bnode_work = True |
|
|
|
results = [] |
|
|
|
while True: |
|
|
|
while True: #遍历节点待执行指令,执行 |
|
|
|
instruction = work_node.get_instr() |
|
|
|
if not instruction: |
|
|
|
break |
|
|
@ -155,18 +198,16 @@ class TaskObject: |
|
|
|
fake_inst,fake_resul = self.DataFilter.filter_result(instr,reslut) |
|
|
|
oneres = {'执行指令': fake_inst, '结果': fake_resul} |
|
|
|
results.append(oneres) #结果入队列后,指令就不能回退 |
|
|
|
#一条指令执行完成 |
|
|
|
self.doing_instr_list[th_index] = "" |
|
|
|
|
|
|
|
#节点执行完成后置空 |
|
|
|
self.doing_instr_list[th_index] = "" |
|
|
|
#指令都执行结束后,入节点待提交队列 |
|
|
|
str_res = json.dumps(results, ensure_ascii=False) |
|
|
|
# 提交llm待处理任务 --更新节点work_status |
|
|
|
if work_node.do_sn >= myCongif.get_data("max_do_sn"): # 该节点执行指令已超过10条 |
|
|
|
llm_type = 10 |
|
|
|
self.put_node_reslist(work_node, str_res, llm_type) |
|
|
|
# 保存记录 |
|
|
|
g_PKM.WriteData(self.attack_tree,str(self.task_id)) |
|
|
|
|
|
|
|
except queue.Empty: |
|
|
|
else: |
|
|
|
if bnode_work: |
|
|
|
bnode_work = False |
|
|
|
self.no_work_to_do() #判断是否需要把当前任务的无工作状态推送到前端 |
|
|
@ -187,10 +228,12 @@ class TaskObject: |
|
|
|
th_DBM.connect() |
|
|
|
th_index = index |
|
|
|
bnode_work = False |
|
|
|
max_llm_sn = myCongif.get_data("max_llm_sn") |
|
|
|
while self.brun: |
|
|
|
if self.task_status == 1: |
|
|
|
try: |
|
|
|
llm_node = self.llm_node_queue.get(block=False) #获取一个待处理节点 |
|
|
|
self.get_llm_node(th_index) |
|
|
|
if self.llmth_node_list[th_index]: |
|
|
|
llm_node = self.llmth_node_list[th_index] |
|
|
|
#开始处理 |
|
|
|
bnode_work = True |
|
|
|
tmp_commands = [] |
|
|
@ -208,6 +251,13 @@ class TaskObject: |
|
|
|
break |
|
|
|
llm_type = llm_data["llm_type"] |
|
|
|
str_res = llm_data["result"] |
|
|
|
#判断执行次数 |
|
|
|
llm_node.llm_sn += 1 |
|
|
|
if llm_node.llm_sn == max_llm_sn: #提交次数达到上限后,提示LLM结束该节点任务 |
|
|
|
llm_type = 10 |
|
|
|
#该节点的剩余任务不执行,若有--暂定 |
|
|
|
llm_node.clear_res() |
|
|
|
|
|
|
|
#获取提示词 |
|
|
|
prompt = self.get_llm_prompt(llm_type,str_res,user_Prompt) |
|
|
|
fake_prompt = self.DataFilter.filter_prompt(prompt) #目标脱敏 |
|
|
@ -221,7 +271,6 @@ class TaskObject: |
|
|
|
continue #丢弃 --若需要再次尝试,把llm_data再入队列 |
|
|
|
# LLM记录存数据库 |
|
|
|
if th_DBM.ok: |
|
|
|
llm_node.llm_sn += 1 |
|
|
|
bres = th_DBM.insert_llm(self.task_id, prompt, reasoning_content, content, post_time, llm_node.llm_sn,llm_node.path) |
|
|
|
if not bres: |
|
|
|
self.logger.error(f"{llm_node.name}-llm入库失败!") |
|
|
@ -236,21 +285,21 @@ class TaskObject: |
|
|
|
bok, new_commands,iadd_node = self.tree_manager(node_cmds, llm_node, commands, th_DBM) |
|
|
|
# 分析指令入对应节点 |
|
|
|
if bok: # 节点指令若存在错误,测试指令都不处理,需要LLM重新生成 |
|
|
|
#tmp_commands.extend(new_commands) |
|
|
|
# 测试指令入节点待处理队列 --同时修改节点的work_status |
|
|
|
self.put_node_instrlist(new_commands, llm_node, iadd_node) |
|
|
|
|
|
|
|
self.doing_llm_list[th_index] = "" |
|
|
|
tmp_commands.extend(new_commands) |
|
|
|
#节点的待提交任务都完成后,统一处理指令 |
|
|
|
self.put_node_instrlist(tmp_commands, llm_node) |
|
|
|
#一个节点完成,节点树持久化---待验证是否有局部更新持久化的方案 |
|
|
|
g_PKM.WriteData(self.attack_tree,str(self.task_id)) |
|
|
|
#推送前端刷新数据 |
|
|
|
if self.taskM.web_cur_task == self.task_id: # 如果新增了节点,且该节点树是当前查看的数据,需要通知前端更新数据 |
|
|
|
#推送前端刷新数据--执行一个节点就刷新一次 |
|
|
|
if self.taskM.web_cur_task == self.task_id: |
|
|
|
idatatype = 2 |
|
|
|
strdata = "update accack_tree!" |
|
|
|
asyncio.run(g_WSM.send_data(idatatype, strdata)) |
|
|
|
# 先取消当前task,已经通知前端重新获取,这样可以避免后端不必要的数据推送 |
|
|
|
#self.taskM.web_cur_task = 0 |
|
|
|
except queue.Empty: |
|
|
|
# 一个节点执行完成后再置空 |
|
|
|
self.doing_llm_list[th_index] = "" |
|
|
|
else: |
|
|
|
if bnode_work: |
|
|
|
bnode_work = False |
|
|
|
self.no_work_to_do() # 判断是否需要把当前任务的无工作状态推送到前端 |
|
|
@ -266,30 +315,36 @@ class TaskObject: |
|
|
|
self.is_had_work = True |
|
|
|
return bsuccess |
|
|
|
|
|
|
|
def no_work_to_do(self): #任务单步状态控制-- 非工作中--2025-5-7增加了轮次,需要全面验证执行逻辑的完整和正确性 |
|
|
|
# 待执行instr-node |
|
|
|
instr_node_list = list(self.instr_node_queue.queue) # 待执行指令的node--线程不安全 |
|
|
|
llm_node_list = list(self.llm_node_queue.queue) # 待提交llm的node--线程不安全 |
|
|
|
if len(instr_node_list) == 0 and len(llm_node_list) == 0: #没有待办节点了 |
|
|
|
#遍历在执行 |
|
|
|
for str_instr in self.doing_instr_list: |
|
|
|
if str_instr != "": |
|
|
|
return |
|
|
|
for str_llm in self.doing_llm_list: |
|
|
|
if str_llm != "": |
|
|
|
return |
|
|
|
def is_work_doing(self): |
|
|
|
'''检查是否还有在执行的事项''' |
|
|
|
#获取队列快照 |
|
|
|
self.rwlock.acquire_write() |
|
|
|
try: |
|
|
|
instr_node_list = list(self.instr_node_queue.queue) # 待执行指令的node |
|
|
|
llm_node_list = list(self.llm_node_queue.queue) # 待提交llm的node |
|
|
|
wth_n_list = self.workth_node_list.copy() |
|
|
|
lth_n_list = self.llmth_node_list.copy() |
|
|
|
finally: |
|
|
|
self.rwlock.release_write() |
|
|
|
#只针对这个快照数据进行判断 |
|
|
|
#先判断正在执行节点是否有值 --- |
|
|
|
for do_node in wth_n_list: |
|
|
|
if do_node: |
|
|
|
return True |
|
|
|
for do_node in lth_n_list: |
|
|
|
if do_node: |
|
|
|
return True |
|
|
|
#再判断待办节点 |
|
|
|
if len(instr_node_list) == 0 and len(llm_node_list) == 0: |
|
|
|
return False |
|
|
|
return True |
|
|
|
|
|
|
|
#是否需要线程锁-待定 |
|
|
|
def no_work_to_do(self): #任务单步状态控制-- 非工作中--2025-5-7增加了轮次,需要全面验证执行逻辑的完整和正确性 |
|
|
|
#是否还有在执行事项 |
|
|
|
bworking = self.is_work_doing() |
|
|
|
if not bworking: |
|
|
|
# 没有在执行任务了 |
|
|
|
self.one_step_num -= 1 |
|
|
|
if not self.one_step_num: # 执行轮次已结束 |
|
|
|
pass |
|
|
|
else:#发起新的一轮 |
|
|
|
bok = self.put_one_task() |
|
|
|
if not bok: |
|
|
|
self.one_step_num = 0 |
|
|
|
#结束轮次--推送前端 |
|
|
|
|
|
|
|
|
|
|
|
#推送是否有工作任务的状态到前端, |
|
|
|
with self.is_had_work_lock: |
|
|
|
if self.is_had_work: #如果已经是False那就不需要修改了 |
|
|
@ -306,6 +361,7 @@ class TaskObject: |
|
|
|
icount = 0 |
|
|
|
while self.brun: |
|
|
|
try: |
|
|
|
bworking = False |
|
|
|
cur_time = get_local_timestr() |
|
|
|
print(f"----------{self.task_id}-当前时间程序运行情况:{cur_time}") |
|
|
|
#执行中instr-node |
|
|
@ -315,6 +371,7 @@ class TaskObject: |
|
|
|
print(f"Work线程-{index}已处于异常状态,需要重新创建一个工作线程") |
|
|
|
else: |
|
|
|
if self.doing_instr_list[index]: |
|
|
|
bworking =True |
|
|
|
print(f"Work线程-{index}-在执行指令:{self.doing_instr_list[index]}") |
|
|
|
index += 1 |
|
|
|
|
|
|
@ -324,8 +381,15 @@ class TaskObject: |
|
|
|
print(f"LLM线程-{index}已处于异常状态,需要重新创建一个LLM线程") |
|
|
|
else: |
|
|
|
if self.doing_llm_list[index]: |
|
|
|
bworking = True |
|
|
|
print(f"LLM线程-{index}-在执行指令:{self.doing_llm_list[index]}") |
|
|
|
index += 1 |
|
|
|
|
|
|
|
#判断任务是否完成 |
|
|
|
bover = self.is_over() |
|
|
|
if bover and not bworking: |
|
|
|
self.stop_task() #自己停自己--确保没有阻塞操作 |
|
|
|
break #退出循环--结束线程 |
|
|
|
#处理点修复操作 |
|
|
|
icount +=1 |
|
|
|
if icount == 5: |
|
|
@ -340,12 +404,12 @@ class TaskObject: |
|
|
|
#------------入两个nodeMQ-禁止直接调用入队列----------- |
|
|
|
def put_instr_mq(self,node): |
|
|
|
#这里不做状态的判断,调用前处理 |
|
|
|
self.instr_node_queue.put(node) |
|
|
|
self.put_instr_node(node) |
|
|
|
self.update_node_work_status(node,2) #在执行--1.work_status不影响整个任务的执行,错了问题不大,2--attack_tree持久化需要出去lock信息。 |
|
|
|
|
|
|
|
def put_llm_mq(self,node): |
|
|
|
#同instr_mq |
|
|
|
self.llm_node_queue.put(node) |
|
|
|
self.put_llm_node(node) |
|
|
|
self.update_node_work_status(node,4) #提交中 |
|
|
|
|
|
|
|
async def put_instr_mq_async(self,node): |
|
|
@ -376,8 +440,11 @@ class TaskObject: |
|
|
|
node.add_res(one_llm) # 入节点结果队列 |
|
|
|
self.update_node_work_status(node,3) #待提交llm |
|
|
|
# 如果是自动执行的模式则入队列交给llm线程处理 |
|
|
|
if self.app_work_type == 1: |
|
|
|
if self.work_type == 1 and node.bwork: |
|
|
|
if node.bwork: #节点是工作状态 |
|
|
|
if self.work_type == 1: #自动模式 |
|
|
|
self.put_llm_mq(node) #变4 |
|
|
|
elif self.work_type == 0 and node.step_num > 0: #人工模式,但是单步步次还没有执行完成 |
|
|
|
node.step_num -= 1 |
|
|
|
self.put_llm_mq(node) #变4 |
|
|
|
|
|
|
|
#递归找节点 |
|
|
@ -399,7 +466,7 @@ class TaskObject: |
|
|
|
command = command.replace("& &","&&") |
|
|
|
return command |
|
|
|
|
|
|
|
def put_node_instrlist(self, commands, node,iadd_node): #如果当前节点没有进一般指令返回,需要修改节点执行状态 |
|
|
|
def put_node_instrlist(self, commands, node): #如果当前节点没有进一般指令返回,需要修改节点执行状态 |
|
|
|
if not node: |
|
|
|
return |
|
|
|
node_list = [] #有待办指令的节点 |
|
|
@ -413,12 +480,13 @@ class TaskObject: |
|
|
|
instruction = re.sub(r'\[.*?\]', "", command, count=1, flags=re.DOTALL) |
|
|
|
#'''强制约束,不是本节点或者是子节点的指令不处理''' |
|
|
|
find_node = None |
|
|
|
if node_name == node.name: |
|
|
|
if node_name == node.name: #指令是当前节点的 |
|
|
|
find_node = node |
|
|
|
else: |
|
|
|
for child_node in node.children: #暂时只找一层 |
|
|
|
if node_name == child_node.name: |
|
|
|
find_node = child_node |
|
|
|
if child_node.do_sn == 0: #只有没执行过指令的子节点,才允许添加指令 2025-5-9 新增限制 避免父节点和子节点同时有指令执行,提交llm后,父节点返回子节点指令。 |
|
|
|
find_node = child_node |
|
|
|
break |
|
|
|
# find_node = self.attack_tree.find_node_by_nodepath_parent(node_path,node,iadd_node,commands) |
|
|
|
# if not find_node:#对于没有基于节点路径找到对应节点--增加通过节点名称匹配的机制 2025-4-13日添加 |
|
|
@ -444,59 +512,64 @@ class TaskObject: |
|
|
|
if node not in node_list: |
|
|
|
#修改该节点状态为0--无待执行任务 |
|
|
|
self.update_node_work_status(node,0) |
|
|
|
#入instr队列 |
|
|
|
if self.app_work_type == 1: |
|
|
|
if self.work_type == 1: #是自动执行模式 |
|
|
|
for node in node_list: |
|
|
|
if node.bwork: |
|
|
|
self.put_instr_mq(node) #2-执行中 |
|
|
|
#判断是否入instr待办队列---放循环外面是等指令都添加完成后提交待办 |
|
|
|
for node in node_list: |
|
|
|
if node.bwork: |
|
|
|
if self.work_type == 1: #是自动执行模式 |
|
|
|
self.put_instr_mq(node) #2-执行中 |
|
|
|
elif self.work_type == 0 and node.step_num > 0: #人工模式 且剩余步次大于0 |
|
|
|
node.step_num -= 1 |
|
|
|
self.put_instr_mq(node) #2-执行中 |
|
|
|
|
|
|
|
def put_work_node(self): |
|
|
|
'''遍历节点需要处理的任务,提交mq''' |
|
|
|
'''遍历节点需要处理的任务,提交mq,load_task-在自动模式下-触发--线程安全''' |
|
|
|
nodes = self.attack_tree.traverse_bfs() |
|
|
|
for node in nodes: |
|
|
|
if not node.is_instr_empty(): #待执行指令有值 |
|
|
|
if not node.is_llm_empty(): |
|
|
|
self.logger.error(f"{node.path}即存在待执行指令,还存在待提交的llm,需要人工介入!!") |
|
|
|
if not node.bwork: |
|
|
|
continue |
|
|
|
node_work_status = node.get_work_status() |
|
|
|
if node_work_status in (1,2): #待执行指令 |
|
|
|
if node.is_instr_empty():#说明数据有问题了,放弃掉 |
|
|
|
node.update_work_status(-1) #置0 -1作为额外的条件参数 |
|
|
|
else: |
|
|
|
if node.bwork: |
|
|
|
self.put_instr_mq(node) #提交执行 |
|
|
|
elif not node.is_llm_empty(): #待提交llm有值 |
|
|
|
if not node.is_instr_empty(): |
|
|
|
self.logger.error(f"{node.path}即存在待执行指令,还存在待提交的llm,需要人工介入!!") |
|
|
|
self.put_instr_node(node) #1,2都提交执行 |
|
|
|
node.update_work_status(-2)# 置2 |
|
|
|
#llm-list不处理,正常应该为空 |
|
|
|
elif node_work_status in (3,4): |
|
|
|
if node.is_llm_empty():#数据有问题,放弃掉 |
|
|
|
node.update_work_status(-1) |
|
|
|
else: |
|
|
|
if node.bwork: |
|
|
|
self.put_llm_mq(node) #提交执行 |
|
|
|
self.put_llm_node(node) |
|
|
|
node.update_work_status(-3) #置4 |
|
|
|
else: |
|
|
|
pass |
|
|
|
|
|
|
|
#web端提交单步任务--节点单步 |
|
|
|
async def put_one_node(self,node): |
|
|
|
#web端提交单步任务--节点单步--start |
|
|
|
async def put_one_node(self,node,step_num=1): |
|
|
|
#提交某个节点的代表任务 |
|
|
|
if self.task_status ==1 and self.work_type==0 and node.bwork: |
|
|
|
# node_status = node.get_work_status() |
|
|
|
# if node_status == 2 or node_status == 4: |
|
|
|
# return False,"当前节点正在执行任务,请稍后点击单步!" |
|
|
|
if not node.is_instr_empty(): #待执行指令有值 |
|
|
|
if not node.is_llm_empty(): |
|
|
|
self.logger.error(f"{node.path}即存在待执行指令,还存在待提交的llm,需要人工介入!!") |
|
|
|
return False,"该节点的待执行任务数据不正确,请联系管理员!" |
|
|
|
else: |
|
|
|
if node.bwork: |
|
|
|
await self.put_instr_mq_async(node) #提交执行 |
|
|
|
elif not node.is_llm_empty(): #待提交llm有值 |
|
|
|
if not node.is_instr_empty(): |
|
|
|
self.logger.error(f"{node.path}即存在待执行指令,还存在待提交的llm,需要人工介入!!") |
|
|
|
return False, "该节点的待执行任务数据不正确,请联系管理员!" |
|
|
|
iwork_status = node.get_work_status() |
|
|
|
if iwork_status in (1,3): |
|
|
|
node.step_num = step_num - 1 #单步步次赋值 -1 规则提交时-1,执行结束连续判断再提交 |
|
|
|
|
|
|
|
if iwork_status == 1: |
|
|
|
self.put_instr_mq(node) |
|
|
|
else: |
|
|
|
if node.bwork: |
|
|
|
await self.put_llm_mq_async(node) #提交执行 |
|
|
|
self.put_llm_mq(node) |
|
|
|
return True,"已提交单步任务" |
|
|
|
else: |
|
|
|
await self.update_node_work_status_async(node,0) #只是修补措施,保障状态的一致性 |
|
|
|
return False,"当前节点没有待执行任务!" |
|
|
|
return True,"已提交单步任务" |
|
|
|
error = "" |
|
|
|
if iwork_status == 0: |
|
|
|
error = "该节点没有待办任务" |
|
|
|
elif iwork_status in (2,4): |
|
|
|
error = "该节点已经在执行事项中" |
|
|
|
else: |
|
|
|
self.logger.error("noed的工作状态值存在问题,需要人工介入!!") |
|
|
|
return False,error |
|
|
|
else: |
|
|
|
return False,"当前的任务或节点状态不允许执行单步,请检查!" |
|
|
|
|
|
|
|
#web端提交任务单步--任务单步 |
|
|
|
#web端提交任务单步--任务单步---2025-5-8-增加约束,只允许单步启动时调用 |
|
|
|
async def put_one_task(self,step_num): |
|
|
|
if self.task_status == 1 and self.work_type == 0: |
|
|
|
bsuccess = self.had_work_to_do() |
|
|
@ -504,12 +577,14 @@ class TaskObject: |
|
|
|
nodes = self.attack_tree.traverse_bfs() |
|
|
|
b_putwork = False |
|
|
|
for node in nodes: |
|
|
|
bput,_ = await self.put_one_node(node) |
|
|
|
bput,_ = await self.put_one_node(node,step_num) #错误信息有丢失 |
|
|
|
if bput: |
|
|
|
b_putwork = True |
|
|
|
if b_putwork: |
|
|
|
return True,"已提交单步任务" |
|
|
|
else: |
|
|
|
else: #所有节点都没有提交任务 |
|
|
|
#可以尝试stop下 |
|
|
|
self.stop_task() |
|
|
|
return False,"该任务已经没有待提交任务" |
|
|
|
else: |
|
|
|
return False,"当前任务正在执行任务中,不需要提交单步任务!" |
|
|
@ -519,9 +594,9 @@ class TaskObject: |
|
|
|
#修改节点的执行状态,并需要基于websocket推送到前端显示 同步线程调用 |
|
|
|
def update_node_work_status(self,node,work_status): |
|
|
|
#更新状态 |
|
|
|
bchange = node.update_work_status(work_status) |
|
|
|
bchange = node.update_work_status(work_status) #1,3会返回Flase |
|
|
|
#基于websocket推送到前端 |
|
|
|
if bchange and work_status != 1: #llm执行完成后会发送单独的指令更新树,所以不发送1更新节点了 |
|
|
|
if work_status != 1: #llm执行完成后会发送单独的指令更新树,所以不发送1更新节点了 |
|
|
|
#判断是否是web端最新获取数据的task |
|
|
|
if self.taskM.web_cur_task == self.task_id: |
|
|
|
idatatype = 1 |
|
|
@ -594,6 +669,7 @@ class TaskObject: |
|
|
|
bok,strerror = g_CV.verify_node_cmds(node_cmds) |
|
|
|
if not bok: #节点指令存在问题,则不进行后续处理,提交一个错误反馈任务 |
|
|
|
# 提交llm待处理任务 |
|
|
|
node.step_num += 1 #单步次数还原一个--暂时只针对有效的返回才算一次 |
|
|
|
self.put_node_reslist(node, strerror, 2) |
|
|
|
return False,commands,0 |
|
|
|
#message_调整传递时机后,可以先执行添加节点 |
|
|
@ -767,7 +843,7 @@ class TaskObject: |
|
|
|
# 插入一个user消息 |
|
|
|
# 提交第一个llm任务,开始工作 |
|
|
|
know_info = f"本测试主机的IP地址为:{self.local_ip}" |
|
|
|
self.put_node_reslist(root_node, know_info, 0) # 入待提交list |
|
|
|
self.put_node_reslist(root_node, know_info, 0) # 入待提交list,若是人工模式则不入待办MQ |
|
|
|
# 初始保存个attack_tree文件 |
|
|
|
g_PKM.WriteData(self.attack_tree, str(self.task_id)) |
|
|
|
|
|
|
@ -812,6 +888,8 @@ class TaskObject: |
|
|
|
:return bool str |
|
|
|
''' |
|
|
|
if self.is_task_stop(): |
|
|
|
if self.is_over(): #只是判断了待办list,在执行的会漏判断 |
|
|
|
return False, "该任务所有未暂停节点的待办事项都已经结束" |
|
|
|
#更新状态标识 |
|
|
|
self.update_task_status(1) |
|
|
|
self.brun = True #线程正常启动 |
|
|
@ -835,14 +913,31 @@ class TaskObject: |
|
|
|
return False,"该任务的工作线程未全面停止,不能重新启动工作,请稍后,若半个小时候还不能启动,请联系技术支持!" |
|
|
|
|
|
|
|
def stop_task(self): #还未处理 |
|
|
|
if self.brun and self.task_status ==1: #不是正常工作状态就不执行停止工作了 |
|
|
|
if self.brun and self.task_status == 1: #不是正常工作状态就不执行停止工作了 |
|
|
|
#停止子进程池 |
|
|
|
self.PythonM.shutdown_pool() |
|
|
|
#停止线程 |
|
|
|
self.brun = False |
|
|
|
self.update_task_status(0) |
|
|
|
self.update_task_status(0) #置状态0 |
|
|
|
# 结束任务需要收尾处理#? |
|
|
|
self.InstrM.init_data() #pass |
|
|
|
|
|
|
|
def is_over(self): |
|
|
|
''' |
|
|
|
判断当前任务是否所有节点都已结束 |
|
|
|
:return: False-非暂停节点有代表事项,True-非粘贴节点事项都已完成 |
|
|
|
''' |
|
|
|
b_over = True |
|
|
|
nodes = self.attack_tree.traverse_bfs() |
|
|
|
for node in nodes: |
|
|
|
if node.bwork: |
|
|
|
work_status = node.get_work_status() |
|
|
|
if work_status != 0: |
|
|
|
b_over = False # 有一个有任务就不继续进行判断 |
|
|
|
break |
|
|
|
return b_over |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if __name__ == "__main__": |
|
|
|
pass |