Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
OpenDAS
ollama
Commits
32bd37ad
Unverified
Commit
32bd37ad
authored
Jan 10, 2025
by
Patrick Devine
Committed by
GitHub
Jan 10, 2025
Browse files
make the modelfile path relative for `ollama create` (#8380)
parent
9446c2c9
Changes
5
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
155 additions
and
25 deletions
+155
-25
cmd/cmd.go
cmd/cmd.go
+3
-4
cmd/cmd_test.go
cmd/cmd_test.go
+129
-2
parser/expandpath_test.go
parser/expandpath_test.go
+13
-11
parser/parser.go
parser/parser.go
+8
-6
parser/parser_test.go
parser/parser_test.go
+2
-2
No files found.
cmd/cmd.go
View file @
32bd37ad
...
@@ -46,9 +46,8 @@ import (
...
@@ -46,9 +46,8 @@ import (
var
errModelfileNotFound
=
errors
.
New
(
"specified Modelfile wasn't found"
)
var
errModelfileNotFound
=
errors
.
New
(
"specified Modelfile wasn't found"
)
func
getModelfileName
(
cmd
*
cobra
.
Command
)
(
string
,
error
)
{
func
getModelfileName
(
cmd
*
cobra
.
Command
)
(
string
,
error
)
{
f
n
,
_
:=
cmd
.
Flags
()
.
GetString
(
"file"
)
f
ilename
,
_
:=
cmd
.
Flags
()
.
GetString
(
"file"
)
filename
:=
fn
if
filename
==
""
{
if
filename
==
""
{
filename
=
"Modelfile"
filename
=
"Modelfile"
}
}
...
@@ -60,7 +59,7 @@ func getModelfileName(cmd *cobra.Command) (string, error) {
...
@@ -60,7 +59,7 @@ func getModelfileName(cmd *cobra.Command) (string, error) {
_
,
err
=
os
.
Stat
(
absName
)
_
,
err
=
os
.
Stat
(
absName
)
if
err
!=
nil
{
if
err
!=
nil
{
return
f
n
,
err
return
f
ilename
,
err
}
}
return
absName
,
nil
return
absName
,
nil
...
@@ -100,7 +99,7 @@ func CreateHandler(cmd *cobra.Command, args []string) error {
...
@@ -100,7 +99,7 @@ func CreateHandler(cmd *cobra.Command, args []string) error {
spinner
:=
progress
.
NewSpinner
(
status
)
spinner
:=
progress
.
NewSpinner
(
status
)
p
.
Add
(
status
,
spinner
)
p
.
Add
(
status
,
spinner
)
req
,
err
:=
modelfile
.
CreateRequest
()
req
,
err
:=
modelfile
.
CreateRequest
(
filepath
.
Dir
(
filename
)
)
if
err
!=
nil
{
if
err
!=
nil
{
return
err
return
err
}
}
...
...
cmd/cmd_test.go
View file @
32bd37ad
...
@@ -279,7 +279,7 @@ func TestGetModelfileName(t *testing.T) {
...
@@ -279,7 +279,7 @@ func TestGetModelfileName(t *testing.T) {
name
:
"no modelfile specified, no modelfile exists"
,
name
:
"no modelfile specified, no modelfile exists"
,
modelfileName
:
""
,
modelfileName
:
""
,
fileExists
:
false
,
fileExists
:
false
,
expectedName
:
""
,
expectedName
:
"
Modelfile
"
,
expectedErr
:
os
.
ErrNotExist
,
expectedErr
:
os
.
ErrNotExist
,
},
},
{
{
...
@@ -338,8 +338,8 @@ func TestGetModelfileName(t *testing.T) {
...
@@ -338,8 +338,8 @@ func TestGetModelfileName(t *testing.T) {
t
.
Fatalf
(
"couldn't set file flag: %v"
,
err
)
t
.
Fatalf
(
"couldn't set file flag: %v"
,
err
)
}
}
}
else
{
}
else
{
expectedFilename
=
tt
.
expectedName
if
tt
.
modelfileName
!=
""
{
if
tt
.
modelfileName
!=
""
{
expectedFilename
=
tt
.
modelfileName
err
:=
cmd
.
Flags
()
.
Set
(
"file"
,
tt
.
modelfileName
)
err
:=
cmd
.
Flags
()
.
Set
(
"file"
,
tt
.
modelfileName
)
if
err
!=
nil
{
if
err
!=
nil
{
t
.
Fatalf
(
"couldn't set file flag: %v"
,
err
)
t
.
Fatalf
(
"couldn't set file flag: %v"
,
err
)
...
@@ -489,3 +489,130 @@ func TestPushHandler(t *testing.T) {
...
@@ -489,3 +489,130 @@ func TestPushHandler(t *testing.T) {
})
})
}
}
}
}
func
TestCreateHandler
(
t
*
testing
.
T
)
{
tests
:=
[]
struct
{
name
string
modelName
string
modelFile
string
serverResponse
map
[
string
]
func
(
w
http
.
ResponseWriter
,
r
*
http
.
Request
)
expectedError
string
expectedOutput
string
}{
{
name
:
"successful create"
,
modelName
:
"test-model"
,
modelFile
:
"FROM foo"
,
serverResponse
:
map
[
string
]
func
(
w
http
.
ResponseWriter
,
r
*
http
.
Request
){
"/api/create"
:
func
(
w
http
.
ResponseWriter
,
r
*
http
.
Request
)
{
if
r
.
Method
!=
http
.
MethodPost
{
t
.
Errorf
(
"expected POST request, got %s"
,
r
.
Method
)
}
req
:=
api
.
CreateRequest
{}
if
err
:=
json
.
NewDecoder
(
r
.
Body
)
.
Decode
(
&
req
);
err
!=
nil
{
http
.
Error
(
w
,
err
.
Error
(),
http
.
StatusBadRequest
)
return
}
if
req
.
Name
!=
"test-model"
{
t
.
Errorf
(
"expected model name 'test-model', got %s"
,
req
.
Name
)
}
if
req
.
From
!=
"foo"
{
t
.
Errorf
(
"expected from 'foo', got %s"
,
req
.
From
)
}
responses
:=
[]
api
.
ProgressResponse
{
{
Status
:
"using existing layer sha256:56bb8bd477a519ffa694fc449c2413c6f0e1d3b1c88fa7e3c9d88d3ae49d4dcb"
},
{
Status
:
"writing manifest"
},
{
Status
:
"success"
},
}
for
_
,
resp
:=
range
responses
{
if
err
:=
json
.
NewEncoder
(
w
)
.
Encode
(
resp
);
err
!=
nil
{
http
.
Error
(
w
,
err
.
Error
(),
http
.
StatusInternalServerError
)
return
}
w
.
(
http
.
Flusher
)
.
Flush
()
}
},
},
expectedOutput
:
""
,
},
}
for
_
,
tt
:=
range
tests
{
t
.
Run
(
tt
.
name
,
func
(
t
*
testing
.
T
)
{
mockServer
:=
httptest
.
NewServer
(
http
.
HandlerFunc
(
func
(
w
http
.
ResponseWriter
,
r
*
http
.
Request
)
{
handler
,
ok
:=
tt
.
serverResponse
[
r
.
URL
.
Path
]
if
!
ok
{
t
.
Errorf
(
"unexpected request to %s"
,
r
.
URL
.
Path
)
http
.
Error
(
w
,
"not found"
,
http
.
StatusNotFound
)
return
}
handler
(
w
,
r
)
}))
t
.
Setenv
(
"OLLAMA_HOST"
,
mockServer
.
URL
)
t
.
Cleanup
(
mockServer
.
Close
)
tempFile
,
err
:=
os
.
CreateTemp
(
""
,
"modelfile"
)
if
err
!=
nil
{
t
.
Fatal
(
err
)
}
defer
os
.
Remove
(
tempFile
.
Name
())
if
_
,
err
:=
tempFile
.
WriteString
(
tt
.
modelFile
);
err
!=
nil
{
t
.
Fatal
(
err
)
}
if
err
:=
tempFile
.
Close
();
err
!=
nil
{
t
.
Fatal
(
err
)
}
cmd
:=
&
cobra
.
Command
{}
cmd
.
Flags
()
.
String
(
"file"
,
""
,
""
)
if
err
:=
cmd
.
Flags
()
.
Set
(
"file"
,
tempFile
.
Name
());
err
!=
nil
{
t
.
Fatal
(
err
)
}
cmd
.
Flags
()
.
Bool
(
"insecure"
,
false
,
""
)
cmd
.
SetContext
(
context
.
TODO
())
// Redirect stderr to capture progress output
oldStderr
:=
os
.
Stderr
r
,
w
,
_
:=
os
.
Pipe
()
os
.
Stderr
=
w
// Capture stdout for the "Model pushed" message
oldStdout
:=
os
.
Stdout
outR
,
outW
,
_
:=
os
.
Pipe
()
os
.
Stdout
=
outW
err
=
CreateHandler
(
cmd
,
[]
string
{
tt
.
modelName
})
// Restore stderr
w
.
Close
()
os
.
Stderr
=
oldStderr
// drain the pipe
if
_
,
err
:=
io
.
ReadAll
(
r
);
err
!=
nil
{
t
.
Fatal
(
err
)
}
// Restore stdout and get output
outW
.
Close
()
os
.
Stdout
=
oldStdout
stdout
,
_
:=
io
.
ReadAll
(
outR
)
if
tt
.
expectedError
==
""
{
if
err
!=
nil
{
t
.
Errorf
(
"expected no error, got %v"
,
err
)
}
if
tt
.
expectedOutput
!=
""
{
if
got
:=
string
(
stdout
);
got
!=
tt
.
expectedOutput
{
t
.
Errorf
(
"expected output %q, got %q"
,
tt
.
expectedOutput
,
got
)
}
}
}
})
}
}
parser/expandpath_test.go
View file @
32bd37ad
...
@@ -31,27 +31,29 @@ func TestExpandPath(t *testing.T) {
...
@@ -31,27 +31,29 @@ func TestExpandPath(t *testing.T) {
}
}
tests
:=
[]
struct
{
tests
:=
[]
struct
{
input
string
path
string
relativeDir
string
expected
string
expected
string
windowsExpected
string
windowsExpected
string
shouldErr
bool
shouldErr
bool
}{
}{
{
"~"
,
"/home/testuser"
,
"D:
\\
home
\\
testuser"
,
false
},
{
"~"
,
""
,
"/home/testuser"
,
"D:
\\
home
\\
testuser"
,
false
},
{
"~/myfolder/myfile.txt"
,
"/home/testuser/myfolder/myfile.txt"
,
"D:
\\
home
\\
testuser
\\
myfolder
\\
myfile.txt"
,
false
},
{
"~/myfolder/myfile.txt"
,
""
,
"/home/testuser/myfolder/myfile.txt"
,
"D:
\\
home
\\
testuser
\\
myfolder
\\
myfile.txt"
,
false
},
{
"~anotheruser/docs/file.txt"
,
"/home/anotheruser/docs/file.txt"
,
"D:
\\
home
\\
anotheruser
\\
docs
\\
file.txt"
,
false
},
{
"~anotheruser/docs/file.txt"
,
""
,
"/home/anotheruser/docs/file.txt"
,
"D:
\\
home
\\
anotheruser
\\
docs
\\
file.txt"
,
false
},
{
"~nonexistentuser/file.txt"
,
""
,
""
,
true
},
{
"~nonexistentuser/file.txt"
,
""
,
""
,
""
,
true
},
{
"relative/path/to/file"
,
filepath
.
Join
(
os
.
Getenv
(
"PWD"
),
"relative/path/to/file"
),
"relative
\\
path
\\
to
\\
file"
,
false
},
{
"relative/path/to/file"
,
""
,
filepath
.
Join
(
os
.
Getenv
(
"PWD"
),
"relative/path/to/file"
),
"relative
\\
path
\\
to
\\
file"
,
false
},
{
"/absolute/path/to/file"
,
"/absolute/path/to/file"
,
"D:
\\
absolute
\\
path
\\
to
\\
file"
,
false
},
{
"/absolute/path/to/file"
,
""
,
"/absolute/path/to/file"
,
"D:
\\
absolute
\\
path
\\
to
\\
file"
,
false
},
{
"."
,
os
.
Getenv
(
"PWD"
),
os
.
Getenv
(
"PWD"
),
false
},
{
"."
,
os
.
Getenv
(
"PWD"
),
""
,
os
.
Getenv
(
"PWD"
),
false
},
{
"somefile"
,
"somedir"
,
filepath
.
Join
(
os
.
Getenv
(
"PWD"
),
"somedir"
,
"somefile"
),
"somedir
\\
somefile"
,
false
},
}
}
for
_
,
test
:=
range
tests
{
for
_
,
test
:=
range
tests
{
result
,
err
:=
expandPathImpl
(
test
.
input
,
mockCurrentUser
,
mockLookupUser
)
result
,
err
:=
expandPathImpl
(
test
.
path
,
test
.
relativeDir
,
mockCurrentUser
,
mockLookupUser
)
if
(
err
!=
nil
)
!=
test
.
shouldErr
{
if
(
err
!=
nil
)
!=
test
.
shouldErr
{
t
.
Errorf
(
"expandPathImpl(%q) returned error: %v, expected error: %v"
,
test
.
input
,
err
!=
nil
,
test
.
shouldErr
)
t
.
Errorf
(
"expandPathImpl(%q) returned error: %v, expected error: %v"
,
test
.
path
,
err
!=
nil
,
test
.
shouldErr
)
}
}
if
result
!=
test
.
expected
&&
result
!=
test
.
windowsExpected
&&
!
test
.
shouldErr
{
if
result
!=
test
.
expected
&&
result
!=
test
.
windowsExpected
&&
!
test
.
shouldErr
{
t
.
Errorf
(
"expandPathImpl(%q) = %q, want %q"
,
test
.
input
,
result
,
test
.
expected
)
t
.
Errorf
(
"expandPathImpl(%q) = %q, want %q"
,
test
.
path
,
result
,
test
.
expected
)
}
}
}
}
}
}
parser/parser.go
View file @
32bd37ad
...
@@ -39,7 +39,7 @@ func (f Modelfile) String() string {
...
@@ -39,7 +39,7 @@ func (f Modelfile) String() string {
var
deprecatedParameters
=
[]
string
{
"penalize_newline"
}
var
deprecatedParameters
=
[]
string
{
"penalize_newline"
}
// CreateRequest creates a new *api.CreateRequest from an existing Modelfile
// CreateRequest creates a new *api.CreateRequest from an existing Modelfile
func
(
f
Modelfile
)
CreateRequest
()
(
*
api
.
CreateRequest
,
error
)
{
func
(
f
Modelfile
)
CreateRequest
(
relativeDir
string
)
(
*
api
.
CreateRequest
,
error
)
{
req
:=
&
api
.
CreateRequest
{}
req
:=
&
api
.
CreateRequest
{}
var
messages
[]
api
.
Message
var
messages
[]
api
.
Message
...
@@ -49,7 +49,7 @@ func (f Modelfile) CreateRequest() (*api.CreateRequest, error) {
...
@@ -49,7 +49,7 @@ func (f Modelfile) CreateRequest() (*api.CreateRequest, error) {
for
_
,
c
:=
range
f
.
Commands
{
for
_
,
c
:=
range
f
.
Commands
{
switch
c
.
Name
{
switch
c
.
Name
{
case
"model"
:
case
"model"
:
path
,
err
:=
expandPath
(
c
.
Args
)
path
,
err
:=
expandPath
(
c
.
Args
,
relativeDir
)
if
err
!=
nil
{
if
err
!=
nil
{
return
nil
,
err
return
nil
,
err
}
}
...
@@ -64,7 +64,7 @@ func (f Modelfile) CreateRequest() (*api.CreateRequest, error) {
...
@@ -64,7 +64,7 @@ func (f Modelfile) CreateRequest() (*api.CreateRequest, error) {
req
.
Files
=
digestMap
req
.
Files
=
digestMap
case
"adapter"
:
case
"adapter"
:
path
,
err
:=
expandPath
(
c
.
Args
)
path
,
err
:=
expandPath
(
c
.
Args
,
relativeDir
)
if
err
!=
nil
{
if
err
!=
nil
{
return
nil
,
err
return
nil
,
err
}
}
...
@@ -563,7 +563,7 @@ func isValidCommand(cmd string) bool {
...
@@ -563,7 +563,7 @@ func isValidCommand(cmd string) bool {
}
}
}
}
func
expandPathImpl
(
path
string
,
currentUserFunc
func
()
(
*
user
.
User
,
error
),
lookupUserFunc
func
(
string
)
(
*
user
.
User
,
error
))
(
string
,
error
)
{
func
expandPathImpl
(
path
,
relativeDir
string
,
currentUserFunc
func
()
(
*
user
.
User
,
error
),
lookupUserFunc
func
(
string
)
(
*
user
.
User
,
error
))
(
string
,
error
)
{
if
strings
.
HasPrefix
(
path
,
"~"
)
{
if
strings
.
HasPrefix
(
path
,
"~"
)
{
var
homeDir
string
var
homeDir
string
...
@@ -591,11 +591,13 @@ func expandPathImpl(path string, currentUserFunc func() (*user.User, error), loo
...
@@ -591,11 +591,13 @@ func expandPathImpl(path string, currentUserFunc func() (*user.User, error), loo
}
}
path
=
filepath
.
Join
(
homeDir
,
path
)
path
=
filepath
.
Join
(
homeDir
,
path
)
}
else
{
path
=
filepath
.
Join
(
relativeDir
,
path
)
}
}
return
filepath
.
Abs
(
path
)
return
filepath
.
Abs
(
path
)
}
}
func
expandPath
(
path
string
)
(
string
,
error
)
{
func
expandPath
(
path
,
relativeDir
string
)
(
string
,
error
)
{
return
expandPathImpl
(
path
,
user
.
Current
,
user
.
Lookup
)
return
expandPathImpl
(
path
,
relativeDir
,
user
.
Current
,
user
.
Lookup
)
}
}
parser/parser_test.go
View file @
32bd37ad
...
@@ -747,7 +747,7 @@ MESSAGE assistant Hi! How are you?
...
@@ -747,7 +747,7 @@ MESSAGE assistant Hi! How are you?
t
.
Error
(
err
)
t
.
Error
(
err
)
}
}
actual
,
err
:=
p
.
CreateRequest
()
actual
,
err
:=
p
.
CreateRequest
(
""
)
if
err
!=
nil
{
if
err
!=
nil
{
t
.
Error
(
err
)
t
.
Error
(
err
)
}
}
...
@@ -816,7 +816,7 @@ func TestCreateRequestFiles(t *testing.T) {
...
@@ -816,7 +816,7 @@ func TestCreateRequestFiles(t *testing.T) {
t
.
Error
(
err
)
t
.
Error
(
err
)
}
}
actual
,
err
:=
p
.
CreateRequest
()
actual
,
err
:=
p
.
CreateRequest
(
""
)
if
err
!=
nil
{
if
err
!=
nil
{
t
.
Error
(
err
)
t
.
Error
(
err
)
}
}
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment