Fix NFS backup destinations broken by the 0.40.0 refactor (0.40.1)
_ensure_helper_image moved to stack_assets_service, but backup_destination_service imports it lazily inside _nfs_run/_nfs_helper, so nothing failed at import time — every NFS destination operation raised ImportError at runtime instead. The helper is now a public ensure_helper_image() and the NFS helpers import it from its new home. Verified: every services/ and routers/ module imports, and both NFS helper paths run through to a Docker call instead of ImportError. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -288,10 +288,10 @@ def _nfs_run(volume: str, command: list[str]) -> str:
|
||||
|
||||
from config import settings
|
||||
from docker_client import DockerError, get_client
|
||||
from services.backup_service import _ensure_helper_image
|
||||
from services.stack_assets_service import ensure_helper_image
|
||||
|
||||
client = get_client()
|
||||
_ensure_helper_image(client)
|
||||
ensure_helper_image(client)
|
||||
try:
|
||||
out = client.containers.run(
|
||||
settings.BACKUP_HELPER_IMAGE,
|
||||
@@ -314,10 +314,10 @@ def _nfs_helper(volume: str):
|
||||
|
||||
from config import settings
|
||||
from docker_client import DockerError, get_client, safe_call
|
||||
from services.backup_service import _ensure_helper_image
|
||||
from services.stack_assets_service import ensure_helper_image
|
||||
|
||||
client = get_client()
|
||||
_ensure_helper_image(client)
|
||||
ensure_helper_image(client)
|
||||
try:
|
||||
return safe_call(
|
||||
client.containers.create,
|
||||
|
||||
@@ -64,7 +64,7 @@ class AssetError(Exception):
|
||||
# --------------------------------------------------------------------------- #
|
||||
|
||||
|
||||
def _ensure_helper_image(client) -> None:
|
||||
def ensure_helper_image(client) -> None:
|
||||
image = settings.BACKUP_HELPER_IMAGE
|
||||
try:
|
||||
safe_call(client.images.get, image)
|
||||
@@ -104,7 +104,7 @@ def inspect_paths(paths: list[str]) -> dict[str, dict]:
|
||||
if not unique:
|
||||
return {}
|
||||
client = get_client()
|
||||
_ensure_helper_image(client)
|
||||
ensure_helper_image(client)
|
||||
mounts = {p: {"bind": f"/m/{i}", "mode": "ro"} for i, p in enumerate(unique)}
|
||||
script_parts = []
|
||||
for i in range(len(unique)):
|
||||
@@ -149,7 +149,7 @@ def inspect_paths(paths: list[str]) -> dict[str, dict]:
|
||||
def export_path(source: str, kind: str, dest_file: str) -> int:
|
||||
"""Tar a host path (dir contents, or a single file) into ``dest_file``."""
|
||||
client = get_client()
|
||||
_ensure_helper_image(client)
|
||||
ensure_helper_image(client)
|
||||
if kind == "file":
|
||||
parent, base = _split(source)
|
||||
if not base:
|
||||
@@ -176,7 +176,7 @@ def export_path(source: str, kind: str, dest_file: str) -> int:
|
||||
def import_path(source: str, kind: str, src_file: str) -> None:
|
||||
"""Unpack an archive produced by :func:`export_path` back to its host path."""
|
||||
client = get_client()
|
||||
_ensure_helper_image(client)
|
||||
ensure_helper_image(client)
|
||||
if kind == "file":
|
||||
parent, _base = _split(source)
|
||||
container = _create_helper(client, {parent: {"bind": "/dst", "mode": "rw"}})
|
||||
@@ -192,7 +192,7 @@ def import_path(source: str, kind: str, src_file: str) -> None:
|
||||
def export_volume(full_name: str, dest_file: str) -> int:
|
||||
"""Stream a named volume's contents into ``dest_file`` (never into RAM)."""
|
||||
client = get_client()
|
||||
_ensure_helper_image(client)
|
||||
ensure_helper_image(client)
|
||||
container = _create_helper(client, {full_name: {"bind": "/v", "mode": "ro"}})
|
||||
written = 0
|
||||
try:
|
||||
@@ -209,7 +209,7 @@ def export_volume(full_name: str, dest_file: str) -> int:
|
||||
def import_volume(full_name: str, labels: dict, src_file: str, wipe: bool = True) -> None:
|
||||
"""Restore a volume from an archive, optionally clearing it first."""
|
||||
client = get_client()
|
||||
_ensure_helper_image(client)
|
||||
ensure_helper_image(client)
|
||||
existed = True
|
||||
try:
|
||||
safe_call(client.volumes.get, full_name)
|
||||
|
||||
+1
-1
@@ -1,3 +1,3 @@
|
||||
"""Single source of truth for the StackPilot release version."""
|
||||
|
||||
APP_VERSION = "0.40.0"
|
||||
APP_VERSION = "0.40.1"
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "stackpilot-frontend",
|
||||
"private": true,
|
||||
"version": "0.40.0",
|
||||
"version": "0.40.1",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"dev": "vite",
|
||||
|
||||
Reference in New Issue
Block a user