Multi-GPU Collection System: - Add modular GPU collector architecture in collectors/gpu/ - Support AMD (amdgpu), NVIDIA (nvidia-smi), and Intel (i915/xe) GPUs - GPU Manager auto-detects and aggregates all vendor collectors - Backward-compatible JSON output for existing frontend Operational Modes: - Standalone mode (default): single-host monitoring, no database - Server mode: multi-device with database, auth, agents (WIP) - Agent mode: lightweight reporter to central server (WIP) - Mode selection via TYTO_MODE env var or config.yaml Configuration Updates: - Add server config (gRPC port, mTLS settings, registration) - Add agent config (ID, server URL, TLS certificates) - Add database config (SQLite/PostgreSQL support) - Support TYTO_* prefixed environment variables 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
105 lines
2.6 KiB
Go
105 lines
2.6 KiB
Go
package main
|
|
|
|
import (
|
|
"log"
|
|
|
|
"tyto/internal/api"
|
|
"tyto/internal/config"
|
|
"tyto/internal/sse"
|
|
)
|
|
|
|
func main() {
|
|
cfg := config.Load()
|
|
|
|
switch {
|
|
case cfg.IsAgent():
|
|
runAgent(cfg)
|
|
case cfg.IsServer():
|
|
runServer(cfg)
|
|
default:
|
|
runStandalone(cfg)
|
|
}
|
|
}
|
|
|
|
// runStandalone starts Tyto in single-host monitoring mode.
|
|
// This is the default mode with no database or agent support.
|
|
func runStandalone(cfg *config.Config) {
|
|
log.Printf("Starting Tyto in standalone mode on port %s", cfg.Port)
|
|
log.Printf("Reading from: proc=%s, sys=%s", cfg.ProcPath, cfg.SysPath)
|
|
log.Printf("Default refresh interval: %s", cfg.RefreshInterval)
|
|
|
|
if cfg.AuthEnabled {
|
|
log.Printf("Basic authentication enabled for user: %s", cfg.AuthUser)
|
|
}
|
|
|
|
if cfg.TLSEnabled {
|
|
log.Printf("TLS enabled with cert: %s", cfg.TLSCertFile)
|
|
}
|
|
|
|
broker := sse.NewBroker(cfg)
|
|
go broker.Run()
|
|
|
|
server := api.NewServer(cfg, broker)
|
|
|
|
var err error
|
|
if cfg.TLSEnabled {
|
|
log.Printf("Starting HTTPS server on port %s", cfg.Port)
|
|
err = server.RunTLS(cfg.TLSCertFile, cfg.TLSKeyFile)
|
|
} else {
|
|
err = server.Run()
|
|
}
|
|
|
|
if err != nil {
|
|
log.Fatalf("Failed to start server: %v", err)
|
|
}
|
|
}
|
|
|
|
// runServer starts Tyto in full server mode with database, agents, and auth.
|
|
func runServer(cfg *config.Config) {
|
|
log.Printf("Starting Tyto in server mode on port %s", cfg.Port)
|
|
log.Printf("gRPC port for agents: %d", cfg.Server.GRPCPort)
|
|
log.Printf("Database: %s", cfg.Database.Type)
|
|
|
|
// TODO: Initialize database
|
|
// TODO: Initialize authentication
|
|
// TODO: Initialize gRPC server for agents
|
|
// TODO: Initialize agent hub
|
|
|
|
// For now, run in standalone-compatible mode
|
|
// Full server mode will be implemented in subsequent sprints
|
|
broker := sse.NewBroker(cfg)
|
|
go broker.Run()
|
|
|
|
server := api.NewServer(cfg, broker)
|
|
|
|
var err error
|
|
if cfg.TLSEnabled {
|
|
log.Printf("Starting HTTPS server on port %s", cfg.Port)
|
|
err = server.RunTLS(cfg.TLSCertFile, cfg.TLSKeyFile)
|
|
} else {
|
|
err = server.Run()
|
|
}
|
|
|
|
if err != nil {
|
|
log.Fatalf("Failed to start server: %v", err)
|
|
}
|
|
}
|
|
|
|
// runAgent starts Tyto as a lightweight agent that reports to a central server.
|
|
func runAgent(cfg *config.Config) {
|
|
if cfg.Agent.ID == "" {
|
|
log.Fatal("Agent ID is required in agent mode (set TYTO_AGENT_ID)")
|
|
}
|
|
if cfg.Agent.ServerURL == "" {
|
|
log.Fatal("Server URL is required in agent mode (set TYTO_SERVER_URL)")
|
|
}
|
|
|
|
log.Printf("Starting Tyto agent '%s'", cfg.Agent.ID)
|
|
log.Printf("Reporting to: %s", cfg.Agent.ServerURL)
|
|
log.Printf("Collection interval: %s", cfg.Agent.Interval)
|
|
|
|
// TODO: Implement gRPC client and metrics collection loop
|
|
// This will be implemented in Sprint 3 (Agent Implementation)
|
|
log.Fatal("Agent mode not yet implemented")
|
|
}
|