mirror of
https://github.com/dogkeeper886/ollama37.git
synced 2025-12-11 00:07:07 +00:00
win: detect background upgrade in progress (#10785)
Give the user a helpful error instead of showing connection refused errors.
This commit is contained in:
@@ -1236,11 +1236,11 @@ func checkServerHeartbeat(cmd *cobra.Command, _ []string) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if err := client.Heartbeat(cmd.Context()); err != nil {
|
if err := client.Heartbeat(cmd.Context()); err != nil {
|
||||||
if !strings.Contains(err.Error(), " refused") {
|
if !(strings.Contains(err.Error(), " refused") || strings.Contains(err.Error(), "could not connect")) {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if err := startApp(cmd.Context(), client); err != nil {
|
if err := startApp(cmd.Context(), client); err != nil {
|
||||||
return errors.New("could not connect to ollama app, is it running?")
|
return fmt.Errorf("ollama server not responding - %w", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
|
|||||||
@@ -4,17 +4,27 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"log/slog"
|
||||||
"os"
|
"os"
|
||||||
"os/exec"
|
"os/exec"
|
||||||
|
"path"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"strings"
|
"strings"
|
||||||
"syscall"
|
"syscall"
|
||||||
|
"unsafe"
|
||||||
|
|
||||||
"github.com/ollama/ollama/api"
|
"github.com/ollama/ollama/api"
|
||||||
|
"golang.org/x/sys/windows"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
Installer = "OllamaSetup.exe"
|
||||||
)
|
)
|
||||||
|
|
||||||
func startApp(ctx context.Context, client *api.Client) error {
|
func startApp(ctx context.Context, client *api.Client) error {
|
||||||
// log.Printf("XXX Attempting to find and start ollama app")
|
if len(isProcRunning(Installer)) > 0 {
|
||||||
|
return fmt.Errorf("upgrade in progress...")
|
||||||
|
}
|
||||||
AppName := "ollama app.exe"
|
AppName := "ollama app.exe"
|
||||||
exe, err := os.Executable()
|
exe, err := os.Executable()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -56,3 +66,41 @@ func startApp(ctx context.Context, client *api.Client) error {
|
|||||||
}
|
}
|
||||||
return waitForServer(ctx, client)
|
return waitForServer(ctx, client)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func isProcRunning(procName string) []uint32 {
|
||||||
|
pids := make([]uint32, 2048)
|
||||||
|
var ret uint32
|
||||||
|
if err := windows.EnumProcesses(pids, &ret); err != nil || ret == 0 {
|
||||||
|
slog.Debug("failed to check for running installers", "error", err)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
pids = pids[:ret]
|
||||||
|
var matches []uint32
|
||||||
|
for _, pid := range pids {
|
||||||
|
if pid == 0 {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
hProcess, err := windows.OpenProcess(windows.PROCESS_QUERY_INFORMATION|windows.PROCESS_VM_READ, false, pid)
|
||||||
|
if err != nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
defer windows.CloseHandle(hProcess)
|
||||||
|
var module windows.Handle
|
||||||
|
var cbNeeded uint32
|
||||||
|
cb := (uint32)(unsafe.Sizeof(module))
|
||||||
|
if err := windows.EnumProcessModules(hProcess, &module, cb, &cbNeeded); err != nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
var sz uint32 = 1024 * 8
|
||||||
|
moduleName := make([]uint16, sz)
|
||||||
|
cb = uint32(len(moduleName)) * (uint32)(unsafe.Sizeof(uint16(0)))
|
||||||
|
if err := windows.GetModuleBaseName(hProcess, module, &moduleName[0], cb); err != nil && err != syscall.ERROR_INSUFFICIENT_BUFFER {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
exeFile := path.Base(strings.ToLower(syscall.UTF16ToString(moduleName)))
|
||||||
|
if strings.EqualFold(exeFile, procName) {
|
||||||
|
matches = append(matches, pid)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return matches
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user