Skip to content

Snapshot verification #1458

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
Jun 2, 2025
Merged

Conversation

engelmi
Copy link
Member

@engelmi engelmi commented Jun 2, 2025

Summary by Sourcery

Implement snapshot endianness verification, refactor GGUF parsing for clearer endianness detection, and improve robustness of snapshot creation and cleanup flows.

New Features:

  • Add dedicated endianness verification methods to ModelStore including a public verify_snapshot API

Enhancements:

  • Refactor GGUF parser to separate model endianness detection from overall parsing
  • Harden snapshot creation with cleanup on HTTP and generic errors and wrap ref-file deletion to ignore missing files
  • Simplify snapshot pull logic in repo_model_base and ollama modules by removing redundant try/except blocks

Copy link
Contributor

sourcery-ai bot commented Jun 2, 2025

Reviewer's Guide

Introduces a dedicated snapshot verification step for model endianness, centralizes GGUF parsing logic and system endianness helpers, refactors snapshot creation with robust error handling and automatic cleanup, and removes redundant code and parameters across model store and client wrappers.

Sequence Diagram for Updated new_snapshot Process in ModelStore

sequenceDiagram
    participant Client
    participant ModelStore

    Client->>ModelStore: new_snapshot(model_tag, snapshot_hash, files)
    activate ModelStore
    Note over ModelStore: Try: Create snapshot
    ModelStore->>ModelStore: _prepare_new_snapshot(...)
    ModelStore->>ModelStore: _download_snapshot_files(...)
    ModelStore->>ModelStore: _ensure_chat_template(...)
    opt On Exception during creation
        ModelStore->>ModelStore: remove_snapshot(model_tag)  // Cleanup
        ModelStore-->>Client: Raise Exception
    end

    Note over ModelStore: Try: Verify snapshot
    ModelStore->>ModelStore: verify_snapshot(model_tag)
    opt On EndianMismatchError during verification
        ModelStore->>ModelStore: remove_snapshot(model_tag)  // Cleanup
        ModelStore-->>Client: Raise EndianMismatchError
    end

    deactivate ModelStore
    Client-->>ModelStore: (Snapshot created and verified or error handled)
Loading

Sequence Diagram for verify_snapshot and Endianness Check

sequenceDiagram
    participant ModelStore
    participant GGUFInfoParser
    participant EndianUtils

    ModelStore->>ModelStore: verify_snapshot(model_tag)
    activate ModelStore
    ModelStore->>ModelStore: _verify_endianess(model_tag)
    activate ModelStore # _verify_endianess
    ModelStore->>ModelStore: get_ref_file(model_tag)
    ModelStore->>ModelStore: get_blob_file_path(model_hash)
    ModelStore->>GGUFInfoParser: is_model_gguf(model_path)
    GGUFInfoParser-->>ModelStore: is_gguf
    alt is_gguf is true
        ModelStore->>GGUFInfoParser: get_model_endianness(model_path)
        GGUFInfoParser-->>ModelStore: model_endianness
        ModelStore->>EndianUtils: get_system_endianness()
        EndianUtils-->>ModelStore: host_endianness
        alt host_endianness != model_endianness
            ModelStore-->>ModelStore: Raise EndianMismatchError
        end
    end
    deactivate ModelStore # _verify_endianess
    ModelStore->>ModelStore: _store.verify_snapshot() // Verifies other aspects
    deactivate ModelStore
Loading

File-Level Changes

Change Details Files
Introduce dedicated snapshot endianness verification step
  • Add _verify_endianess and verify_snapshot methods
  • Invoke verification after snapshot creation and cleanup on failure
  • Raise EndianMismatchError on mismatch
ramalama/model_store.py
Centralize GGUF endianness determination and system helper functions
  • Extract get_model_endianness from GGUFInfoParser
  • Adjust parse to defer magic and version reading using unified endianness
  • Add get_system_endianness helper
  • Define custom EndianMismatchError for consistent error reporting
ramalama/gguf_parser.py
ramalama/endian.py
Refactor new_snapshot to wrap steps in error-handling and ensure cleanup
  • Wrap preparation, download, and template setup in try/except blocks
  • Remove snapshot and ref files on HTTPError and generic exceptions
  • Chain verify_snapshot call with cleanup on mismatch
ramalama/model_store.py
Improve error handling in remove_snapshot
  • Catch and ignore FileNotFoundError when removing missing ref file
ramalama/model_store.py
Eliminate redundant endianness flags and simplify client wrappers
  • Remove should_verify_endianness parameter from SnapshotFile constructors
  • Delete inline endianness checks in _download_snapshot_files
  • Remove redundant exception wrappers around new_snapshot in repo_model_base and ollama
ramalama/model_store.py
ramalama/repo_model_base.py
ramalama/ollama.py

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

@taronaeo
Copy link
Collaborator

taronaeo commented Jun 2, 2025

Hi, when this PR is ready, please allow me to test it on IBM Z & LinuxONE as well to ensure that the endianness checks are still intact :)

Self-assigning for now

@taronaeo taronaeo self-requested a review June 2, 2025 08:46
@engelmi engelmi marked this pull request as ready for review June 2, 2025 09:15
@engelmi
Copy link
Member Author

engelmi commented Jun 2, 2025

Hi, when this PR is ready, please allow me to test it on IBM Z & LinuxONE as well to ensure that the endianness checks are still intact :)

Self-assigning for now

@taronaeo Ping :)
Would be great if you can test it on IBM Z + LinuxONE.

Copy link
Contributor

@sourcery-ai sourcery-ai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey @engelmi - I've reviewed your changes - here's some feedback:

  • In _verify_endianess, replace the if ref_file is None: pass with an explicit early return to make the no-ref_file case clearer and prevent accidental fallthrough.
  • The generic except Exception block in new_snapshot can mask unexpected bugs—consider catching only the specific errors you expect or re-raising after cleanup to preserve the original traceback.
  • You have almost identical cleanup logic in both error handlers in new_snapshot—extracting that into a small helper function could reduce duplication and make the flow clearer.
Here's what I looked at during the review
  • 🟡 General issues: 1 issue found
  • 🟢 Security: all looks good
  • 🟢 Testing: all looks good
  • 🟢 Complexity: all looks good
  • 🟢 Documentation: all looks good

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

@taronaeo
Copy link
Collaborator

taronaeo commented Jun 2, 2025

Hi, when this PR is ready, please allow me to test it on IBM Z & LinuxONE as well to ensure that the endianness checks are still intact :)
Self-assigning for now

@taronaeo Ping :) Would be great if you can test it on IBM Z + LinuxONE.

Gotcha! I have dispatched a runner to test this PR, will update again once the test is complete :)

@engelmi engelmi force-pushed the snapshot-verification branch from 2db17bb to 322d65b Compare June 2, 2025 09:27
Copy link
Collaborator

@taronaeo taronaeo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM! Works as intended on IBM Z & LinuxONE!

engelmi added 5 commits June 2, 2025 13:11
By moving the recently improved code to detect the endianness into
a dedicated function, its reusability is increased. Also, a specific
exception class if the model is not in the gguf format has been added.

Signed-off-by: Michael Engel <[email protected]>
Previously, the endianness check was done for each SnapshotFile and
these files might not be models, but could also be miscellaneous such
as chat templates or other meta data. By removing only the affected file
on a mismatch error the store might get into an inconsistent state since
the cleanup depends on the error handling of the caller.
Therefore, the check for endianness has been moved one layer up and only
checks the flagged model file. In case of a mismatch an implicit removal
of the whole snapshot is triggered.

Signed-off-by: Michael Engel <[email protected]>
An error when creating new snapshots has only been partially handled
inside the model store and the caller side had to clean up properly.
In order to simplify this, more error handling has been added when
creating new snapshots - removing the (faulty) snapshot, logging and
passing the exception upwards so that the caller can do additional
actions. This ensures that the state remains consistent.

Signed-off-by: Michael Engel <[email protected]>
@engelmi engelmi force-pushed the snapshot-verification branch from 322d65b to b84527b Compare June 2, 2025 11:11
@ericcurtin ericcurtin merged commit 75b36dc into containers:main Jun 2, 2025
15 checks passed
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.

3 participants