docs: document repeatable LFS upload path
This commit is contained in:
@@ -23,6 +23,24 @@ GIT_LFS_SKIP_SMUDGE=1 git clone git@192.168.10.248:cogito/calculet-npu-research-
|
|||||||
|
|
||||||
随后可按需执行 `git lfs pull --include='archives/<路径>'`。
|
随后可按需执行 `git lfs pull --include='archives/<路径>'`。
|
||||||
|
|
||||||
|
### 从当前网络追加 LFS 大文件
|
||||||
|
|
||||||
|
Gitea 当前对 SSH LFS 上传返回的内部地址是 `http://gitea/...`。匿名克隆和 LFS 下载通过上面的 IP 地址已经验收;如果贡献者电脑不能解析主机名 `gitea`,SSH 推送 LFS 时可在另一个终端启动仅监听本机回环地址的临时转发:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
python3 scripts/lfs-host-proxy.py --port 18765
|
||||||
|
```
|
||||||
|
|
||||||
|
然后在仓库终端执行:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
http_proxy=http://127.0.0.1:18765 \
|
||||||
|
HTTP_PROXY=http://127.0.0.1:18765 \
|
||||||
|
no_proxy= NO_PROXY= git push
|
||||||
|
```
|
||||||
|
|
||||||
|
推送完成后用 `Ctrl-C` 关闭转发器。长期方案是在 Gitea 服务端把 `ROOT_URL`/LFS 外部地址改成团队实际可解析的 IP 或 DNS 名称。
|
||||||
|
|
||||||
## 目录
|
## 目录
|
||||||
|
|
||||||
| 路径 | 内容 | 用途 |
|
| 路径 | 内容 | 用途 |
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
174185a34cee598ff33cf4b2b75dbe1688d1000478f95f37dcc3f24ecb11cf46 ./.gitattributes
|
174185a34cee598ff33cf4b2b75dbe1688d1000478f95f37dcc3f24ecb11cf46 ./.gitattributes
|
||||||
3f01c5ebf226064b0f0992ea7506c038dfb9d453e35d2864db06f91966b5baaf ./README.md
|
0b94311217982321bcd106d3170256676b2313eda512af1519099b236a5290eb ./README.md
|
||||||
6dda8faa0e2a14362eac47dcdc192094e631fc47a37e978eb0f745e556b4e7be ./checksums/main-archives.sha256
|
6dda8faa0e2a14362eac47dcdc192094e631fc47a37e978eb0f745e556b4e7be ./checksums/main-archives.sha256
|
||||||
4b1b7a92f9502c7d84a240888fac838d43af2bfbe7c821468d148a643dce5d6a ./documentation/Calculet Runtime API C++ 开发文档-v78-20260710_074837.pdf
|
4b1b7a92f9502c7d84a240888fac838d43af2bfbe7c821468d148a643dce5d6a ./documentation/Calculet Runtime API C++ 开发文档-v78-20260710_074837.pdf
|
||||||
4a7c3b83977fc853eebcd8e306dbd9a4f846d9cfb03c89214a088c7034ec632c ./documentation/VPN接入及远程连接.pdf
|
4a7c3b83977fc853eebcd8e306dbd9a4f846d9cfb03c89214a088c7034ec632c ./documentation/VPN接入及远程连接.pdf
|
||||||
@@ -269,6 +269,7 @@ c16023ac93e955138329561a82a0b5932ea168acb1346ec05197bee8f8b96af4 ./reports/Calc
|
|||||||
eb0692b1e09e8c0049ecddc4ecaf84860a4b31375535bbed3716b983f2579b30 ./reports/Calculet-NPU-逐算子优化实验手册-20260802.md
|
eb0692b1e09e8c0049ecddc4ecaf84860a4b31375535bbed3716b983f2579b30 ./reports/Calculet-NPU-逐算子优化实验手册-20260802.md
|
||||||
a81d9dd8e5b8ae475f4eabdb2f187381ea4c45d77aa352c1d7ee30d2dea22502 ./reports/calculet_package_validate.rb
|
a81d9dd8e5b8ae475f4eabdb2f187381ea4c45d77aa352c1d7ee30d2dea22502 ./reports/calculet_package_validate.rb
|
||||||
29727a6e2734c9458ff1853a4f94e7fdf1e109d2fa6b51cd7062a5bd11924479 ./scripts/clone-bundle.sh
|
29727a6e2734c9458ff1853a4f94e7fdf1e109d2fa6b51cd7062a5bd11924479 ./scripts/clone-bundle.sh
|
||||||
|
363b3bf7e2c3d53df0c95843b770e1922b19b044e8be01e6acef088401821747 ./scripts/lfs-host-proxy.py
|
||||||
fa1c6a60eab70ae3ee215f4850313e1abf1ed5765bfd9860e7b3042afa638e17 ./scripts/reassemble-archives.sh
|
fa1c6a60eab70ae3ee215f4850313e1abf1ed5765bfd9860e7b3042afa638e17 ./scripts/reassemble-archives.sh
|
||||||
15e8c8711c017cb9a31a1499ad9f8479216eff47427a303cafbdc34959f797c2 ./scripts/verify-repository.sh
|
15e8c8711c017cb9a31a1499ad9f8479216eff47427a303cafbdc34959f797c2 ./scripts/verify-repository.sh
|
||||||
46ce4c2a910cadf07a9f45d3f2ad0b5a151fbbc9c60a82bbcbb354e0bd71a00e ./source/baseline-expanded/calrt-sdk-0.7.6/usr/local/include/calrt/calrt.h
|
46ce4c2a910cadf07a9f45d3f2ad0b5a151fbbc9c60a82bbcbb354e0bd71a00e ./source/baseline-expanded/calrt-sdk-0.7.6/usr/local/include/calrt/calrt.h
|
||||||
|
|||||||
Executable
+125
@@ -0,0 +1,125 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
import argparse
|
||||||
|
import http.client
|
||||||
|
import shutil
|
||||||
|
from http.server import BaseHTTPRequestHandler, ThreadingHTTPServer
|
||||||
|
from urllib.parse import urlsplit, urlunsplit
|
||||||
|
|
||||||
|
|
||||||
|
HOP_BY_HOP = {
|
||||||
|
"connection",
|
||||||
|
"keep-alive",
|
||||||
|
"proxy-authenticate",
|
||||||
|
"proxy-authorization",
|
||||||
|
"proxy-connection",
|
||||||
|
"te",
|
||||||
|
"trailers",
|
||||||
|
"transfer-encoding",
|
||||||
|
"upgrade",
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
class GiteaProxy(BaseHTTPRequestHandler):
|
||||||
|
protocol_version = "HTTP/1.1"
|
||||||
|
target_host = "192.168.10.248"
|
||||||
|
|
||||||
|
def do_GET(self):
|
||||||
|
self._forward()
|
||||||
|
|
||||||
|
def do_HEAD(self):
|
||||||
|
self._forward(send_body=False)
|
||||||
|
|
||||||
|
def do_POST(self):
|
||||||
|
self._forward()
|
||||||
|
|
||||||
|
def do_PUT(self):
|
||||||
|
self._forward()
|
||||||
|
|
||||||
|
def _forward(self, send_body=True):
|
||||||
|
parsed = urlsplit(self.path)
|
||||||
|
path = urlunsplit(("", "", parsed.path or "/", parsed.query, ""))
|
||||||
|
print(
|
||||||
|
f"{self.command} content-length={self.headers.get('Content-Length')} "
|
||||||
|
f"transfer-encoding={self.headers.get('Transfer-Encoding')}",
|
||||||
|
flush=True,
|
||||||
|
)
|
||||||
|
upstream = http.client.HTTPConnection(self.target_host, 80, timeout=3600)
|
||||||
|
upstream.putrequest(
|
||||||
|
self.command,
|
||||||
|
path,
|
||||||
|
skip_host=True,
|
||||||
|
skip_accept_encoding=True,
|
||||||
|
)
|
||||||
|
|
||||||
|
for name, value in self.headers.items():
|
||||||
|
lower_name = name.lower()
|
||||||
|
if lower_name in HOP_BY_HOP:
|
||||||
|
continue
|
||||||
|
upstream.putheader(name, "gitea" if lower_name == "host" else value)
|
||||||
|
transfer_encoding = self.headers.get("Transfer-Encoding", "").lower()
|
||||||
|
if transfer_encoding == "chunked":
|
||||||
|
upstream.putheader("Transfer-Encoding", "chunked")
|
||||||
|
upstream.endheaders()
|
||||||
|
|
||||||
|
if transfer_encoding == "chunked":
|
||||||
|
self._forward_chunked_body(upstream)
|
||||||
|
else:
|
||||||
|
content_length = int(self.headers.get("Content-Length", "0"))
|
||||||
|
remaining = content_length
|
||||||
|
while remaining:
|
||||||
|
chunk = self.rfile.read(min(1024 * 1024, remaining))
|
||||||
|
if not chunk:
|
||||||
|
raise ConnectionError("request body ended early")
|
||||||
|
upstream.send(chunk)
|
||||||
|
remaining -= len(chunk)
|
||||||
|
|
||||||
|
response = upstream.getresponse()
|
||||||
|
self.send_response(response.status, response.reason)
|
||||||
|
for name, value in response.getheaders():
|
||||||
|
if name.lower() not in HOP_BY_HOP:
|
||||||
|
self.send_header(name, value)
|
||||||
|
self.send_header("Connection", "close")
|
||||||
|
self.end_headers()
|
||||||
|
self.close_connection = True
|
||||||
|
|
||||||
|
if send_body:
|
||||||
|
shutil.copyfileobj(response, self.wfile, 1024 * 1024)
|
||||||
|
upstream.close()
|
||||||
|
|
||||||
|
def _forward_chunked_body(self, upstream):
|
||||||
|
while True:
|
||||||
|
size_line = self.rfile.readline()
|
||||||
|
if not size_line:
|
||||||
|
raise ConnectionError("chunked request ended before size line")
|
||||||
|
upstream.send(size_line)
|
||||||
|
chunk_size = int(size_line.split(b";", 1)[0].strip(), 16)
|
||||||
|
if chunk_size == 0:
|
||||||
|
while True:
|
||||||
|
trailer_line = self.rfile.readline()
|
||||||
|
upstream.send(trailer_line)
|
||||||
|
if trailer_line in (b"\r\n", b"\n", b""):
|
||||||
|
return
|
||||||
|
|
||||||
|
remaining = chunk_size + 2
|
||||||
|
while remaining:
|
||||||
|
data = self.rfile.read(min(1024 * 1024, remaining))
|
||||||
|
if not data:
|
||||||
|
raise ConnectionError("chunked request ended inside data")
|
||||||
|
upstream.send(data)
|
||||||
|
remaining -= len(data)
|
||||||
|
|
||||||
|
def log_message(self, fmt, *args):
|
||||||
|
print("%s - %s" % (self.address_string(), fmt % args), flush=True)
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
parser = argparse.ArgumentParser()
|
||||||
|
parser.add_argument("--port", type=int, default=18765)
|
||||||
|
args = parser.parse_args()
|
||||||
|
server = ThreadingHTTPServer(("127.0.0.1", args.port), GiteaProxy)
|
||||||
|
print(f"Listening on 127.0.0.1:{args.port}", flush=True)
|
||||||
|
server.serve_forever()
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
||||||
Reference in New Issue
Block a user