server/internal: replace model delete API with new registry handler. (#9347)

This commit introduces a new API implementation for handling
interactions with the registry and the local model cache. The new API is
located in server/internal/registry. The package name is "registry" and
should be considered temporary; it is hidden and not bleeding outside of
the server package. As the commits roll in, we'll start consuming more
of the API and then let reverse osmosis take effect, at which point it
will surface closer to the root level packages as much as needed.
This commit is contained in:
Blake Mizerany
2025-02-27 12:04:53 -08:00
committed by GitHub
parent be2ac1ed93
commit 2412adf42b
16 changed files with 705 additions and 90 deletions

View File

@@ -279,6 +279,18 @@ func (c *DiskCache) Get(d Digest) (Entry, error) {
// It returns an error if either the name or digest is invalid, or if link
// creation encounters any issues.
func (c *DiskCache) Link(name string, d Digest) error {
// TODO(bmizerany): Move link handling from cache to registry.
//
// We originally placed links in the cache due to its storage
// knowledge. However, the registry likely offers better context for
// naming concerns, and our API design shouldn't be tightly coupled to
// our on-disk format.
//
// Links work effectively when independent from physical location -
// they can reference content with matching SHA regardless of storage
// location. In an upcoming change, we plan to shift this
// responsibility to the registry where it better aligns with the
// system's conceptual model.
manifest, err := c.manifestPath(name)
if err != nil {
return err
@@ -304,21 +316,19 @@ func (c *DiskCache) Link(name string, d Digest) error {
return c.copyNamedFile(manifest, f, d, info.Size())
}
// Unlink removes the any link for name. If the link does not exist, nothing
// happens, and no error is returned.
//
// It returns an error if the name is invalid or if the link removal encounters
// any issues.
func (c *DiskCache) Unlink(name string) error {
// Unlink unlinks the manifest by name from the cache. If the name is not
// found. If a manifest is removed ok will be true, otherwise false. If an
// error occurs, it returns ok false, and the error.
func (c *DiskCache) Unlink(name string) (ok bool, _ error) {
manifest, err := c.manifestPath(name)
if err != nil {
return err
return false, err
}
err = os.Remove(manifest)
if errors.Is(err, fs.ErrNotExist) {
return nil
return false, nil
}
return err
return true, err
}
// GetFile returns the absolute path to the file, in the cache, for the given

View File

@@ -13,7 +13,7 @@ import (
"testing"
"time"
"github.com/ollama/ollama/server/internal/internal/testutil"
"github.com/ollama/ollama/server/internal/testutil"
)
func init() {
@@ -479,8 +479,11 @@ func testManifestNameReuse(t *testing.T) {
}
// relink with different case
err = c.Unlink("h/n/m:t")
unlinked, err := c.Unlink("h/n/m:t")
check(err)
if !unlinked {
t.Fatal("expected unlinked")
}
err = c.Link("h/n/m:T", d1)
check(err)

View File

@@ -86,7 +86,7 @@ func useCaseInsensitiveTempDir(t *testing.T) bool {
// link to docs on that topic.
lines := strings.Split(volumeHint, "\n")
for _, line := range lines {
t.Log(line)
t.Skip(line)
}
}
return false