107 lines
3.6 KiB
Python
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
|