- Replace API field names (guestok, abe, ro, maproot_user, etc.) with
plain-English headers (Guest Access, Access-Based Enumeration, Read Only,
Map Root User, etc.) for customer clarity
- Drop comment rows that rendered poorly in spreadsheet apps
- Use two realistic example rows instead to teach by example
- Update csv_source.py to map friendly header names to API field names
before validation and coercion (raw API names still accepted)
- Update README column reference to match new header names
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Add truenas_migrate/csv_source.py: parses SMB and NFS share definitions
from customer-supplied CSV files; returns same dict shape as parse_archive()
so migrate.py is untouched
- Add smb_shares_template.csv and nfs_shares_template.csv with annotated
headers and example rows (# comment rows are skipped by the parser)
- Update cli.py: interactive wizard gains a source-type step (archive vs CSV);
run() resolves CSV source via --smb-csv / --nfs-csv args; --debug-tar is now
optional; argparse validates mutual exclusion of archive and CSV flags
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Split single-file script into truenas_migrate/ package
- Removed SMB global config migration (not needed for deployment use)
- Added compatibility shim so both invocation styles still work
- Added __pycache__ to .gitignore
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Replaces the numbered-input share picker with a full TTY checkbox UI:
↑/↓ to move cursor, Space to toggle, A to select/deselect all, Enter to confirm.
Falls back to the original numbered text input when stdin is not a TTY.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
After parsing the archive, present a numbered list of SMB and NFS
shares and let the user pick which ones to migrate. Entering nothing
(or 'all') keeps everything; 'n' skips the type entirely; space-
separated numbers select specific shares.
Because archive_data is filtered before the dry run, only selected
shares are processed in both the dry and live runs, and the dataset
existence check covers exactly the chosen share paths.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Auto-detected ANSI colors (disabled when stderr is not a TTY)
- Colored log formatter: dim timestamps, level names styled by severity
- Migration status keywords colored: SKIP=yellow, CREATED=bold-green,
FAILED=bold-red, [DRY RUN]=cyan
- Share/export header lines bold with share name in bold-cyan
- Dry-run banner rendered as a bold-yellow framed box
- Summary report: cyan border, colored per-stat counts (green/yellow/red),
errors and warnings highlighted; fixed box width (w=60) with ANSI-aware
padding so columns stay aligned with color codes present
- Interactive wizard: styled header, cyan numbered list items
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Strip CORE-only SMB share field (vuid) and NFS share fields
(paths, alldirs, quiet) that are rejected by the SCALE API.
Convert CORE's NFS paths list to the single path string SCALE expects.
Also include NFS paths in dry-run dataset existence checks.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
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>
When run with no arguments the script now guides the user through the
full migration interactively:
1. Lists debug archives found in the current directory and prompts
for selection (auto-selects when only one is present)
2. Prompts for destination host, port, and API key (key input hidden)
3. Prompts for migration scope (SMB shares / NFS shares / SMB config)
4. Runs a dry run and displays the summary
5. Asks for confirmation before applying changes live
The archive is parsed once and reused for both the dry and live runs.
The existing CLI flag interface is unchanged.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Replaces the third-party `websockets` package with a self-contained
implementation built on asyncio.open_connection, ssl, hashlib, base64,
struct, and os — all Python stdlib modules available on TrueNAS OS.
The script now runs directly on TrueNAS without any pip install.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>