Add package data for GPU rent and update CLI documentation
- Added package data configuration for the 'gpu_rent' package in pyproject.toml. - Updated README.md to include usage instructions for Windows and Unix launchers. - Enhanced CLI documentation in cli.md to reflect new commands and their functionalities. - Revised setup.md to clarify installation steps and environment setup. - Improved error handling and command descriptions in the CLI implementation. - Added new functions for model version handling and flavor resolution in the codebase. - Updated state management to include additional properties for better tracking.
This commit is contained in:
@@ -0,0 +1,76 @@
|
||||
"""SFTP push/pull of local app folders. Never delete remote extras."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from collections.abc import Callable
|
||||
from pathlib import Path
|
||||
|
||||
from gpu_rent.config import Config
|
||||
from gpu_rent.payload import has_payload, iter_payload_files, model_push_set, sha256_file
|
||||
from gpu_rent.ssh_ops import get_file, put_file, remote_sha256, run_ssh
|
||||
|
||||
Log = Callable[[str], None]
|
||||
|
||||
|
||||
def push_tree(
|
||||
cfg: Config,
|
||||
host: str,
|
||||
local_root: Path,
|
||||
remote_root: str,
|
||||
log: Log,
|
||||
*,
|
||||
models: bool,
|
||||
) -> int:
|
||||
if not has_payload(local_root):
|
||||
log(f"push {local_root.name}: пусто — skip")
|
||||
return 0
|
||||
files = model_push_set(local_root) if models else iter_payload_files(local_root)
|
||||
sent = 0
|
||||
for path in files:
|
||||
rel = path.relative_to(local_root).as_posix()
|
||||
remote = f"{remote_root.rstrip('/')}/{rel}"
|
||||
local_hash = sha256_file(path)
|
||||
remote_hash = remote_sha256(cfg, host, remote)
|
||||
if remote_hash and remote_hash.lower() == local_hash.lower():
|
||||
continue
|
||||
if models and not _is_weight_name(path.name):
|
||||
# sidecar: warn if we somehow got here without weight — still send
|
||||
pass
|
||||
log(f"push {rel}")
|
||||
put_file(cfg, host, path, remote)
|
||||
sent += 1
|
||||
if sent == 0:
|
||||
log(f"push {local_root.name}: всё уже на VM")
|
||||
else:
|
||||
log(f"push {local_root.name}: {sent} файл(ов)")
|
||||
return sent
|
||||
|
||||
|
||||
def _is_weight_name(name: str) -> bool:
|
||||
lower = name.lower()
|
||||
return lower.endswith((".safetensors", ".ckpt", ".pt", ".pth", ".bin", ".gguf", ".sft", ".onnx"))
|
||||
|
||||
|
||||
def pull_tree(cfg: Config, host: str, remote_root: str, local_root: Path, log: Log) -> int:
|
||||
listing = run_ssh(
|
||||
cfg,
|
||||
host,
|
||||
f"find {remote_root} -type f 2>/dev/null | sed 's|^{remote_root}/||'",
|
||||
check=False,
|
||||
timeout=120,
|
||||
)
|
||||
names = [line.strip() for line in listing.splitlines() if line.strip()]
|
||||
pulled = 0
|
||||
for rel in names:
|
||||
if rel.endswith("/.gitkeep") or rel.rsplit("/", 1)[-1] in {".gitkeep", "README.md"}:
|
||||
continue
|
||||
remote = f"{remote_root.rstrip('/')}/{rel}"
|
||||
local = local_root / rel
|
||||
remote_hash = remote_sha256(cfg, host, remote)
|
||||
if local.is_file() and remote_hash and sha256_file(local).lower() == remote_hash.lower():
|
||||
continue
|
||||
log(f"pull {rel}")
|
||||
get_file(cfg, host, remote, local)
|
||||
pulled += 1
|
||||
log(f"pull Output: {pulled} файл(ов)" if pulled else "pull Output: нечего забирать")
|
||||
return pulled
|
||||
Reference in New Issue
Block a user