diff --git a/truenas_migrate.py b/truenas_migrate.py index 292bddf..d7fcada 100644 --- a/truenas_migrate.py +++ b/truenas_migrate.py @@ -539,16 +539,33 @@ def list_archive_and_exit(tar_path: str) -> None: # Read-only / server-generated fields that must NOT be sent on create/update _SMB_SHARE_READONLY = frozenset({"id", "locked"}) -_NFS_SHARE_READONLY = frozenset({"id", "locked"}) _SMB_CONFIG_READONLY = frozenset({"id", "server_sid"}) +# CORE SMB share fields that do not exist in the SCALE API +_SMB_SHARE_CORE_EXTRAS = frozenset({ + "vuid", # server-generated Time Machine UUID; SCALE sets this automatically +}) + +# CORE NFS share fields that do not exist in the SCALE API +_NFS_SHARE_CORE_EXTRAS = frozenset({ + "paths", # CORE uses a list; SCALE uses a single "path" string (converted below) + "alldirs", # removed in SCALE + "quiet", # removed in SCALE +}) + def _smb_share_payload(share: dict) -> dict: - return {k: v for k, v in share.items() if k not in _SMB_SHARE_READONLY} + exclude = _SMB_SHARE_READONLY | _SMB_SHARE_CORE_EXTRAS + return {k: v for k, v in share.items() if k not in exclude} def _nfs_share_payload(share: dict) -> dict: - return {k: v for k, v in share.items() if k not in _NFS_SHARE_READONLY} + payload = {k: v for k, v in share.items() + if k not in {"id", "locked"} | _NFS_SHARE_CORE_EXTRAS} + # CORE stores export paths as a list under "paths"; SCALE expects a single "path" string. + if "path" not in payload and share.get("paths"): + payload["path"] = share["paths"][0] + return payload def _smb_config_payload(config: dict) -> dict: @@ -952,7 +969,10 @@ async def migrate_nfs_shares( log.info(" Destination has %d existing NFS share(s).", len(existing_paths)) for share in shares: - path = share.get("path", "").rstrip("/") + # CORE archives store paths as a list; SCALE uses a single string. + core_paths = share.get("paths") or [] + path = (share.get("path") or (core_paths[0] if core_paths else "")).rstrip("/") + all_paths = [p.rstrip("/") for p in (core_paths if core_paths else ([path] if path else []))] log.info("── NFS export %r", path) if path in existing_paths: @@ -966,8 +986,7 @@ async def migrate_nfs_shares( if dry_run: log.info(" [DRY RUN] would create NFS export for %r", path) summary.nfs_created += 1 - if path: - summary.paths_to_create.append(path) + summary.paths_to_create.extend(all_paths) continue try: