daemon

package
v0.13.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jun 15, 2026 License: MIT Imports: 37 Imported by: 0

Documentation

Index

Constants

This section is empty.

Variables

View Source
var (
	CommandsHandled = expvar.NewInt("commands_handled")
	RequestsTotal   = expvar.NewInt("requests_total")
	StartTime       = time.Now()
)

Functions

func CheckRuntimeDrift added in v0.10.0

func CheckRuntimeDrift(sm *StateManager) []string

CheckRuntimeDrift records the baseline fingerprint on first use and, on later deploys, returns warnings describing any host runtime drift. The caller surfaces them to the operator (daemon log, which streams to the CLI).

func Coalesce

func Coalesce(values ...string) string

func DriftWarnings added in v0.10.0

func DriftWarnings(baseline, current *EnvFingerprint) []string

DriftWarnings returns a human-readable description of every field that changed from baseline to current. An empty slice means the environments match. A field that was unknown ("") at baseline is not reported as drift (we only flag a value we actually recorded changing out from under the deploy).

func IsIPAllowed

func IsIPAllowed(ipStr string, whitelist []string) bool

func StartMetricsServer

func StartMetricsServer(addr string)

func StringArg

func StringArg(args map[string]interface{}, key string) (string, bool)

func VerifySignature

func VerifySignature(payload []byte, signature, secret string) bool

Types

type AuditEntry

type AuditEntry struct {
	Timestamp      time.Time   `json:"timestamp"`
	CommandType    string      `json:"command_type"`
	ClientIdentity string      `json:"client_identity"`
	Result         string      `json:"result"`
	ErrorDetails   string      `json:"error_details,omitempty"`
	Args           interface{} `json:"args,omitempty"`
}

type AuditLogger

type AuditLogger struct {
	// contains filtered or unexported fields
}

func NewAuditLogger

func NewAuditLogger(path string) *AuditLogger

func (*AuditLogger) Log

func (al *AuditLogger) Log(entry AuditEntry)

type CaddyManager

type CaddyManager struct {
	// contains filtered or unexported fields
}

func NewCaddyManager

func NewCaddyManager() *CaddyManager

func (*CaddyManager) EnsureMainCaddyfile

func (cm *CaddyManager) EnsureMainCaddyfile() error

func (*CaddyManager) GenerateConfig

func (cm *CaddyManager) GenerateConfig(appName, domain, outputMode string, port int, appDir string, features *nextcore.DetectedFeatures, distDir, exportDir string) error

func (*CaddyManager) Reload

func (cm *CaddyManager) Reload() error

func (*CaddyManager) RemoveConfig

func (cm *CaddyManager) RemoveConfig(appName string) error

func (*CaddyManager) Validate

func (cm *CaddyManager) Validate() error

type CommandHandler

type CommandHandler struct {
	// contains filtered or unexported fields
}

func NewCommandHandler

func NewCommandHandler(config *types.DaemonConfig) *CommandHandler

func (*CommandHandler) HandleCommand

func (ch *CommandHandler) HandleCommand(cmd types.Command, clientIdentity string) types.Response

func (*CommandHandler) Shutdown

func (ch *CommandHandler) Shutdown()

func (*CommandHandler) ValidateCommand

func (ch *CommandHandler) ValidateCommand(cmd types.Command) error

type EnvFingerprint added in v0.10.0

type EnvFingerprint struct {
	Node  string `json:"node"`  // e.g. "24.16.0"
	Bun   string `json:"bun"`   // e.g. "1.1.0" ("" if not installed)
	Glibc string `json:"glibc"` // e.g. "2.43"  (version only; distro packaging stripped)
	Arch  string `json:"arch"`  // GOARCH of the daemon == host arch
	OS    string `json:"os"`    // GOOS
}

EnvFingerprint captures the host runtime parameters a locally-compiled Next.js artifact is sensitive to. The baseline is recorded on the first deploy and re-checked on every subsequent one, so an out-of-band host change (an `apt upgrade` that moves glibc, a manual Node bump) surfaces as a clear operator warning instead of a silent crash loop on the next restart.

This is the bare-metal equivalent of Docker's image pinning — without a container runtime.

func CaptureEnvFingerprint added in v0.10.0

func CaptureEnvFingerprint() *EnvFingerprint

CaptureEnvFingerprint probes the host. Every probe is best-effort: a missing tool yields an empty field rather than an error, so a partial fingerprint is still useful (and Arch/OS are always present from the Go runtime).

func (*EnvFingerprint) Hash added in v0.10.0

func (ef *EnvFingerprint) Hash() string

Hash is a stable token over the whole fingerprint, for quick equality checks.

type HealthMonitor

type HealthMonitor struct {
	// contains filtered or unexported fields
}

func NewHealthMonitor

func NewHealthMonitor(config *types.DaemonConfig) *HealthMonitor

func (*HealthMonitor) Start

func (hm *HealthMonitor) Start()

func (*HealthMonitor) Stop added in v0.11.0

func (hm *HealthMonitor) Stop()

Stop cancels the monitor's context, ending monitorLoop and releasing the cancel function created in NewHealthMonitor. Without this the context's cancel is never called — a goroutine + context leak (gosec G118).

type MonitoredApp

type MonitoredApp struct {
	ContainerName string
	DesiredState  string // "running" or "stopped"
	RestartPolicy string // "always", "on-failure", "never"
	MaxRestarts   int
	RestartCount  int
	LastCheck     time.Time
}

type NextDeployDaemon

type NextDeployDaemon struct {
	// contains filtered or unexported fields
}

func NewNextDeployDaemon

func NewNextDeployDaemon(configPath string, socketPathOverride string) (*NextDeployDaemon, error)

func (*NextDeployDaemon) Shutdown

func (d *NextDeployDaemon) Shutdown()

func (*NextDeployDaemon) Start

func (d *NextDeployDaemon) Start() error

type ProcessManager

type ProcessManager struct {
	// contains filtered or unexported fields
}

func NewProcessManager

func NewProcessManager() *ProcessManager

func (*ProcessManager) CurrentServiceName

func (pm *ProcessManager) CurrentServiceName() string

func (*ProcessManager) FindAppServices

func (pm *ProcessManager) FindAppServices(appName string) ([]string, error)

func (*ProcessManager) GenerateServiceFile

func (pm *ProcessManager) GenerateServiceFile(appName, projectDir, outputMode string, dopplerToken string, port int, packageManager string, releaseID string, limits *config.ResourceLimits) (string, bool, error)

func (*ProcessManager) RemoveService

func (pm *ProcessManager) RemoveService(serviceName string) error

func (*ProcessManager) RestartService

func (pm *ProcessManager) RestartService(serviceName string) error

func (*ProcessManager) StartService

func (pm *ProcessManager) StartService(serviceName string) error

func (*ProcessManager) StopService

func (pm *ProcessManager) StopService(serviceName string) error

type RateLimiter

type RateLimiter struct {
	// contains filtered or unexported fields
}

func NewRateLimiter

func NewRateLimiter(rate, burst float64) *RateLimiter

func (*RateLimiter) Allow

func (rl *RateLimiter) Allow(id string) bool

type ReleaseContext

type ReleaseContext struct {
	AppName          string
	Domain           string
	ReleaseDir       string
	ReleaseID        string
	OutputMode       string
	DopplerToken     string
	PackageManager   string
	TarballPath      string
	DetectedFeatures *nextcore.DetectedFeatures
	DistDir          string
	ExportDir        string
	Resources        *config.ResourceLimits
	HealthPath       string
}

type ReplayGuard added in v0.8.2

type ReplayGuard struct {
	// contains filtered or unexported fields
}

ReplayGuard rejects commands whose signed timestamp is outside an allowed skew window, and commands whose nonce has already been seen within that window. Combined with the HMAC signature (which covers the timestamp and nonce), this prevents a captured command from being replayed.

func NewReplayGuard added in v0.8.2

func NewReplayGuard(window time.Duration) *ReplayGuard

func (*ReplayGuard) Check added in v0.8.2

func (rg *ReplayGuard) Check(ts int64, nonce string) error

Check validates freshness and uniqueness. ts is a Unix timestamp (seconds) and nonce is a per-command random value; both are part of the signed payload.

type SocketServer

type SocketServer struct {
	// contains filtered or unexported fields
}

func NewSocketServer

func NewSocketServer(config *types.DaemonConfig, commandHandler *CommandHandler) *SocketServer

func (*SocketServer) AcceptConnections

func (ss *SocketServer) AcceptConnections()

func (*SocketServer) Close

func (ss *SocketServer) Close() error

func (*SocketServer) Start

func (ss *SocketServer) Start() error

type State

type State struct {
	Ports map[string]int `json:"ports"` // appName -> port
	// Fingerprint is the host runtime baseline recorded on the first deploy.
	// Re-checked each deploy to detect out-of-band host drift (glibc/Node bumps).
	Fingerprint *EnvFingerprint `json:"fingerprint,omitempty"`
}

type StateManager

type StateManager struct {
	// contains filtered or unexported fields
}

func NewStateManager

func NewStateManager(path string) *StateManager

func (*StateManager) GetFingerprint added in v0.10.0

func (sm *StateManager) GetFingerprint() *EnvFingerprint

GetFingerprint returns the recorded host runtime baseline, or nil if none has been captured yet.

func (*StateManager) GetPort

func (sm *StateManager) GetPort(appName string) int

func (*StateManager) Save

func (sm *StateManager) Save() error

func (*StateManager) SetFingerprint added in v0.10.0

func (sm *StateManager) SetFingerprint(fp *EnvFingerprint)

SetFingerprint records the host runtime baseline. Caller must Save() to persist.

func (*StateManager) SetPort

func (sm *StateManager) SetPort(appName string, port int)

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL