Selaa lähdekoodia

fix(kernel): stop parent's program when restart

0xJacky 5 kuukautta sitten
vanhempi
commit
f44c44ccdf

+ 16 - 0
api/system/restart.go

@@ -0,0 +1,16 @@
+package system
+
+import (
+	"net/http"
+
+	"code.pfad.fr/risefront"
+	"github.com/gin-gonic/gin"
+)
+
+func Restart(c *gin.Context) {
+	risefront.Restart()
+
+	c.JSON(http.StatusOK, gin.H{
+		"message": "restarting...",
+	})
+}

+ 3 - 4
api/system/router.go

@@ -24,6 +24,9 @@ func InitPrivateRouter(r *gin.RouterGroup) {
 	r.GET("upgrade/current", GetCurrentVersion)
 
 	r.POST("system/port_scan", PortScan)
+
+	r.Any("system/stats", GetProcessStats)
+	r.Any("system/restart", Restart)
 }
 
 func InitSelfCheckRouter(r *gin.RouterGroup) {
@@ -34,10 +37,6 @@ func InitSelfCheckRouter(r *gin.RouterGroup) {
 	g.GET("timeout", middleware.Proxy(), TimeoutCheck)
 }
 
-func InitBackupRestoreRouter(r *gin.RouterGroup) {
-	// Backup and restore routes moved to api/backup package
-}
-
 func InitWebSocketRouter(r *gin.RouterGroup) {
 	r.GET("upgrade/perform", PerformCoreUpgrade)
 }

+ 16 - 0
api/system/stats.go

@@ -0,0 +1,16 @@
+package system
+
+import (
+	"net/http"
+	"os"
+
+	"github.com/gin-gonic/gin"
+)
+
+func GetProcessStats(c *gin.Context) {
+	pid := os.Getpid()
+
+	c.JSON(http.StatusOK, gin.H{
+		"pid": pid,
+	})
+}

Tiedoston diff-näkymää rajattu, sillä se on liian suuri
+ 182 - 175
app/src/language/ar/app.po


Tiedoston diff-näkymää rajattu, sillä se on liian suuri
+ 184 - 166
app/src/language/de_DE/app.po


Tiedoston diff-näkymää rajattu, sillä se on liian suuri
+ 129 - 130
app/src/language/en/app.po


Tiedoston diff-näkymää rajattu, sillä se on liian suuri
+ 170 - 158
app/src/language/es/app.po


Tiedoston diff-näkymää rajattu, sillä se on liian suuri
+ 190 - 171
app/src/language/fr_FR/app.po


Tiedoston diff-näkymää rajattu, sillä se on liian suuri
+ 227 - 157
app/src/language/ja_JP/app.po


Tiedoston diff-näkymää rajattu, sillä se on liian suuri
+ 209 - 163
app/src/language/ko_KR/app.po


Tiedoston diff-näkymää rajattu, sillä se on liian suuri
+ 130 - 131
app/src/language/messages.pot


Tiedoston diff-näkymää rajattu, sillä se on liian suuri
+ 171 - 156
app/src/language/pt_PT/app.po


Tiedoston diff-näkymää rajattu, sillä se on liian suuri
+ 174 - 166
app/src/language/ru_RU/app.po


Tiedoston diff-näkymää rajattu, sillä se on liian suuri
+ 181 - 168
app/src/language/tr_TR/app.po


Tiedoston diff-näkymää rajattu, sillä se on liian suuri
+ 189 - 176
app/src/language/uk_UA/app.po


Tiedoston diff-näkymää rajattu, sillä se on liian suuri
+ 178 - 169
app/src/language/vi_VN/app.po


Tiedoston diff-näkymää rajattu, sillä se on liian suuri
+ 188 - 157
app/src/language/zh_CN/app.po


Tiedoston diff-näkymää rajattu, sillä se on liian suuri
+ 190 - 159
app/src/language/zh_TW/app.po


+ 3 - 3
go.mod

@@ -47,7 +47,7 @@ require (
 	github.com/stretchr/testify v1.10.0
 	github.com/tufanbarisyildirim/gonginx v0.0.0-20250620092546-c3e307e36701
 	github.com/ulikunitz/xz v0.5.12
-	github.com/uozi-tech/cosy v1.25.6
+	github.com/uozi-tech/cosy v1.25.8
 	github.com/uozi-tech/cosy-driver-sqlite v0.2.1
 	github.com/urfave/cli/v3 v3.4.1
 	golang.org/x/crypto v0.41.0
@@ -354,7 +354,7 @@ require (
 	google.golang.org/api v0.245.0 // indirect
 	google.golang.org/genproto/googleapis/api v0.0.0-20250804133106-a7a43d27e69b // indirect
 	google.golang.org/genproto/googleapis/rpc v0.0.0-20250804133106-a7a43d27e69b // indirect
-	google.golang.org/protobuf v1.36.7 // indirect
+	google.golang.org/protobuf v1.36.8 // indirect
 	gopkg.in/natefinch/lumberjack.v2 v2.2.1 // indirect
 	gopkg.in/ns1/ns1-go.v2 v2.14.4 // indirect
 	gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 // indirect
@@ -369,7 +369,7 @@ require (
 )
 
 replace (
-	code.pfad.fr/risefront => github.com/nginxui/risefront v1.2.3
+	code.pfad.fr/risefront => github.com/nginxui/risefront v1.3.0
 	github.com/minio/selfupdate => github.com/nginxui/selfupdate v0.0.0-20250508140228-a7dab39cec4a
 	github.com/nikoksr/notify => github.com/nginxui/notify v0.0.0-20250509000747-c76622723eb1
 )

+ 7 - 0
go.sum

@@ -891,6 +891,7 @@ github.com/cenkalti/backoff/v5 v5.0.2/go.mod h1:rkhZdG3JZukswDf7f0cwqPNk4K0sa+F9
 github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
 github.com/census-instrumentation/opencensus-proto v0.3.0/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
 github.com/census-instrumentation/opencensus-proto v0.4.1/go.mod h1:4T9NM4+4Vw91VeyqjLS6ao50K5bOcLKN6Q42XnYaRYw=
+github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko=
 github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc=
 github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
 github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
@@ -1659,6 +1660,7 @@ github.com/nginxui/notify v0.0.0-20250509000747-c76622723eb1 h1:tTFu+N3ukz73Lv4L
 github.com/nginxui/notify v0.0.0-20250509000747-c76622723eb1/go.mod h1:5xiIPJd5HveRkca2gA8K//HLdupJuB7uHHBdzDQQN6g=
 github.com/nginxui/risefront v1.2.3 h1:UXVt+yzGtWyFHQsnLG3HJNv+RHllVyUEG7zHZryOpxE=
 github.com/nginxui/risefront v1.2.3/go.mod h1:QX3OyvazX3Mi/X2NZKl9ylDrFVUeaogwSMKyEsnRCHE=
+github.com/nginxui/risefront v1.3.0/go.mod h1:G2J7TdMAyBuzfWD1fCGkmPATbXElUCs+yeVJfrPXfPQ=
 github.com/nginxui/selfupdate v0.0.0-20250508140228-a7dab39cec4a h1:KNDT8WAMtclTjmHtlqvy02sXUPNxErKNcyB3bjTRsEM=
 github.com/nginxui/selfupdate v0.0.0-20250508140228-a7dab39cec4a/go.mod h1:bO02GTIPCMQFTEvE5h4DjYB58bCoZ35XLeBf0buTDdM=
 github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
@@ -1747,6 +1749,7 @@ github.com/phpdave11/gofpdf v1.4.2/go.mod h1:zpO6xFn9yxo3YLyMvW8HcKWVdbNqgIfOOp2
 github.com/phpdave11/gofpdi v1.0.12/go.mod h1:vBmVV0Do6hSBHC8uKUQ71JGW+ZGQq74llk/7bXwjDoI=
 github.com/phpdave11/gofpdi v1.0.13/go.mod h1:vBmVV0Do6hSBHC8uKUQ71JGW+ZGQq74llk/7bXwjDoI=
 github.com/pierrec/lz4 v1.0.2-0.20190131084431-473cd7ce01a1/go.mod h1:3/3N9NVKO0jef7pBehbT1qWhCMrIgbYNnFAZCqQ5LRc=
+github.com/pierrec/lz4 v2.6.1+incompatible h1:9UY3+iC23yxF0UfGaYrGplQ+79Rg+h/q9FV9ix19jjM=
 github.com/pierrec/lz4 v2.6.1+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY=
 github.com/pierrec/lz4/v4 v4.1.15/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4=
 github.com/pierrec/lz4/v4 v4.1.22 h1:cKFw6uJDK+/gfw5BcDL0JL5aBsAFdsIT18eRtLj7VIU=
@@ -1998,6 +2001,8 @@ github.com/ultradns/ultradns-go-sdk v1.8.1-20250722213956-faef419 h1:/VaznPrb/b6
 github.com/ultradns/ultradns-go-sdk v1.8.1-20250722213956-faef419/go.mod h1:QN0/PdenvYWB0GRMz6JJbPeZz2Lph2iys1p8AFVHm2c=
 github.com/uozi-tech/cosy v1.25.6 h1:a0wrGIGrDmEbXpxL85XC5J81nFjoIn5KNrj3oBS6M1A=
 github.com/uozi-tech/cosy v1.25.6/go.mod h1:eQ1upugkrOcNzwie9Ug8GRvPhU3vgGPGl3Be9lHjVh0=
+github.com/uozi-tech/cosy v1.25.8 h1:rsYFDFZmfRRzgvZQAilS38fHgizaDsno/Jfvrd0GUAI=
+github.com/uozi-tech/cosy v1.25.8/go.mod h1:eQ1upugkrOcNzwie9Ug8GRvPhU3vgGPGl3Be9lHjVh0=
 github.com/uozi-tech/cosy-driver-mysql v0.2.2 h1:22S/XNIvuaKGqxQPsYPXN8TZ8hHjCQdcJKVQ83Vzxoo=
 github.com/uozi-tech/cosy-driver-mysql v0.2.2/go.mod h1:EZnRIbSj1V5U0gEeTobrXai/d1SV11lkl4zP9NFEmyE=
 github.com/uozi-tech/cosy-driver-postgres v0.2.1 h1:OICakGuT+omva6QOJCxTJ5Lfr7CGXLmk/zD+aS51Z2o=
@@ -2937,6 +2942,8 @@ google.golang.org/protobuf v1.29.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqw
 google.golang.org/protobuf v1.30.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
 google.golang.org/protobuf v1.36.7 h1:IgrO7UwFQGJdRNXH/sQux4R1Dj1WAKcLElzeeRaXV2A=
 google.golang.org/protobuf v1.36.7/go.mod h1:jduwjTPXsFjZGTmRluh+L6NjiWu7pchiJ2/5YcXBHnY=
+google.golang.org/protobuf v1.36.8 h1:xHScyCOEuuwZEc6UtSOvPbAT4zRh0xcNRYekJwfqyMc=
+google.golang.org/protobuf v1.36.8/go.mod h1:fuxRtAxBytpl4zzqUh6/eyUujkJdNiuEkXntxiD/uRU=
 gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
 gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
 gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=

+ 3 - 1
internal/analytic/node_record.go

@@ -326,7 +326,9 @@ func RetrieveNodesStatus(ctx context.Context) {
 						continue
 					}
 					if err := nodeAnalyticRecord(n, ctx); err != nil {
-						logger.Error(err)
+						if helper.IsUnexpectedWebsocketError(err) {
+							logger.Error(err)
+						}
 						markConnectionFailure(n.ID, err)
 					} else {
 						markConnectionSuccess(n.ID)

+ 4 - 4
internal/cron/upstream_availability.go

@@ -40,13 +40,13 @@ func executeUpstreamAvailabilityTest() {
 		return
 	}
 
-	start := time.Now()
-	logger.Debug("Starting scheduled upstream availability test for", targetCount, "targets")
+	// start := time.Now()
+	// logger.Debug("Starting scheduled upstream availability test for", targetCount, "targets")
 
 	service.PerformAvailabilityTest()
 
-	duration := time.Since(start)
-	logger.Debug("Upstream availability test completed in", duration)
+	// duration := time.Since(start)
+	// logger.Debug("Upstream availability test completed in", duration)
 }
 
 // RestartUpstreamAvailabilityJob restarts the upstream availability job

+ 2 - 12
internal/kernel/boot.go

@@ -87,18 +87,8 @@ func InitAfterDatabase(ctx context.Context) {
 		analytic.RetrieveNodesStatus,
 		passkey.Init,
 		mcp.Init,
-		func(ctx context.Context) {
-			service := sitecheck.GetService()
-			service.Start()
-		},
-		func(ctx context.Context) {
-			// Initialize background log service
-			if err := nginx_log.InitBackgroundLogService(ctx); err != nil {
-				logger.Errorf("Failed to initialize background log service: %v", err)
-			} else {
-				logger.Info("Background log service initialized successfully")
-			}
-		},
+		sitecheck.Init,
+		nginx_log.InitBackgroundLogService,
 	}
 
 	for _, v := range asyncs {

+ 1 - 1
internal/middleware/ip_whitelist.go

@@ -11,7 +11,7 @@ import (
 func IPWhiteList() gin.HandlerFunc {
 	return func(c *gin.Context) {
 		clientIP := c.ClientIP()
-		if len(settings.AuthSettings.IPWhiteList) == 0 || clientIP == "127.0.0.1" || clientIP == "::1" {
+		if len(settings.AuthSettings.IPWhiteList) == 0 || clientIP == "" || clientIP == "127.0.0.1" || clientIP == "::1" {
 			c.Next()
 			return
 		}

+ 9 - 16
internal/nginx_log/background_service.go

@@ -18,8 +18,8 @@ type BackgroundLogService struct {
 }
 
 // NewBackgroundLogService creates a new background log service
-func NewBackgroundLogService() (*BackgroundLogService, error) {
-	indexer, err := NewLogIndexer()
+func NewBackgroundLogService(ctx context.Context) (*BackgroundLogService, error) {
+	indexer, err := NewLogIndexer(ctx)
 	if err != nil {
 		return nil, err
 	}
@@ -84,8 +84,6 @@ func (s *BackgroundLogService) discoverInitialLogs() {
 		logger.Warn("Access log path not available or not in whitelist")
 	}
 
-	// Skip error logs - they have different format and are not indexed for structured search
-
 	logger.Info("Initial log discovery completed")
 }
 
@@ -197,28 +195,23 @@ func (s *BackgroundLogService) loadExistingIndexes() {
 var backgroundService *BackgroundLogService
 
 // InitBackgroundLogService initializes the global background log service
-func InitBackgroundLogService(ctx context.Context) error {
+func InitBackgroundLogService(ctx context.Context) {
 	var err error
-	backgroundService, err = NewBackgroundLogService()
+	backgroundService, err = NewBackgroundLogService(ctx)
 	if err != nil {
-		return err
+		logger.Fatalf("Failed to initialize background log service: %v", err)
+		return
 	}
 
 	// Use the provided context instead of creating a new one
 	backgroundService.ctx, backgroundService.cancel = context.WithCancel(ctx)
 	backgroundService.Start()
-	return nil
+
+	<-ctx.Done()
+	backgroundService.Stop()
 }
 
 // GetBackgroundLogService returns the global background service instance
 func GetBackgroundLogService() *BackgroundLogService {
 	return backgroundService
 }
-
-// StopBackgroundLogService stops the global background log service
-func StopBackgroundLogService() {
-	if backgroundService != nil {
-		backgroundService.Stop()
-		backgroundService = nil
-	}
-}

+ 1 - 1
internal/nginx_log/indexer_file_management.go

@@ -172,4 +172,4 @@ func (li *LogIndexer) watchFiles() {
 			logger.Errorf("File watcher error: %v", err)
 		}
 	}
-}
+}

+ 16 - 16
internal/nginx_log/log_indexer_core.go

@@ -57,7 +57,7 @@ type LogIndexer struct {
 }
 
 // NewLogIndexer creates a new log indexer instance
-func NewLogIndexer() (*LogIndexer, error) {
+func NewLogIndexer(ctx context.Context) (*LogIndexer, error) {
 	// Use nginx-ui config directory for index storage
 	configDir := filepath.Dir(cosysettings.ConfPath)
 	if configDir == "" {
@@ -109,25 +109,25 @@ func NewLogIndexer() (*LogIndexer, error) {
 	}
 
 	// Create context for background processing
-	ctx, cancel := context.WithCancel(context.Background())
+	ctx, cancel := context.WithCancel(ctx)
 
 	// Create persistence manager
 	persistence := NewPersistenceManager()
 
 	indexer := &LogIndexer{
-		indexPath:      indexPath,
-		index:          index,
-		cache:          cache,
-		statsCache:     statsCache,
-		parser:         parser,
-		watcher:        watcher,
-		logPaths:       make(map[string]*LogFileInfo),
-		ctx:            ctx,
-		cancel:         cancel,
-		indexQueue:     make(chan *IndexTask, 1000),
-		persistence:    persistence,
-		maxCacheSize:   128 * 1024 * 1024, // 128MB
-		indexBatch:     1000,               // Process 1000 entries per batch
+		indexPath:    indexPath,
+		index:        index,
+		cache:        cache,
+		statsCache:   statsCache,
+		parser:       parser,
+		watcher:      watcher,
+		logPaths:     make(map[string]*LogFileInfo),
+		ctx:          ctx,
+		cancel:       cancel,
+		indexQueue:   make(chan *IndexTask, 1000),
+		persistence:  persistence,
+		maxCacheSize: 128 * 1024 * 1024, // 128MB
+		indexBatch:   1000,              // Process 1000 entries per batch
 	}
 
 	// Start background processing
@@ -275,4 +275,4 @@ func (li *LogIndexer) Close() error {
 
 	logger.Info("Log indexer closed successfully")
 	return nil
-}
+}

+ 20 - 1
internal/nginx_log/log_indexer_tasks.go

@@ -10,6 +10,17 @@ import (
 
 // debounceIndexTask implements file-level debouncing for index operations
 func (li *LogIndexer) debounceIndexTask(task *IndexTask) {
+	// First, check if the context is already cancelled
+	select {
+	case <-li.ctx.Done():
+		logger.Debugf("Debounce check cancelled for %s as context is done.", task.FilePath)
+		if task.Wg != nil {
+			task.Wg.Done()
+		}
+		return
+	default:
+	}
+
 	filePath := task.FilePath
 
 	// Check if we need to respect the minimum interval
@@ -50,6 +61,14 @@ func (li *LogIndexer) executeIndexTask(task *IndexTask) {
 	// Update last index time before processing
 	li.lastIndexTime.Store(task.FilePath, time.Now())
 
+	// Check if context is still valid
+	select {
+	case <-li.ctx.Done():
+		logger.Warnf("Index task cancelled for file: %s", task.FilePath)
+		return
+	default:
+	}
+
 	// Queue the task for processing
 	select {
 	case li.indexQueue <- task:
@@ -99,4 +118,4 @@ func (li *LogIndexer) processIndexTask(task *IndexTask) {
 		logger.Infof("Successfully indexed file: %s", task.FilePath)
 		// Note: Log group notifications are handled centrally after all files complete
 	}
-}
+}

+ 5 - 5
internal/sitecheck/checker.go

@@ -87,20 +87,20 @@ func (sc *SiteChecker) CollectSites() {
 		// Check site status - only collect from enabled sites
 		siteStatus := site.GetSiteStatus(siteName)
 		if siteStatus != site.SiteStatusEnabled {
-			logger.Debugf("Skipping site %s (status: %s) - only collecting from enabled sites", siteName, siteStatus)
+			// logger.Debugf("Skipping site %s (status: %s) - only collecting from enabled sites", siteName, siteStatus)
 			continue
 		}
 
-		logger.Debugf("Processing enabled site: %s with %d URLs", siteName, len(indexedSite.Urls))
+		// logger.Debugf("Processing enabled site: %s with %d URLs", siteName, len(indexedSite.Urls))
 		for _, url := range indexedSite.Urls {
 			if url != "" {
-				logger.Debugf("Adding site URL: %s", url)
+				// logger.Debugf("Adding site URL: %s", url)
 				// Load site config to determine display URL
 				config, err := LoadSiteConfig(url)
 				protocol := "http" // default protocol
 				if err == nil && config != nil && config.HealthCheckConfig != nil && config.HealthCheckConfig.Protocol != "" {
 					protocol = config.HealthCheckConfig.Protocol
-					logger.Debugf("Site %s using protocol: %s", url, protocol)
+					// logger.Debugf("Site %s using protocol: %s", url, protocol)
 				} else {
 					logger.Debugf("Site %s using default protocol: %s (config error: %v)", url, protocol, err)
 				}
@@ -371,7 +371,7 @@ func (sc *SiteChecker) CheckAllSites(ctx context.Context) {
 	}
 
 	wg.Wait()
-	logger.Infof("Completed checking %d sites", len(urls))
+	// logger.Infof("Completed checking %d sites", len(urls))
 
 	// Notify WebSocket clients of the update
 	if sc.onUpdateCallback != nil {

+ 9 - 6
internal/sitecheck/service.go

@@ -20,20 +20,23 @@ type Service struct {
 
 var (
 	globalService *Service
-	serviceOnce   sync.Once
 )
 
+// Init initializes the site checking service
+func Init(ctx context.Context) {
+	globalService = NewService(ctx, DefaultCheckOptions())
+
+	globalService.Start()
+}
+
 // GetService returns the singleton service instance
 func GetService() *Service {
-	serviceOnce.Do(func() {
-		globalService = NewService(DefaultCheckOptions())
-	})
 	return globalService
 }
 
 // NewService creates a new site checking service
-func NewService(options CheckOptions) *Service {
-	return NewServiceWithContext(context.Background(), options)
+func NewService(ctx context.Context, options CheckOptions) *Service {
+	return NewServiceWithContext(ctx, options)
 }
 
 // NewServiceWithContext creates a new site checking service with a parent context

+ 1 - 1
internal/upstream/service.go

@@ -234,7 +234,7 @@ func (s *UpstreamService) PerformAvailabilityTest() {
 		return
 	}
 
-	logger.Debug("Performing availability test for", targetCount, "unique targets")
+	// logger.Debug("Performing availability test for", targetCount, "unique targets")
 
 	// Separate targets into traditional and consul groups from the start
 	s.targetsMutex.RLock()

+ 30 - 10
main.go

@@ -29,9 +29,6 @@ import (
 
 func Program(ctx context.Context, confPath string) func(l []net.Listener) error {
 	return func(l []net.Listener) error {
-		ctx, cancel := context.WithCancel(ctx)
-		defer cancel()
-
 		listener := l[0]
 
 		cosy.RegisterMigrationsBeforeAutoMigrate(migrate.BeforeAutoMigrate)
@@ -103,20 +100,29 @@ func Program(ctx context.Context, confPath string) func(l []net.Listener) error
 			return err
 		}
 
+		go func() {
+			// Wait for context cancellation
+			<-ctx.Done()
+
+			// Graceful shutdown
+			logger.Info("Shutting down servers...")
+			if err := serverFactory.Shutdown(ctx); err != nil {
+				logger.Errorf("Error during server shutdown: %v", err)
+			}
+		}()
+
 		// Start the servers
 		if err := serverFactory.Start(ctx, listener); err != nil {
 			logger.Fatalf("Failed to start servers: %v", err)
 			return err
 		}
 
-		// Wait for context cancellation
 		<-ctx.Done()
 
 		// Graceful shutdown
 		logger.Info("Shutting down servers...")
 		if err := serverFactory.Shutdown(ctx); err != nil {
 			logger.Errorf("Error during server shutdown: %v", err)
-			return err
 		}
 
 		return nil
@@ -130,8 +136,8 @@ func main() {
 	confPath := appCmd.String("config")
 	settings.Init(confPath)
 
-	ctx, cancel := signal.NotifyContext(context.Background(), syscall.SIGHUP, syscall.SIGINT, syscall.SIGTERM)
-	defer cancel()
+	mainCtx, mainCancel := signal.NotifyContext(context.Background(), syscall.SIGHUP, syscall.SIGINT, syscall.SIGTERM)
+	defer mainCancel()
 
 	pidPath := appCmd.String("pidfile")
 	if pidPath != "" {
@@ -141,11 +147,25 @@ func main() {
 		defer process.RemovePIDFile(pidPath)
 	}
 
-	err := risefront.New(ctx, risefront.Config{
-		Run:       Program(ctx, confPath),
+	var programCancel context.CancelFunc
+
+	err := risefront.New(mainCtx, risefront.Config{
+		Run: func(l []net.Listener) error {
+			// Create a new context for the program itself, derived from the main context.
+			programCtx, cancel := context.WithCancel(mainCtx)
+			// Store the cancel function so the Shutdown callback can use it.
+			programCancel = cancel
+			return Program(programCtx, confPath)(l)
+		},
+		Shutdown: func() {
+			// This is called by risefront.Restart() to shut down the old program.
+			if programCancel != nil {
+				programCancel()
+			}
+		},
 		Name:      "nginx-ui",
 		Addresses: []string{fmt.Sprintf("%s:%d", cSettings.ServerSettings.Host, cSettings.ServerSettings.Port)},
-		LogHandler: func(loglevel risefront.LogLevel, kind string, args ...interface{}) {
+		LogHandler: func(loglevel risefront.LogLevel, kind string, args ...any) {
 			switch loglevel {
 			case risefront.DebugLevel:
 				logger.Debugf(kind, args...)

+ 2 - 1
router/routers.go

@@ -37,6 +37,8 @@ import (
 func InitRouter() {
 	r := cosy.GetEngine()
 
+	r.SetTrustedProxies(nil)
+
 	// Add CORS middleware to allow all origins
 	r.Use(middleware.CORS())
 
@@ -59,7 +61,6 @@ func InitRouter() {
 		user.InitAuthRouter(root)
 
 		system.InitPublicRouter(root)
-		system.InitBackupRestoreRouter(root)
 		system.InitSelfCheckRouter(root)
 		backup.InitRouter(root)
 

Kaikkia tiedostoja ei voida näyttää, sillä liian monta tiedostoa muuttui tässä diffissä