浏览代码

allow relative paths in `FROM` instruction

Jeffrey Morgan 1 年之前
父节点
当前提交
2d305fa99a
共有 2 个文件被更改,包括 23 次插入28 次删除
  1. 22 18
      server/images.go
  2. 1 10
      server/routes.go

+ 22 - 18
server/images.go

@@ -137,21 +137,14 @@ func GetModel(name string) (*Model, error) {
 	return model, nil
 }
 
-func getAbsPath(fp string) (string, error) {
-	if strings.HasPrefix(fp, "~/") {
-		parts := strings.Split(fp, "/")
-		home, err := os.UserHomeDir()
-		if err != nil {
-			return "", err
-		}
-
-		fp = filepath.Join(home, filepath.Join(parts[1:]...))
+func CreateModel(name string, path string, fn func(status string)) error {
+	mf, err := os.Open(path)
+	if err != nil {
+		fn(fmt.Sprintf("couldn't open modelfile '%s'", path))
+		return fmt.Errorf("failed to open file: %w", err)
 	}
+	defer mf.Close()
 
-	return os.ExpandEnv(fp), nil
-}
-
-func CreateModel(name string, mf io.Reader, fn func(status string)) error {
 	fn("parsing modelfile")
 	commands, err := parser.Parse(mf)
 	if err != nil {
@@ -169,11 +162,22 @@ func CreateModel(name string, mf io.Reader, fn func(status string)) error {
 			fn("looking for model")
 			mf, err := GetManifest(ParseModelPath(c.Arg))
 			if err != nil {
-				// if we couldn't read the manifest, try getting the bin file
-				fp, err := getAbsPath(c.Arg)
-				if err != nil {
-					fn("error determing path. exiting.")
-					return err
+				fp := c.Arg
+
+				// If filePath starts with ~/, replace it with the user's home directory.
+				if strings.HasPrefix(fp, "~/") {
+					parts := strings.Split(fp, "/")
+					home, err := os.UserHomeDir()
+					if err != nil {
+						return fmt.Errorf("failed to open file: %v", err)
+					}
+
+					fp = filepath.Join(home, filepath.Join(parts[1:]...))
+				}
+
+				// If filePath is not an absolute path, make it relative to the modelfile path
+				if !filepath.IsAbs(fp) {
+					fp = filepath.Join(filepath.Dir(path), fp)
 				}
 
 				fn("creating model layer")

+ 1 - 10
server/routes.go

@@ -144,15 +144,6 @@ func create(c *gin.Context) {
 		return
 	}
 
-	// NOTE consider passing the entire Modelfile in the json instead of the path to it
-
-	file, err := os.Open(req.Path)
-	if err != nil {
-		c.JSON(http.StatusBadRequest, gin.H{"message": err.Error()})
-		return
-	}
-	defer file.Close()
-
 	ch := make(chan any)
 	go func() {
 		defer close(ch)
@@ -162,7 +153,7 @@ func create(c *gin.Context) {
 			}
 		}
 
-		if err := CreateModel(req.Name, file, fn); err != nil {
+		if err := CreateModel(req.Name, req.Path, fn); err != nil {
 			c.JSON(http.StatusBadRequest, gin.H{"message": err.Error()})
 			return
 		}