"""
* 模块名 : clear_occupy.py
* 函数功能: 清理占用工作空间的进程,避免流水线出错,只应用于windows节点。linux不需要
"""
import os
import signal
import subprocess
import sys
import traceback
import chardet
import psutil
def release_opened_file(process_id, file_name):
print(f"开始释放{process_id}对文件{file_name}的占用")
cur_dir = os.path.dirname(os.path.abspath(__file__))
try:
cmd = f"{cur_dir}/handle64.exe /s /accepteula"
ret, info = run_shell(cmd)
if ret:
print(f"静默安装失败:{info}")
cmd = f"{cur_dir}/handle64.exe /v -nobanner {file_name}"
ret, info = run_shell(cmd)
if ret:
print(f"获取{file_name}的handle失败")
file_handles = info.split("\r\n")[1:-1]
os.chdir(cur_dir)
for h in file_handles:
pid = h.split(",")[1]
handle = h.split(",")[3]
if int(pid) == int(process_id):
cmd = f"echo y|handle64.exe -nobanner -p {process_id} -c {handle}"
ret, info = run_shell(cmd)
if ret:
print(f"解除占用失败")
except Exception as e:
print(traceback.format_exc())
def run_shell(cmdline, env=None):
handle = subprocess.Popen(cmdline, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, shell=True, env=env)
data = b""
while True:
line = handle.stdout.readline()
if not line:
break
# print(line)
data += line
ret_code = handle.wait()
if not data:
return ret_code, data
charset = chardet.detect(data)["encoding"]
if charset.lower() == "gb2312":
charset = "gbk"
data_str = data.decode(encoding=charset)
# print("%s -- cost %d s" % (cmdline, (time.time() - time_begin)))
return ret_code, data_str
def clear_occupy_processes(workspace):
processes = []
for process in psutil.process_iter():
processes.append(process)
print(len(processes))
count = 0
for process in processes:
count += 1
# print(count)
try:
proc_info_dict = process.as_dict(attrs=["pid", "name", "cmdline", "cwd"])
print(f"-----{proc_info_dict}-----")
p = psutil.Process(pid=proc_info_dict["pid"])
if "remoting.jar" in proc_info_dict["cmdline"] and proc_info_dict["name"] == "java.exe":
for f in p.open_files():
print(f"opened files: {f[0]}")
if workspace in f[0]:
release_opened_file(proc_info_dict["pid"], f[0])
if proc_info_dict["cmdline"] and is_ws_in_cmdline(workspace, proc_info_dict["cmdline"]):
# print(proc_info_dict)
if "clear_occupy.py" in proc_info_dict["cmdline"][-2]:
print("不清理clear_occupy.py")
continue
if "jenkins-main.bat" in proc_info_dict["cmdline"][-1]:
print("不清理jenkins-main.bat")
continue
if "jenkins-wrap.bat" in proc_info_dict["cmdline"][-1]:
print("不清理jenkins-wrap.bat")
continue
os.kill(proc_info_dict["pid"], signal.SIGINT)
elif proc_info_dict["cwd"] and workspace in proc_info_dict["cwd"]:
print(proc_info_dict)
os.kill(proc_info_dict["pid"], signal.SIGINT)
except Exception as e:
print(e)
if count == len(processes):
break
print("清理完占用进程")
sys.exit(0)
def is_ws_in_cmdline(ws, cmdline):
if cmdline:
for cmd in cmdline:
if ws in cmd:
return True
if __name__ == '__main__':
workspace = sys.argv[1]
workspace = workspace.replace("/", "\\")
print(f"workspace:{workspace}")
clear_occupy_processes(workspace)
找到节点上占用工作空间的进程及进程打开的文件,并且释放文件占用,保证清理工作空间成功
最新推荐文章于 2024-08-24 23:46:07 发布