assets.go 1.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667
  1. package gpu
  2. import (
  3. "fmt"
  4. "log/slog"
  5. "os"
  6. "path/filepath"
  7. "runtime"
  8. "strings"
  9. "sync"
  10. )
  11. var (
  12. lock sync.Mutex
  13. payloadsDir = ""
  14. )
  15. func PayloadsDir() (string, error) {
  16. lock.Lock()
  17. defer lock.Unlock()
  18. if payloadsDir == "" {
  19. tmpDir, err := os.MkdirTemp("", "ollama")
  20. if err != nil {
  21. return "", fmt.Errorf("failed to generate tmp dir: %w", err)
  22. }
  23. // We create a distinct subdirectory for payloads within the tmpdir
  24. // This will typically look like /tmp/ollama3208993108/runners on linux
  25. payloadsDir = filepath.Join(tmpDir, "runners")
  26. }
  27. return payloadsDir, nil
  28. }
  29. func Cleanup() {
  30. lock.Lock()
  31. defer lock.Unlock()
  32. if payloadsDir != "" {
  33. // We want to fully clean up the tmpdir parent of the payloads dir
  34. tmpDir := filepath.Clean(filepath.Join(payloadsDir, ".."))
  35. slog.Debug("cleaning up", "dir", tmpDir)
  36. err := os.RemoveAll(tmpDir)
  37. if err != nil {
  38. slog.Warn("failed to clean up", "dir", tmpDir, "err", err)
  39. }
  40. }
  41. }
  42. func UpdatePath(dir string) {
  43. if runtime.GOOS == "windows" {
  44. tmpDir := filepath.Dir(dir)
  45. pathComponents := strings.Split(os.Getenv("PATH"), ";")
  46. i := 0
  47. for _, comp := range pathComponents {
  48. if strings.EqualFold(comp, dir) {
  49. return
  50. }
  51. // Remove any other prior paths to our temp dir
  52. if !strings.HasPrefix(strings.ToLower(comp), strings.ToLower(tmpDir)) {
  53. pathComponents[i] = comp
  54. i++
  55. }
  56. }
  57. newPath := strings.Join(append([]string{dir}, pathComponents...), ";")
  58. slog.Info(fmt.Sprintf("Updating PATH to %s", newPath))
  59. os.Setenv("PATH", newPath)
  60. }
  61. // linux and darwin rely on rpath
  62. }