Files
TrueMigration/CLAUDE.md
scott ddb3fbd3ff Add dry-run dataset existence checks with option to create missing datasets
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>
2026-03-04 09:37:44 -05:00

3.0 KiB

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

# 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).