Browse Source

add version

Michael Yang 1 year ago
parent
commit
2c7f956b38
7 changed files with 47 additions and 36 deletions
  1. 13 8
      api/client.go
  2. 2 0
      cmd/cmd.go
  3. 4 2
      scripts/build_darwin.sh
  4. 2 4
      server/auth.go
  5. 3 3
      server/download.go
  6. 20 19
      server/images.go
  7. 3 0
      version/version.go

+ 13 - 8
api/client.go

@@ -10,7 +10,10 @@ import (
 	"net/http"
 	"net/url"
 	"os"
+	"runtime"
 	"strings"
+
+	"github.com/jmorganca/ollama/version"
 )
 
 const DefaultHost = "localhost:11434"
@@ -83,21 +86,21 @@ func (c *Client) do(ctx context.Context, method, path string, reqData, respData
 		reqBody = bytes.NewReader(data)
 	}
 
-	url := c.Base.JoinPath(path).String()
-
-	req, err := http.NewRequestWithContext(ctx, method, url, reqBody)
+	requestURL := c.Base.JoinPath(path)
+	request, err := http.NewRequestWithContext(ctx, method, requestURL.String(), reqBody)
 	if err != nil {
 		return err
 	}
 
-	req.Header.Set("Content-Type", "application/json")
-	req.Header.Set("Accept", "application/json")
+	request.Header.Set("Content-Type", "application/json")
+	request.Header.Set("Accept", "application/json")
+	request.Header.Set("User-Agent", fmt.Sprintf("ollama/%s (%s %s) Go/%s", version.Version, runtime.GOARCH, runtime.GOOS, runtime.Version()))
 
 	for k, v := range c.Headers {
-		req.Header[k] = v
+		request.Header[k] = v
 	}
 
-	respObj, err := c.HTTP.Do(req)
+	respObj, err := c.HTTP.Do(request)
 	if err != nil {
 		return err
 	}
@@ -131,13 +134,15 @@ func (c *Client) stream(ctx context.Context, method, path string, data any, fn f
 		buf = bytes.NewBuffer(bts)
 	}
 
-	request, err := http.NewRequestWithContext(ctx, method, c.Base.JoinPath(path).String(), buf)
+	requestURL := c.Base.JoinPath(path)
+	request, err := http.NewRequestWithContext(ctx, method, requestURL.String(), buf)
 	if err != nil {
 		return err
 	}
 
 	request.Header.Set("Content-Type", "application/json")
 	request.Header.Set("Accept", "application/json")
+	request.Header.Set("User-Agent", fmt.Sprintf("ollama/%s (%s %s) Go/%s", version.Version, runtime.GOARCH, runtime.GOOS, runtime.Version()))
 
 	response, err := http.DefaultClient.Do(request)
 	if err != nil {

+ 2 - 0
cmd/cmd.go

@@ -30,6 +30,7 @@ import (
 	"github.com/jmorganca/ollama/format"
 	"github.com/jmorganca/ollama/progressbar"
 	"github.com/jmorganca/ollama/server"
+	"github.com/jmorganca/ollama/version"
 )
 
 func CreateHandler(cmd *cobra.Command, args []string) error {
@@ -727,6 +728,7 @@ func NewCLI() *cobra.Command {
 		CompletionOptions: cobra.CompletionOptions{
 			DisableDefaultCmd: true,
 		},
+		Version: version.Version,
 	}
 
 	cobra.EnableCommandSorting = false

+ 4 - 2
scripts/build_darwin.sh

@@ -2,9 +2,11 @@
 
 mkdir -p dist
 
+GO_LDFLAGS="-X github.com/jmorganca/ollama/version.Version=$VERSION"
+
 # build universal binary
-CGO_ENABLED=1 GOARCH=arm64 go build -o dist/ollama-darwin-arm64
-CGO_ENABLED=1 GOARCH=amd64 go build -o dist/ollama-darwin-amd64
+CGO_ENABLED=1 GOARCH=arm64 go build -ldflags "$GO_LDFLAGS" -o dist/ollama-darwin-arm64
+CGO_ENABLED=1 GOARCH=amd64 go build -ldflags "$GO_LDFLAGS" -o dist/ollama-darwin-amd64
 lipo -create -output dist/ollama dist/ollama-darwin-arm64 dist/ollama-darwin-amd64
 rm dist/ollama-darwin-amd64 dist/ollama-darwin-arm64
 codesign --deep --force --options=runtime --sign "$APPLE_IDENTITY" --timestamp dist/ollama

+ 2 - 4
server/auth.go

@@ -94,10 +94,8 @@ func getAuthToken(ctx context.Context, redirData AuthRedirect, regOpts *Registry
 		return "", err
 	}
 
-	headers := map[string]string{
-		"Authorization": sig,
-	}
-
+	headers := make(http.Header)
+	headers.Set("Authorization", sig)
 	resp, err := makeRequest(ctx, "GET", url, headers, nil, regOpts)
 	if err != nil {
 		log.Printf("couldn't get token: %q", err)

+ 3 - 3
server/download.go

@@ -156,9 +156,9 @@ func doDownload(ctx context.Context, opts downloadOpts, f *FileDownload) error {
 	}
 
 	url := fmt.Sprintf("%s/v2/%s/blobs/%s", opts.mp.Registry, opts.mp.GetNamespaceRepository(), f.Digest)
-	headers := map[string]string{
-		"Range": fmt.Sprintf("bytes=%d-", size),
-	}
+
+	headers := make(http.Header)
+	headers.Set("Range", fmt.Sprintf("bytes=%d-", size))
 
 	resp, err := makeRequest(ctx, "GET", url, headers, nil, opts.regOpts)
 	if err != nil {

+ 20 - 19
server/images.go

@@ -16,6 +16,7 @@ import (
 	"path"
 	"path/filepath"
 	"reflect"
+	"runtime"
 	"strconv"
 	"strings"
 
@@ -23,6 +24,7 @@ import (
 	"github.com/jmorganca/ollama/llm"
 	"github.com/jmorganca/ollama/parser"
 	"github.com/jmorganca/ollama/vector"
+	"github.com/jmorganca/ollama/version"
 )
 
 const MaxRetries = 3
@@ -1005,15 +1007,14 @@ func PushModel(ctx context.Context, name string, regOpts *RegistryOptions, fn fu
 
 	fn(api.ProgressResponse{Status: "pushing manifest"})
 	url := fmt.Sprintf("%s/v2/%s/manifests/%s", mp.Registry, mp.GetNamespaceRepository(), mp.Tag)
-	headers := map[string]string{
-		"Content-Type": "application/vnd.docker.distribution.manifest.v2+json",
-	}
 
 	manifestJSON, err := json.Marshal(manifest)
 	if err != nil {
 		return err
 	}
 
+	headers := make(http.Header)
+	headers.Set("Content-Type", "application/vnd.docker.distribution.manifest.v2+json")
 	resp, err := makeRequestWithRetry(ctx, "PUT", url, headers, bytes.NewReader(manifestJSON), regOpts)
 	if err != nil {
 		return err
@@ -1098,10 +1099,9 @@ func PullModel(ctx context.Context, name string, regOpts *RegistryOptions, fn fu
 
 func pullModelManifest(ctx context.Context, mp ModelPath, regOpts *RegistryOptions) (*ManifestV2, error) {
 	url := fmt.Sprintf("%s/v2/%s/manifests/%s", mp.Registry, mp.GetNamespaceRepository(), mp.Tag)
-	headers := map[string]string{
-		"Accept": "application/vnd.docker.distribution.manifest.v2+json",
-	}
 
+	headers := make(http.Header)
+	headers.Set("Accept", "application/vnd.docker.distribution.manifest.v2+json")
 	resp, err := makeRequest(ctx, "GET", url, headers, nil, regOpts)
 	if err != nil {
 		log.Printf("couldn't get manifest: %v", err)
@@ -1226,11 +1226,10 @@ func uploadBlobChunked(ctx context.Context, mp ModelPath, url string, layer *Lay
 
 		sectionReader := io.NewSectionReader(f, int64(completed), chunk)
 
-		headers := make(map[string]string)
-		headers["Content-Type"] = "application/octet-stream"
-		headers["Content-Length"] = strconv.Itoa(int(chunk))
-		headers["Content-Range"] = fmt.Sprintf("%d-%d", completed, completed+sectionReader.Size()-1)
-
+		headers := make(http.Header)
+		headers.Set("Content-Type", "application/octet-stream")
+		headers.Set("Content-Length", strconv.Itoa(int(chunk)))
+		headers.Set("Content-Range", fmt.Sprintf("%d-%d", completed, completed+sectionReader.Size()-1))
 		resp, err := makeRequestWithRetry(ctx, "PATCH", url, headers, sectionReader, regOpts)
 		if err != nil && !errors.Is(err, io.EOF) {
 			fn(api.ProgressResponse{
@@ -1260,9 +1259,9 @@ func uploadBlobChunked(ctx context.Context, mp ModelPath, url string, layer *Lay
 
 	url = fmt.Sprintf("%s&digest=%s", url, layer.Digest)
 
-	headers := make(map[string]string)
-	headers["Content-Type"] = "application/octet-stream"
-	headers["Content-Length"] = "0"
+	headers := make(http.Header)
+	headers.Set("Content-Type", "application/octet-stream")
+	headers.Set("Content-Length", "0")
 
 	// finish the upload
 	resp, err := makeRequest(ctx, "PUT", url, headers, nil, regOpts)
@@ -1279,7 +1278,7 @@ func uploadBlobChunked(ctx context.Context, mp ModelPath, url string, layer *Lay
 	return nil
 }
 
-func makeRequestWithRetry(ctx context.Context, method, url string, headers map[string]string, body io.ReadSeeker, regOpts *RegistryOptions) (*http.Response, error) {
+func makeRequestWithRetry(ctx context.Context, method, url string, headers http.Header, body io.ReadSeeker, regOpts *RegistryOptions) (*http.Response, error) {
 	var status string
 	for try := 0; try < MaxRetries; try++ {
 		resp, err := makeRequest(ctx, method, url, headers, body, regOpts)
@@ -1318,7 +1317,7 @@ func makeRequestWithRetry(ctx context.Context, method, url string, headers map[s
 	return nil, fmt.Errorf("max retry exceeded: %v", status)
 }
 
-func makeRequest(ctx context.Context, method, url string, headers map[string]string, body io.Reader, regOpts *RegistryOptions) (*http.Response, error) {
+func makeRequest(ctx context.Context, method, url string, headers http.Header, body io.Reader, regOpts *RegistryOptions) (*http.Response, error) {
 	if !strings.HasPrefix(url, "http") {
 		if regOpts.Insecure {
 			url = "http://" + url
@@ -1332,15 +1331,17 @@ func makeRequest(ctx context.Context, method, url string, headers map[string]str
 		return nil, err
 	}
 
+	if headers != nil {
+		req.Header = headers
+	}
+
 	if regOpts.Token != "" {
 		req.Header.Set("Authorization", "Bearer "+regOpts.Token)
 	} else if regOpts.Username != "" && regOpts.Password != "" {
 		req.SetBasicAuth(regOpts.Username, regOpts.Password)
 	}
 
-	for k, v := range headers {
-		req.Header.Set(k, v)
-	}
+	req.Header.Set("User-Agent", fmt.Sprintf("ollama/%s (%s %s) Go/%s", version.Version, runtime.GOARCH, runtime.GOOS, runtime.Version()))
 
 	client := &http.Client{
 		CheckRedirect: func(req *http.Request, via []*http.Request) error {

+ 3 - 0
version/version.go

@@ -0,0 +1,3 @@
+package version
+
+var Version string = "0.0.0"