Explorar el Código

Merge pull request #6247 from ollama/jessegross/layers

Store layers inside manifests consistently as values.
Jesse Gross hace 8 meses
padre
commit
7d1c0047fa
Se han modificado 6 ficheros con 36 adiciones y 36 borrados
  1. 10 10
      server/images.go
  2. 14 14
      server/layer.go
  3. 8 8
      server/manifest.go
  4. 1 1
      server/model.go
  5. 1 1
      server/routes_delete_test.go
  6. 2 2
      server/upload.go

+ 10 - 10
server/images.go

@@ -373,7 +373,7 @@ func CreateModel(ctx context.Context, name model.Name, modelFileDir, quantizatio
 	var messages []*api.Message
 	var messages []*api.Message
 	parameters := make(map[string]any)
 	parameters := make(map[string]any)
 
 
-	var layers []*Layer
+	var layers []Layer
 	for _, c := range modelfile.Commands {
 	for _, c := range modelfile.Commands {
 		mediatype := fmt.Sprintf("application/vnd.ollama.image.%s", c.Name)
 		mediatype := fmt.Sprintf("application/vnd.ollama.image.%s", c.Name)
 
 
@@ -499,7 +499,7 @@ func CreateModel(ctx context.Context, name model.Name, modelFileDir, quantizatio
 
 
 			if c.Name != "license" {
 			if c.Name != "license" {
 				// replace
 				// replace
-				layers = slices.DeleteFunc(layers, func(layer *Layer) bool {
+				layers = slices.DeleteFunc(layers, func(layer Layer) bool {
 					if layer.MediaType != mediatype {
 					if layer.MediaType != mediatype {
 						return false
 						return false
 					}
 					}
@@ -545,7 +545,7 @@ func CreateModel(ctx context.Context, name model.Name, modelFileDir, quantizatio
 	}
 	}
 
 
 	var err2 error
 	var err2 error
-	layers = slices.DeleteFunc(layers, func(layer *Layer) bool {
+	layers = slices.DeleteFunc(layers, func(layer Layer) bool {
 		switch layer.MediaType {
 		switch layer.MediaType {
 		case "application/vnd.ollama.image.message":
 		case "application/vnd.ollama.image.message":
 			// if there are new messages, remove the inherited ones
 			// if there are new messages, remove the inherited ones
@@ -625,12 +625,12 @@ func CreateModel(ctx context.Context, name model.Name, modelFileDir, quantizatio
 		return err
 		return err
 	}
 	}
 
 
-	layer, err := NewLayer(&b, "application/vnd.docker.container.image.v1+json")
+	configLayer, err := NewLayer(&b, "application/vnd.docker.container.image.v1+json")
 	if err != nil {
 	if err != nil {
 		return err
 		return err
 	}
 	}
 
 
-	for _, layer := range append(layers, layer) {
+	for _, layer := range append(layers, configLayer) {
 		if layer.status != "" {
 		if layer.status != "" {
 			fn(api.ProgressResponse{Status: layer.status})
 			fn(api.ProgressResponse{Status: layer.status})
 		}
 		}
@@ -639,7 +639,7 @@ func CreateModel(ctx context.Context, name model.Name, modelFileDir, quantizatio
 	old, _ := ParseNamedManifest(name)
 	old, _ := ParseNamedManifest(name)
 
 
 	fn(api.ProgressResponse{Status: "writing manifest"})
 	fn(api.ProgressResponse{Status: "writing manifest"})
-	if err := WriteManifest(name, layer, layers); err != nil {
+	if err := WriteManifest(name, configLayer, layers); err != nil {
 		return err
 		return err
 	}
 	}
 
 
@@ -839,10 +839,10 @@ func PushModel(ctx context.Context, name string, regOpts *registryOptions, fn fu
 		return err
 		return err
 	}
 	}
 
 
-	var layers []*Layer
+	var layers []Layer
 	layers = append(layers, manifest.Layers...)
 	layers = append(layers, manifest.Layers...)
 	if manifest.Config.Digest != "" {
 	if manifest.Config.Digest != "" {
-		layers = append(layers, &manifest.Config)
+		layers = append(layers, manifest.Config)
 	}
 	}
 
 
 	for _, layer := range layers {
 	for _, layer := range layers {
@@ -911,10 +911,10 @@ func PullModel(ctx context.Context, name string, regOpts *registryOptions, fn fu
 		return fmt.Errorf("pull model manifest: %s", err)
 		return fmt.Errorf("pull model manifest: %s", err)
 	}
 	}
 
 
-	var layers []*Layer
+	var layers []Layer
 	layers = append(layers, manifest.Layers...)
 	layers = append(layers, manifest.Layers...)
 	if manifest.Config.Digest != "" {
 	if manifest.Config.Digest != "" {
-		layers = append(layers, &manifest.Config)
+		layers = append(layers, manifest.Config)
 	}
 	}
 
 
 	skipVerify := make(map[string]bool)
 	skipVerify := make(map[string]bool)

+ 14 - 14
server/layer.go

@@ -16,15 +16,15 @@ type Layer struct {
 	status    string
 	status    string
 }
 }
 
 
-func NewLayer(r io.Reader, mediatype string) (*Layer, error) {
+func NewLayer(r io.Reader, mediatype string) (Layer, error) {
 	blobs, err := GetBlobsPath("")
 	blobs, err := GetBlobsPath("")
 	if err != nil {
 	if err != nil {
-		return nil, err
+		return Layer{}, err
 	}
 	}
 
 
 	temp, err := os.CreateTemp(blobs, "sha256-")
 	temp, err := os.CreateTemp(blobs, "sha256-")
 	if err != nil {
 	if err != nil {
-		return nil, err
+		return Layer{}, err
 	}
 	}
 	defer temp.Close()
 	defer temp.Close()
 	defer os.Remove(temp.Name())
 	defer os.Remove(temp.Name())
@@ -32,28 +32,28 @@ func NewLayer(r io.Reader, mediatype string) (*Layer, error) {
 	sha256sum := sha256.New()
 	sha256sum := sha256.New()
 	n, err := io.Copy(io.MultiWriter(temp, sha256sum), r)
 	n, err := io.Copy(io.MultiWriter(temp, sha256sum), r)
 	if err != nil {
 	if err != nil {
-		return nil, err
+		return Layer{}, err
 	}
 	}
 
 
 	if err := temp.Close(); err != nil {
 	if err := temp.Close(); err != nil {
-		return nil, err
+		return Layer{}, err
 	}
 	}
 
 
 	digest := fmt.Sprintf("sha256:%x", sha256sum.Sum(nil))
 	digest := fmt.Sprintf("sha256:%x", sha256sum.Sum(nil))
 	blob, err := GetBlobsPath(digest)
 	blob, err := GetBlobsPath(digest)
 	if err != nil {
 	if err != nil {
-		return nil, err
+		return Layer{}, err
 	}
 	}
 
 
 	status := "using existing layer"
 	status := "using existing layer"
 	if _, err := os.Stat(blob); err != nil {
 	if _, err := os.Stat(blob); err != nil {
 		status = "creating new layer"
 		status = "creating new layer"
 		if err := os.Rename(temp.Name(), blob); err != nil {
 		if err := os.Rename(temp.Name(), blob); err != nil {
-			return nil, err
+			return Layer{}, err
 		}
 		}
 	}
 	}
 
 
-	return &Layer{
+	return Layer{
 		MediaType: mediatype,
 		MediaType: mediatype,
 		Digest:    digest,
 		Digest:    digest,
 		Size:      n,
 		Size:      n,
@@ -61,22 +61,22 @@ func NewLayer(r io.Reader, mediatype string) (*Layer, error) {
 	}, nil
 	}, nil
 }
 }
 
 
-func NewLayerFromLayer(digest, mediatype, from string) (*Layer, error) {
+func NewLayerFromLayer(digest, mediatype, from string) (Layer, error) {
 	if digest == "" {
 	if digest == "" {
-		return nil, errors.New("creating new layer from layer with empty digest")
+		return Layer{}, errors.New("creating new layer from layer with empty digest")
 	}
 	}
 
 
 	blob, err := GetBlobsPath(digest)
 	blob, err := GetBlobsPath(digest)
 	if err != nil {
 	if err != nil {
-		return nil, err
+		return Layer{}, err
 	}
 	}
 
 
 	fi, err := os.Stat(blob)
 	fi, err := os.Stat(blob)
 	if err != nil {
 	if err != nil {
-		return nil, err
+		return Layer{}, err
 	}
 	}
 
 
-	return &Layer{
+	return Layer{
 		MediaType: mediatype,
 		MediaType: mediatype,
 		Digest:    digest,
 		Digest:    digest,
 		Size:      fi.Size(),
 		Size:      fi.Size(),
@@ -109,7 +109,7 @@ func (l *Layer) Remove() error {
 	}
 	}
 
 
 	for _, m := range ms {
 	for _, m := range ms {
-		for _, layer := range append(m.Layers, &m.Config) {
+		for _, layer := range append(m.Layers, m.Config) {
 			if layer.Digest == l.Digest {
 			if layer.Digest == l.Digest {
 				// something is using this layer
 				// something is using this layer
 				return nil
 				return nil

+ 8 - 8
server/manifest.go

@@ -14,10 +14,10 @@ import (
 )
 )
 
 
 type Manifest struct {
 type Manifest struct {
-	SchemaVersion int      `json:"schemaVersion"`
-	MediaType     string   `json:"mediaType"`
-	Config        Layer    `json:"config"`
-	Layers        []*Layer `json:"layers"`
+	SchemaVersion int     `json:"schemaVersion"`
+	MediaType     string  `json:"mediaType"`
+	Config        Layer   `json:"config"`
+	Layers        []Layer `json:"layers"`
 
 
 	filepath string
 	filepath string
 	fi       os.FileInfo
 	fi       os.FileInfo
@@ -25,7 +25,7 @@ type Manifest struct {
 }
 }
 
 
 func (m *Manifest) Size() (size int64) {
 func (m *Manifest) Size() (size int64) {
-	for _, layer := range append(m.Layers, &m.Config) {
+	for _, layer := range append(m.Layers, m.Config) {
 		size += layer.Size
 		size += layer.Size
 	}
 	}
 
 
@@ -46,7 +46,7 @@ func (m *Manifest) Remove() error {
 }
 }
 
 
 func (m *Manifest) RemoveLayers() error {
 func (m *Manifest) RemoveLayers() error {
-	for _, layer := range append(m.Layers, &m.Config) {
+	for _, layer := range append(m.Layers, m.Config) {
 		if layer.Digest != "" {
 		if layer.Digest != "" {
 			if err := layer.Remove(); errors.Is(err, os.ErrNotExist) {
 			if err := layer.Remove(); errors.Is(err, os.ErrNotExist) {
 				slog.Debug("layer does not exist", "digest", layer.Digest)
 				slog.Debug("layer does not exist", "digest", layer.Digest)
@@ -95,7 +95,7 @@ func ParseNamedManifest(n model.Name) (*Manifest, error) {
 	return &m, nil
 	return &m, nil
 }
 }
 
 
-func WriteManifest(name model.Name, config *Layer, layers []*Layer) error {
+func WriteManifest(name model.Name, config Layer, layers []Layer) error {
 	manifests, err := GetManifestPath()
 	manifests, err := GetManifestPath()
 	if err != nil {
 	if err != nil {
 		return err
 		return err
@@ -115,7 +115,7 @@ func WriteManifest(name model.Name, config *Layer, layers []*Layer) error {
 	m := Manifest{
 	m := Manifest{
 		SchemaVersion: 2,
 		SchemaVersion: 2,
 		MediaType:     "application/vnd.docker.distribution.manifest.v2+json",
 		MediaType:     "application/vnd.docker.distribution.manifest.v2+json",
-		Config:        *config,
+		Config:        config,
 		Layers:        layers,
 		Layers:        layers,
 	}
 	}
 
 

+ 1 - 1
server/model.go

@@ -26,7 +26,7 @@ import (
 var intermediateBlobs map[string]string = make(map[string]string)
 var intermediateBlobs map[string]string = make(map[string]string)
 
 
 type layerGGML struct {
 type layerGGML struct {
-	*Layer
+	Layer
 	*llm.GGML
 	*llm.GGML
 }
 }
 
 

+ 1 - 1
server/routes_delete_test.go

@@ -98,7 +98,7 @@ func TestDeleteDuplicateLayers(t *testing.T) {
 	}
 	}
 
 
 	// create a manifest with duplicate layers
 	// create a manifest with duplicate layers
-	if err := WriteManifest(n, config, []*Layer{config}); err != nil {
+	if err := WriteManifest(n, config, []Layer{config}); err != nil {
 		t.Fatal(err)
 		t.Fatal(err)
 	}
 	}
 
 

+ 2 - 2
server/upload.go

@@ -26,7 +26,7 @@ import (
 var blobUploadManager sync.Map
 var blobUploadManager sync.Map
 
 
 type blobUpload struct {
 type blobUpload struct {
-	*Layer
+	Layer
 
 
 	Total     int64
 	Total     int64
 	Completed atomic.Int64
 	Completed atomic.Int64
@@ -362,7 +362,7 @@ func (p *progressWriter) Rollback() {
 	p.written = 0
 	p.written = 0
 }
 }
 
 
-func uploadBlob(ctx context.Context, mp ModelPath, layer *Layer, opts *registryOptions, fn func(api.ProgressResponse)) error {
+func uploadBlob(ctx context.Context, mp ModelPath, layer Layer, opts *registryOptions, fn func(api.ProgressResponse)) error {
 	requestURL := mp.BaseURL()
 	requestURL := mp.BaseURL()
 	requestURL = requestURL.JoinPath("v2", mp.GetNamespaceRepository(), "blobs", layer.Digest)
 	requestURL = requestURL.JoinPath("v2", mp.GetNamespaceRepository(), "blobs", layer.Digest)