Procházet zdrojové kódy

Fix duplicate menus on update and exit on signals

Also fixes a few fit-and-finish items for better developer experience
Daniel Hiltgen před 1 rokem
rodič
revize
df6dc4fd96

+ 9 - 1
app/lifecycle/lifecycle.go

@@ -6,6 +6,8 @@ import (
 	"log"
 	"log/slog"
 	"os"
+	"os/signal"
+	"syscall"
 
 	"github.com/jmorganca/ollama/app/store"
 	"github.com/jmorganca/ollama/app/tray"
@@ -23,12 +25,18 @@ func Run() {
 	}
 	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")
+				slog.Debug("quit called")
+				t.Quit()
+			case <-signals:
+				slog.Debug("shutting down due to signal")
 				t.Quit()
 			case <-callbacks.Update:
 				err := DoUpgrade(cancel, done)

+ 7 - 3
app/lifecycle/server.go

@@ -31,11 +31,15 @@ func getCLIFullPath(command string) string {
 			return cmdPath
 		}
 	}
-	cmdPath = filepath.Join(".", command)
-	_, err = os.Stat(cmdPath)
+	pwd, err := os.Getwd()
 	if err == nil {
-		return cmdPath
+		cmdPath = filepath.Join(pwd, command)
+		_, err = os.Stat(cmdPath)
+		if err == nil {
+			return cmdPath
+		}
 	}
+
 	return command
 }
 

+ 5 - 5
app/lifecycle/updater.go

@@ -23,8 +23,9 @@ import (
 )
 
 var (
-	UpdateCheckURLBase = "https://ollama.com/api/update"
-	UpdateDownloaded   = false
+	UpdateCheckURLBase  = "https://ollama.com/api/update"
+	UpdateDownloaded    = false
+	UpdateCheckInterval = 60 * 60 * time.Second
 )
 
 // TODO - maybe move up to the API package?
@@ -112,7 +113,6 @@ func IsNewReleaseAvailable(ctx context.Context) (bool, UpdateResponse) {
 	return true, updateResp
 }
 
-// Returns true if we downloaded a new update, false if we already had it
 func DownloadNewRelease(ctx context.Context, updateResp UpdateResponse) error {
 	// Do a head first to check etag info
 	req, err := http.NewRequestWithContext(ctx, http.MethodHead, updateResp.UpdateURL, nil)
@@ -144,7 +144,7 @@ func DownloadNewRelease(ctx context.Context, updateResp UpdateResponse) error {
 	// Check to see if we already have it downloaded
 	_, err = os.Stat(stageFilename)
 	if err == nil {
-		slog.Debug("update already downloaded")
+		slog.Info("update already downloaded")
 		return nil
 	}
 
@@ -231,7 +231,7 @@ func StartBackgroundUpdaterChecker(ctx context.Context, cb func(string) error) {
 				slog.Debug("stopping background update checker")
 				return
 			default:
-				time.Sleep(60 * 60 * time.Second)
+				time.Sleep(UpdateCheckInterval)
 			}
 		}
 	}()

+ 21 - 21
app/tray/wintray/menus.go

@@ -33,27 +33,28 @@ func (t *winTray) initMenus() error {
 }
 
 func (t *winTray) UpdateAvailable(ver string) error {
-	slog.Debug("updating menu and sending notification for new update")
-	if err := t.addOrUpdateMenuItem(updatAvailableMenuID, 0, updateAvailableMenuTitle, true); err != nil {
-		return fmt.Errorf("unable to create menu entries %w", err)
-	}
-	if err := t.addOrUpdateMenuItem(updateMenuID, 0, updateMenutTitle, false); err != nil {
-		return fmt.Errorf("unable to create menu entries %w", err)
-	}
-	if err := t.addSeparatorMenuItem(separatorMenuID, 0); err != nil {
-		return fmt.Errorf("unable to create menu entries %w", err)
-	}
-	iconFilePath, err := iconBytesToFilePath(wt.updateIcon)
-	if err != nil {
-		return fmt.Errorf("unable to write icon data to temp file: %w", err)
-	}
-	if err := wt.setIcon(iconFilePath); err != nil {
-		return fmt.Errorf("unable to set icon: %w", err)
-	}
-
-	t.pendingUpdate = true
-	// Now pop up the notification
 	if !t.updateNotified {
+		slog.Debug("updating menu and sending notification for new update")
+		if err := t.addOrUpdateMenuItem(updatAvailableMenuID, 0, updateAvailableMenuTitle, true); err != nil {
+			return fmt.Errorf("unable to create menu entries %w", err)
+		}
+		if err := t.addOrUpdateMenuItem(updateMenuID, 0, updateMenutTitle, false); err != nil {
+			return fmt.Errorf("unable to create menu entries %w", err)
+		}
+		if err := t.addSeparatorMenuItem(separatorMenuID, 0); err != nil {
+			return fmt.Errorf("unable to create menu entries %w", err)
+		}
+		iconFilePath, err := iconBytesToFilePath(wt.updateIcon)
+		if err != nil {
+			return fmt.Errorf("unable to write icon data to temp file: %w", err)
+		}
+		if err := wt.setIcon(iconFilePath); err != nil {
+			return fmt.Errorf("unable to set icon: %w", err)
+		}
+		t.updateNotified = true
+
+		t.pendingUpdate = true
+		// Now pop up the notification
 		t.muNID.Lock()
 		defer t.muNID.Unlock()
 		copy(t.nid.InfoTitle[:], windows.StringToUTF16(updateTitle))
@@ -65,7 +66,6 @@ func (t *winTray) UpdateAvailable(ver string) error {
 		if err != nil {
 			return err
 		}
-		t.updateNotified = true
 	}
 	return nil
 }

+ 5 - 1
llm/generate/gen_windows.ps1

@@ -3,6 +3,7 @@
 $ErrorActionPreference = "Stop"
 
 function init_vars {
+    $script:SRC_DIR = $(resolve-path "..\..\")
     $script:llamacppDir = "../llama.cpp"
     $script:cmakeDefs = @("-DBUILD_SHARED_LIBS=on", "-DLLAMA_NATIVE=off",  "-A", "x64")
     $script:cmakeTargets = @("ext_server")
@@ -33,6 +34,9 @@ function init_vars {
     }
     # Note: 10 Windows Kit signtool crashes with GCP's plugin
     ${script:SignTool}="C:\Program Files (x86)\Windows Kits\8.1\bin\x64\signtool.exe"
+    if ("${env:KEY_CONTAINER}") {
+        ${script:OLLAMA_CERT}=$(resolve-path "${script:SRC_DIR}\ollama_inc.crt")
+    }
 }
 
 function git_module_setup {
@@ -102,7 +106,7 @@ function sign {
     if ("${env:KEY_CONTAINER}") {
         write-host "Signing ${script:buildDir}/lib/*.dll"
         foreach ($file in (get-childitem "${script:buildDir}/lib/*.dll")){
-            & "${script:SignTool}" sign /v /fd sha256 /t http://timestamp.digicert.com /f "${env:OLLAMA_CERT}" `
+            & "${script:SignTool}" sign /v /fd sha256 /t http://timestamp.digicert.com /f "${script:OLLAMA_CERT}" `
                 /csp "Google Cloud KMS Provider" /kc "${env:KEY_CONTAINER}" $file
             if ($LASTEXITCODE -ne 0) { exit($LASTEXITCODE)}
         }

+ 5 - 5
scripts/build_windows.ps1

@@ -38,7 +38,7 @@ function checkEnv() {
 
     # Check for signing key
     if ("${env:KEY_CONTAINER}") {
-        ${env:OLLAMA_CERT}=$(resolve-path "${script:SRC_DIR}\ollama_inc.crt")
+        ${script:OLLAMA_CERT}=$(resolve-path "${script:SRC_DIR}\ollama_inc.crt")
         Write-host "Code signing enabled"
         # Note: 10 Windows Kit signtool crashes with GCP's plugin
         ${script:SignTool}="C:\Program Files (x86)\Windows Kits\8.1\bin\x64\signtool.exe"
@@ -56,7 +56,7 @@ function buildOllama() {
     & go build "-ldflags=-w -s ""-X=github.com/jmorganca/ollama/version.Version=$script:VERSION"" ""-X=github.com/jmorganca/ollama/server.mode=release""" .
     if ($LASTEXITCODE -ne 0) { exit($LASTEXITCODE)}
     if ("${env:KEY_CONTAINER}") {
-        & "${script:SignTool}" sign /v /fd sha256 /t http://timestamp.digicert.com /f "${env:OLLAMA_CERT}" `
+        & "${script:SignTool}" sign /v /fd sha256 /t http://timestamp.digicert.com /f "${script:OLLAMA_CERT}" `
             /csp "Google Cloud KMS Provider" /kc ${env:KEY_CONTAINER} ollama.exe
         if ($LASTEXITCODE -ne 0) { exit($LASTEXITCODE)}
     }
@@ -70,7 +70,7 @@ function buildApp() {
     & go build "-ldflags=-H windowsgui -w -s ""-X=github.com/jmorganca/ollama/version.Version=$script:VERSION"" ""-X=github.com/jmorganca/ollama/server.mode=release""" .
     if ($LASTEXITCODE -ne 0) { exit($LASTEXITCODE)}
     if ("${env:KEY_CONTAINER}") {
-        & "${script:SignTool}" sign /v /fd sha256 /t http://timestamp.digicert.com /f "${env:OLLAMA_CERT}" `
+        & "${script:SignTool}" sign /v /fd sha256 /t http://timestamp.digicert.com /f "${script:OLLAMA_CERT}" `
             /csp "Google Cloud KMS Provider" /kc ${env:KEY_CONTAINER} app.exe
         if ($LASTEXITCODE -ne 0) { exit($LASTEXITCODE)}
     }
@@ -97,7 +97,7 @@ function gatherDependencies() {
         write-host "about to sign"
         foreach ($file in (get-childitem "${script:DEPS_DIR}/cu*.dll") + @("${script:SRC_DIR}\dist\ollama_welcome.ps1")){
             write-host "signing $file"
-            & "${script:SignTool}" sign /v /fd sha256 /t http://timestamp.digicert.com /f "${env:OLLAMA_CERT}" `
+            & "${script:SignTool}" sign /v /fd sha256 /t http://timestamp.digicert.com /f "${script:OLLAMA_CERT}" `
                 /csp "Google Cloud KMS Provider" /kc ${env:KEY_CONTAINER} $file
             if ($LASTEXITCODE -ne 0) { exit($LASTEXITCODE)}
         }
@@ -110,7 +110,7 @@ function buildInstaller() {
     cd "${script:SRC_DIR}\app"
     $env:PKG_VERSION=$script:PKG_VERSION
     if ("${env:KEY_CONTAINER}") {
-        & "${script:INNO_SETUP_DIR}\ISCC.exe" /SMySignTool="${script:SignTool} sign /fd sha256 /t http://timestamp.digicert.com /f ${env:OLLAMA_CERT} /csp `$qGoogle Cloud KMS Provider`$q /kc ${env:KEY_CONTAINER} `$f" .\ollama.iss
+        & "${script:INNO_SETUP_DIR}\ISCC.exe" /SMySignTool="${script:SignTool} sign /fd sha256 /t http://timestamp.digicert.com /f ${script:OLLAMA_CERT} /csp `$qGoogle Cloud KMS Provider`$q /kc ${env:KEY_CONTAINER} `$f" .\ollama.iss
     } else {
         & "${script:INNO_SETUP_DIR}\ISCC.exe" .\ollama.iss
     }