rename.go 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127
  1. package stream
  2. import (
  3. "fmt"
  4. "net/http"
  5. "os"
  6. "runtime"
  7. "sync"
  8. "github.com/0xJacky/Nginx-UI/internal/helper"
  9. "github.com/0xJacky/Nginx-UI/internal/nginx"
  10. "github.com/0xJacky/Nginx-UI/internal/notification"
  11. "github.com/0xJacky/Nginx-UI/query"
  12. "github.com/go-resty/resty/v2"
  13. "github.com/uozi-tech/cosy"
  14. "github.com/uozi-tech/cosy/logger"
  15. )
  16. func Rename(oldName string, newName string) (err error) {
  17. oldPath := nginx.GetConfPath("streams-available", oldName)
  18. newPath := nginx.GetConfPath("streams-available", newName)
  19. if oldPath == newPath {
  20. return
  21. }
  22. // check if dst file exists, do not rename
  23. if helper.FileExists(newPath) {
  24. return ErrDstFileExists
  25. }
  26. s := query.Site
  27. _, _ = s.Where(s.Path.Eq(oldPath)).Update(s.Path, newPath)
  28. err = os.Rename(oldPath, newPath)
  29. if err != nil {
  30. return
  31. }
  32. // recreate a soft link
  33. oldEnabledConfigFilePath := nginx.GetConfPath("streams-enabled", oldName)
  34. if helper.SymbolLinkExists(oldEnabledConfigFilePath) {
  35. _ = os.Remove(oldEnabledConfigFilePath)
  36. newEnabledConfigFilePath := nginx.GetConfPath("streams-enabled", newName)
  37. err = os.Symlink(newPath, newEnabledConfigFilePath)
  38. if err != nil {
  39. return
  40. }
  41. }
  42. // test nginx configuration
  43. output, err := nginx.TestConfig()
  44. if err != nil {
  45. return
  46. }
  47. if nginx.GetLogLevel(output) > nginx.Warn {
  48. return cosy.WrapErrorWithParams(ErrNginxTestFailed, output)
  49. }
  50. // reload nginx
  51. output, err = nginx.Reload()
  52. if err != nil {
  53. return
  54. }
  55. if nginx.GetLogLevel(output) > nginx.Warn {
  56. return cosy.WrapErrorWithParams(ErrNginxReloadFailed, output)
  57. }
  58. // update ChatGPT history
  59. g := query.ChatGPTLog
  60. _, _ = g.Where(g.Name.Eq(oldName)).Update(g.Name, newName)
  61. // update config history
  62. b := query.ConfigBackup
  63. _, _ = b.Where(b.FilePath.Eq(oldPath)).Updates(map[string]interface{}{
  64. "filepath": newPath,
  65. "name": newName,
  66. })
  67. go syncRename(oldName, newName)
  68. return
  69. }
  70. func syncRename(oldName, newName string) {
  71. nodes := getSyncNodes(newName)
  72. wg := &sync.WaitGroup{}
  73. wg.Add(len(nodes))
  74. for _, node := range nodes {
  75. go func() {
  76. defer func() {
  77. if err := recover(); err != nil {
  78. buf := make([]byte, 1024)
  79. runtime.Stack(buf, false)
  80. logger.Error(err)
  81. }
  82. }()
  83. defer wg.Done()
  84. client := resty.New()
  85. client.SetBaseURL(node.URL)
  86. resp, err := client.R().
  87. SetHeader("X-Node-Secret", node.Token).
  88. SetBody(map[string]string{
  89. "new_name": newName,
  90. }).
  91. Post(fmt.Sprintf("/api/streams/%s/rename", oldName))
  92. if err != nil {
  93. notification.Error("Rename Remote Stream Error", err.Error(), nil)
  94. return
  95. }
  96. if resp.StatusCode() != http.StatusOK {
  97. notification.Error("Rename Remote Stream Error", "Rename stream %{name} to %{new_name} on %{node} failed",
  98. NewSyncResult(node.Name, oldName, resp).
  99. SetNewName(newName))
  100. return
  101. }
  102. notification.Success("Rename Remote Stream Success", "Rename stream %{name} to %{new_name} on %{node} successfully",
  103. NewSyncResult(node.Name, oldName, resp).
  104. SetNewName(newName))
  105. }()
  106. }
  107. wg.Wait()
  108. }