| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126 | package siteimport (	"fmt"	"net/http"	"os"	"runtime"	"sync"	"github.com/0xJacky/Nginx-UI/internal/helper"	"github.com/0xJacky/Nginx-UI/internal/nginx"	"github.com/0xJacky/Nginx-UI/internal/notification"	"github.com/0xJacky/Nginx-UI/query"	"github.com/go-resty/resty/v2"	"github.com/uozi-tech/cosy/logger")func Rename(oldName string, newName string) (err error) {	oldPath := nginx.GetConfPath("sites-available", oldName)	newPath := nginx.GetConfPath("sites-available", newName)	if oldPath == newPath {		return	}	// check if dst file exists, do not rename	if helper.FileExists(newPath) {		return ErrDstFileExists	}	s := query.Site	_, _ = s.Where(s.Path.Eq(oldPath)).Update(s.Path, newPath)	err = os.Rename(oldPath, newPath)	if err != nil {		return	}	// recreate a soft link	oldEnabledConfigFilePath := nginx.GetConfPath("sites-enabled", oldName)	if helper.SymbolLinkExists(oldEnabledConfigFilePath) {		_ = os.Remove(oldEnabledConfigFilePath)		newEnabledConfigFilePath := nginx.GetConfPath("sites-enabled", newName)		err = os.Symlink(newPath, newEnabledConfigFilePath)		if err != nil {			return		}	}	// test nginx configuration	output, err := nginx.TestConfig()	if err != nil {		return	}	if nginx.GetLogLevel(output) > nginx.Warn {		return fmt.Errorf("%s", output)	}	// reload nginx	output, err = nginx.Reload()	if err != nil {		return	}	if nginx.GetLogLevel(output) > nginx.Warn {		return fmt.Errorf("%s", output)	}	// update ChatGPT history	g := query.ChatGPTLog	_, _ = g.Where(g.Name.Eq(oldName)).Update(g.Name, newName)	// update config history	b := query.ConfigBackup	_, _ = b.Where(b.FilePath.Eq(oldPath)).Updates(map[string]interface{}{		"filepath": newPath,		"name":     newName,	})	go syncRename(oldName, newName)	return}func syncRename(oldName, newName string) {	nodes := getSyncNodes(newName)	wg := &sync.WaitGroup{}	wg.Add(len(nodes))	for _, node := range nodes {		go func() {			defer func() {				if err := recover(); err != nil {					buf := make([]byte, 1024)					runtime.Stack(buf, false)					logger.Error(err)				}			}()			defer wg.Done()			client := resty.New()			client.SetBaseURL(node.URL)			resp, err := client.R().				SetHeader("X-Node-Secret", node.Token).				SetBody(map[string]string{					"new_name": newName,				}).				Post(fmt.Sprintf("/api/sites/%s/rename", oldName))			if err != nil {				notification.Error("Rename Remote Site Error", err.Error(), nil)				return			}			if resp.StatusCode() != http.StatusOK {				notification.Error("Rename Remote Site Error", "Rename site %{name} to %{new_name} on %{node} failed",					NewSyncResult(node.Name, oldName, resp).						SetNewName(newName))				return			}			notification.Success("Rename Remote Site Success", "Rename site %{name} to %{new_name} on %{node} successfully",				NewSyncResult(node.Name, oldName, resp).					SetNewName(newName))		}()	}	wg.Wait()}
 |