CloudStorage CLI Reference
Two CLI commands — import (external → CloudStorage) then transfer (between providers).
1. lutish-cloudstorage:import
Import attachment metadata from external sources into CloudStorage.
Syntax
Code:
php cmd.php lutish-cloudstorage:import [--source=<src>] [--target-server=<id>] [options]
Options
| Option | Req | Default | Description |
|---|---|---|---|
| --source | No | auto | bd | rfs | local (omit = all detected sources) |
| --engine | No | - | BD filter: ftp | s3 | gcs |
| --target-server | Yes* | - | Target server ID. Required when --source=local |
| --batch-size, -b | No | 100 | Records per batch |
| --dry-run | No | off | Preview, no DB writes |
| --fix-thumbnails | No | off | Post-import thumbnail path correction |
| --thumb-batch-size | No | 50 | Batch size for thumbnail fix |
Examples
Code:
# Auto-detect everything
php cmd.php lutish-cloudstorage:import
# Dry-run first
php cmd.php lutish-cloudstorage:import --dry-run
# BD only (all engines)
php cmd.php lutish-cloudstorage:import --source=bd
# BD S3 engine only
php cmd.php lutish-cloudstorage:import --source=bd --engine=s3
# RemoteFtp only
php cmd.php lutish-cloudstorage:import --source=rfs
# Local XF files → server #3
php cmd.php lutish-cloudstorage:import --source=local --target-server=3
# Large batch + thumbnail fix
php cmd.php lutish-cloudstorage:import --source=bd --batch-size=200 --fix-thumbnails
Source Types
| --source | Imports from | Needs --target-server? |
|---|---|---|
| bd | BD Attachment Store (xf_bd_attachmentstore_*) | No |
| rfs | RemoteFtp / Lutish (xf_lutish_remote_ftp_*) | No |
| local | Local XF files (data/ + internal_data/) | Yes |
2. lutish-cloudstorage:transfer
Transfer files between CloudStorage servers. from → to via local temp transit:
Code:
Source ──readStream──▶ Local Temp ──writeStream──▶ Target
Syntax
Code:
php cmd.php lutish-cloudstorage:transfer --from=<id> --to=<id> [options]
Options
| Option | Req | Default | Description |
|---|---|---|---|
| --from | Yes | - | Source server ID |
| --to | Yes | - | Target server ID |
| --batch-size, -b | No | 50 | Attachments per batch |
| --dry-run | No | off | Preview, no file ops |
| --delete-source | No | off | Delete source after success (MOVE mode) |
Examples
Code:
# Dry-run preview
php cmd.php lutish-cloudstorage:transfer --from=1 --to=2 --dry-run
# Copy (keep source)
php cmd.php lutish-cloudstorage:transfer --from=1 --to=2
# Move (delete source)
php cmd.php lutish-cloudstorage:transfer --from=1 --to=2 --delete-source
# Large batch
php cmd.php lutish-cloudstorage:transfer --from=1 --to=2 --batch-size=200
Common Scenarios
| Scenario | Command |
|---|---|
| FTP → R2 | php cmd.php lutish-cloudstorage:transfer --from=1 --to=2 --delete-source |
| R2 → S3 | php cmd.php lutish-cloudstorage:transfer --from=2 --to=3 --delete-source |
| Local → R2 | php cmd.php lutish-cloudstorage:transfer --from=1 --to=2 |
| Backup to R2 | php cmd.php lutish-cloudstorage:transfer --from=1 --to=2 |
| S3 → GCS | php cmd.php lutish-cloudstorage:transfer --from=3 --to=4 --delete-source |
Output Legend
- OK — File transferred (main + thumb/ + 2x/), DB updated
- SKIP — No
cs_file_path, nothing to do - FAIL — Source file missing, network error, or permission issue
Safety & Troubleshooting
- Idempotent — Both commands safe to re-run; already-processed records skipped automatically.
- Per-record isolation — Failure of one attachment never stops the batch.
- Stream-based —
stream_copy_to_streamthrough local temp; constant memory usage. - Temp cleanup — Transit files deleted immediately after each copy.
- Error log — Failures logged to AdminCP → Tools → Server error log; last 100 shown in CLI.
Quick Checks
- Import fails? Verify source tables exist (BD/RFS) or
--target-serverprovided (local). - Transfer fails? Both server IDs exist and are different. Source has attachments:
SELECT COUNT(*) FROM xf_attachment_data WHERE cs_server_id=<id>. - Many FAILs? Check source connectivity + target write permissions + local disk space.
- Slow? Increase
--batch-size. Network latency between providers is the main bottleneck. - Interrupted? Just re-run — idempotent. Records already at target are skipped.