2025-02-28 04:04:53 +08:00
|
|
|
package registry
|
|
|
|
|
|
|
|
import (
|
server/internal/registry: take over pulls from server package (#9485)
This commit replaces the old pull implementation in the server package
with the new, faster, more robust pull implementation in the registry
package.
The new endpoint, and now the remove endpoint too, are behind the
feature gate "client2" enabled only by setting the OLLAMA_EXPERIMENT
environment variable include "client2".
Currently, the progress indication is wired to perform the same as the
previous implementation to avoid making changes to the CLI, and because
the status reports happen at the start of the download, and the end of
the write to disk, the progress indication is not as smooth as it could
be. This is a known issue and will be addressed in a future change.
This implementation may be ~0.5-1.0% slower in rare cases, depending on
network and disk speed, but is generally MUCH faster and more robust
than the its predecessor in all other cases.
2025-03-06 06:48:18 +08:00
|
|
|
"bytes"
|
|
|
|
"context"
|
2025-02-28 04:04:53 +08:00
|
|
|
"encoding/json"
|
server/internal/registry: take over pulls from server package (#9485)
This commit replaces the old pull implementation in the server package
with the new, faster, more robust pull implementation in the registry
package.
The new endpoint, and now the remove endpoint too, are behind the
feature gate "client2" enabled only by setting the OLLAMA_EXPERIMENT
environment variable include "client2".
Currently, the progress indication is wired to perform the same as the
previous implementation to avoid making changes to the CLI, and because
the status reports happen at the start of the download, and the end of
the write to disk, the progress indication is not as smooth as it could
be. This is a known issue and will be addressed in a future change.
This implementation may be ~0.5-1.0% slower in rare cases, depending on
network and disk speed, but is generally MUCH faster and more robust
than the its predecessor in all other cases.
2025-03-06 06:48:18 +08:00
|
|
|
"io"
|
|
|
|
"io/fs"
|
|
|
|
"net"
|
2025-02-28 04:04:53 +08:00
|
|
|
"net/http"
|
|
|
|
"net/http/httptest"
|
|
|
|
"os"
|
|
|
|
"regexp"
|
|
|
|
"strings"
|
server/internal/registry: take over pulls from server package (#9485)
This commit replaces the old pull implementation in the server package
with the new, faster, more robust pull implementation in the registry
package.
The new endpoint, and now the remove endpoint too, are behind the
feature gate "client2" enabled only by setting the OLLAMA_EXPERIMENT
environment variable include "client2".
Currently, the progress indication is wired to perform the same as the
previous implementation to avoid making changes to the CLI, and because
the status reports happen at the start of the download, and the end of
the write to disk, the progress indication is not as smooth as it could
be. This is a known issue and will be addressed in a future change.
This implementation may be ~0.5-1.0% slower in rare cases, depending on
network and disk speed, but is generally MUCH faster and more robust
than the its predecessor in all other cases.
2025-03-06 06:48:18 +08:00
|
|
|
"sync"
|
2025-02-28 04:04:53 +08:00
|
|
|
"testing"
|
|
|
|
|
|
|
|
"github.com/ollama/ollama/server/internal/cache/blob"
|
|
|
|
"github.com/ollama/ollama/server/internal/client/ollama"
|
|
|
|
"github.com/ollama/ollama/server/internal/testutil"
|
server/internal/registry: take over pulls from server package (#9485)
This commit replaces the old pull implementation in the server package
with the new, faster, more robust pull implementation in the registry
package.
The new endpoint, and now the remove endpoint too, are behind the
feature gate "client2" enabled only by setting the OLLAMA_EXPERIMENT
environment variable include "client2".
Currently, the progress indication is wired to perform the same as the
previous implementation to avoid making changes to the CLI, and because
the status reports happen at the start of the download, and the end of
the write to disk, the progress indication is not as smooth as it could
be. This is a known issue and will be addressed in a future change.
This implementation may be ~0.5-1.0% slower in rare cases, depending on
network and disk speed, but is generally MUCH faster and more robust
than the its predecessor in all other cases.
2025-03-06 06:48:18 +08:00
|
|
|
"golang.org/x/tools/txtar"
|
|
|
|
|
|
|
|
_ "embed"
|
2025-02-28 04:04:53 +08:00
|
|
|
)
|
|
|
|
|
|
|
|
type panicTransport struct{}
|
|
|
|
|
|
|
|
func (t *panicTransport) RoundTrip(r *http.Request) (*http.Response, error) {
|
|
|
|
panic("unexpected RoundTrip call")
|
|
|
|
}
|
|
|
|
|
|
|
|
var panicOnRoundTrip = &http.Client{Transport: &panicTransport{}}
|
|
|
|
|
|
|
|
// bytesResetter is an interface for types that can be reset and return a byte
|
|
|
|
// slice, only. This is to prevent inadvertent use of bytes.Buffer.Read/Write
|
|
|
|
// etc for the purpose of checking logs.
|
|
|
|
type bytesResetter interface {
|
|
|
|
Bytes() []byte
|
|
|
|
Reset()
|
|
|
|
}
|
|
|
|
|
server/internal/registry: take over pulls from server package (#9485)
This commit replaces the old pull implementation in the server package
with the new, faster, more robust pull implementation in the registry
package.
The new endpoint, and now the remove endpoint too, are behind the
feature gate "client2" enabled only by setting the OLLAMA_EXPERIMENT
environment variable include "client2".
Currently, the progress indication is wired to perform the same as the
previous implementation to avoid making changes to the CLI, and because
the status reports happen at the start of the download, and the end of
the write to disk, the progress indication is not as smooth as it could
be. This is a known issue and will be addressed in a future change.
This implementation may be ~0.5-1.0% slower in rare cases, depending on
network and disk speed, but is generally MUCH faster and more robust
than the its predecessor in all other cases.
2025-03-06 06:48:18 +08:00
|
|
|
func newTestServer(t *testing.T, upstreamRegistry http.HandlerFunc) *Local {
|
2025-02-28 04:04:53 +08:00
|
|
|
t.Helper()
|
|
|
|
dir := t.TempDir()
|
|
|
|
err := os.CopyFS(dir, os.DirFS("testdata/models"))
|
|
|
|
if err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
c, err := blob.Open(dir)
|
|
|
|
if err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
server/internal/registry: take over pulls from server package (#9485)
This commit replaces the old pull implementation in the server package
with the new, faster, more robust pull implementation in the registry
package.
The new endpoint, and now the remove endpoint too, are behind the
feature gate "client2" enabled only by setting the OLLAMA_EXPERIMENT
environment variable include "client2".
Currently, the progress indication is wired to perform the same as the
previous implementation to avoid making changes to the CLI, and because
the status reports happen at the start of the download, and the end of
the write to disk, the progress indication is not as smooth as it could
be. This is a known issue and will be addressed in a future change.
This implementation may be ~0.5-1.0% slower in rare cases, depending on
network and disk speed, but is generally MUCH faster and more robust
than the its predecessor in all other cases.
2025-03-06 06:48:18 +08:00
|
|
|
|
|
|
|
client := panicOnRoundTrip
|
|
|
|
if upstreamRegistry != nil {
|
|
|
|
s := httptest.NewTLSServer(upstreamRegistry)
|
|
|
|
t.Cleanup(s.Close)
|
|
|
|
tr := s.Client().Transport.(*http.Transport).Clone()
|
|
|
|
tr.DialContext = func(ctx context.Context, _, _ string) (net.Conn, error) {
|
|
|
|
var d net.Dialer
|
|
|
|
return d.DialContext(ctx, "tcp", s.Listener.Addr().String())
|
|
|
|
}
|
|
|
|
client = &http.Client{Transport: tr}
|
|
|
|
}
|
|
|
|
|
2025-02-28 04:04:53 +08:00
|
|
|
rc := &ollama.Registry{
|
2025-03-03 12:55:44 +08:00
|
|
|
Cache: c,
|
server/internal/registry: take over pulls from server package (#9485)
This commit replaces the old pull implementation in the server package
with the new, faster, more robust pull implementation in the registry
package.
The new endpoint, and now the remove endpoint too, are behind the
feature gate "client2" enabled only by setting the OLLAMA_EXPERIMENT
environment variable include "client2".
Currently, the progress indication is wired to perform the same as the
previous implementation to avoid making changes to the CLI, and because
the status reports happen at the start of the download, and the end of
the write to disk, the progress indication is not as smooth as it could
be. This is a known issue and will be addressed in a future change.
This implementation may be ~0.5-1.0% slower in rare cases, depending on
network and disk speed, but is generally MUCH faster and more robust
than the its predecessor in all other cases.
2025-03-06 06:48:18 +08:00
|
|
|
HTTPClient: client,
|
|
|
|
Mask: "example.com/library/_:latest",
|
2025-02-28 04:04:53 +08:00
|
|
|
}
|
server/internal/registry: take over pulls from server package (#9485)
This commit replaces the old pull implementation in the server package
with the new, faster, more robust pull implementation in the registry
package.
The new endpoint, and now the remove endpoint too, are behind the
feature gate "client2" enabled only by setting the OLLAMA_EXPERIMENT
environment variable include "client2".
Currently, the progress indication is wired to perform the same as the
previous implementation to avoid making changes to the CLI, and because
the status reports happen at the start of the download, and the end of
the write to disk, the progress indication is not as smooth as it could
be. This is a known issue and will be addressed in a future change.
This implementation may be ~0.5-1.0% slower in rare cases, depending on
network and disk speed, but is generally MUCH faster and more robust
than the its predecessor in all other cases.
2025-03-06 06:48:18 +08:00
|
|
|
|
2025-02-28 04:04:53 +08:00
|
|
|
l := &Local{
|
|
|
|
Client: rc,
|
|
|
|
Logger: testutil.Slogger(t),
|
|
|
|
}
|
|
|
|
return l
|
|
|
|
}
|
|
|
|
|
|
|
|
func (s *Local) send(t *testing.T, method, path, body string) *httptest.ResponseRecorder {
|
|
|
|
t.Helper()
|
2025-04-16 14:24:44 +08:00
|
|
|
ctx := ollama.WithTrace(t.Context(), &ollama.Trace{
|
|
|
|
Update: func(l *ollama.Layer, n int64, err error) {
|
|
|
|
t.Logf("update: %s %d %v", l.Digest, n, err)
|
|
|
|
},
|
|
|
|
})
|
|
|
|
req := httptest.NewRequestWithContext(ctx, method, path, strings.NewReader(body))
|
2025-02-28 04:04:53 +08:00
|
|
|
return s.sendRequest(t, req)
|
|
|
|
}
|
|
|
|
|
|
|
|
func (s *Local) sendRequest(t *testing.T, req *http.Request) *httptest.ResponseRecorder {
|
|
|
|
t.Helper()
|
|
|
|
w := httptest.NewRecorder()
|
|
|
|
s.ServeHTTP(w, req)
|
|
|
|
return w
|
|
|
|
}
|
|
|
|
|
|
|
|
type invalidReader struct{}
|
|
|
|
|
|
|
|
func (r *invalidReader) Read(p []byte) (int, error) {
|
|
|
|
return 0, os.ErrInvalid
|
|
|
|
}
|
|
|
|
|
|
|
|
// captureLogs is a helper to capture logs from the server. It returns a
|
|
|
|
// shallow copy of the server with a new logger and a bytesResetter for the
|
|
|
|
// logs.
|
|
|
|
func captureLogs(t *testing.T, s *Local) (*Local, bytesResetter) {
|
|
|
|
t.Helper()
|
|
|
|
log, logs := testutil.SlogBuffer()
|
|
|
|
l := *s // shallow copy
|
|
|
|
l.Logger = log
|
|
|
|
return &l, logs
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestServerDelete(t *testing.T) {
|
|
|
|
check := testutil.Checker(t)
|
|
|
|
|
server/internal/registry: take over pulls from server package (#9485)
This commit replaces the old pull implementation in the server package
with the new, faster, more robust pull implementation in the registry
package.
The new endpoint, and now the remove endpoint too, are behind the
feature gate "client2" enabled only by setting the OLLAMA_EXPERIMENT
environment variable include "client2".
Currently, the progress indication is wired to perform the same as the
previous implementation to avoid making changes to the CLI, and because
the status reports happen at the start of the download, and the end of
the write to disk, the progress indication is not as smooth as it could
be. This is a known issue and will be addressed in a future change.
This implementation may be ~0.5-1.0% slower in rare cases, depending on
network and disk speed, but is generally MUCH faster and more robust
than the its predecessor in all other cases.
2025-03-06 06:48:18 +08:00
|
|
|
s := newTestServer(t, nil)
|
2025-02-28 04:04:53 +08:00
|
|
|
|
2025-03-03 12:55:44 +08:00
|
|
|
_, err := s.Client.ResolveLocal("smol")
|
2025-02-28 04:04:53 +08:00
|
|
|
check(err)
|
|
|
|
|
|
|
|
got := s.send(t, "DELETE", "/api/delete", `{"model": "smol"}`)
|
|
|
|
if got.Code != 200 {
|
|
|
|
t.Fatalf("Code = %d; want 200", got.Code)
|
|
|
|
}
|
|
|
|
|
2025-03-03 12:55:44 +08:00
|
|
|
_, err = s.Client.ResolveLocal("smol")
|
2025-02-28 04:04:53 +08:00
|
|
|
if err == nil {
|
|
|
|
t.Fatal("expected smol to have been deleted")
|
|
|
|
}
|
|
|
|
|
|
|
|
got = s.send(t, "DELETE", "/api/delete", `!`)
|
|
|
|
checkErrorResponse(t, got, 400, "bad_request", "invalid character '!' looking for beginning of value")
|
|
|
|
|
|
|
|
got = s.send(t, "GET", "/api/delete", `{"model": "smol"}`)
|
|
|
|
checkErrorResponse(t, got, 405, "method_not_allowed", "method not allowed")
|
|
|
|
|
|
|
|
got = s.send(t, "DELETE", "/api/delete", ``)
|
|
|
|
checkErrorResponse(t, got, 400, "bad_request", "empty request body")
|
|
|
|
|
|
|
|
got = s.send(t, "DELETE", "/api/delete", `{"model": "://"}`)
|
2025-03-02 05:15:14 +08:00
|
|
|
checkErrorResponse(t, got, 400, "bad_request", "invalid or missing name")
|
2025-02-28 04:04:53 +08:00
|
|
|
|
|
|
|
got = s.send(t, "DELETE", "/unknown_path", `{}`) // valid body
|
|
|
|
checkErrorResponse(t, got, 404, "not_found", "not found")
|
|
|
|
|
|
|
|
s, logs := captureLogs(t, s)
|
|
|
|
req := httptest.NewRequestWithContext(t.Context(), "DELETE", "/api/delete", &invalidReader{})
|
|
|
|
got = s.sendRequest(t, req)
|
|
|
|
checkErrorResponse(t, got, 500, "internal_error", "internal server error")
|
|
|
|
ok, err := regexp.Match(`ERROR.*error="invalid argument"`, logs.Bytes())
|
|
|
|
check(err)
|
|
|
|
if !ok {
|
|
|
|
t.Logf("logs:\n%s", logs)
|
|
|
|
t.Fatalf("expected log to contain ERROR with invalid argument")
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
server/internal/registry: take over pulls from server package (#9485)
This commit replaces the old pull implementation in the server package
with the new, faster, more robust pull implementation in the registry
package.
The new endpoint, and now the remove endpoint too, are behind the
feature gate "client2" enabled only by setting the OLLAMA_EXPERIMENT
environment variable include "client2".
Currently, the progress indication is wired to perform the same as the
previous implementation to avoid making changes to the CLI, and because
the status reports happen at the start of the download, and the end of
the write to disk, the progress indication is not as smooth as it could
be. This is a known issue and will be addressed in a future change.
This implementation may be ~0.5-1.0% slower in rare cases, depending on
network and disk speed, but is generally MUCH faster and more robust
than the its predecessor in all other cases.
2025-03-06 06:48:18 +08:00
|
|
|
//go:embed testdata/registry.txt
|
|
|
|
var registryTXT []byte
|
|
|
|
|
|
|
|
var registryFS = sync.OnceValue(func() fs.FS {
|
|
|
|
// Txtar gets hung up on \r\n line endings, so we need to convert them
|
|
|
|
// to \n when parsing the txtar on Windows.
|
|
|
|
data := bytes.ReplaceAll(registryTXT, []byte("\r\n"), []byte("\n"))
|
|
|
|
a := txtar.Parse(data)
|
|
|
|
fsys, err := txtar.FS(a)
|
|
|
|
if err != nil {
|
|
|
|
panic(err)
|
|
|
|
}
|
|
|
|
return fsys
|
|
|
|
})
|
|
|
|
|
|
|
|
func TestServerPull(t *testing.T) {
|
|
|
|
modelsHandler := http.FileServerFS(registryFS())
|
|
|
|
s := newTestServer(t, func(w http.ResponseWriter, r *http.Request) {
|
|
|
|
switch r.URL.Path {
|
|
|
|
case "/v2/library/BOOM/manifests/latest":
|
|
|
|
w.WriteHeader(999)
|
|
|
|
io.WriteString(w, `{"error": "boom"}`)
|
|
|
|
case "/v2/library/unknown/manifests/latest":
|
|
|
|
w.WriteHeader(404)
|
|
|
|
io.WriteString(w, `{"errors": [{"code": "MANIFEST_UNKNOWN", "message": "manifest unknown"}]}`)
|
|
|
|
default:
|
2025-03-14 13:18:29 +08:00
|
|
|
t.Logf("serving blob: %s", r.URL.Path)
|
server/internal/registry: take over pulls from server package (#9485)
This commit replaces the old pull implementation in the server package
with the new, faster, more robust pull implementation in the registry
package.
The new endpoint, and now the remove endpoint too, are behind the
feature gate "client2" enabled only by setting the OLLAMA_EXPERIMENT
environment variable include "client2".
Currently, the progress indication is wired to perform the same as the
previous implementation to avoid making changes to the CLI, and because
the status reports happen at the start of the download, and the end of
the write to disk, the progress indication is not as smooth as it could
be. This is a known issue and will be addressed in a future change.
This implementation may be ~0.5-1.0% slower in rare cases, depending on
network and disk speed, but is generally MUCH faster and more robust
than the its predecessor in all other cases.
2025-03-06 06:48:18 +08:00
|
|
|
modelsHandler.ServeHTTP(w, r)
|
|
|
|
}
|
|
|
|
})
|
|
|
|
|
|
|
|
checkResponse := func(got *httptest.ResponseRecorder, wantlines string) {
|
|
|
|
t.Helper()
|
|
|
|
if got.Code != 200 {
|
2025-03-14 13:18:29 +08:00
|
|
|
t.Errorf("Code = %d; want 200", got.Code)
|
server/internal/registry: take over pulls from server package (#9485)
This commit replaces the old pull implementation in the server package
with the new, faster, more robust pull implementation in the registry
package.
The new endpoint, and now the remove endpoint too, are behind the
feature gate "client2" enabled only by setting the OLLAMA_EXPERIMENT
environment variable include "client2".
Currently, the progress indication is wired to perform the same as the
previous implementation to avoid making changes to the CLI, and because
the status reports happen at the start of the download, and the end of
the write to disk, the progress indication is not as smooth as it could
be. This is a known issue and will be addressed in a future change.
This implementation may be ~0.5-1.0% slower in rare cases, depending on
network and disk speed, but is generally MUCH faster and more robust
than the its predecessor in all other cases.
2025-03-06 06:48:18 +08:00
|
|
|
}
|
|
|
|
gotlines := got.Body.String()
|
2025-04-16 14:24:44 +08:00
|
|
|
if strings.TrimSpace(gotlines) == "" {
|
|
|
|
gotlines = "<empty>"
|
|
|
|
}
|
server/internal/registry: take over pulls from server package (#9485)
This commit replaces the old pull implementation in the server package
with the new, faster, more robust pull implementation in the registry
package.
The new endpoint, and now the remove endpoint too, are behind the
feature gate "client2" enabled only by setting the OLLAMA_EXPERIMENT
environment variable include "client2".
Currently, the progress indication is wired to perform the same as the
previous implementation to avoid making changes to the CLI, and because
the status reports happen at the start of the download, and the end of
the write to disk, the progress indication is not as smooth as it could
be. This is a known issue and will be addressed in a future change.
This implementation may be ~0.5-1.0% slower in rare cases, depending on
network and disk speed, but is generally MUCH faster and more robust
than the its predecessor in all other cases.
2025-03-06 06:48:18 +08:00
|
|
|
t.Logf("got:\n%s", gotlines)
|
|
|
|
for want := range strings.Lines(wantlines) {
|
|
|
|
want = strings.TrimSpace(want)
|
|
|
|
want, unwanted := strings.CutPrefix(want, "!")
|
|
|
|
want = strings.TrimSpace(want)
|
|
|
|
if !unwanted && !strings.Contains(gotlines, want) {
|
2025-04-16 14:24:44 +08:00
|
|
|
t.Errorf("\t! missing %q in body", want)
|
server/internal/registry: take over pulls from server package (#9485)
This commit replaces the old pull implementation in the server package
with the new, faster, more robust pull implementation in the registry
package.
The new endpoint, and now the remove endpoint too, are behind the
feature gate "client2" enabled only by setting the OLLAMA_EXPERIMENT
environment variable include "client2".
Currently, the progress indication is wired to perform the same as the
previous implementation to avoid making changes to the CLI, and because
the status reports happen at the start of the download, and the end of
the write to disk, the progress indication is not as smooth as it could
be. This is a known issue and will be addressed in a future change.
This implementation may be ~0.5-1.0% slower in rare cases, depending on
network and disk speed, but is generally MUCH faster and more robust
than the its predecessor in all other cases.
2025-03-06 06:48:18 +08:00
|
|
|
}
|
|
|
|
if unwanted && strings.Contains(gotlines, want) {
|
2025-04-16 14:24:44 +08:00
|
|
|
t.Errorf("\t! unexpected %q in body", want)
|
server/internal/registry: take over pulls from server package (#9485)
This commit replaces the old pull implementation in the server package
with the new, faster, more robust pull implementation in the registry
package.
The new endpoint, and now the remove endpoint too, are behind the
feature gate "client2" enabled only by setting the OLLAMA_EXPERIMENT
environment variable include "client2".
Currently, the progress indication is wired to perform the same as the
previous implementation to avoid making changes to the CLI, and because
the status reports happen at the start of the download, and the end of
the write to disk, the progress indication is not as smooth as it could
be. This is a known issue and will be addressed in a future change.
This implementation may be ~0.5-1.0% slower in rare cases, depending on
network and disk speed, but is generally MUCH faster and more robust
than the its predecessor in all other cases.
2025-03-06 06:48:18 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2025-04-16 14:24:44 +08:00
|
|
|
got := s.send(t, "POST", "/api/pull", `{"model": "smol"}`)
|
server/internal/registry: take over pulls from server package (#9485)
This commit replaces the old pull implementation in the server package
with the new, faster, more robust pull implementation in the registry
package.
The new endpoint, and now the remove endpoint too, are behind the
feature gate "client2" enabled only by setting the OLLAMA_EXPERIMENT
environment variable include "client2".
Currently, the progress indication is wired to perform the same as the
previous implementation to avoid making changes to the CLI, and because
the status reports happen at the start of the download, and the end of
the write to disk, the progress indication is not as smooth as it could
be. This is a known issue and will be addressed in a future change.
This implementation may be ~0.5-1.0% slower in rare cases, depending on
network and disk speed, but is generally MUCH faster and more robust
than the its predecessor in all other cases.
2025-03-06 06:48:18 +08:00
|
|
|
checkResponse(got, `
|
2025-04-16 14:24:44 +08:00
|
|
|
{"status":"pulling manifest"}
|
2025-03-14 13:18:29 +08:00
|
|
|
{"digest":"sha256:68e0ec597aee59d35f8dc44942d7b17d471ade10d3aca07a5bb7177713950312","total":5,"completed":5}
|
2025-04-16 14:24:44 +08:00
|
|
|
{"status":"verifying sha256 digest"}
|
|
|
|
{"status":"writing manifest"}
|
|
|
|
{"status":"success"}
|
server/internal/registry: take over pulls from server package (#9485)
This commit replaces the old pull implementation in the server package
with the new, faster, more robust pull implementation in the registry
package.
The new endpoint, and now the remove endpoint too, are behind the
feature gate "client2" enabled only by setting the OLLAMA_EXPERIMENT
environment variable include "client2".
Currently, the progress indication is wired to perform the same as the
previous implementation to avoid making changes to the CLI, and because
the status reports happen at the start of the download, and the end of
the write to disk, the progress indication is not as smooth as it could
be. This is a known issue and will be addressed in a future change.
This implementation may be ~0.5-1.0% slower in rare cases, depending on
network and disk speed, but is generally MUCH faster and more robust
than the its predecessor in all other cases.
2025-03-06 06:48:18 +08:00
|
|
|
`)
|
|
|
|
|
|
|
|
got = s.send(t, "POST", "/api/pull", `{"model": "unknown"}`)
|
|
|
|
checkResponse(got, `
|
2025-04-19 09:12:28 +08:00
|
|
|
{"code":"not_found","error":"model \"unknown\" not found"}
|
server/internal/registry: take over pulls from server package (#9485)
This commit replaces the old pull implementation in the server package
with the new, faster, more robust pull implementation in the registry
package.
The new endpoint, and now the remove endpoint too, are behind the
feature gate "client2" enabled only by setting the OLLAMA_EXPERIMENT
environment variable include "client2".
Currently, the progress indication is wired to perform the same as the
previous implementation to avoid making changes to the CLI, and because
the status reports happen at the start of the download, and the end of
the write to disk, the progress indication is not as smooth as it could
be. This is a known issue and will be addressed in a future change.
This implementation may be ~0.5-1.0% slower in rare cases, depending on
network and disk speed, but is generally MUCH faster and more robust
than the its predecessor in all other cases.
2025-03-06 06:48:18 +08:00
|
|
|
`)
|
|
|
|
|
|
|
|
got = s.send(t, "DELETE", "/api/pull", `{"model": "smol"}`)
|
|
|
|
checkErrorResponse(t, got, 405, "method_not_allowed", "method not allowed")
|
|
|
|
|
|
|
|
got = s.send(t, "POST", "/api/pull", `!`)
|
|
|
|
checkErrorResponse(t, got, 400, "bad_request", "invalid character '!' looking for beginning of value")
|
|
|
|
|
|
|
|
got = s.send(t, "POST", "/api/pull", ``)
|
|
|
|
checkErrorResponse(t, got, 400, "bad_request", "empty request body")
|
|
|
|
|
|
|
|
got = s.send(t, "POST", "/api/pull", `{"model": "://"}`)
|
|
|
|
checkResponse(got, `
|
2025-04-19 09:12:28 +08:00
|
|
|
{"code":"bad_request","error":"invalid or missing name: \"\""}
|
2025-03-14 13:18:29 +08:00
|
|
|
`)
|
server/internal/registry: take over pulls from server package (#9485)
This commit replaces the old pull implementation in the server package
with the new, faster, more robust pull implementation in the registry
package.
The new endpoint, and now the remove endpoint too, are behind the
feature gate "client2" enabled only by setting the OLLAMA_EXPERIMENT
environment variable include "client2".
Currently, the progress indication is wired to perform the same as the
previous implementation to avoid making changes to the CLI, and because
the status reports happen at the start of the download, and the end of
the write to disk, the progress indication is not as smooth as it could
be. This is a known issue and will be addressed in a future change.
This implementation may be ~0.5-1.0% slower in rare cases, depending on
network and disk speed, but is generally MUCH faster and more robust
than the its predecessor in all other cases.
2025-03-06 06:48:18 +08:00
|
|
|
|
2025-03-14 13:18:29 +08:00
|
|
|
// Non-streaming pulls
|
|
|
|
got = s.send(t, "POST", "/api/pull", `{"model": "://", "stream": false}`)
|
|
|
|
checkErrorResponse(t, got, 400, "bad_request", "invalid or missing name")
|
|
|
|
got = s.send(t, "POST", "/api/pull", `{"model": "smol", "stream": false}`)
|
|
|
|
checkResponse(got, `
|
|
|
|
{"status":"success"}
|
|
|
|
!digest
|
|
|
|
!total
|
|
|
|
!completed
|
server/internal/registry: take over pulls from server package (#9485)
This commit replaces the old pull implementation in the server package
with the new, faster, more robust pull implementation in the registry
package.
The new endpoint, and now the remove endpoint too, are behind the
feature gate "client2" enabled only by setting the OLLAMA_EXPERIMENT
environment variable include "client2".
Currently, the progress indication is wired to perform the same as the
previous implementation to avoid making changes to the CLI, and because
the status reports happen at the start of the download, and the end of
the write to disk, the progress indication is not as smooth as it could
be. This is a known issue and will be addressed in a future change.
This implementation may be ~0.5-1.0% slower in rare cases, depending on
network and disk speed, but is generally MUCH faster and more robust
than the its predecessor in all other cases.
2025-03-06 06:48:18 +08:00
|
|
|
`)
|
2025-03-14 13:18:29 +08:00
|
|
|
got = s.send(t, "POST", "/api/pull", `{"model": "unknown", "stream": false}`)
|
|
|
|
checkErrorResponse(t, got, 404, "not_found", "model not found")
|
server/internal/registry: take over pulls from server package (#9485)
This commit replaces the old pull implementation in the server package
with the new, faster, more robust pull implementation in the registry
package.
The new endpoint, and now the remove endpoint too, are behind the
feature gate "client2" enabled only by setting the OLLAMA_EXPERIMENT
environment variable include "client2".
Currently, the progress indication is wired to perform the same as the
previous implementation to avoid making changes to the CLI, and because
the status reports happen at the start of the download, and the end of
the write to disk, the progress indication is not as smooth as it could
be. This is a known issue and will be addressed in a future change.
This implementation may be ~0.5-1.0% slower in rare cases, depending on
network and disk speed, but is generally MUCH faster and more robust
than the its predecessor in all other cases.
2025-03-06 06:48:18 +08:00
|
|
|
}
|
|
|
|
|
2025-02-28 04:04:53 +08:00
|
|
|
func TestServerUnknownPath(t *testing.T) {
|
server/internal/registry: take over pulls from server package (#9485)
This commit replaces the old pull implementation in the server package
with the new, faster, more robust pull implementation in the registry
package.
The new endpoint, and now the remove endpoint too, are behind the
feature gate "client2" enabled only by setting the OLLAMA_EXPERIMENT
environment variable include "client2".
Currently, the progress indication is wired to perform the same as the
previous implementation to avoid making changes to the CLI, and because
the status reports happen at the start of the download, and the end of
the write to disk, the progress indication is not as smooth as it could
be. This is a known issue and will be addressed in a future change.
This implementation may be ~0.5-1.0% slower in rare cases, depending on
network and disk speed, but is generally MUCH faster and more robust
than the its predecessor in all other cases.
2025-03-06 06:48:18 +08:00
|
|
|
s := newTestServer(t, nil)
|
2025-02-28 04:04:53 +08:00
|
|
|
got := s.send(t, "DELETE", "/api/unknown", `{}`)
|
|
|
|
checkErrorResponse(t, got, 404, "not_found", "not found")
|
2025-03-14 13:18:29 +08:00
|
|
|
|
|
|
|
var fellback bool
|
|
|
|
s.Fallback = http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
|
|
fellback = true
|
|
|
|
})
|
|
|
|
got = s.send(t, "DELETE", "/api/unknown", `{}`)
|
|
|
|
if !fellback {
|
|
|
|
t.Fatal("expected Fallback to be called")
|
|
|
|
}
|
|
|
|
if got.Code != 200 {
|
|
|
|
t.Fatalf("Code = %d; want 200", got.Code)
|
|
|
|
}
|
2025-02-28 04:04:53 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
func checkErrorResponse(t *testing.T, got *httptest.ResponseRecorder, status int, code, msg string) {
|
|
|
|
t.Helper()
|
|
|
|
|
|
|
|
var printedBody bool
|
|
|
|
errorf := func(format string, args ...any) {
|
|
|
|
t.Helper()
|
|
|
|
if !printedBody {
|
|
|
|
t.Logf("BODY:\n%s", got.Body.String())
|
|
|
|
printedBody = true
|
|
|
|
}
|
|
|
|
t.Errorf(format, args...)
|
|
|
|
}
|
|
|
|
|
|
|
|
if got.Code != status {
|
|
|
|
errorf("Code = %d; want %d", got.Code, status)
|
|
|
|
}
|
|
|
|
|
|
|
|
// unmarshal the error as *ollama.Error (proving *serverError is an *ollama.Error)
|
|
|
|
var e *ollama.Error
|
|
|
|
if err := json.Unmarshal(got.Body.Bytes(), &e); err != nil {
|
|
|
|
errorf("unmarshal error: %v", err)
|
|
|
|
t.FailNow()
|
|
|
|
}
|
|
|
|
if e.Code != code {
|
|
|
|
errorf("Code = %q; want %q", e.Code, code)
|
|
|
|
}
|
|
|
|
if !strings.Contains(e.Message, msg) {
|
|
|
|
errorf("Message = %q; want to contain %q", e.Message, msg)
|
|
|
|
}
|
|
|
|
}
|