|
@@ -29,6 +29,7 @@ import (
|
|
"github.com/ollama/ollama/llm"
|
|
"github.com/ollama/ollama/llm"
|
|
"github.com/ollama/ollama/openai"
|
|
"github.com/ollama/ollama/openai"
|
|
"github.com/ollama/ollama/parser"
|
|
"github.com/ollama/ollama/parser"
|
|
|
|
+ "github.com/ollama/ollama/types/model"
|
|
"github.com/ollama/ollama/version"
|
|
"github.com/ollama/ollama/version"
|
|
)
|
|
)
|
|
|
|
|
|
@@ -788,35 +789,35 @@ func (s *Server) ListModelsHandler(c *gin.Context) {
|
|
}
|
|
}
|
|
|
|
|
|
func (s *Server) CopyModelHandler(c *gin.Context) {
|
|
func (s *Server) CopyModelHandler(c *gin.Context) {
|
|
- var req api.CopyRequest
|
|
|
|
- err := c.ShouldBindJSON(&req)
|
|
|
|
- switch {
|
|
|
|
- case errors.Is(err, io.EOF):
|
|
|
|
|
|
+ var r api.CopyRequest
|
|
|
|
+ if err := c.ShouldBindJSON(&r); errors.Is(err, io.EOF) {
|
|
c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"error": "missing request body"})
|
|
c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"error": "missing request body"})
|
|
return
|
|
return
|
|
- case err != nil:
|
|
|
|
|
|
+ } else if err != nil {
|
|
c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"error": err.Error()})
|
|
c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"error": err.Error()})
|
|
return
|
|
return
|
|
}
|
|
}
|
|
|
|
|
|
- if req.Source == "" || req.Destination == "" {
|
|
|
|
- c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"error": "source add destination are required"})
|
|
|
|
- return
|
|
|
|
|
|
+ src := model.ParseName(r.Source)
|
|
|
|
+ if !src.IsValid() {
|
|
|
|
+ _ = c.Error(fmt.Errorf("source %q is invalid", r.Source))
|
|
}
|
|
}
|
|
|
|
|
|
- if err := ParseModelPath(req.Destination).Validate(); err != nil {
|
|
|
|
- c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"error": err.Error()})
|
|
|
|
- return
|
|
|
|
|
|
+ dst := model.ParseName(r.Destination)
|
|
|
|
+ if !dst.IsValid() {
|
|
|
|
+ _ = c.Error(fmt.Errorf("destination %q is invalid", r.Destination))
|
|
}
|
|
}
|
|
|
|
|
|
- if err := CopyModel(req.Source, req.Destination); err != nil {
|
|
|
|
- if os.IsNotExist(err) {
|
|
|
|
- c.JSON(http.StatusNotFound, gin.H{"error": fmt.Sprintf("model '%s' not found", req.Source)})
|
|
|
|
- } else {
|
|
|
|
- c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
|
|
|
|
- }
|
|
|
|
|
|
+ if len(c.Errors) > 0 {
|
|
|
|
+ c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"error": c.Errors.Errors()})
|
|
return
|
|
return
|
|
}
|
|
}
|
|
|
|
+
|
|
|
|
+ if err := CopyModel(src, dst); errors.Is(err, os.ErrNotExist) {
|
|
|
|
+ c.JSON(http.StatusNotFound, gin.H{"error": fmt.Sprintf("model %q not found", r.Source)})
|
|
|
|
+ } else if err != nil {
|
|
|
|
+ c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
|
|
|
|
+ }
|
|
}
|
|
}
|
|
|
|
|
|
func (s *Server) HeadBlobHandler(c *gin.Context) {
|
|
func (s *Server) HeadBlobHandler(c *gin.Context) {
|