Skip to main content

Adopt the Unraid data disks

POST 

/migrate/import

Required role: admin. Only an account or token with the admin role can call this operation.

Example request
curl --request POST \
--header "Authorization: Bearer $HOSERVA_TOKEN" \
--header "Content-Type: application/json" \
--data @body.json \
"https://$HOSERVA_HOST:8008/api/v1/migrate/import"

Phase C of the migration: queues a migration_import job (topology class) that adopts the Unraid data disks into the pool at /mnt/user without formatting them and without writing a byte to them. Each data disk is mounted by its own device, never by a filesystem UUID another disk may share, with ro,norecovery (XFS), ro,noload (ext4) or ro,rescue=nologreplay (btrfs), and the catch-all pool over them is read-only, with the share directory structure intact. The former parity and cache disks are recorded by identity and are neither formatted, mounted nor opened: formatting them is the point of no return. No snapraid.conf is generated, so no parity engine exists and no sync can run. While the import is pending (getMigration phase is imported), parity, array-write and topology jobs other than this one's own retry are refused with 409 migration_in_progress, a scan included, and forgetMigration is refused with the same code. roles is the disk-role mapping the user confirmed against the serial table, one entry per disk, keyed by serial or wwn; the review of getMigration proposes a role for each disk the capture names. A cache on a spare partition of the boot disk (listDisks cachePartitions) is keyed by that partition's byId and partUuid instead, with no serial or WWN. The mapping is refused with 400 invalid_import_roles, before anything is queued, unless every role names a disk the scan listed and this machine still has; a disk the scan refused, an Unraid boot device or the Unraid USB stick has no role but ignore; a disk disks.ini records as parity is never data, whatever filesystem it reports, and a disk it records as data is never parity or cache; a weak-identity disk is never parity; the disk this machine boots from is never parity or data and is the cache only by a spare partition of it; parity is one or two disks, each at least as large as the largest data disk; and every data disk has a filesystem Hoserva adopts whose UUID is not another data disk's; and the layout must be one snapraid.conf can be rendered for at the point of no return, which is the same check that step makes: the content-file copies (the parity disks + 2, on distinct devices) need the boot device, a cache that is a device of its own (a cache that is a partition of the boot disk is the boot device's copy) and enough data disks. A layout that falls short is refused with 400 invalid_import_roles, naming the shortfall and what to add (a data disk or a cache device), never left to fail at step 17. The Unraid USB stick in any role is refused with 409 unraid_stick. Also refused before queueing: 409 confirmation_required unless confirm is true, 404 no_migration_report before a scan, 409 scan_not_finished while a scan runs or the latest one failed, 409 migration_no_go when the report's verdict is no-go, 409 scan_outdated for a report made before the disk table existed, 409 array_exists when the array is not a pending import's, and 501 not_configured. The job reads every data disk's identity again and re-runs its read-only filesystem check immediately before mounting; a disk that changed since the request, or now fails, is refused and nothing is mounted. A failure after the array is recorded unmounts what was mounted, deletes the record and leaves no pool; a retry of the same mapping applies a recorded import again. Nothing is read from the Unraid flash: the import uses the report the scan stored.

With undo true the request takes back an import that is pending its point of no return instead (getMigration phase imported, verifying, verify_failed or verified): it queues a migration_import job (topology class) that unmounts the read-only pool and the adopted data disks, forgets the verify result, deletes the recorded array and removes the generated mount units. roles is then omitted. Nothing is written to any adopted disk, and the former parity and cache disks, which the import never touched, are untouched. A mount that cannot be released keeps the record and fails the job, so the request can be made again. The shares and accounts the import created are kept (they hold no data); a new import finds them and leaves them as they are. Afterwards the scan's report is still there (getMigration phase scanned), forgetMigration is no longer refused, and the disks can be imported again with a mapping that works. It is the way out of an import whose layout the point of no return would refuse. Refused before anything is queued with 409 confirmation_required unless confirm is true, 400 invalid_import_roles when roles is given, and 409 no_import_pending unless an import is pending its point of no return: an array that has been through it is never touched. Without undo, roles is required and an empty one is refused with 400 invalid_import_roles.

Once the disks are adopted the job seeds the scan's shares and accounts, and writes nothing to an adopted disk to do it. Each share the scan kept is created, its allocation method mapped to a create policy, its Unraid cache setting recorded as migration.targetCacheMode while the share is array-only (no cache exists before the point of no return), its floor as minFreeSpace, its export and security settings as SMB settings and its read and write lists as per-user access for the imported accounts; what Hoserva has no equivalent of, such as High-water allocation or a split level, is in migration.notes. The shares are exported read-only over SMB while the import is pending. A share whose name Hoserva does not accept (spaces, for instance) is reported in the job's log with the reason and never renamed, and the scan's report flags it. Each account is created share-only without a password: passwords are never read from the flash, and each one is set by the user with setUserPassword (the job's log lists them). The job is all-or-nothing: a share or account that cannot be created undoes the adoption too. A share or account that already exists is left as it is.

Request​

Responses​

The queued migration_import job.