feat: git node

This commit is contained in:
李如威 2025-08-25 14:57:26 +08:00
parent bd7a0e44bd
commit a66dd72594
5 changed files with 96 additions and 9 deletions

View File

@ -27,7 +27,7 @@ ch = logging.StreamHandler()
ch.setLevel(logging.DEBUG)
# 设置带颜色的 formatter
formatter = ColorFormatter("%(levelname)s: \t %(name)s - %(asctime)s\n%(message)s")
formatter = ColorFormatter("%(levelname)s: \t %(name)s - %(asctime)s - %(message)s")
ch.setFormatter(formatter)
logger.addHandler(ch)

View File

@ -158,13 +158,17 @@ def create_app():
a800_node.set_id("1")
nodes.append(a800_node)
a800_git_node = F.GitNode()
a800_git_node.set_id("2")
nodes.append(a800_git_node)
# 设置依赖关系
# node0 - "true" >> node1 - "true" >> node2
for i in range(len(nodes) -1):
# nodes[i] - "error" >> nodes[i + 1]
pass
flow = F.AsyncFlow(a800_node)
flow = F.AsyncFlow(a800_git_node)
flow.set_params(
{
"0": {
@ -211,6 +215,20 @@ def create_app():
"port": 6378,
"sudo": True,
},
"2": {
"host": "58.214.239.10",
"user": "dgx07",
"password": "f=bHt/.7kRo:KIXq",
"port": 6378,
"sudo": True,
"git_path": "/data/PAI/demo/dbpai-web",
"git_user": "liruwei",
"git_password": "Wsad.8246",
"git_url": "https://tencentgit.dabby.com.cn/dbpai/dbpai-web.git",
"git_branch": "v3.4.2",
"git_clone_type": "http/https",
"git_clone_depth": 0,
},
}
)
shared = {}

View File

@ -1,2 +1,3 @@
from core.pocket_flow import AsyncFlow
from .cmd_node import *
from .cmd_node import *
from .git_node import *

View File

@ -1,5 +1,4 @@
from core.pocket_flow import AsyncNode
from core.logger import logger
import asyncio
import asyncssh
@ -23,6 +22,7 @@ async def async_run_cmd(
text = line
if not isinstance(text, str):
text = line.decode()
print(text)
yield stream_type, text.rstrip()
if not host:
@ -129,7 +129,6 @@ class CmdNode(AsyncNode):
err.append(str(line))
else:
out.append(str(line))
logger.info(line)
err_str = "\n".join(err)
out_str = "\n".join(out)

View File

@ -1,17 +1,86 @@
from core.pocket_flow import AsyncNode
from core.logger import logger
from .cmd_node import async_run_cmd
from pathlib import Path
class GitNode(AsyncNode):
def set_id(self, id):
self.id = id
async def prep_async(self, shared):
pass
return {
"client": {
"host": self.params[self.id].get("host"),
"user": self.params[self.id].get("user"),
"password": self.params[self.id].get("password"),
"port": self.params[self.id].get("port"),
"sudo": self.params[self.id].get("sudo", False),
},
"git": {
"url": self.params[self.id].get("git_url"),
"user": self.params[self.id].get("git_user"),
"password": self.params[self.id].get("git_password"),
"branch": self.params[self.id].get("git_branch"),
"path": self.params[self.id].get("git_path"),
"clone_type": self.params[self.id].get("git_clone_type", "http/https"),
"depth": self.params[self.id].get("git_clone_depth", 1)
},
}
async def exec_async(self, prep_res):
client:dict = prep_res.get("client")
git:dict = prep_res.get("git")
path = git.get("path")
git_path = str(Path(path) / ".git")
parent_path = str(Path(path).parent)
clone_url:str = git.get('url')
clone_type = git.get("clone_type")
clone_branch = git.get("branch")
clone_depth = git.get("depth")
if clone_type == "http/https":
_info = clone_url.split("://")
user = git.get("user")
password = git.get("password")
clone_url = f"{_info[0]}://{user}:{password}@{_info[-1]}"
cmd = (
f"mkdir -p {parent_path} \n"
f"cd {parent_path} \n"
f"[ ! -d '{git_path}' ] && git clone -b {clone_branch} --single-branch --depth=1 --quiet {clone_url} \n"
f"cd {path} \n"
"git stash \n"
f"git fetch --depth=1 origin {clone_branch} --quiet \n"
f"git switch -C {clone_branch} FETCH_HEAD"
)
if clone_depth == 0:
cmd = f"{cmd} \n[ -e .git/shallow ] && git fetch --unshallow --quiet"
logger.info(cmd)
err = []
out = []
async for stream_type, line in async_run_cmd(**client, cmd=cmd):
if stream_type == "stderr":
err.append(str(line))
else:
out.append(str(line))
err_str = "\n".join(err)
out_str = "\n".join(out)
# 补充一下密码失效问题
if "Sorry, try again." in out_str and not err_str:
err_str = "SSH connection failed no password was provided"
return {"err": err_str, "out": out_str}
return None
async def post_async(self, shared, prep_res, exec_res):
if exec_res:
return "true"
else:
shared[self.id] = exec_res
if exec_res.get("err"):
return "false"
return "true"