Skip to content

Commit 14a6108

Browse files
committed
✨工具拉取支持htttp zip包地址
1 parent d1c3b43 commit 14a6108

12 files changed

Lines changed: 126 additions & 14 deletions
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
# -*- encoding: utf-8 -*-
2+
# Copyright (c) 2022 THL A29 Limited
3+
#
4+
# This source code file is made available under MIT License
5+
# See LICENSE for details
6+
# ==============================================================================
7+
8+
"""
9+
通过http方式拉取工具
10+
"""
11+
12+
import os
13+
14+
from util.logutil import LogPrinter
15+
from util.api.fileserver import RetryFileServer
16+
from util.exceptions import FileServerError
17+
from util.ziplib import ZipMgr
18+
19+
20+
class HttpToolLoader(object):
21+
"""通过http方式拉取工具,如果目录已存在,不拉取"""
22+
@staticmethod
23+
def download_tool(tool_url, dest_dir):
24+
if os.path.exists(dest_dir):
25+
# 工具目录存在时,直接复用,不重新拉取(如需更新,先删除工具目录)
26+
LogPrinter.debug(f"tool dir({os.path.basename(dest_dir)}) from zip can be reused.")
27+
return
28+
29+
tool_root_dir = os.path.dirname(dest_dir)
30+
if not os.path.exists(tool_root_dir): # 如果上层目录不存在,先创建
31+
os.makedirs(tool_root_dir)
32+
zip_file_name = tool_url.split('/')[-1]
33+
dest_zip_file_path = os.path.join(tool_root_dir, zip_file_name)
34+
35+
file_server = RetryFileServer(retry_times=2).get_server(server_url=tool_url)
36+
file_server.download_big_file("", dest_zip_file_path)
37+
38+
if os.path.exists(dest_zip_file_path):
39+
LogPrinter.debug(f"download {tool_url} to {dest_zip_file_path}")
40+
ZipMgr.depress(dest_zip_file_path, tool_root_dir)
41+
LogPrinter.debug(f"unzip {dest_zip_file_path} to {dest_dir}")
42+
else:
43+
raise FileServerError(f"download {tool_url} failed!")
44+
45+
46+
if __name__ == '__main__':
47+
pass

client/node/toolloader/loadconfig.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -310,7 +310,8 @@ def read_config_from_tool_schemes(self, tool_names=None, task_list=None):
310310
new_lib_envs = {}
311311

312312
scm_url = tool_lib.get("scm_url")
313-
lib_dir_name = scm_url.split('/')[-1].strip().replace(".git", "")
313+
# 支持git仓库地址和zip包地址两种格式
314+
lib_dir_name = BaseScmUrlMgr.get_last_dir_name_from_url(scm_url)
314315
lib_dir_path = os.path.join(settings.TOOL_BASE_DIR, lib_dir_name)
315316

316317
# 将环境变量中的$ROOT_DIR替换为实际路径,重新保存到new_lib_envs

client/node/toolloader/loadtool.py

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,16 +18,25 @@
1818
from node.app import settings
1919
from node.toolloader.gitload import GitLoader
2020
from node.toolloader.loadconfig import ConfigLoader, ToolConfig, LoadToolTypes
21+
from node.toolloader.httploadtool import HttpToolLoader
2122
from util.envset import EnvSet
2223
from util.scanlang.callback_queue import CallbackQueue
2324
from util.pathlib import PathMgr
2425
from util.logutil import LogPrinter
2526
from util.scmurlmgr import BaseScmUrlMgr
2627
from util.subprocc import SubProcController
28+
from util.textutil import ZIP_EXT
2729

2830

2931
class ToolCommonLoader(object):
3032
@staticmethod
33+
def is_zip_url(tool_url):
34+
"""判断是否是压缩包地址"""
35+
if tool_url.lower().endswith(ZIP_EXT):
36+
return True
37+
else:
38+
return False
39+
@staticmethod
3140
def load_tool_type(tool_dirpath, tool_dirname, tool_url=None):
3241
"""
3342
判断使用哪种方式加载工具
@@ -38,8 +47,10 @@ def load_tool_type(tool_dirpath, tool_dirname, tool_url=None):
3847
"""
3948
if settings.USE_LOCAL_TOOL == "True":
4049
if os.path.exists(tool_dirpath):
41-
# LogPrinter.info(f"USE_LOCAL_TOOL=True, use local tool dir: {tool_dirpath}")
50+
LogPrinter.info(f"USE_LOCAL_TOOL=True, use local tool dir: {tool_dirpath}")
4251
return "Local", None
52+
elif tool_url and ToolCommonLoader.is_zip_url(tool_url):
53+
return "HTTP", None
4354
else:
4455
return "Git", None
4556
else:
@@ -54,6 +65,8 @@ def load_tool_type(tool_dirpath, tool_dirname, tool_url=None):
5465
return "Copy", tool_dirpath_copy_from
5566
else: # 拷贝源目录不存在,从git拉取
5667
return "Git", None
68+
elif tool_url and ToolCommonLoader.is_zip_url(tool_url):
69+
return "HTTP", None
5770
else:
5871
return "Git", None
5972

@@ -69,6 +82,8 @@ def load_tool(load_type, tool_dirpath, tool_dirpath_copy_from, git_url, scm_auth
6982
:param print_enable:
7083
:return:
7184
"""
85+
if settings.DEBUG:
86+
print_enable = True
7287
if load_type == "Local":
7388
if print_enable:
7489
LogPrinter.info(f"Use local tool dir: {tool_dirpath}")
@@ -78,6 +93,11 @@ def load_tool(load_type, tool_dirpath, tool_dirpath_copy_from, git_url, scm_auth
7893
LogPrinter.info(f"Copy from {tool_dirpath_copy_from} to {tool_dirpath}")
7994
PathMgr().retry_copy(tool_dirpath_copy_from, tool_dirpath)
8095
return tool_dirpath
96+
elif load_type == "HTTP":
97+
if print_enable:
98+
LogPrinter.info(f"Load from {git_url} to {tool_dirpath}")
99+
HttpToolLoader.download_tool(git_url, tool_dirpath)
100+
return tool_dirpath
81101
else:
82102
if print_enable:
83103
LogPrinter.info(f"Load from git to {tool_dirpath} ...")

client/task/basic/downloader.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
import tempfile
1515

1616
from node.app import settings
17-
from task.basic.zipmgr import Zip
17+
from util.zipmgr import Zip
1818
from util.exceptions import TransferModuleError
1919
from util.pathlib import PathMgr
2020
from util.api.fileserver import RetryFileServer

client/task/transfermgr.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717

1818
from task.basic.downloader import Downloader
1919
from node.app import settings
20-
from task.basic.zipmgr import Zip
20+
from util.zipmgr import Zip
2121
from util.exceptions import TransferModuleError
2222
from util.api.fileserver import RetryFileServer
2323
from util.pathlib import PathMgr
2 KB
Binary file not shown.
4.95 KB
Binary file not shown.
9.4 KB
Binary file not shown.
9.47 KB
Binary file not shown.

client/util/api/fileserver.py

Lines changed: 28 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,13 @@
1212
import logging
1313
import hashlib
1414
import os
15+
import ssl
1516

1617
from urllib.parse import urljoin
1718
from util import wrapper
1819
from node.app import settings
1920
from util.api.httpclient import HttpClient
21+
from urllib.request import urlopen
2022

2123
logger = logging.getLogger(__name__)
2224

@@ -46,15 +48,20 @@ def get_sha256(file_path):
4648

4749

4850
class FileServer(object):
49-
def __init__(self):
51+
def __init__(self, server_url=None, headers=None):
5052
"""
5153
构造函数
5254
:return:
5355
"""
54-
# 优先从环境变量读取文件服务器url和token,没有再使用默认值
55-
self._server_url = os.getenv("FILE_SERVER_URL", settings.FILE_SERVER['URL'])
56-
file_server_token = os.getenv("FILE_SERVER_TOKEN", settings.FILE_SERVER['TOKEN'])
57-
self._headers = {'Authorization': 'Token %s' % file_server_token}
56+
if server_url:
57+
self._server_url = server_url
58+
self._headers = headers if headers else {}
59+
else:
60+
# 优先从环境变量读取文件服务器url和token,没有再使用默认值
61+
self._server_url = os.getenv("FILE_SERVER_URL", settings.FILE_SERVER['URL'])
62+
file_server_token = os.getenv("FILE_SERVER_TOKEN", settings.FILE_SERVER['TOKEN'])
63+
self._headers = {'Authorization': 'Token %s' % file_server_token}
64+
5865
self._proxies = None
5966

6067
def modify_save_time(self, rel_dir, days):
@@ -117,6 +124,20 @@ def download_file(self, rel_url, filepath):
117124
wf.write(data)
118125
return filepath
119126

127+
def download_big_file(self, rel_url, filepath):
128+
"""大文件下载"""
129+
context = ssl._create_unverified_context()
130+
download_url = urljoin(self._server_url, rel_url)
131+
resp = urlopen(download_url, context=context)
132+
chunk_size = 16 * 1024
133+
with open(filepath, 'wb') as wf:
134+
while True:
135+
trunk = resp.read(chunk_size)
136+
if not trunk:
137+
break
138+
wf.write(trunk)
139+
return filepath
140+
120141

121142
class RetryFileServer(object):
122143
def __init__(self, retry_times=-1):
@@ -136,10 +157,10 @@ def retry_on_error(self, error, method_name):
136157
"""
137158
return
138159

139-
def get_server(self):
160+
def get_server(self, server_url=None):
140161
"""
141162
获取一个server实例
142163
:return:
143164
"""
144-
file_server = FileServer()
165+
file_server = FileServer(server_url=server_url)
145166
return wrapper.Retry(server=file_server, on_error=self.retry_on_error, total=self._retry_times)

0 commit comments

Comments
 (0)