modelpath.go 2.76 KB
Newer Older
Patrick Devine's avatar
Patrick Devine committed
1
2
3
4
5
6
package server

import (
	"fmt"
	"os"
	"path/filepath"
Michael Yang's avatar
Michael Yang committed
7
	"runtime"
Patrick Devine's avatar
Patrick Devine committed
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
	"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"
)

func ParseModelPath(name string) ModelPath {
	slashParts := strings.Split(name, "/")
	var registry, namespace, repository, tag string

	switch len(slashParts) {
	case 3:
		registry = slashParts[0]
		namespace = slashParts[1]
		repository = strings.Split(slashParts[2], ":")[0]
	case 2:
		registry = DefaultRegistry
		namespace = slashParts[0]
		repository = strings.Split(slashParts[1], ":")[0]
	case 1:
		registry = DefaultRegistry
		namespace = DefaultNamespace
		repository = strings.Split(slashParts[0], ":")[0]
	default:
		fmt.Println("Invalid image format.")
		return ModelPath{}
	}

Patrick Devine's avatar
Patrick Devine committed
48
	colonParts := strings.Split(slashParts[len(slashParts)-1], ":")
Patrick Devine's avatar
Patrick Devine committed
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
	if len(colonParts) == 2 {
		tag = colonParts[1]
	} else {
		tag = DefaultTag
	}

	return ModelPath{
		ProtocolScheme: DefaultProtocolScheme,
		Registry:       registry,
		Namespace:      namespace,
		Repository:     repository,
		Tag:            tag,
	}
}

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 {
73
74
75
76
77
	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)
Patrick Devine's avatar
Patrick Devine committed
78
	}
79
	return fmt.Sprintf("%s/%s/%s:%s", mp.Registry, mp.Namespace, mp.Repository, mp.Tag)
Patrick Devine's avatar
Patrick Devine committed
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
}

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
}

Patrick Devine's avatar
Patrick Devine committed
98
99
100
101
102
103
104
105
106
func GetManifestPath() (string, error) {
	home, err := os.UserHomeDir()
	if err != nil {
		return "", err
	}

	return filepath.Join(home, ".ollama", "models", "manifests"), nil
}

Patrick Devine's avatar
Patrick Devine committed
107
108
109
110
111
112
func GetBlobsPath(digest string) (string, error) {
	home, err := os.UserHomeDir()
	if err != nil {
		return "", err
	}

Michael Yang's avatar
Michael Yang committed
113
114
115
116
	if runtime.GOOS == "windows" {
		digest = strings.ReplaceAll(digest, ":", "-")
	}

Michael Yang's avatar
Michael Yang committed
117
	path := filepath.Join(home, ".ollama", "models", "blobs", digest)
Patrick Devine's avatar
Patrick Devine committed
118
119
120
121
	if err := os.MkdirAll(filepath.Dir(path), 0o755); err != nil {
		return "", err
	}

Michael Yang's avatar
Michael Yang committed
122
	return path, nil
Patrick Devine's avatar
Patrick Devine committed
123
}