your-workflow/backend/app/nodes/git_node.py

107 lines
3.6 KiB
Python

from fastapi import FastAPI
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_info(self, id, callback):
self.id = id
self.callback = callback
async def prep_async(self, shared):
if self.callback:
await self.callback(self.id, "prep")
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):
if self.callback:
await self.callback(self.id, "exec")
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"
)
if clone_depth == 0:
cmd = (
f"{cmd} \n"
f"git fetch origin {clone_branch} --quiet \n"
f"git switch -C {clone_branch} FETCH_HEAD \n"
f"[ -e .git/shallow ] && git fetch --unshallow --quiet"
)
else:
cmd = (
f"{cmd} \n"
f"git fetch --depth={clone_depth} origin {clone_branch} --quiet \n"
f"git switch -C {clone_branch} FETCH_HEAD"
)
err = []
out = []
ignore_err = [f"Reset branch '{clone_branch}'"]
async for stream_type, line in async_run_cmd(**client, cmd=cmd):
if stream_type == "stdout" or line in ignore_err:
out.append(line)
else:
err.append(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}
async def post_async(self, shared, prep_res, exec_res):
shared[self.id] = exec_res
result = "true"
if exec_res.get("err"):
result = "false"
if self.callback:
await self.callback(self.id, "post")
return result