Skip to content

Add rc commands for On-Demand Migration #364

Description

@overtrue

What this is

RustFS server now ships On-Demand Migration: a bucket can name an external S3-compatible source bucket, a GET that misses locally is served from that source and stored locally, and a background backfill job pulls the rest. It is the RustFS equivalent of Cloudflare R2's Sippy (wrangler r2 bucket sippy enable) or Tigris buckets set-migration.

The server side is complete and merged (tracking plan rustfs/backlog#2147; operations guide docs/operations/on-demand-migration.md in rustfs/rustfs). This issue asks rc for the command surface. The wire contract is pinned by golden fixtures in crates/madmin/fixtures/on_demand_migration/ — parse tests should read those files (vendored with the source commit noted) rather than hand-written literals.

Proposed commands

rc admin bucket migration set <alias>/<bucket> --provider s3|aws|minio|rustfs|r2|gcs --endpoint URL --region R --source-bucket B [--prefix P] [--source-prefix SP] [--access-key AK --secret-key SK | --public] [--path-style auto|path|virtual] [--skip-tls-verify] [--ca-cert FILE] [--head proxy|local_only] [--range-get serve_and_backfill|serve_only] [--source-error propagate|not_found] [--no-preserve-etag] [--copy-tags] [--no-events] [--inline-max-bytes N] [--max-concurrent-pulls N] [--dry-run]
rc admin bucket migration get     <alias>/<bucket> [--json]
rc admin bucket migration rm      <alias>/<bucket>
rc admin bucket migration status  <alias>/<bucket> [--json] [--watch]
rc admin bucket migration backfill start  <alias>/<bucket> [--prefix P] [--skip-existing always|etag_or_size] [--dry-run]
rc admin bucket migration backfill cancel <alias>/<bucket>
rc admin bucket migration backfill status <alias>/<bucket> [--json] [--watch]

--dry-run on set maps to PUT ...?dry-run=true, which validates the config and probes the source without saving.

Details that matter

  • Never take the secret from argv when avoidable. Read --secret-key from RC_ODM_SECRET_KEY or a hidden prompt when the flag is absent, so it stays out of shell history.
  • Human-readable output. get prints the redacted config as a table (the server returns secret_key: "REDACTED"). status prints the source-hit ratio, migrated bytes, in-flight and queued pulls, breaker state and the last source error; served_by_source_ratio is deliberately null on the server and must render as an em dash, never as zero. backfill status --watch refreshes a progress line every couple of seconds.
  • Forward compatibility. Every field optional with a sane default, so an older server that omits fields does not break parsing; a 404 on the route family means the server predates the feature, so print "server does not support on-demand migration" rather than a stack trace.
  • Exit codes. Validation failure 2, source unreachable 3, licence rejection 4, backfill conflict (409) 5.
  • Editing an existing configuration replaces it wholesale, so set must require the secret again rather than sending back the redaction placeholder.

Admin API

Method Path
PUT / GET / DELETE /rustfs/admin/v3/on-demand-migration/{bucket}
GET /rustfs/admin/v3/on-demand-migration/{bucket}/status
POST /rustfs/admin/v3/on-demand-migration/{bucket}/backfill?op=start|cancel
GET /rustfs/admin/v3/on-demand-migration/{bucket}/backfill

Actions: admin:SetBucketOnDemandMigration for writes, admin:GetBucketOnDemandMigration for reads.

References

  • Tracking plan: rustfs/backlog#2147
  • This task: rustfs/backlog#2162
  • Operations guide: docs/operations/on-demand-migration.md in rustfs/rustfs
  • Wire fixtures: crates/madmin/fixtures/on_demand_migration/*.json in rustfs/rustfs

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions