manifest.go 1.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879
  1. package server
  2. import (
  3. "bytes"
  4. "crypto/sha256"
  5. "encoding/json"
  6. "fmt"
  7. "io"
  8. "os"
  9. "path/filepath"
  10. "github.com/ollama/ollama/types/model"
  11. )
  12. type Manifest struct {
  13. ManifestV2
  14. Digest string `json:"-"`
  15. }
  16. func (m *Manifest) Size() (size int64) {
  17. for _, layer := range append(m.Layers, m.Config) {
  18. size += layer.Size
  19. }
  20. return
  21. }
  22. func ParseNamedManifest(name model.Name) (*Manifest, error) {
  23. if !name.IsFullyQualified() {
  24. return nil, model.Unqualified(name)
  25. }
  26. manifests, err := GetManifestPath()
  27. if err != nil {
  28. return nil, err
  29. }
  30. var manifest ManifestV2
  31. manifestfile, err := os.Open(filepath.Join(manifests, name.Filepath()))
  32. if err != nil {
  33. return nil, err
  34. }
  35. sha256sum := sha256.New()
  36. if err := json.NewDecoder(io.TeeReader(manifestfile, sha256sum)).Decode(&manifest); err != nil {
  37. return nil, err
  38. }
  39. return &Manifest{
  40. ManifestV2: manifest,
  41. Digest: fmt.Sprintf("%x", sha256sum.Sum(nil)),
  42. }, nil
  43. }
  44. func WriteManifest(name string, config *Layer, layers []*Layer) error {
  45. manifest := ManifestV2{
  46. SchemaVersion: 2,
  47. MediaType: "application/vnd.docker.distribution.manifest.v2+json",
  48. Config: config,
  49. Layers: layers,
  50. }
  51. var b bytes.Buffer
  52. if err := json.NewEncoder(&b).Encode(manifest); err != nil {
  53. return err
  54. }
  55. modelpath := ParseModelPath(name)
  56. manifestPath, err := modelpath.GetManifestPath()
  57. if err != nil {
  58. return err
  59. }
  60. if err := os.MkdirAll(filepath.Dir(manifestPath), 0o755); err != nil {
  61. return err
  62. }
  63. return os.WriteFile(manifestPath, b.Bytes(), 0o644)
  64. }