During dry runs, query pool.dataset.query on the destination to verify that every share path would have a backing ZFS dataset. Missing paths are collected in Summary.missing_datasets and surfaced as a WARNING block in the report. In interactive mode the user is prompted to create any auto-creatable (/mnt/…) datasets before the live migration proceeds. Non-interactive --dry-run mode prints the same warning in the summary report. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
56 lines
3.0 KiB
Markdown
56 lines
3.0 KiB
Markdown
# CLAUDE.md
|
|
|
|
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
|
|
|
|
## Project Overview
|
|
|
|
Single-file Python CLI tool (`truenas_migrate.py`) that reads SMB shares, NFS shares, and SMB global config from a TrueNAS debug archive (`.tar`/`.tgz`) and re-creates them on a destination TrueNAS system via its JSON-RPC 2.0 WebSocket API (TrueNAS 25.04+).
|
|
|
|
## Running the Tool
|
|
|
|
```bash
|
|
# Install the only dependency
|
|
pip install websockets
|
|
|
|
# Inspect the archive
|
|
python truenas_migrate.py --debug-tar debug.tgz --list-archive
|
|
|
|
# Dry run (no changes made)
|
|
python truenas_migrate.py --debug-tar debug.tgz --dest 192.168.1.50 --api-key "1-xxx" --dry-run
|
|
|
|
# Live migration
|
|
python truenas_migrate.py --debug-tar debug.tgz --dest 192.168.1.50 --api-key "1-xxx"
|
|
|
|
# Migrate a subset (smb, nfs, smb-config)
|
|
python truenas_migrate.py --debug-tar debug.tgz --dest 192.168.1.50 --api-key "1-xxx" --migrate smb
|
|
```
|
|
|
|
## Architecture
|
|
|
|
The script is structured as a linear pipeline with no external config files or modules:
|
|
|
|
1. **Archive parser** (`parse_archive`, `_find_data`) — Opens the `.tgz` using `tarfile`, tries a ranked list of known paths (`_CANDIDATES`) for each data type, then falls back to keyword heuristic scanning (`_KEYWORDS`). Handles both `ixdiagnose` (SCALE) and `freenas-debug` (CORE) archive layouts, as well as date-stamped top-level directories.
|
|
|
|
2. **Payload builders** (`_smb_share_payload`, `_nfs_share_payload`, `_smb_config_payload`) — Strip read-only/server-generated fields (`id`, `locked`, `server_sid`) before sending to the destination API.
|
|
|
|
3. **`TrueNASClient`** — Minimal async JSON-RPC 2.0 WebSocket client. Authenticates with `auth.login_with_api_key`, drains server-push notifications to match replies by `id`. Used as an async context manager.
|
|
|
|
4. **Migration routines** (`migrate_smb_shares`, `migrate_nfs_shares`, `migrate_smb_config`) — Each queries existing shares on the destination first, then skips conflicts (SMB: by name case-insensitively; NFS: by path exactly), then creates or dry-runs each share.
|
|
|
|
5. **`Summary` dataclass** — Accumulates counts and errors, renders a box-drawing table at the end. Exit code 2 if any errors occurred.
|
|
|
|
## TrueNAS API Reference
|
|
|
|
When working with TrueNAS API methods, payloads, or field names, consult the official documentation:
|
|
|
|
- **API Docs**: https://api.truenas.com/v25.10/
|
|
- Always verify method signatures, required fields, and valid enum values against the docs before modifying API calls or payload builders.
|
|
- The API version in use is TrueNAS 25.10 (SCALE). Legacy CORE field names may differ.
|
|
|
|
## Key Design Constraints
|
|
|
|
- **Never overwrites or deletes** existing shares on the destination — conflict policy is skip-only.
|
|
- SSL verification is off by default (self-signed certs are common on TrueNAS).
|
|
- The WebSocket API endpoint is `wss://<host>:<port>/api/current` (TrueNAS 25.04+).
|
|
- The `call()` method has a 60-second per-message timeout and skips server-initiated notifications (messages without an `id`).
|