Skip to content

Add bulk dataset storage migration#22606

Draft
davelopez wants to merge 73 commits intogalaxyproject:devfrom
davelopez:feature/bulk-storage-migration
Draft

Add bulk dataset storage migration#22606
davelopez wants to merge 73 commits intogalaxyproject:devfrom
davelopez:feature/bulk-storage-migration

Conversation

@davelopez
Copy link
Copy Markdown
Contributor

@davelopez davelopez commented Apr 30, 2026

Resolves #22404

Summary

This branch introduces end-to-end bulk storage migration for history items.

Users can now:

  • Start a bulk Move operation for selected history datasets and collections.
  • Choose a target storage location.
  • Preview eligibility before execution, including:
    • eligible vs ineligible items,
    • estimated transfer size,
    • quota delta per source/target,
    • warnings (for example, moving from private to shareable storage).
  • Execute the operation and track progress through a dedicated run view (in-progress and finished runs, per-run details, per-item outcomes).
  • Receive completion notifications (optional at submission time, with category-level notification preferences).

Notes:

  • Only "Move" operations are supported for now.
  • Runs include detailed terminal outcomes (succeeded, failed, skipped) with reason codes.

Screenshots

New bulk selection option (requires celery and selectable object stores)

image

For potentially long operations, you can opt to receive a notification/email.

image

Select the destination storage location for the selected datasets and collections

image

You can preview the estimated impact of the operation

image

When a background operation is running, you will see this indicator

image

Here, you can inspect the latest operations you have run in the current history

image

When some datasets are skipped or fail, you can see the reason for each of them in the details

image

You can also access the results from the notification received after the operation is completed

image

Most Relevant Backend Changes

  • Added persistent tracking models for storage operations:
    • snapshot table (preview snapshot and expiry),
    • run table (operation lifecycle and aggregate counters),
    • run item table (per-dataset state/reason/message/bytes).
  • Added a new migration to create these tables and relationships.
  • Added history content API endpoints for:
    • previewing a storage operation,
    • executing from a preview snapshot,
    • retrieving run summary,
    • retrieving paginated/searchable run items.
  • Extended storage operation schemas with typed request/response models, run states, item states, and failure reason codes.
  • Implemented backend execution flow for bulk storage operations, including async run tracking and robust item-level result reporting.
  • Integrated storage-operation completion notifications, including:
    • new notification category and payload shape,
    • email templates for completion messaging.

Testing

Coverage added/updated in this branch includes:

  • Integration tests for bulk storage operations, covering:
    • preview eligibility behavior,
    • invalid/edge reason codes,
    • execution lifecycle and terminal run states,
    • skip_ineligible behavior,
    • per-item status/results,
    • run-items filtering/search,
    • snapshot/history mismatch errors,
    • collection (HDCA) expansion/execution,
    • dataset-not-found between preview and execute.
  • Unit tests for notification manager behavior for storage operation completion notifications.
  • Frontend/store/query/component tests updated for the new storage operation flows and notification handling.

TODO

  • Automatically prune the database tables for storage operations (snapshot, run, run item) after a reasonable retention period

How to test the changes?

  • I've included appropriate automated tests.
  • This is a refactoring of components with existing test coverage.
  • Instructions for manual testing are as follows:
    • This is a basic object_store_conf.yml. You should replace the files_dir with something that works for you and play around with different device and quota, etc.

      type: distributed
      backends:
          - id: default
            type: disk
            device: device1
            weight: 1
            allow_selection: true
            name: Default Galaxy Storage
            description: >
                Some description for Default Galaxy Storage
            files_dir: /home/dlopez/sandbox/data-gx/dev/objects/default
            badges:
                - type: slower
                - type: more_stable
                - type: backed_up
                  message: >
                      Backed up to Galaxy's institutional long term tape drive nightly. More information about our tape drive can be
                      found on our [Archive Tier Storage](https://www.msi.umn.edu/content/archive-tier-storage) page.
          - id: second_tier
            type: disk
            device: device1
            weight: 0
            allow_selection: true
            name: Second Tier Storage
            description: >
                This object store is connected in the same disk as the default object store.
            quota:
                source: second_tier
            files_dir: /home/dlopez/sandbox/data-gx/dev/objects/second_tier
            badges:
                - type: slower
                - type: more_stable
                - type: backed_up
                  message: >
                      Backed up to Galaxy's institutional long term tape drive nightly. More information about our tape drive can be
                      found on our [Archive Tier Storage](https://www.msi.umn.edu/content/archive-tier-storage) page.
          - id: scratch
            type: disk
            device: device2
            weight: 0
            allow_selection: true
            private: true
            name: Scratch Storage
            description: >
                This object store is connected to institutional scratch storage. This disk space is not backed up and private to
                your user, and datasets belonging to this storage will be automatically deleted after one month.
            quota:
                source: scratch
            files_dir: /home/dlopez/sandbox/data-gx/dev/objects/temp
            badges:
                - type: faster
                - type: less_stable
                - type: not_backed_up
                - type: short_term
                  message: The data stored here is purged after a month.
            object_expires_after_days: 30
      

License

  • I agree to license these and all my past contributions to the core galaxy codebase under the MIT license.

@davelopez davelopez added kind/enhancement area/UI-UX area/API area/objectstore highlight Included in user-facing release notes at the top labels Apr 30, 2026
@davelopez davelopez force-pushed the feature/bulk-storage-migration branch from 482ae7f to fcf65ec Compare May 1, 2026 08:42
davelopez added 24 commits May 4, 2026 15:00
Splits the API for storage operation runs to return only run summaries, moving per-item results to a new paginated endpoint. Updates frontend and schema to use the new endpoint, adjusts tests, and refactors backend logic accordingly. Improves scalability and performance by avoiding large payloads and enabling filtered, paginated access to run items.
davelopez and others added 25 commits May 4, 2026 15:03
Improves clarity and detail for quota availability changes by
replacing a generic dictionary with a structured list of transfers.
This provides explicit source and target object store IDs for each
quota impact, making the information more precise for the user
interface. It enhances the accuracy and reviewability of storage
operation previews.
Clarifies user understanding of the implications when datasets
move from private to shareable storage. The updated message is
more informative about the potential for sharing after the
operation, making the warning less ambiguous.
Creates a dedicated Vue component to display the storage operation
preview. This component centralizes the complex rendering logic,
improving maintainability and allowing for a clearer separation
of concerns within the storage operation wizard.
Simplifies the storage operation wizard by offloading preview
rendering to a dedicated component. This reduces the modal's
complexity, removes duplicated logic, and improves the overall
user experience with clearer instructions and titles.
Prevents dataset transfer attempts when the source data is unavailable
by detecting missing files beforehand and recording a specific failure.
Improves error reporting and robustness against purged or absent datasets.

Co-authored-by: Copilot <copilot@github.com>
Introduces new helper methods to support preview, execute,
and monitor bulk storage operations within test populators.
Introduces comprehensive integration tests covering preview, execution, and run status for bulk storage operations across distributed object store backends. Validates eligibility, error handling, warnings, run lifecycle, collection support, and edge cases including quota transfers and privacy warnings.
@davelopez davelopez force-pushed the feature/bulk-storage-migration branch from fcf65ec to 2542aeb Compare May 4, 2026 13:04
davelopez and others added 3 commits May 4, 2026 17:29
Ensures that re-executing a storage snapshot with mixed eligible and ineligible states does not duplicate file moves or mutate data. Validates correct handling of already migrated datasets and verifies file counts remain unchanged on repeated execution.

Co-authored-by: Copilot <copilot@github.com>
Adds cleanup of partially transferred files in the target store when a checksum verification error or other exception occurs during cross-device dataset transfer. Updates tests to verify that failed transfers do not result in data loss and are safely rerunnable.

Co-authored-by: Copilot <copilot@github.com>
Prevents users from seeing and toggling the "notify on completion" option unless the notification system is enabled in config.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Bulk storage operations (copy/move) support

1 participant