Artifact Pulling
There are a number of open issues related to pulling and running generic model artifacts with a number of open technical questions related to each. Among which include
- Using
podman artifacthttps://github.com/containers/ramalama/issues/1152 - How to implement equivalent docker functionality for artifact pulling
- standards compliance https://github.com/containers/ramalama/issues/1674
This PR does not attempt to address all of these question. Given the scope of the problem though, I thought having some code to look at might form a useful jumping off point to begin picking off problems one at a time.
As pertains standards, one path is to implement a system capable of identifying discrete packaging strategies (like modelpack) but so far as I'm aware docker doesn't provide equivalent functionality to podman artifact. To that end, I've taken a rough shot at a pure python implementation for oci_artifacts.
I've attached some of this code to the rlcr transport option only because I have a variety of oras packaged model artifacts (e.g. rlcr://gemma3-270m:gguf) I could test against already.
I just want to reiterate this PR is only intended to facilitate the broader conversation around artifact pulling. Would it be better to only support podman for artifact running? Are there strong opinions about package structure?
Comments and thoughts would be welcome @rhatdan @engelmi.
Summary by Sourcery
Add pure Python OCI artifact pulling support and integrate it as a fallback in the RLCR transport when standard pulls fail.
New Features:
- Implement a new oci_artifact module to fetch OCI manifests and download blobs over HTTP with checksum verification and token authentication
- Enable RamalamaContainerRegistry to fall back to OCI artifact pulling when conventional container pulls fail
Enhancements:
- Track and detect cached artifact snapshots in RLCR transport, overriding exists, pull, entry model path, and mount setup accordingly
Tests:
- Add unit tests for RLCR fallback behavior, including successful and failed artifact download scenarios
- Add unit tests for OCI artifact download to verify manifest parsing, blob retrieval, snapshot creation, and model path resolution
Reviewer's Guide
This PR introduces Python-based OCI artifact pulling support and integrates it as a fallback in the RLCR transport when container pulls fail, along with unit tests validating both the fallback logic and the new OCI artifact download module.
Sequence diagram for RLCR transport artifact pulling fallback
sequenceDiagram
participant User
participant RLCRTransport
participant OCI
participant OCIArtifactModule
User->>RLCRTransport: pull(args)
RLCRTransport->>OCI: pull(args)
alt OCI pull fails
RLCRTransport->>OCIArtifactModule: attempt_artifact_pull(args)
OCIArtifactModule->>OCIArtifactModule: download_oci_artifact(...)
OCIArtifactModule-->>RLCRTransport: success/failure
RLCRTransport-->>User: result
else OCI pull succeeds
OCI-->>RLCRTransport: success
RLCRTransport-->>User: result
end
Class diagram for new and updated RLCR and OCI artifact classes
classDiagram
class RamalamaContainerRegistry {
- _artifact_downloaded: bool
+ pull(args)
+ _attempt_artifact_pull(args) bool
+ _has_artifact_snapshot() bool
+ exists() bool
+ _get_entry_model_path(*args, **kwargs) str
+ setup_mounts(args)
}
RamalamaContainerRegistry --|> OCI
class OCIRegistryClient {
- registry: str
- repository: str
- reference: str
- base_url: str
- _bearer_token: str | None
+ get_manifest() (dict, str)
+ download_blob(digest, dest_path)
+ _prepare_headers(headers)
+ _open(url, headers)
+ _request_bearer_token(challenge)
}
class RegistryBlobSnapshotFile {
+ download(blob_file_path, snapshot_dir) str
- client: OCIRegistryClient
- digest: str
}
RegistryBlobSnapshotFile --|> SnapshotFile
class SnapshotFile {
<<external>>
}
class download_oci_artifact {
<<function>>
}
OCIRegistryClient <.. RegistryBlobSnapshotFile : uses
RegistryBlobSnapshotFile <.. download_oci_artifact : used by
File-Level Changes
| Change | Details | Files |
|---|---|---|
| RLCR transport now falls back to OCI artifact download and tracks snapshot state |
|
ramalama/transports/rlcr.py |
| Add pure-Python OCI artifact client and download integration |
|
ramalama/transports/oci_artifact.py |
| Enhance unit tests to cover RLCR fallback and OCI artifact download |
|
test/unit/test_rlcr.py |
Possibly linked issues
- #unknown: PR implements pure Python OCI artifact pulling, addressing the issue's question on pulling new OCI artifact types.
Tips and commands
Interacting with Sourcery
- Trigger a new review: Comment
@sourcery-ai reviewon 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 issueto create an issue from it. - Generate a pull request title: Write
@sourcery-aianywhere in the pull request title to generate a title at any time. You can also comment@sourcery-ai titleon the pull request to (re-)generate the title at any time. - Generate a pull request summary: Write
@sourcery-ai summaryanywhere in the pull request body to generate a PR summary at any time exactly where you want it. You can also comment@sourcery-ai summaryon the pull request to (re-)generate the summary at any time. - Generate reviewer's guide: Comment
@sourcery-ai guideon the pull request to (re-)generate the reviewer's guide at any time. - Resolve all Sourcery comments: Comment
@sourcery-ai resolveon 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 dismisson 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 reviewto 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
- Contact our support team for questions or feedback.
- Visit our documentation for detailed guides and information.
- Keep in touch with the Sourcery team by following us on X/Twitter, LinkedIn or GitHub.
Summary of Changes
Hello @ieaves, I'm Gemini Code Assist[^1]! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!
This pull request lays the groundwork for more flexible model artifact management by introducing direct OCI artifact pulling capabilities. It provides a pure Python implementation for interacting with OCI registries to fetch model artifacts, serving as an initial step towards addressing broader issues related to generic model artifact handling. The changes integrate this new functionality into the existing rlcr transport, enabling it to fall back to OCI artifact pulling when traditional container image pulls are unsuccessful, thereby enhancing the robustness of model retrieval.
Highlights
- OCI Artifact Pulling Implementation: Introduces a new Python module (
oci_artifact.py) to handle pulling Open Container Initiative (OCI) artifacts from registries, including manifest fetching, authentication, and blob downloading. - Fallback Mechanism for Model Pulling: Modifies the
rlcrtransport to attempt OCI artifact pulling as a fallback mechanism if the primary container image pulling (e.g., via Podman) fails. - Enhanced Model Lifecycle Management: Integrates OCI artifact handling into the
RamalamaContainerRegistryclass, allowing it to recognize and manage models downloaded as OCI artifacts, affectingexists,_get_entry_model_path, andsetup_mountsmethods. - Comprehensive Unit Tests: Adds new unit tests to validate the OCI artifact fallback logic and the core functionality of downloading OCI artifacts and creating model snapshots.
Using Gemini Code Assist
The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.
Invoking Gemini
You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.
| Feature | Command | Description |
|---|---|---|
| Code Review | /gemini review |
Performs a code review for the current pull request in its current state. |
| Pull Request Summary | /gemini summary |
Provides a summary of the current pull request in its current state. |
| Comment | @gemini-code-assist | Responds in comments when explicitly tagged, both in pull request comments and review comments. |
| Help | /gemini help |
Displays a list of available commands. |
Customization
To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.
Limitations & Feedback
Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with :thumbsup: and :thumbsdown: on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.
You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.
[^1]: Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.
@ieaves still working on this? I think this along with the podman PR which is waiting for podman 5.7 release should move us forward with artifact support.
@rhatdan I'm taking a look at your podman changes now. I need to adapt this to use
- The podman annotation specs
- Add this is a fallback to the podman functionality you PRed.
@rhatdan I rebased this to your branch and took a shot at integrating a hierarchy of decision strategies depending on the users configuration. The basic structure is supposed to be
- If there is a sufficiently advanced version of podman use podman pull
- If not, identify whether the artifact exists locally and check the manifest to distinguish artifacts from images
- If not, http probe the manifest to identify its type and use the appropriate strategy (docker / podman for images, http for artifacts)
Then, if the user is running docker we pipe the model file into the container since we can't use artifact/image mounting the same way we can with podman.
I haven't done extensive testing but I've got things working with both docker and podman testing against one of my models at rlcr.io/ramalama/gemma3-270m:gguf.
A friendly reminder that this PR had no activity for 30 days.
@ieaves still working on this? Can this be rebased after my Artifact PR was merged?