feat(env_group): add post-sync action to environment and stream configurations #725

This commit is contained in:
Jacky 2025-04-05 10:55:26 +00:00
parent c0f0980e9e
commit 94fcbf6362
No known key found for this signature in database
GPG key ID: 215C21B10DF38B4D
31 changed files with 606 additions and 337 deletions

View file

@ -17,7 +17,7 @@ import (
)
// Save saves a site configuration file
func Save(name string, content string, overwrite bool, envGroupId uint64, syncNodeIds []uint64) (err error) {
func Save(name string, content string, overwrite bool, envGroupId uint64, syncNodeIds []uint64, postAction string) (err error) {
path := nginx.GetConfPath("sites-available", name)
if !overwrite && helper.FileExists(path) {
return ErrDstFileExists
@ -37,10 +37,11 @@ func Save(name string, content string, overwrite bool, envGroupId uint64, syncNo
return fmt.Errorf("%s", output)
}
output = nginx.Reload()
if nginx.GetLogLevel(output) > nginx.Warn {
return fmt.Errorf("%s", output)
if postAction == model.PostSyncActionReloadNginx {
output = nginx.Reload()
if nginx.GetLogLevel(output) > nginx.Warn {
return fmt.Errorf("%s", output)
}
}
}
@ -61,13 +62,17 @@ func Save(name string, content string, overwrite bool, envGroupId uint64, syncNo
}
func syncSave(name string, content string) {
nodes := getSyncNodes(name)
nodes, postSyncAction := getSyncData(name)
wg := &sync.WaitGroup{}
wg.Add(len(nodes))
// Map to track successful nodes for potential post-sync action
successfulNodes := make([]*model.Environment, 0)
var nodesMutex sync.Mutex
for _, node := range nodes {
go func() {
go func(node *model.Environment) {
defer func() {
if err := recover(); err != nil {
buf := make([]byte, 1024)
@ -82,8 +87,9 @@ func syncSave(name string, content string) {
resp, err := client.R().
SetHeader("X-Node-Secret", node.Token).
SetBody(map[string]interface{}{
"content": content,
"overwrite": true,
"content": content,
"overwrite": true,
"post_action": postSyncAction,
}).
Post(fmt.Sprintf("/api/sites/%s", name))
if err != nil {
@ -96,12 +102,17 @@ func syncSave(name string, content string) {
}
notification.Success("Save Remote Site Success", "Save site %{name} to %{node} successfully", NewSyncResult(node.Name, name, resp))
// Track successful sync for post-sync action
nodesMutex.Lock()
successfulNodes = append(successfulNodes, node)
nodesMutex.Unlock()
// Check if the site is enabled, if so then enable it on the remote node
enabledConfigFilePath := nginx.GetConfPath("sites-enabled", name)
if helper.FileExists(enabledConfigFilePath) {
syncEnable(name)
}
}()
}(node)
}
wg.Wait()

View file

@ -2,6 +2,7 @@ package site
import (
"encoding/json"
"github.com/0xJacky/Nginx-UI/internal/nginx"
"github.com/0xJacky/Nginx-UI/model"
"github.com/0xJacky/Nginx-UI/query"
@ -11,8 +12,8 @@ import (
"github.com/uozi-tech/cosy/logger"
)
// getSyncNodes returns the nodes that need to be synchronized by site name
func getSyncNodes(name string) (nodes []*model.Environment) {
// getSyncData returns the nodes that need to be synchronized by site name and the post-sync action
func getSyncData(name string) (nodes []*model.Environment, postSyncAction string) {
configFilePath := nginx.GetConfPath("sites-available", name)
s := query.Site
site, err := s.Where(s.Path.Eq(configFilePath)).
@ -26,6 +27,7 @@ func getSyncNodes(name string) (nodes []*model.Environment) {
// inherit sync node ids from site category
if site.EnvGroup != nil {
syncNodeIds = append(syncNodeIds, site.EnvGroup.SyncNodeIds...)
postSyncAction = site.EnvGroup.PostSyncAction
}
syncNodeIds = lo.Uniq(syncNodeIds)
@ -38,6 +40,12 @@ func getSyncNodes(name string) (nodes []*model.Environment) {
return
}
// getSyncNodes returns the nodes that need to be synchronized by site name (for backward compatibility)
func getSyncNodes(name string) (nodes []*model.Environment) {
nodes, _ = getSyncData(name)
return
}
type SyncResult struct {
StatusCode int `json:"status_code"`
Node string `json:"node"`