fix: standardize log prefixes, remove duplicates, add missing module tags
Second-pass logging cleanup: consistent [LEVEL] [module] format across all 41 files. Remove stale prefixes ([CF], [SYNC], [SCHED], [API], [STORAGE], [HEALTH], [ROLLBACK]). Remove 5 duplicate log lines. Gate ungated DEBUG lines. Fix wrong log levels (restore start WARN→INFO). Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -152,9 +152,6 @@ func (am *AlertManager) Refresh(report *monitor.HealthReport, cfg *config.Config
|
||||
am.mu.Lock()
|
||||
am.alerts = alerts
|
||||
am.mu.Unlock()
|
||||
|
||||
am.logger.Printf("[DEBUG] AlertManager refreshed: %d alerts (%d error, %d warning)",
|
||||
len(alerts), countLevel(alerts, "error"), countLevel(alerts, "warning"))
|
||||
}
|
||||
|
||||
// GetAlerts returns a copy of the current alerts, optionally excluding specific IDs.
|
||||
|
||||
@@ -140,7 +140,7 @@ func (s *Server) handleLogin(w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
if attempt != nil && attempt.count >= loginMaxAttempts {
|
||||
s.loginAttemptMu.Unlock()
|
||||
s.logger.Printf("[WARN] Login rate limited for %s (%d attempts)", ip, attempt.count)
|
||||
s.logger.Printf("[WARN] [web] Login rate limited for %s (%d attempts)", ip, attempt.count)
|
||||
s.renderLogin(w, "Túl sok sikertelen próbálkozás, próbálja újra 1 perc múlva", "")
|
||||
return
|
||||
}
|
||||
@@ -148,7 +148,7 @@ func (s *Server) handleLogin(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
effectiveHash := s.effectivePasswordHash()
|
||||
if err := bcrypt.CompareHashAndPassword([]byte(effectiveHash), []byte(password)); err != nil {
|
||||
s.logger.Printf("[WARN] Failed login from %s", r.RemoteAddr)
|
||||
s.logger.Printf("[WARN] [web] Failed login from %s", r.RemoteAddr)
|
||||
s.loginAttemptMu.Lock()
|
||||
if s.loginAttempts[ip] == nil {
|
||||
s.loginAttempts[ip] = &loginAttempt{}
|
||||
@@ -181,7 +181,7 @@ func (s *Server) handleLogin(w http.ResponseWriter, r *http.Request) {
|
||||
Secure: isSecure,
|
||||
})
|
||||
|
||||
s.logger.Printf("[INFO] Login from %s", r.RemoteAddr)
|
||||
s.logger.Printf("[INFO] [web] Login from %s", r.RemoteAddr)
|
||||
|
||||
// Redirect to ?next= target if provided, otherwise to dashboard
|
||||
redirectTo := "/"
|
||||
@@ -260,9 +260,6 @@ func (s *Server) invalidateAllSessions() {
|
||||
s.sessions = make(map[string]*session)
|
||||
s.sessionsMu.Unlock()
|
||||
s.logger.Printf("[INFO] [web] All sessions invalidated (cleared %d)", count)
|
||||
if s.isDebug() {
|
||||
s.logger.Printf("[DEBUG] [web] invalidated all sessions (cleared %d)", count)
|
||||
}
|
||||
}
|
||||
|
||||
func (s *Server) cleanupSessions() {
|
||||
@@ -310,7 +307,7 @@ func (s *Server) renderLogin(w http.ResponseWriter, errorMsg, flashMsg string) {
|
||||
}
|
||||
w.Header().Set("Content-Type", "text/html; charset=utf-8")
|
||||
if err := s.tmpl.ExecuteTemplate(w, "login", data); err != nil {
|
||||
s.logger.Printf("[ERROR] Template error (login): %v", err)
|
||||
s.logger.Printf("[ERROR] [web] Template error (login): %v", err)
|
||||
http.Error(w, "Internal error", http.StatusInternalServerError)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -95,14 +95,14 @@ func (s *Server) apiExportEstimate(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
stackName := r.URL.Query().Get("stack")
|
||||
drive := r.URL.Query().Get("drive")
|
||||
s.logger.Printf("[DEBUG] [handler_export] apiExportEstimate: stack=%q drive=%q", stackName, drive)
|
||||
s.logger.Printf("[DEBUG] [web] apiExportEstimate: stack=%q drive=%q", stackName, drive)
|
||||
if stackName == "" || drive == "" {
|
||||
jsonError(w, "Missing stack or drive parameter", http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
if !s.isValidDrivePath(drive) {
|
||||
s.logger.Printf("[DEBUG] [handler_export] apiExportEstimate: invalid drive path %q", drive)
|
||||
s.logger.Printf("[DEBUG] [web] apiExportEstimate: invalid drive path %q", drive)
|
||||
jsonError(w, "Invalid drive path", http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
@@ -110,12 +110,12 @@ func (s *Server) apiExportEstimate(w http.ResponseWriter, r *http.Request) {
|
||||
est, err := s.appExporter.EstimateExport(stackName, drive)
|
||||
if err != nil {
|
||||
s.logger.Printf("[ERROR] [web] Export estimate failed for %s: %v", stackName, err)
|
||||
s.logger.Printf("[DEBUG] [handler_export] apiExportEstimate error: %v", err)
|
||||
s.logger.Printf("[DEBUG] [web] apiExportEstimate error: %v", err)
|
||||
jsonError(w, err.Error(), http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
||||
s.logger.Printf("[DEBUG] [handler_export] apiExportEstimate: total=%s free=%s fits=%v",
|
||||
s.logger.Printf("[DEBUG] [web] apiExportEstimate: total=%s free=%s fits=%v",
|
||||
est.TotalSizeHuman, est.DestFreeHuman, est.FitsOnDest)
|
||||
jsonResponse(w, map[string]interface{}{
|
||||
"ok": true,
|
||||
@@ -137,12 +137,12 @@ func (s *Server) apiExportStart(w http.ResponseWriter, r *http.Request) {
|
||||
StopApp bool `json:"stop_app"`
|
||||
}
|
||||
if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
|
||||
s.logger.Printf("[DEBUG] [handler_export] apiExportStart: invalid body: %v", err)
|
||||
s.logger.Printf("[DEBUG] [web] apiExportStart: invalid body: %v", err)
|
||||
jsonError(w, "Invalid request body", http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
s.logger.Printf("[DEBUG] [handler_export] apiExportStart: stack=%q drive=%q encrypted=%v stopApp=%v",
|
||||
s.logger.Printf("[DEBUG] [web] apiExportStart: stack=%q drive=%q encrypted=%v stopApp=%v",
|
||||
req.StackName, req.DestDrive, req.Password != "", req.StopApp)
|
||||
|
||||
if req.StackName == "" || req.DestDrive == "" {
|
||||
@@ -151,7 +151,7 @@ func (s *Server) apiExportStart(w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
|
||||
if !s.isValidDrivePath(req.DestDrive) {
|
||||
s.logger.Printf("[DEBUG] [handler_export] apiExportStart: invalid drive path %q", req.DestDrive)
|
||||
s.logger.Printf("[DEBUG] [web] apiExportStart: invalid drive path %q", req.DestDrive)
|
||||
jsonError(w, "Invalid drive path", http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
@@ -164,12 +164,12 @@ func (s *Server) apiExportStart(w http.ResponseWriter, r *http.Request) {
|
||||
})
|
||||
if err != nil {
|
||||
s.logger.Printf("[ERROR] [web] Export start failed for %s: %v", req.StackName, err)
|
||||
s.logger.Printf("[DEBUG] [handler_export] apiExportStart error: %v", err)
|
||||
s.logger.Printf("[DEBUG] [web] apiExportStart error: %v", err)
|
||||
jsonError(w, err.Error(), http.StatusConflict)
|
||||
return
|
||||
}
|
||||
|
||||
s.logger.Printf("[INFO] Export started for %s to %s", req.StackName, req.DestDrive)
|
||||
s.logger.Printf("[INFO] [web] Export started for %s to %s", req.StackName, req.DestDrive)
|
||||
jsonResponse(w, map[string]interface{}{"ok": true})
|
||||
}
|
||||
|
||||
@@ -230,23 +230,23 @@ func (s *Server) apiExportManifest(w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
s.logger.Printf("[DEBUG] [handler_export] apiExportManifest: path=%q hasPassword=%v", req.Path, req.Password != "")
|
||||
s.logger.Printf("[DEBUG] [web] apiExportManifest: path=%q hasPassword=%v", req.Path, req.Password != "")
|
||||
|
||||
// Security: validate path is within a registered exports directory
|
||||
if !s.isValidExportPath(req.Path) {
|
||||
s.logger.Printf("[DEBUG] [handler_export] apiExportManifest: invalid path %q", req.Path)
|
||||
s.logger.Printf("[DEBUG] [web] apiExportManifest: invalid path %q", req.Path)
|
||||
jsonError(w, "Invalid bundle path", http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
encrypted, _ := appexport.IsEncryptedFAB(req.Path)
|
||||
s.logger.Printf("[DEBUG] [handler_export] apiExportManifest: encrypted=%v", encrypted)
|
||||
s.logger.Printf("[DEBUG] [web] apiExportManifest: encrypted=%v", encrypted)
|
||||
|
||||
var manifest *appexport.Manifest
|
||||
var err error
|
||||
if encrypted {
|
||||
if req.Password == "" {
|
||||
s.logger.Printf("[DEBUG] [handler_export] apiExportManifest: encrypted, needs password")
|
||||
s.logger.Printf("[DEBUG] [web] apiExportManifest: encrypted, needs password")
|
||||
jsonResponse(w, map[string]interface{}{
|
||||
"ok": true,
|
||||
"encrypted": true,
|
||||
@@ -260,12 +260,12 @@ func (s *Server) apiExportManifest(w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
s.logger.Printf("[DEBUG] [handler_export] apiExportManifest: error: %v", err)
|
||||
s.logger.Printf("[DEBUG] [web] apiExportManifest: error: %v", err)
|
||||
jsonError(w, err.Error(), http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
s.logger.Printf("[DEBUG] [handler_export] apiExportManifest: app=%s display=%s size=%d",
|
||||
s.logger.Printf("[DEBUG] [web] apiExportManifest: app=%s display=%s size=%d",
|
||||
manifest.AppName, manifest.DisplayName, manifest.TotalSizeBytes)
|
||||
jsonResponse(w, map[string]interface{}{
|
||||
"ok": true,
|
||||
@@ -285,12 +285,12 @@ func (s *Server) apiImportStart(w http.ResponseWriter, r *http.Request) {
|
||||
Password string `json:"password"`
|
||||
}
|
||||
if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
|
||||
s.logger.Printf("[DEBUG] [handler_export] apiImportStart: invalid body: %v", err)
|
||||
s.logger.Printf("[DEBUG] [web] apiImportStart: invalid body: %v", err)
|
||||
jsonError(w, "Invalid request body", http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
s.logger.Printf("[DEBUG] [handler_export] apiImportStart: path=%q hasPassword=%v", req.Path, req.Password != "")
|
||||
s.logger.Printf("[DEBUG] [web] apiImportStart: path=%q hasPassword=%v", req.Path, req.Password != "")
|
||||
|
||||
if req.Path == "" {
|
||||
jsonError(w, "Missing path", http.StatusBadRequest)
|
||||
@@ -298,7 +298,7 @@ func (s *Server) apiImportStart(w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
|
||||
if !s.isValidExportPath(req.Path) {
|
||||
s.logger.Printf("[DEBUG] [handler_export] apiImportStart: invalid path %q", req.Path)
|
||||
s.logger.Printf("[DEBUG] [web] apiImportStart: invalid path %q", req.Path)
|
||||
jsonError(w, "Invalid bundle path", http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
@@ -309,12 +309,12 @@ func (s *Server) apiImportStart(w http.ResponseWriter, r *http.Request) {
|
||||
})
|
||||
if err != nil {
|
||||
s.logger.Printf("[ERROR] [web] Import start failed for %s: %v", req.Path, err)
|
||||
s.logger.Printf("[DEBUG] [handler_export] apiImportStart error: %v", err)
|
||||
s.logger.Printf("[DEBUG] [web] apiImportStart error: %v", err)
|
||||
jsonError(w, err.Error(), http.StatusConflict)
|
||||
return
|
||||
}
|
||||
|
||||
s.logger.Printf("[INFO] Import started from %s", req.Path)
|
||||
s.logger.Printf("[INFO] [web] Import started from %s", req.Path)
|
||||
jsonResponse(w, map[string]interface{}{"ok": true})
|
||||
}
|
||||
|
||||
|
||||
@@ -111,7 +111,7 @@ func (s *Server) apiRestoreSkip(w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
s.logger.Println("[INFO] User skipped DR restore — entering normal mode")
|
||||
s.logger.Println("[INFO] [web] User skipped DR restore — entering normal mode")
|
||||
s.clearRestoreMode()
|
||||
|
||||
jsonResponse(w, map[string]interface{}{
|
||||
@@ -122,14 +122,14 @@ func (s *Server) apiRestoreSkip(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
// executeAllRestores runs the restore for each pending app sequentially.
|
||||
func (s *Server) executeAllRestores() {
|
||||
s.logger.Println("[INFO] Starting DR restore for all apps")
|
||||
s.logger.Println("[INFO] [web] Starting DR restore for all apps")
|
||||
restoreStart := time.Now()
|
||||
|
||||
s.restoreMu.RLock()
|
||||
plan := s.restorePlan
|
||||
s.restoreMu.RUnlock()
|
||||
if plan == nil {
|
||||
s.logger.Println("[WARN] Restore plan cleared before execution could start")
|
||||
s.logger.Println("[WARN] [web] Restore plan cleared before execution could start")
|
||||
return
|
||||
}
|
||||
|
||||
@@ -155,7 +155,7 @@ func (s *Server) executeAllRestores() {
|
||||
}
|
||||
|
||||
plan.UpdateApp(app.Name, "restoring", "")
|
||||
s.logger.Printf("[INFO] Restoring app %s (%s)", app.Name, app.DisplayName)
|
||||
s.logger.Printf("[INFO] [web] Restoring app %s (%s)", app.Name, app.DisplayName)
|
||||
appStart := time.Now()
|
||||
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Minute)
|
||||
@@ -164,14 +164,14 @@ func (s *Server) executeAllRestores() {
|
||||
|
||||
if err != nil {
|
||||
plan.UpdateApp(app.Name, "failed", err.Error())
|
||||
s.logger.Printf("[ERROR] Restore failed for %s: %v", app.Name, err)
|
||||
s.logger.Printf("[ERROR] [web] Restore failed for %s: %v", app.Name, err)
|
||||
if s.isDebug() {
|
||||
s.logger.Printf("[DEBUG] [web] executeAllRestores: app=%s failed after %s", app.Name, time.Since(appStart))
|
||||
}
|
||||
failCount++
|
||||
} else {
|
||||
plan.UpdateApp(app.Name, "done", "")
|
||||
s.logger.Printf("[INFO] Restore completed for %s", app.Name)
|
||||
s.logger.Printf("[INFO] [web] Restore completed for %s", app.Name)
|
||||
if s.isDebug() {
|
||||
s.logger.Printf("[DEBUG] [web] executeAllRestores: app=%s completed in %s", app.Name, time.Since(appStart))
|
||||
}
|
||||
@@ -180,7 +180,7 @@ func (s *Server) executeAllRestores() {
|
||||
}
|
||||
|
||||
plan.SetStatus("done")
|
||||
s.logger.Println("[INFO] All app restores completed")
|
||||
s.logger.Println("[INFO] [web] All app restores completed")
|
||||
if s.isDebug() {
|
||||
s.logger.Printf("[DEBUG] [web] executeAllRestores: total=%d success=%d fail=%d elapsed=%s", pendingCount, successCount, failCount, time.Since(restoreStart))
|
||||
}
|
||||
@@ -193,7 +193,7 @@ func (s *Server) executeAllRestores() {
|
||||
// Re-scan stacks so dashboard picks up restored apps
|
||||
if s.stackMgr != nil {
|
||||
if err := s.stackMgr.ScanStacks(); err != nil {
|
||||
s.logger.Printf("[WARN] Post-restore stack scan failed: %v", err)
|
||||
s.logger.Printf("[WARN] [web] Post-restore stack scan failed: %v", err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -992,7 +992,7 @@ func (s *Server) settingsCrossBackupHandler(w http.ResponseWriter, r *http.Reque
|
||||
}
|
||||
}
|
||||
if !validDest {
|
||||
s.logger.Printf("[WARN] Cross-drive backup: rejected invalid dest path %q for %s", destPath, name)
|
||||
s.logger.Printf("[WARN] [web] Cross-drive backup: rejected invalid dest path %q for %s", destPath, name)
|
||||
http.Redirect(w, r, "/stacks/"+name+"/deploy?flash_error="+url.QueryEscape("Érvénytelen célútvonal: "+destPath), http.StatusFound)
|
||||
return
|
||||
}
|
||||
@@ -1016,12 +1016,12 @@ func (s *Server) settingsCrossBackupHandler(w http.ResponseWriter, r *http.Reque
|
||||
}
|
||||
|
||||
if err := s.settings.SetCrossDriveConfig(name, cfg); err != nil {
|
||||
s.logger.Printf("[ERROR] Failed to save cross-drive config for %s: %v", name, err)
|
||||
s.logger.Printf("[ERROR] [web] Failed to save cross-drive config for %s: %v", name, err)
|
||||
http.Redirect(w, r, "/stacks/"+name+"/deploy?flash_error=Hiba+a+ment%C3%A9si+be%C3%A1ll%C3%ADt%C3%A1s+ment%C3%A9sakor", http.StatusFound)
|
||||
return
|
||||
}
|
||||
|
||||
s.logger.Printf("[INFO] Cross-drive backup config saved for %s: dest=%s schedule=%s enabled=%v",
|
||||
s.logger.Printf("[INFO] [web] Cross-drive backup config saved for %s: dest=%s schedule=%s enabled=%v",
|
||||
name, destPath, schedule, enabled)
|
||||
|
||||
http.Redirect(w, r, "/stacks/"+name+"/deploy?flash=Ment%C3%A9si+be%C3%A1ll%C3%ADt%C3%A1s+mentve.", http.StatusFound)
|
||||
@@ -1047,11 +1047,11 @@ func (s *Server) backupRestoreHandler(w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
s.logger.Printf("[WARN] Restore requested: stack=%s, snapshot=%s from %s", stackName, snapshotID, r.RemoteAddr)
|
||||
s.logger.Printf("[WARN] [web] Restore requested: stack=%s, snapshot=%s from %s", stackName, snapshotID, r.RemoteAddr)
|
||||
|
||||
start := time.Now()
|
||||
if err := s.backupMgr.RestoreApp(stackName, snapshotID); err != nil {
|
||||
s.logger.Printf("[ERROR] Restore failed: %v", err)
|
||||
s.logger.Printf("[ERROR] [web] Restore failed: %v", err)
|
||||
if s.isDebug() {
|
||||
s.logger.Printf("[DEBUG] [web] backupRestoreHandler: stack=%s failed after %s", stackName, time.Since(start))
|
||||
}
|
||||
@@ -1223,7 +1223,7 @@ func (s *Server) settingsPasswordHandler(w http.ResponseWriter, r *http.Request)
|
||||
// Generate bcrypt hash
|
||||
hash, err := bcrypt.GenerateFromPassword([]byte(newPassword), 10)
|
||||
if err != nil {
|
||||
s.logger.Printf("[ERROR] Failed to hash new password: %v", err)
|
||||
s.logger.Printf("[ERROR] [web] Failed to hash new password: %v", err)
|
||||
data["PasswordError"] = "Belső hiba a jelszó mentésekor"
|
||||
s.executeTemplate(w, r, "settings", data)
|
||||
return
|
||||
@@ -1231,13 +1231,13 @@ func (s *Server) settingsPasswordHandler(w http.ResponseWriter, r *http.Request)
|
||||
|
||||
// Save to settings.json
|
||||
if err := s.settings.SetPasswordHash(string(hash)); err != nil {
|
||||
s.logger.Printf("[ERROR] Failed to save password to settings.json: %v", err)
|
||||
s.logger.Printf("[ERROR] [web] Failed to save password to settings.json: %v", err)
|
||||
data["PasswordError"] = "Belső hiba a jelszó mentésekor"
|
||||
s.executeTemplate(w, r, "settings", data)
|
||||
return
|
||||
}
|
||||
|
||||
s.logger.Printf("[INFO] Password changed via settings page from %s", r.RemoteAddr)
|
||||
s.logger.Printf("[INFO] [web] Password changed via settings page from %s", r.RemoteAddr)
|
||||
|
||||
// Invalidate all sessions (force re-login)
|
||||
s.invalidateAllSessions()
|
||||
@@ -1297,20 +1297,20 @@ func (s *Server) settingsNotificationsHandler(w http.ResponseWriter, r *http.Req
|
||||
}
|
||||
|
||||
if err := s.settings.SetNotificationPrefs(prefs); err != nil {
|
||||
s.logger.Printf("[ERROR] Failed to save notification prefs: %v", err)
|
||||
s.logger.Printf("[ERROR] [web] Failed to save notification prefs: %v", err)
|
||||
data := s.settingsData()
|
||||
data["NotificationError"] = "Hiba a beállítások mentésekor"
|
||||
s.executeTemplate(w, r, "settings", data)
|
||||
return
|
||||
}
|
||||
|
||||
s.logger.Printf("[INFO] Notification preferences updated: email=%s, events=%v", email, enabledEvents)
|
||||
s.logger.Printf("[INFO] [web] Notification preferences updated: email=%s, events=%v", email, enabledEvents)
|
||||
|
||||
// Sync preferences to hub
|
||||
data := s.settingsData()
|
||||
if s.notifier != nil && s.notifier.IsEnabled() {
|
||||
if err := s.notifier.SyncPreferences(email, enabledEvents, cooldownHours); err != nil {
|
||||
s.logger.Printf("[WARN] Failed to sync preferences to hub: %v", err)
|
||||
s.logger.Printf("[WARN] [web] Failed to sync preferences to hub: %v", err)
|
||||
data["NotificationSuccess"] = fmt.Sprintf("Értesítési beállítások mentve (helyi). A központi szinkronizálás sikertelen: %v", err)
|
||||
} else {
|
||||
data["NotificationSuccess"] = "Értesítési beállítások mentve."
|
||||
@@ -1332,7 +1332,7 @@ func (s *Server) settingsNotificationsTestHandler(w http.ResponseWriter, r *http
|
||||
|
||||
err := s.notifier.SendTest()
|
||||
if err != nil {
|
||||
s.logger.Printf("[ERROR] Test notification failed: %v", err)
|
||||
s.logger.Printf("[ERROR] [web] Test notification failed: %v", err)
|
||||
data["NotificationError"] = fmt.Sprintf("Teszt email küldése sikertelen: %v", err)
|
||||
s.executeTemplate(w, r, "settings", data)
|
||||
return
|
||||
@@ -1486,7 +1486,7 @@ func (s *Server) settingsStorageAddHandler(w http.ResponseWriter, r *http.Reques
|
||||
|
||||
// 5. Soft warning if not under /mnt/
|
||||
if !strings.HasPrefix(path, "/mnt/") {
|
||||
s.logger.Printf("[WARN] Storage path %s is not under /mnt/ — unusual but allowed", path)
|
||||
s.logger.Printf("[WARN] [web] Storage path %s is not under /mnt/ — unusual but allowed", path)
|
||||
}
|
||||
|
||||
sp := settings.StoragePath{
|
||||
@@ -1498,13 +1498,13 @@ func (s *Server) settingsStorageAddHandler(w http.ResponseWriter, r *http.Reques
|
||||
}
|
||||
|
||||
if err := s.settings.AddStoragePath(sp); err != nil {
|
||||
s.logger.Printf("[ERROR] Failed to add storage path: %v", err)
|
||||
s.logger.Printf("[ERROR] [web] Failed to add storage path: %v", err)
|
||||
data["StorageError"] = "Hiba a mentés során."
|
||||
s.executeTemplate(w, r, "settings", data)
|
||||
return
|
||||
}
|
||||
|
||||
s.logger.Printf("[INFO] Storage path added: %s (%s)", path, label)
|
||||
s.logger.Printf("[INFO] [web] Storage path added: %s (%s)", path, label)
|
||||
go s.SyncFileBrowserMounts()
|
||||
http.Redirect(w, r, "/settings?storage_msg=success&storage_detail="+url.QueryEscape("Adattároló sikeresen hozzáadva: "+path), http.StatusFound)
|
||||
}
|
||||
@@ -1549,7 +1549,7 @@ func (s *Server) settingsStorageRemoveHandler(w http.ResponseWriter, r *http.Req
|
||||
return
|
||||
}
|
||||
|
||||
s.logger.Printf("[INFO] Storage path removed: %s", path)
|
||||
s.logger.Printf("[INFO] [web] Storage path removed: %s", path)
|
||||
// Sync FileBrowser mounts after storage path removal
|
||||
go s.SyncFileBrowserMounts()
|
||||
http.Redirect(w, r, "/settings?storage_msg=success&storage_detail="+url.QueryEscape("Adattároló eltávolítva: "+path), http.StatusFound)
|
||||
@@ -1564,7 +1564,7 @@ func (s *Server) settingsStorageDefaultHandler(w http.ResponseWriter, r *http.Re
|
||||
}
|
||||
|
||||
if err := s.settings.SetDefaultStoragePath(path); err != nil {
|
||||
s.logger.Printf("[ERROR] Failed to set default storage path: %v", err)
|
||||
s.logger.Printf("[ERROR] [web] Failed to set default storage path: %v", err)
|
||||
http.Redirect(w, r, "/settings", http.StatusFound)
|
||||
return
|
||||
}
|
||||
@@ -1582,7 +1582,7 @@ func (s *Server) settingsStorageSchedulableHandler(w http.ResponseWriter, r *htt
|
||||
}
|
||||
|
||||
if err := s.settings.SetSchedulable(path, schedulable); err != nil {
|
||||
s.logger.Printf("[ERROR] Failed to update schedulable: %v", err)
|
||||
s.logger.Printf("[ERROR] [web] Failed to update schedulable: %v", err)
|
||||
http.Redirect(w, r, "/settings", http.StatusFound)
|
||||
return
|
||||
}
|
||||
@@ -1607,14 +1607,14 @@ func (s *Server) settingsStorageLabelHandler(w http.ResponseWriter, r *http.Requ
|
||||
}
|
||||
|
||||
if err := s.settings.SetStorageLabel(path, label); err != nil {
|
||||
s.logger.Printf("[ERROR] Failed to set storage label: %v", err)
|
||||
s.logger.Printf("[ERROR] [web] Failed to set storage label: %v", err)
|
||||
data := s.settingsData()
|
||||
data["StorageError"] = "Hiba a megnevezés mentésekor."
|
||||
s.executeTemplate(w, r, "settings", data)
|
||||
return
|
||||
}
|
||||
|
||||
s.logger.Printf("[INFO] Storage label updated: %s → %q", path, label)
|
||||
s.logger.Printf("[INFO] [web] Storage label updated: %s → %q", path, label)
|
||||
http.Redirect(w, r, "/settings?storage_msg=success&storage_detail="+url.QueryEscape("Megnevezés módosítva: "+label), http.StatusFound)
|
||||
}
|
||||
|
||||
@@ -1641,7 +1641,7 @@ func (s *Server) syncFileBrowserMounts(resetDBOnChange bool) {
|
||||
|
||||
// Check if FileBrowser stack exists
|
||||
if _, err := os.Stat(composePath); os.IsNotExist(err) {
|
||||
s.logger.Printf("[WARN] FileBrowser stack not found at %s — skipping mount sync", composePath)
|
||||
s.logger.Printf("[WARN] [web] FileBrowser stack not found at %s — skipping mount sync", composePath)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -1651,7 +1651,7 @@ func (s *Server) syncFileBrowserMounts(resetDBOnChange bool) {
|
||||
// Use domain from controller config
|
||||
domain := s.cfg.Customer.Domain
|
||||
if domain == "" {
|
||||
s.logger.Printf("[WARN] Cannot sync FileBrowser mounts — customer domain not configured")
|
||||
s.logger.Printf("[WARN] [web] Cannot sync FileBrowser mounts — customer domain not configured")
|
||||
return
|
||||
}
|
||||
|
||||
@@ -1675,7 +1675,7 @@ func (s *Server) syncFileBrowserMounts(resetDBOnChange bool) {
|
||||
}
|
||||
|
||||
if err := os.WriteFile(configPath, []byte(fbConfig), 0644); err != nil {
|
||||
s.logger.Printf("[ERROR] Failed to write FileBrowser config: %v", err)
|
||||
s.logger.Printf("[ERROR] [web] Failed to write FileBrowser config: %v", err)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -1687,7 +1687,7 @@ func (s *Server) syncFileBrowserMounts(resetDBOnChange bool) {
|
||||
// Generate and write compose (includes config.yaml mount)
|
||||
compose := generateFileBrowserCompose(domain, storageMounts)
|
||||
if err := os.WriteFile(composePath, []byte(compose), 0644); err != nil {
|
||||
s.logger.Printf("[ERROR] Failed to write FileBrowser compose: %v", err)
|
||||
s.logger.Printf("[ERROR] [web] Failed to write FileBrowser compose: %v", err)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -1695,13 +1695,13 @@ func (s *Server) syncFileBrowserMounts(resetDBOnChange bool) {
|
||||
// nuke the data volume so FileBrowser re-reads config.yaml from scratch.
|
||||
// Normal operations skip this to preserve user accounts, permissions, and share links.
|
||||
if sourcesChanged && resetDBOnChange {
|
||||
s.logger.Printf("[INFO] FileBrowser sources changed — resetting database (restore mode)")
|
||||
s.logger.Printf("[INFO] [web] FileBrowser sources changed — resetting database (restore mode)")
|
||||
resetCtx, resetCancel := context.WithTimeout(context.Background(), 30*time.Second)
|
||||
defer resetCancel()
|
||||
stop := exec.CommandContext(resetCtx, "docker", "compose", "down", "-v")
|
||||
stop.Dir = stackDir
|
||||
if out, err := stop.CombinedOutput(); err != nil {
|
||||
s.logger.Printf("[WARN] FileBrowser down -v: %s — %v", strings.TrimSpace(string(out)), err)
|
||||
s.logger.Printf("[WARN] [web] FileBrowser down -v: %s — %v", strings.TrimSpace(string(out)), err)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1711,9 +1711,9 @@ func (s *Server) syncFileBrowserMounts(resetDBOnChange bool) {
|
||||
cmd := exec.CommandContext(ctx, "docker", "compose", "up", "-d", "--force-recreate", "--remove-orphans")
|
||||
cmd.Dir = stackDir
|
||||
if out, err := cmd.CombinedOutput(); err != nil {
|
||||
s.logger.Printf("[ERROR] Failed to recreate FileBrowser: %s — %v", string(out), err)
|
||||
s.logger.Printf("[ERROR] [web] Failed to recreate FileBrowser: %s — %v", string(out), err)
|
||||
} else {
|
||||
s.logger.Printf("[INFO] FileBrowser mounts synced — %d storage path(s), config updated", len(paths))
|
||||
s.logger.Printf("[INFO] [web] FileBrowser mounts synced — %d storage path(s), config updated", len(paths))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -118,11 +118,11 @@ func NewServer(cfg *config.Config, stackMgr *stacks.Manager, cpuCollector *syste
|
||||
|
||||
// Log auth source on startup
|
||||
if sett != nil && sett.GetPasswordHash() != "" {
|
||||
logger.Printf("[INFO] Auth: using password from settings.json")
|
||||
logger.Printf("[INFO] [web] Auth: using password from settings.json")
|
||||
} else if cfg.Web.PasswordHash != "" {
|
||||
logger.Printf("[INFO] Auth: using password from controller.yaml")
|
||||
logger.Printf("[INFO] [web] Auth: using password from controller.yaml")
|
||||
} else {
|
||||
logger.Printf("[INFO] Auth: no password configured — dashboard is open")
|
||||
logger.Printf("[INFO] [web] Auth: no password configured — dashboard is open")
|
||||
}
|
||||
|
||||
// Sync FileBrowser config on startup to ensure mounts and sources are current.
|
||||
@@ -416,7 +416,7 @@ func (s *Server) serveCatchAll(w http.ResponseWriter, r *http.Request, host stri
|
||||
w.Header().Set("Content-Type", "text/html; charset=utf-8")
|
||||
w.WriteHeader(http.StatusNotFound)
|
||||
if err := s.tmpl.ExecuteTemplate(w, "catchall", data); err != nil {
|
||||
s.logger.Printf("[ERROR] Catch-all template error: %v", err)
|
||||
s.logger.Printf("[ERROR] [web] Catch-all template error: %v", err)
|
||||
http.Error(w, "Internal error", http.StatusInternalServerError)
|
||||
}
|
||||
}
|
||||
@@ -459,7 +459,7 @@ func (s *Server) primaryHDDPath() string {
|
||||
func (s *Server) render(w http.ResponseWriter, name string, data interface{}) {
|
||||
var buf bytes.Buffer
|
||||
if err := s.tmpl.ExecuteTemplate(&buf, name, data); err != nil {
|
||||
s.logger.Printf("[ERROR] Template error (%s): %v", name, err)
|
||||
s.logger.Printf("[ERROR] [web] Template error (%s): %v", name, err)
|
||||
http.Error(w, "Internal error", http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
@@ -477,7 +477,7 @@ func (s *Server) executeTemplate(w http.ResponseWriter, r *http.Request, name st
|
||||
data["CSRFToken"] = s.csrfToken(r)
|
||||
var buf bytes.Buffer
|
||||
if err := s.tmpl.ExecuteTemplate(&buf, name, data); err != nil {
|
||||
s.logger.Printf("[ERROR] Template error (%s): %v", name, err)
|
||||
s.logger.Printf("[ERROR] [web] Template error (%s): %v", name, err)
|
||||
http.Error(w, "Internal error", http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -206,7 +206,7 @@ func (s *Server) storageScanAPIHandler(w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
result, err := storage.ScanDisks(s.logger, s.cfg.Logging.Level == "debug")
|
||||
if err != nil {
|
||||
s.logger.Printf("[ERROR] storageScan: %v", err)
|
||||
s.logger.Printf("[ERROR] [web] storageScan: %v", err)
|
||||
jsonError(w, "Meghajtók keresése sikertelen: "+err.Error(), http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
@@ -256,7 +256,7 @@ func (s *Server) storageInitAPIHandler(w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
s.logger.Printf("[INFO] Storage init started: device=%s mountName=%s by %s", req.DevicePath, req.MountName, r.RemoteAddr)
|
||||
s.logger.Printf("[INFO] [web] Storage init started: device=%s mountName=%s by %s", req.DevicePath, req.MountName, r.RemoteAddr)
|
||||
|
||||
fmtReq := storage.FormatRequest{
|
||||
DevicePath: req.DevicePath,
|
||||
@@ -274,7 +274,7 @@ func (s *Server) storageInitAPIHandler(w http.ResponseWriter, r *http.Request) {
|
||||
if scanResult, scanErr := storage.ScanDisks(s.logger, s.cfg.Logging.Level == "debug"); scanErr == nil {
|
||||
for _, disk := range scanResult.AvailableDisks {
|
||||
if disk.Path == req.DevicePath && len(disk.Partitions) == 1 && disk.Partitions[0].FSType == "" {
|
||||
s.logger.Printf("[INFO] Disk %s has 1 empty partition (%s) — skipping repartition",
|
||||
s.logger.Printf("[INFO] [web] Disk %s has 1 empty partition (%s) — skipping repartition",
|
||||
req.DevicePath, disk.Partitions[0].Path)
|
||||
fmtReq.DevicePath = disk.Partitions[0].Path
|
||||
fmtReq.CreatePartition = false
|
||||
@@ -297,7 +297,7 @@ func (s *Server) storageInitAPIHandler(w http.ResponseWriter, r *http.Request) {
|
||||
close(progressCh)
|
||||
|
||||
if err != nil {
|
||||
s.logger.Printf("[ERROR] Storage init failed: %v", err)
|
||||
s.logger.Printf("[ERROR] [web] Storage init failed: %v", err)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -314,9 +314,9 @@ func (s *Server) storageInitAPIHandler(w http.ResponseWriter, r *http.Request) {
|
||||
AddedAt: time.Now().UTC().Format(time.RFC3339),
|
||||
}
|
||||
if err := s.settings.AddStoragePath(sp); err != nil {
|
||||
s.logger.Printf("[WARN] Failed to register storage path after init: %v", err)
|
||||
s.logger.Printf("[WARN] [web] Failed to register storage path after init: %v", err)
|
||||
} else {
|
||||
s.logger.Printf("[INFO] Storage path registered: %s (%s)", mountPath, label)
|
||||
s.logger.Printf("[INFO] [web] Storage path registered: %s (%s)", mountPath, label)
|
||||
// Sync FileBrowser mounts with new storage path
|
||||
s.SyncFileBrowserMounts()
|
||||
}
|
||||
@@ -505,7 +505,7 @@ func (s *Server) storageMigrateAPIHandler(w http.ResponseWriter, r *http.Request
|
||||
return
|
||||
}
|
||||
|
||||
s.logger.Printf("[INFO] Migration started: stack=%s from=%s to=%s by %s",
|
||||
s.logger.Printf("[INFO] [web] Migration started: stack=%s from=%s to=%s by %s",
|
||||
req.StackName, currentHDDPath, req.TargetPath, r.RemoteAddr)
|
||||
|
||||
migrReq := storage.MigrateRequest{
|
||||
@@ -551,9 +551,9 @@ func (s *Server) storageMigrateAPIHandler(w http.ResponseWriter, r *http.Request
|
||||
}()
|
||||
|
||||
if err := orch.RunEnhancedMigration(migrReq, stopFn, startFn, updateFn, opts, progressCh); err != nil {
|
||||
s.logger.Printf("[ERROR] Migration failed: stack=%s: %v", req.StackName, err)
|
||||
s.logger.Printf("[ERROR] [web] Migration failed: stack=%s: %v", req.StackName, err)
|
||||
} else {
|
||||
s.logger.Printf("[INFO] Migration complete: stack=%s → %s", req.StackName, req.TargetPath)
|
||||
s.logger.Printf("[INFO] [web] Migration complete: stack=%s → %s", req.StackName, req.TargetPath)
|
||||
// Sync FileBrowser mounts (storage paths may now have new app data)
|
||||
go s.SyncFileBrowserMounts()
|
||||
}
|
||||
@@ -879,7 +879,7 @@ func (s *Server) staleDataCleanupHandler(w http.ResponseWriter, r *http.Request)
|
||||
|
||||
// Safety: never delete protected top-level dirs
|
||||
if protected != nil && protected[cleanPath] {
|
||||
s.logger.Printf("[WARN] Refusing to delete protected HDD path: %s", cleanPath)
|
||||
s.logger.Printf("[WARN] [web] Refusing to delete protected HDD path: %s", cleanPath)
|
||||
errors = append(errors, fmt.Sprintf("Védett útvonal, nem törölhető: %s", cleanPath))
|
||||
continue
|
||||
}
|
||||
@@ -893,10 +893,10 @@ func (s *Server) staleDataCleanupHandler(w http.ResponseWriter, r *http.Request)
|
||||
size := dirSizeInt64(cleanPath)
|
||||
|
||||
if err := os.RemoveAll(cleanPath); err != nil {
|
||||
s.logger.Printf("[ERROR] Failed to remove stale data %s: %v", cleanPath, err)
|
||||
s.logger.Printf("[ERROR] [web] Failed to remove stale data %s: %v", cleanPath, err)
|
||||
errors = append(errors, fmt.Sprintf("Törlés sikertelen: %s — %v", cleanPath, err))
|
||||
} else {
|
||||
s.logger.Printf("[INFO] Removed stale data: %s (%s) for stack %s", cleanPath, dirSizeBytesHuman(size), req.StackName)
|
||||
s.logger.Printf("[INFO] [web] Removed stale data: %s (%s) for stack %s", cleanPath, dirSizeBytesHuman(size), req.StackName)
|
||||
deleted = append(deleted, cleanPath)
|
||||
totalFreed += size
|
||||
}
|
||||
@@ -952,7 +952,7 @@ func (s *Server) storageAttachMountRawHandler(w http.ResponseWriter, r *http.Req
|
||||
rawPath, err := storage.MountRaw(req.DevicePath)
|
||||
if err != nil {
|
||||
s.diskJobMu.Unlock()
|
||||
s.logger.Printf("[ERROR] storageAttachMountRaw: %v", err)
|
||||
s.logger.Printf("[ERROR] [web] storageAttachMountRaw: %v", err)
|
||||
jsonError(w, err.Error(), http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
@@ -960,7 +960,7 @@ func (s *Server) storageAttachMountRawHandler(w http.ResponseWriter, r *http.Req
|
||||
s.activeRawMount = rawPath
|
||||
s.diskJobMu.Unlock()
|
||||
|
||||
s.logger.Printf("[INFO] Raw mount for attach: %s → %s", req.DevicePath, rawPath)
|
||||
s.logger.Printf("[INFO] [web] Raw mount for attach: %s → %s", req.DevicePath, rawPath)
|
||||
|
||||
jsonResponse(w, map[string]interface{}{
|
||||
"ok": true,
|
||||
@@ -1026,7 +1026,7 @@ func (s *Server) storageAttachMkdirHandler(w http.ResponseWriter, r *http.Reques
|
||||
return
|
||||
}
|
||||
|
||||
s.logger.Printf("[INFO] Created directory for attach: %s", createdPath)
|
||||
s.logger.Printf("[INFO] [web] Created directory for attach: %s", createdPath)
|
||||
|
||||
jsonResponse(w, map[string]interface{}{
|
||||
"ok": true,
|
||||
@@ -1064,7 +1064,7 @@ func (s *Server) storageAttachAPIHandler(w http.ResponseWriter, r *http.Request)
|
||||
return
|
||||
}
|
||||
|
||||
s.logger.Printf("[INFO] Storage attach started: device=%s mountName=%s subPath=%s by %s",
|
||||
s.logger.Printf("[INFO] [web] Storage attach started: device=%s mountName=%s subPath=%s by %s",
|
||||
req.DevicePath, req.MountName, req.SubPath, r.RemoteAddr)
|
||||
|
||||
attachReq := storage.AttachRequest{
|
||||
@@ -1089,7 +1089,7 @@ func (s *Server) storageAttachAPIHandler(w http.ResponseWriter, r *http.Request)
|
||||
close(progressCh)
|
||||
|
||||
if err != nil {
|
||||
s.logger.Printf("[ERROR] Storage attach failed: %v", err)
|
||||
s.logger.Printf("[ERROR] [web] Storage attach failed: %v", err)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -1111,9 +1111,9 @@ func (s *Server) storageAttachAPIHandler(w http.ResponseWriter, r *http.Request)
|
||||
AddedAt: time.Now().UTC().Format(time.RFC3339),
|
||||
}
|
||||
if err := s.settings.AddStoragePath(sp); err != nil {
|
||||
s.logger.Printf("[WARN] Failed to register storage path after attach: %v", err)
|
||||
s.logger.Printf("[WARN] [web] Failed to register storage path after attach: %v", err)
|
||||
} else {
|
||||
s.logger.Printf("[INFO] Storage path registered: %s (%s)", mountPath, label)
|
||||
s.logger.Printf("[INFO] [web] Storage path registered: %s (%s)", mountPath, label)
|
||||
s.SyncFileBrowserMounts()
|
||||
}
|
||||
}()
|
||||
@@ -1169,9 +1169,9 @@ func (s *Server) storageAttachCancelHandler(w http.ResponseWriter, r *http.Reque
|
||||
|
||||
if rawMount != "" {
|
||||
if err := storage.CleanupRawMount(rawMount); err != nil {
|
||||
s.logger.Printf("[WARN] Failed to cleanup raw mount %s: %v", rawMount, err)
|
||||
s.logger.Printf("[WARN] [web] Failed to cleanup raw mount %s: %v", rawMount, err)
|
||||
} else {
|
||||
s.logger.Printf("[INFO] Cleaned up raw mount: %s", rawMount)
|
||||
s.logger.Printf("[INFO] [web] Cleaned up raw mount: %s", rawMount)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1217,7 +1217,7 @@ func (s *Server) storageDisconnectHandler(w http.ResponseWriter, r *http.Request
|
||||
|
||||
stoppedStacks, err := s.storageWatchdog.SafeDisconnect(r.Context(), req.Path)
|
||||
if err != nil {
|
||||
s.logger.Printf("[ERROR] Safe disconnect %s: %v", req.Path, err)
|
||||
s.logger.Printf("[ERROR] [web] Safe disconnect %s: %v", req.Path, err)
|
||||
jsonError(w, fmt.Sprintf("Leválasztás sikertelen: %v", err), http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
@@ -1260,7 +1260,7 @@ func (s *Server) storageReconnectHandler(w http.ResponseWriter, r *http.Request)
|
||||
|
||||
stoppedStacks, err := s.storageWatchdog.Reconnect(r.Context(), req.Path)
|
||||
if err != nil {
|
||||
s.logger.Printf("[ERROR] Reconnect %s: %v", req.Path, err)
|
||||
s.logger.Printf("[ERROR] [web] Reconnect %s: %v", req.Path, err)
|
||||
jsonError(w, fmt.Sprintf("Csatlakoztatás sikertelen: %v", err), http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
@@ -1482,7 +1482,7 @@ func (s *Server) driveMigrateAPIHandler(w http.ResponseWriter, r *http.Request)
|
||||
return
|
||||
}
|
||||
|
||||
s.logger.Printf("[INFO] Drive migration started: %s → %s by %s", req.SourcePath, req.DestPath, r.RemoteAddr)
|
||||
s.logger.Printf("[INFO] [web] Drive migration started: %s → %s by %s", req.SourcePath, req.DestPath, r.RemoteAddr)
|
||||
|
||||
go func() {
|
||||
ctx := context.Background()
|
||||
@@ -1498,9 +1498,9 @@ func (s *Server) driveMigrateAPIHandler(w http.ResponseWriter, r *http.Request)
|
||||
DestPath: req.DestPath,
|
||||
}
|
||||
if err := s.driveMigrator.MigrateDrive(ctx, migrReq, progressCh); err != nil {
|
||||
s.logger.Printf("[ERROR] Drive migration failed: %v", err)
|
||||
s.logger.Printf("[ERROR] [web] Drive migration failed: %v", err)
|
||||
} else {
|
||||
s.logger.Printf("[INFO] Drive migration complete: %s → %s", req.SourcePath, req.DestPath)
|
||||
s.logger.Printf("[INFO] [web] Drive migration complete: %s → %s", req.SourcePath, req.DestPath)
|
||||
go s.SyncFileBrowserMounts()
|
||||
}
|
||||
close(progressCh)
|
||||
@@ -1580,12 +1580,12 @@ func (s *Server) decommissionRemoveHandler(w http.ResponseWriter, r *http.Reques
|
||||
}
|
||||
|
||||
if err := s.settings.RemoveStoragePath(req.Path); err != nil {
|
||||
s.logger.Printf("[ERROR] Failed to remove decommissioned path %s: %v", req.Path, err)
|
||||
s.logger.Printf("[ERROR] [web] Failed to remove decommissioned path %s: %v", req.Path, err)
|
||||
jsonError(w, "Eltávolítás sikertelen: "+err.Error(), http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
||||
s.logger.Printf("[INFO] Decommissioned storage path removed: %s", req.Path)
|
||||
s.logger.Printf("[INFO] [web] Decommissioned storage path removed: %s", req.Path)
|
||||
|
||||
// For form submissions, redirect back to settings
|
||||
if r.Header.Get("Content-Type") != "application/json" {
|
||||
|
||||
Reference in New Issue
Block a user