rename.go 2.9 KB

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