updater_windows.go 2.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879
  1. package lifecycle
  2. import (
  3. "context"
  4. "fmt"
  5. "log/slog"
  6. "os"
  7. "os/exec"
  8. "path/filepath"
  9. )
  10. func DoUpgrade(cancel context.CancelFunc, done chan int) error {
  11. files, err := filepath.Glob(filepath.Join(UpdateStageDir, "*", "*.exe")) // TODO generalize for multiplatform
  12. if err != nil {
  13. return fmt.Errorf("failed to lookup downloads: %s", err)
  14. }
  15. if len(files) == 0 {
  16. return fmt.Errorf("no update downloads found")
  17. } else if len(files) > 1 {
  18. // Shouldn't happen
  19. slog.Warn(fmt.Sprintf("multiple downloads found, using first one %v", files))
  20. }
  21. installerExe := files[0]
  22. slog.Info("starting upgrade with " + installerExe)
  23. slog.Info("upgrade log file " + UpgradeLogFile)
  24. // When running in debug mode, we'll be "verbose" and let the installer pop up and prompt
  25. installArgs := []string{
  26. "/CLOSEAPPLICATIONS", // Quit the tray app if it's still running
  27. "/LOG=" + filepath.Base(UpgradeLogFile), // Only relative seems reliable, so set pwd
  28. "/FORCECLOSEAPPLICATIONS", // Force close the tray app - might be needed
  29. }
  30. // When we're not in debug mode, make the upgrade as quiet as possible (no GUI, no prompts)
  31. // TODO - temporarily disable since we're pinning in debug mode for the preview
  32. // if debug := os.Getenv("OLLAMA_DEBUG"); debug == "" {
  33. installArgs = append(installArgs,
  34. "/SP", // Skip the "This will install... Do you wish to continue" prompt
  35. "/SUPPRESSMSGBOXES",
  36. "/SILENT",
  37. "/VERYSILENT",
  38. )
  39. // }
  40. // Safeguard in case we have requests in flight that need to drain...
  41. slog.Info("Waiting for server to shutdown")
  42. cancel()
  43. if done != nil {
  44. <-done
  45. } else {
  46. slog.Warn("XXX done chan was nil, not actually waiting")
  47. }
  48. slog.Debug(fmt.Sprintf("starting installer: %s %v", installerExe, installArgs))
  49. os.Chdir(filepath.Dir(UpgradeLogFile)) //nolint:errcheck
  50. cmd := exec.Command(installerExe, installArgs...)
  51. if err := cmd.Start(); err != nil {
  52. return fmt.Errorf("unable to start ollama app %w", err)
  53. }
  54. if cmd.Process != nil {
  55. err = cmd.Process.Release()
  56. if err != nil {
  57. slog.Error(fmt.Sprintf("failed to release server process: %s", err))
  58. }
  59. } else {
  60. // TODO - some details about why it didn't start, or is this a pedantic error case?
  61. return fmt.Errorf("installer process did not start")
  62. }
  63. // TODO should we linger for a moment and check to make sure it's actually running by checking the pid?
  64. slog.Info("Installer started in background, exiting")
  65. os.Exit(0)
  66. // Not reached
  67. return nil
  68. }