mirror of
https://github.com/rcourtman/Pulse.git
synced 2026-09-22 11:13:26 +00:00
chore: reorganize repository structure for better maintainability
- Move development scripts to scripts/ directory (dev.sh, hot-dev.sh, build.sh, etc.) - Move UPGRADE_NOTICE to docs/ directory - Remove empty 2025-08-14 file - Update all references to moved scripts in documentation
This commit is contained in:
@@ -404,7 +404,7 @@ journalctl -u pulse -f
|
||||
### Quick Start - Hot Reload (Recommended)
|
||||
```bash
|
||||
# Best development experience with instant frontend updates
|
||||
./hot-dev.sh
|
||||
./scripts/hot-dev.sh
|
||||
# Frontend: http://localhost:5173 (hot reload)
|
||||
# Backend: http://localhost:7655
|
||||
```
|
||||
|
||||
@@ -46,6 +46,18 @@ func getCookieSettings(r *http.Request) (secure bool, sameSite http.SameSite) {
|
||||
isProxied := detectProxy(r)
|
||||
isSecure := isConnectionSecure(r)
|
||||
|
||||
// Debug logging for Cloudflare tunnel issues
|
||||
if isProxied {
|
||||
log.Debug().
|
||||
Bool("proxied", isProxied).
|
||||
Bool("secure", isSecure).
|
||||
Str("cf_ray", r.Header.Get("CF-Ray")).
|
||||
Str("cf_connecting_ip", r.Header.Get("CF-Connecting-IP")).
|
||||
Str("x_forwarded_for", r.Header.Get("X-Forwarded-For")).
|
||||
Str("x_forwarded_proto", r.Header.Get("X-Forwarded-Proto")).
|
||||
Msg("Proxy/tunnel detected - adjusting cookie settings")
|
||||
}
|
||||
|
||||
// Default to Lax for better compatibility
|
||||
sameSitePolicy := http.SameSiteLaxMode
|
||||
|
||||
@@ -209,7 +221,20 @@ func CheckAuth(cfg *config.Config, w http.ResponseWriter, r *http.Request) bool
|
||||
if cookie, err := r.Cookie("pulse_session"); err == nil && cookie.Value != "" {
|
||||
if ValidateSession(cookie.Value) {
|
||||
return true
|
||||
} else {
|
||||
// Debug logging for failed session validation
|
||||
log.Debug().
|
||||
Str("session_token", cookie.Value[:8]+"...").
|
||||
Str("path", r.URL.Path).
|
||||
Msg("Session validation failed - token not found or expired")
|
||||
}
|
||||
} else if err != nil {
|
||||
// Debug logging when no session cookie found
|
||||
log.Debug().
|
||||
Err(err).
|
||||
Str("path", r.URL.Path).
|
||||
Bool("has_cf_headers", r.Header.Get("CF-Ray") != "").
|
||||
Msg("No session cookie found")
|
||||
}
|
||||
|
||||
// Check basic auth
|
||||
@@ -298,6 +323,24 @@ func CheckAuth(cfg *config.Config, w http.ResponseWriter, r *http.Request) bool
|
||||
// Get appropriate cookie settings based on proxy detection
|
||||
isSecure, sameSitePolicy := getCookieSettings(r)
|
||||
|
||||
// Debug logging for Cloudflare tunnel issues
|
||||
sameSiteName := "Default"
|
||||
switch sameSitePolicy {
|
||||
case http.SameSiteNoneMode:
|
||||
sameSiteName = "None"
|
||||
case http.SameSiteLaxMode:
|
||||
sameSiteName = "Lax"
|
||||
case http.SameSiteStrictMode:
|
||||
sameSiteName = "Strict"
|
||||
}
|
||||
|
||||
log.Debug().
|
||||
Bool("secure", isSecure).
|
||||
Str("same_site", sameSiteName).
|
||||
Str("token", token[:8]+"...").
|
||||
Str("remote_addr", r.RemoteAddr).
|
||||
Msg("Setting session cookie after successful login")
|
||||
|
||||
// Set session cookie
|
||||
http.SetCookie(w, &http.Cookie{
|
||||
Name: "pulse_session",
|
||||
|
||||
@@ -796,9 +796,16 @@ func (m *Monitor) pollPVEInstance(ctx context.Context, instanceName string, clie
|
||||
case <-ctx.Done():
|
||||
return
|
||||
default:
|
||||
// Try to use efficient cluster/resources endpoint
|
||||
if !m.pollVMsAndContainersEfficient(ctx, instanceName, client) {
|
||||
// Fall back to old method if cluster/resources fails
|
||||
// Only try cluster endpoints if this is configured as a cluster
|
||||
// This prevents syslog spam on non-clustered nodes from certificate checks
|
||||
useClusterEndpoint := false
|
||||
if instanceCfg.IsCluster {
|
||||
// Try to use efficient cluster/resources endpoint
|
||||
useClusterEndpoint = m.pollVMsAndContainersEfficient(ctx, instanceName, client)
|
||||
}
|
||||
|
||||
if !useClusterEndpoint {
|
||||
// Use traditional polling for non-clusters or if cluster endpoint fails
|
||||
// Use WithNodes versions to avoid duplicate GetNodes calls
|
||||
if instanceCfg.MonitorVMs {
|
||||
m.pollVMsWithNodes(ctx, instanceName, client, nodes)
|
||||
@@ -855,35 +862,8 @@ func (m *Monitor) pollPVEInstance(ctx context.Context, instanceName string, clie
|
||||
}
|
||||
|
||||
// pollVMsAndContainersEfficient uses the cluster/resources endpoint to get all VMs and containers in one call
|
||||
// This should only be called for instances configured as clusters
|
||||
func (m *Monitor) pollVMsAndContainersEfficient(ctx context.Context, instanceName string, client PVEClientInterface) bool {
|
||||
// Get instance config to check if this is configured as a cluster
|
||||
var instanceCfg *config.PVEInstance
|
||||
for _, cfg := range m.config.PVEInstances {
|
||||
if cfg.Name == instanceName {
|
||||
instanceCfg = &cfg
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
// If not configured as a cluster, don't even try cluster endpoints
|
||||
if instanceCfg == nil || !instanceCfg.IsCluster {
|
||||
log.Debug().Str("instance", instanceName).Bool("isCluster", instanceCfg != nil && instanceCfg.IsCluster).Msg("Instance not configured as cluster, using traditional polling")
|
||||
return false
|
||||
}
|
||||
|
||||
// For cluster configurations, verify it's still a cluster
|
||||
// This check is cached in the configuration, so we avoid repeated API calls
|
||||
isCluster, err := client.IsClusterMember(ctx)
|
||||
if err != nil {
|
||||
log.Debug().Err(err).Str("instance", instanceName).Msg("Could not verify cluster membership, falling back to traditional polling")
|
||||
return false
|
||||
}
|
||||
|
||||
if !isCluster {
|
||||
log.Debug().Str("instance", instanceName).Msg("Configured as cluster but node reports not in a cluster, using traditional polling")
|
||||
return false
|
||||
}
|
||||
|
||||
log.Info().Str("instance", instanceName).Msg("Polling VMs and containers using cluster/resources")
|
||||
|
||||
// Get all resources in a single API call
|
||||
|
||||
Reference in New Issue
Block a user