91dfbb1bba
* windows: Support alt install paths Advanced users are leveraging innosetup's /DIR switch to target an alternate location, but we get confused by things not existing in the LocalAppData dir. This also hardens the server path lookup code for a future attempt to unify with a ./bin prefix * Fit and finish improvements for windows app Document alternate install location instructions for binaries and model. Pop up progress UI for upgrades (automatic, with cancel button). Expose non-default port in menu to disambiguate mutiple instances. Set minimum Windows version to 10 22H2
94 lines
2.1 KiB
Go
94 lines
2.1 KiB
Go
package lifecycle
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"log"
|
|
"log/slog"
|
|
"os"
|
|
"os/signal"
|
|
"syscall"
|
|
|
|
"github.com/ollama/ollama/app/store"
|
|
"github.com/ollama/ollama/app/tray"
|
|
"github.com/ollama/ollama/envconfig"
|
|
)
|
|
|
|
func Run() {
|
|
InitLogging()
|
|
slog.Info("app config", "env", envconfig.Values())
|
|
|
|
ctx, cancel := context.WithCancel(context.Background())
|
|
var done chan int
|
|
|
|
t, err := tray.NewTray()
|
|
if err != nil {
|
|
log.Fatalf("Failed to start: %s", err)
|
|
}
|
|
callbacks := t.GetCallbacks()
|
|
|
|
signals := make(chan os.Signal, 1)
|
|
signal.Notify(signals, syscall.SIGINT, syscall.SIGTERM)
|
|
|
|
go func() {
|
|
slog.Debug("starting callback loop")
|
|
for {
|
|
select {
|
|
case <-callbacks.Quit:
|
|
slog.Debug("quit called")
|
|
t.Quit()
|
|
case <-signals:
|
|
slog.Debug("shutting down due to signal")
|
|
t.Quit()
|
|
case <-callbacks.Update:
|
|
err := DoUpgrade(cancel, done)
|
|
if err != nil {
|
|
slog.Warn(fmt.Sprintf("upgrade attempt failed: %s", err))
|
|
}
|
|
case <-callbacks.ShowLogs:
|
|
ShowLogs()
|
|
case <-callbacks.DoFirstUse:
|
|
err := GetStarted()
|
|
if err != nil {
|
|
slog.Warn(fmt.Sprintf("Failed to launch getting started shell: %s", err))
|
|
}
|
|
}
|
|
}
|
|
}()
|
|
|
|
// Are we first use?
|
|
if !store.GetFirstTimeRun() {
|
|
slog.Debug("First time run")
|
|
err = t.DisplayFirstUseNotification()
|
|
if err != nil {
|
|
slog.Debug(fmt.Sprintf("XXX failed to display first use notification %v", err))
|
|
}
|
|
store.SetFirstTimeRun(true)
|
|
} else {
|
|
slog.Debug("Not first time, skipping first run notification")
|
|
}
|
|
|
|
if IsServerRunning(ctx) {
|
|
slog.Info("Detected another instance of ollama running, exiting")
|
|
os.Exit(1)
|
|
} else {
|
|
done, err = SpawnServer(ctx, CLIName)
|
|
if err != nil {
|
|
// TODO - should we retry in a backoff loop?
|
|
// TODO - should we pop up a warning and maybe add a menu item to view application logs?
|
|
slog.Error(fmt.Sprintf("Failed to spawn ollama server %s", err))
|
|
done = make(chan int, 1)
|
|
done <- 1
|
|
}
|
|
}
|
|
|
|
StartBackgroundUpdaterChecker(ctx, t.UpdateAvailable)
|
|
|
|
t.Run()
|
|
cancel()
|
|
slog.Info("Waiting for ollama server to shutdown...")
|
|
if done != nil {
|
|
<-done
|
|
}
|
|
slog.Info("Ollama app exiting")
|
|
}
|