Skip to content

feat(nextcloud): trigger endpoint for bulk migrations#4728

Open
rezk2ll wants to merge 1 commit intomasterfrom
feat/nextcloud-migration
Open

feat(nextcloud): trigger endpoint for bulk migrations#4728
rezk2ll wants to merge 1 commit intomasterfrom
feat/nextcloud-migration

Conversation

@rezk2ll
Copy link
Copy Markdown
Contributor

@rezk2ll rezk2ll commented Apr 13, 2026

Summary

Adds POST /remote/nextcloud/migration to start a Nextcloud-to-Cozy bulk migration from the Settings UI.

The endpoint probes the supplied credentials against the Nextcloud OCS user_status endpoint, upserts an io.cozy.accounts document with the resolved WebDAV user ID, creates an io.cozy.nextcloud.migrations tracking document in pending state, and publishes a nextcloud.migration.requested command to the new migration RabbitMQ exchange.

A separate migration service consumes the command and drives the existing /remote/nextcloud/:account/* routes to perform the transfer, writing progress back to the tracking document.

The Settings UI monitors the document in real time to display progress. Only one migration can be in flight per instance; failed migrations do not block new attempts.

API

POST /remote/nextcloud/migration (requires POST io.cozy.nextcloud.migrations)

{
  "nextcloud_url": "https://nextcloud.example.com",
  "nextcloud_login": "alice",
  "nextcloud_app_password": "xxxxx-xxxxx-xxxxx-xxxxx-xxxxx",
  "source_path": "/"
}

source_path is optional and defaults to /. The password should be a Nextcloud app password.

201 Created

{
  "data": {
    "id": "d4e5f6a7b8c94d0ea1b2c3d4e5f6a7b8",
    "type": "io.cozy.nextcloud.migrations",
    "attributes": {
      "status": "pending",
      "target_dir": "/Nextcloud",
      "progress": {
        "files_imported": 0,
        "files_total": 0,
        "bytes_imported": 0,
        "bytes_total": 0
      },
      "errors": [],
      "skipped": [],
      "started_at": null,
      "finished_at": null
    }
  }
}

Error responses

Code When
401 Unauthorized The Nextcloud server rejected the supplied credentials
409 Conflict A pending or running migration already exists for this instance
500 Internal Server Error Conflict check, account upsert, or tracking document creation failed
502 Bad Gateway The Nextcloud instance is unreachable
503 Service Unavailable RabbitMQ publish failed; the tracking document is marked failed before returning

RabbitMQ contract

Exchange migration, routing key nextcloud.migration.requested. Payload (the consumer is responsible for declaring its queue and binding):

{
  "migrationId": "d4e5f6a7b8c94d0ea1b2c3d4e5f6a7b8",
  "workplaceFqdn": "alice.cozy.example.com",
  "accountId": "a1b2c3d4e5f6",
  "sourcePath": "/",
  "timestamp": 1712563200
}

Credentials are never in the payload; they live in the io.cozy.accounts document referenced by accountId. MessageID is set to the migration ID for cross-system tracing.

@rezk2ll rezk2ll requested a review from a team as a code owner April 13, 2026 11:21
Twake users migrating from Nextcloud need a way to import their entire
file tree into their Cozy. Konnectors and stack workers are bounded by
job timeouts, so the heavy lifting has to live outside the stack. This
endpoint is the user-facing entry point: it validates the credentials
synchronously, persists the account, creates a tracking document, and
hands the work off to a separate migration service via RabbitMQ. The
service drives the existing /remote/nextcloud/:account/* routes and
updates the tracking document, which the Settings UI watches over
realtime.
@rezk2ll rezk2ll force-pushed the feat/nextcloud-migration branch from 641380f to e01ad4c Compare April 13, 2026 11:24
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant