ollama/server/modelpath.go

137 lines
2.9 KiB
Go
Raw Normal View History

2023-07-18 05:44:21 +00:00
package server
import (
2023-08-22 04:56:56 +00:00
"errors"
2023-07-18 05:44:21 +00:00
"fmt"
2023-08-22 01:38:31 +00:00
"net/url"
2023-07-18 05:44:21 +00:00
"os"
"path/filepath"
2023-07-20 18:23:43 +00:00
"runtime"
2023-07-18 05:44:21 +00:00
"strings"
)
type ModelPath struct {
ProtocolScheme string
Registry string
Namespace string
Repository string
Tag string
}
const (
DefaultRegistry = "registry.ollama.ai"
DefaultNamespace = "library"
DefaultTag = "latest"
DefaultProtocolScheme = "https"
)
2023-08-22 04:56:56 +00:00
var (
ErrInvalidImageFormat = errors.New("invalid image format")
ErrInvalidProtocol = errors.New("invalid protocol scheme")
ErrInsecureProtocol = errors.New("insecure protocol http")
)
func ParseModelPath(name string) ModelPath {
2023-08-22 04:56:56 +00:00
mp := ModelPath{
ProtocolScheme: DefaultProtocolScheme,
Registry: DefaultRegistry,
Namespace: DefaultNamespace,
Repository: "",
Tag: DefaultTag,
}
2023-07-18 05:44:21 +00:00
2023-08-22 01:38:31 +00:00
before, after, found := strings.Cut(name, "://")
if found {
mp.ProtocolScheme = before
name = after
2023-08-22 04:56:56 +00:00
}
2023-08-22 01:38:31 +00:00
parts := strings.Split(name, "/")
switch len(parts) {
2023-07-18 05:44:21 +00:00
case 3:
mp.Registry = parts[0]
mp.Namespace = parts[1]
mp.Repository = parts[2]
2023-07-18 05:44:21 +00:00
case 2:
mp.Namespace = parts[0]
mp.Repository = parts[1]
2023-07-18 05:44:21 +00:00
case 1:
mp.Repository = parts[0]
2023-07-18 05:44:21 +00:00
}
if repo, tag, found := strings.Cut(mp.Repository, ":"); found {
2023-08-22 04:56:56 +00:00
mp.Repository = repo
mp.Tag = tag
2023-07-18 05:44:21 +00:00
}
return mp
2023-07-18 05:44:21 +00:00
}
func (mp ModelPath) GetNamespaceRepository() string {
return fmt.Sprintf("%s/%s", mp.Namespace, mp.Repository)
}
func (mp ModelPath) GetFullTagname() string {
return fmt.Sprintf("%s/%s/%s:%s", mp.Registry, mp.Namespace, mp.Repository, mp.Tag)
}
func (mp ModelPath) GetShortTagname() string {
if mp.Registry == DefaultRegistry {
if mp.Namespace == DefaultNamespace {
return fmt.Sprintf("%s:%s", mp.Repository, mp.Tag)
}
return fmt.Sprintf("%s/%s:%s", mp.Namespace, mp.Repository, mp.Tag)
2023-07-18 05:44:21 +00:00
}
return fmt.Sprintf("%s/%s/%s:%s", mp.Registry, mp.Namespace, mp.Repository, mp.Tag)
2023-07-18 05:44:21 +00:00
}
func (mp ModelPath) GetManifestPath(createDir bool) (string, error) {
home, err := os.UserHomeDir()
if err != nil {
return "", err
}
path := filepath.Join(home, ".ollama", "models", "manifests", mp.Registry, mp.Namespace, mp.Repository, mp.Tag)
if createDir {
if err := os.MkdirAll(filepath.Dir(path), 0o755); err != nil {
return "", err
}
}
return path, nil
}
2023-08-22 01:38:31 +00:00
func (mp ModelPath) BaseURL() *url.URL {
return &url.URL{
Scheme: mp.ProtocolScheme,
Host: mp.Registry,
}
}
2023-07-18 16:09:45 +00:00
func GetManifestPath() (string, error) {
home, err := os.UserHomeDir()
if err != nil {
return "", err
}
return filepath.Join(home, ".ollama", "models", "manifests"), nil
}
2023-07-18 05:44:21 +00:00
func GetBlobsPath(digest string) (string, error) {
home, err := os.UserHomeDir()
if err != nil {
return "", err
}
2023-07-20 18:23:43 +00:00
if runtime.GOOS == "windows" {
digest = strings.ReplaceAll(digest, ":", "-")
}
2023-07-18 18:24:19 +00:00
path := filepath.Join(home, ".ollama", "models", "blobs", digest)
2023-07-18 05:44:21 +00:00
if err := os.MkdirAll(filepath.Dir(path), 0o755); err != nil {
return "", err
}
2023-07-18 18:24:19 +00:00
return path, nil
2023-07-18 05:44:21 +00:00
}