Enhance CLI and documentation for capturing VM inventory
- Introduced new `capture` commands in the CLI to allow users to merge VM inventory into local manifests without downloading weights. - Updated `README.md` and `cli.md` to include detailed instructions for the new capture functionality, including options for models and extensions. - Enhanced `decisions.md` to clarify the role of captured links in the manifest files. - Improved `extensions.md` to document the process of capturing installed extensions back to the local configuration. - Added new functions in `civitai.py` to support fetching model versions by hash and generating canonical URLs for models.
This commit is contained in:
@@ -683,6 +683,120 @@ def seed_extensions_cmd() -> None:
|
||||
_die(exc)
|
||||
|
||||
|
||||
capture_app = typer.Typer(
|
||||
help=(
|
||||
"Снять с VM инвентарь → локальные манифесты (только ссылки, без весов). "
|
||||
"Merge в models.yaml / extensions.yaml."
|
||||
),
|
||||
no_args_is_help=False,
|
||||
)
|
||||
app.add_typer(capture_app, name="capture")
|
||||
|
||||
|
||||
@capture_app.callback(invoke_without_command=True)
|
||||
def capture_root(
|
||||
ctx: typer.Context,
|
||||
dry_run: bool = typer.Option(False, "--dry-run", help="Не писать yaml, только отчёт"),
|
||||
kind: Optional[str] = typer.Option(
|
||||
None, "--kind", help="Только models: checkpoint|lora|vae|…"
|
||||
),
|
||||
) -> None:
|
||||
"""Без подкоманды — capture all."""
|
||||
if ctx.invoked_subcommand is not None:
|
||||
return
|
||||
try:
|
||||
from gpu_rent.capture import capture_all, print_report
|
||||
from gpu_rent.manifests import MODEL_TYPES
|
||||
|
||||
if kind and kind not in MODEL_TYPES:
|
||||
raise GpuRentError(f"--kind: жду один из {', '.join(MODEL_TYPES)}")
|
||||
cfg, host = _live()
|
||||
report = capture_all(
|
||||
cfg,
|
||||
host,
|
||||
dry_run=dry_run,
|
||||
kind_filter=kind,
|
||||
log=lambda m: console.print(m),
|
||||
)
|
||||
print_report(report, lambda m: console.print(m), dry_run=dry_run)
|
||||
except GpuRentError as exc:
|
||||
_die(exc)
|
||||
|
||||
|
||||
@capture_app.command("models")
|
||||
def capture_models_cmd(
|
||||
dry_run: bool = typer.Option(False, "--dry-run"),
|
||||
kind: Optional[str] = typer.Option(
|
||||
None, "--kind", help="checkpoint|lora|vae|embedding|controlnet|upscaler|clip"
|
||||
),
|
||||
) -> None:
|
||||
"""Models на VM → merge Civitai url в models.yaml."""
|
||||
try:
|
||||
from gpu_rent.capture import capture_models, print_report
|
||||
from gpu_rent.manifests import MODEL_TYPES
|
||||
|
||||
if kind and kind not in MODEL_TYPES:
|
||||
raise GpuRentError(f"--kind: жду один из {', '.join(MODEL_TYPES)}")
|
||||
cfg, host = _live()
|
||||
report = capture_models(
|
||||
cfg,
|
||||
host,
|
||||
None,
|
||||
dry_run=dry_run,
|
||||
kind_filter=kind,
|
||||
log=lambda m: console.print(m),
|
||||
)
|
||||
print_report(report, lambda m: console.print(m), dry_run=dry_run)
|
||||
except GpuRentError as exc:
|
||||
_die(exc)
|
||||
|
||||
|
||||
@capture_app.command("extensions")
|
||||
def capture_extensions_cmd(
|
||||
dry_run: bool = typer.Option(False, "--dry-run"),
|
||||
) -> None:
|
||||
"""Extensions/DLNodes на VM → merge git url в extensions.yaml."""
|
||||
try:
|
||||
from gpu_rent.capture import capture_extensions, print_report
|
||||
|
||||
cfg, host = _live()
|
||||
report = capture_extensions(
|
||||
cfg,
|
||||
host,
|
||||
None,
|
||||
dry_run=dry_run,
|
||||
log=lambda m: console.print(m),
|
||||
)
|
||||
print_report(report, lambda m: console.print(m), dry_run=dry_run)
|
||||
except GpuRentError as exc:
|
||||
_die(exc)
|
||||
|
||||
|
||||
@capture_app.command("all")
|
||||
def capture_all_cmd(
|
||||
dry_run: bool = typer.Option(False, "--dry-run"),
|
||||
kind: Optional[str] = typer.Option(None, "--kind", help="Фильтр только для models"),
|
||||
) -> None:
|
||||
"""models + extensions."""
|
||||
try:
|
||||
from gpu_rent.capture import capture_all, print_report
|
||||
from gpu_rent.manifests import MODEL_TYPES
|
||||
|
||||
if kind and kind not in MODEL_TYPES:
|
||||
raise GpuRentError(f"--kind: жду один из {', '.join(MODEL_TYPES)}")
|
||||
cfg, host = _live()
|
||||
report = capture_all(
|
||||
cfg,
|
||||
host,
|
||||
dry_run=dry_run,
|
||||
kind_filter=kind,
|
||||
log=lambda m: console.print(m),
|
||||
)
|
||||
print_report(report, lambda m: console.print(m), dry_run=dry_run)
|
||||
except GpuRentError as exc:
|
||||
_die(exc)
|
||||
|
||||
|
||||
@app.command("resize-data")
|
||||
def resize_data(gb: int = typer.Option(..., "--gb", help="Новый размер data volume, GB (только вверх)")) -> None:
|
||||
"""Cinder extend data volume + resize2fs на VM."""
|
||||
|
||||
Reference in New Issue
Block a user