Files
gpu-rent/src/gpu_rent/sync_files.py
T
Leonid Pershin adba4976ee Enhance SwarmUI integration and GPU environment verification
- Updated CLI documentation to reflect the new handling of `CIVITAI_API_TOKEN`, which is now automatically passed to SwarmUI user settings during startup.
- Improved the `render_access_panel` function to include additional warnings for idle-killer failures and stack errors, enhancing user feedback.
- Introduced a new function `seed_swarmui_api_keys` to manage API key injection into SwarmUI, ensuring seamless integration with the Model Downloader.
- Enhanced GPU environment verification logic to include fail-fast checks for critical components like CUDA, improving error handling and user notifications.
- Updated tests to validate the new API key handling and access panel behavior, ensuring robustness in the integration process.
2026-08-21 07:09:20 +03:00

98 lines
3.1 KiB
Python

"""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_on,
open_ssh,
put_file_on,
remote_sha256_on,
run_ssh_on,
)
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)
file_list = list(files)
total = len(file_list)
sent = 0
skipped = 0
client = open_ssh(cfg, host)
try:
for i, path in enumerate(file_list, start=1):
rel = path.relative_to(local_root).as_posix()
remote = f"{remote_root.rstrip('/')}/{rel}"
local_hash = sha256_file(path)
remote_hash = remote_sha256_on(client, remote)
if remote_hash and remote_hash.lower() == local_hash.lower():
skipped += 1
continue
log(f"push [{i}/{total}] {rel}")
put_file_on(client, path, remote)
sent += 1
finally:
client.close()
if sent == 0:
log(f"push {local_root.name}: всё уже на VM ({total} файл(ов), skip={skipped})")
else:
log(f"push {local_root.name}: {sent}/{total} отправлено (skip={skipped})")
return sent
def pull_tree(cfg: Config, host: str, remote_root: str, local_root: Path, log: Log) -> int:
client = open_ssh(cfg, host)
try:
listing = run_ssh_on(
client,
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()]
work = [
rel
for rel in names
if not (
rel.endswith("/.gitkeep")
or rel.rsplit("/", 1)[-1] in {".gitkeep", "README.md"}
)
]
total = len(work)
pulled = 0
skipped = 0
for i, rel in enumerate(work, start=1):
remote = f"{remote_root.rstrip('/')}/{rel}"
local = local_root / rel
remote_hash = remote_sha256_on(client, remote)
if local.is_file() and remote_hash and sha256_file(local).lower() == remote_hash.lower():
skipped += 1
continue
log(f"pull [{i}/{total}] {rel}")
get_file_on(client, remote, local)
pulled += 1
finally:
client.close()
if pulled:
log(f"pull Output: {pulled}/{total} (skip={skipped})")
else:
log(f"pull Output: нечего забирать ({total} файл(ов), skip={skipped})")
return pulled