mirror of
https://github.com/ollama/ollama.git
synced 2026-01-29 07:12:03 +03:00
96 lines
1.9 KiB
Go
96 lines
1.9 KiB
Go
package manifest
|
|
|
|
import (
|
|
"errors"
|
|
"fmt"
|
|
"os"
|
|
"path/filepath"
|
|
"regexp"
|
|
"strings"
|
|
|
|
"github.com/ollama/ollama/envconfig"
|
|
"github.com/ollama/ollama/types/model"
|
|
)
|
|
|
|
var ErrInvalidDigestFormat = errors.New("invalid digest format")
|
|
|
|
func Path() (string, error) {
|
|
path := filepath.Join(envconfig.Models(), "manifests")
|
|
if err := os.MkdirAll(path, 0o755); err != nil {
|
|
return "", fmt.Errorf("%w: ensure path elements are traversable", err)
|
|
}
|
|
|
|
return path, nil
|
|
}
|
|
|
|
// PathForName returns the path to the manifest file for a specific model name.
|
|
func PathForName(n model.Name) (string, error) {
|
|
if !n.IsValid() {
|
|
return "", os.ErrNotExist
|
|
}
|
|
|
|
manifests, err := Path()
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
|
|
return filepath.Join(manifests, n.Filepath()), nil
|
|
}
|
|
|
|
func BlobsPath(digest string) (string, error) {
|
|
// only accept actual sha256 digests
|
|
pattern := "^sha256[:-][0-9a-fA-F]{64}$"
|
|
re := regexp.MustCompile(pattern)
|
|
|
|
if digest != "" && !re.MatchString(digest) {
|
|
return "", ErrInvalidDigestFormat
|
|
}
|
|
|
|
digest = strings.ReplaceAll(digest, ":", "-")
|
|
path := filepath.Join(envconfig.Models(), "blobs", digest)
|
|
dirPath := filepath.Dir(path)
|
|
if digest == "" {
|
|
dirPath = path
|
|
}
|
|
|
|
if err := os.MkdirAll(dirPath, 0o755); err != nil {
|
|
return "", fmt.Errorf("%w: ensure path elements are traversable", err)
|
|
}
|
|
|
|
return path, nil
|
|
}
|
|
|
|
// PruneDirectory removes empty directories recursively.
|
|
func PruneDirectory(path string) error {
|
|
info, err := os.Lstat(path)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
if info.IsDir() && info.Mode()&os.ModeSymlink == 0 {
|
|
entries, err := os.ReadDir(path)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
for _, entry := range entries {
|
|
if err := PruneDirectory(filepath.Join(path, entry.Name())); err != nil {
|
|
return err
|
|
}
|
|
}
|
|
|
|
entries, err = os.ReadDir(path)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
if len(entries) > 0 {
|
|
return nil
|
|
}
|
|
|
|
return os.Remove(path)
|
|
}
|
|
|
|
return nil
|
|
}
|