Experimental daemon.
This commit is contained in:
@@ -11,9 +11,9 @@ import (
|
|||||||
// Config represents the main configuration structure
|
// Config represents the main configuration structure
|
||||||
type Config struct {
|
type Config struct {
|
||||||
Wildcloud struct {
|
Wildcloud struct {
|
||||||
Repository string `yaml:"repository" json:"repository"`
|
Repository string `yaml:"repository" json:"repository"`
|
||||||
CurrentPhase string `yaml:"currentPhase" json:"currentPhase"`
|
CurrentPhase string `yaml:"currentPhase" json:"currentPhase"`
|
||||||
CompletedPhases []string `yaml:"completedPhases" json:"completedPhases"`
|
CompletedPhases []string `yaml:"completedPhases" json:"completedPhases"`
|
||||||
} `yaml:"wildcloud" json:"wildcloud"`
|
} `yaml:"wildcloud" json:"wildcloud"`
|
||||||
Server struct {
|
Server struct {
|
||||||
Port int `yaml:"port" json:"port"`
|
Port int `yaml:"port" json:"port"`
|
||||||
@@ -86,9 +86,9 @@ func (c *Config) IsEmpty() bool {
|
|||||||
if c == nil {
|
if c == nil {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if any essential fields are empty
|
// Check if any essential fields are empty
|
||||||
return c.Cloud.Domain == "" ||
|
return c.Cloud.Domain == "" ||
|
||||||
c.Cloud.DNS.IP == "" ||
|
c.Cloud.DNS.IP == "" ||
|
||||||
c.Cluster.Nodes.Talos.Version == ""
|
c.Cluster.Nodes.Talos.Version == ""
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ func NewManager() *Manager {
|
|||||||
func (m *Manager) Initialize() error {
|
func (m *Manager) Initialize() error {
|
||||||
// Detect environment: development vs production
|
// Detect environment: development vs production
|
||||||
m.isDev = m.isDevelopmentMode()
|
m.isDev = m.isDevelopmentMode()
|
||||||
|
|
||||||
var dataDir string
|
var dataDir string
|
||||||
if m.isDev {
|
if m.isDev {
|
||||||
// Development mode: use .wildcloud in current directory
|
// Development mode: use .wildcloud in current directory
|
||||||
@@ -47,19 +47,19 @@ func (m *Manager) Initialize() error {
|
|||||||
dataDir = "/var/lib/wild-cloud-central"
|
dataDir = "/var/lib/wild-cloud-central"
|
||||||
log.Printf("Running in production mode, using data directory: %s", dataDir)
|
log.Printf("Running in production mode, using data directory: %s", dataDir)
|
||||||
}
|
}
|
||||||
|
|
||||||
m.dataDir = dataDir
|
m.dataDir = dataDir
|
||||||
|
|
||||||
// Create directory structure
|
// Create directory structure
|
||||||
paths := m.GetPaths()
|
paths := m.GetPaths()
|
||||||
|
|
||||||
// Create all necessary directories
|
// Create all necessary directories
|
||||||
for _, dir := range []string{paths.DataDir, paths.LogsDir, paths.AssetsDir} {
|
for _, dir := range []string{paths.DataDir, paths.LogsDir, paths.AssetsDir} {
|
||||||
if err := os.MkdirAll(dir, 0755); err != nil {
|
if err := os.MkdirAll(dir, 0755); err != nil {
|
||||||
return fmt.Errorf("failed to create directory %s: %w", dir, err)
|
return fmt.Errorf("failed to create directory %s: %w", dir, err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Printf("Data directory structure initialized at: %s", dataDir)
|
log.Printf("Data directory structure initialized at: %s", dataDir)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@@ -67,17 +67,17 @@ func (m *Manager) Initialize() error {
|
|||||||
// isDevelopmentMode detects if we're running in development mode
|
// isDevelopmentMode detects if we're running in development mode
|
||||||
func (m *Manager) isDevelopmentMode() bool {
|
func (m *Manager) isDevelopmentMode() bool {
|
||||||
// Check multiple indicators for development mode
|
// Check multiple indicators for development mode
|
||||||
|
|
||||||
// 1. Check if GO_ENV is set to development
|
// 1. Check if GO_ENV is set to development
|
||||||
if env := os.Getenv("GO_ENV"); env == "development" {
|
if env := os.Getenv("GO_ENV"); env == "development" {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
// 2. Check if running as systemd service (has INVOCATION_ID)
|
// 2. Check if running as systemd service (has INVOCATION_ID)
|
||||||
if os.Getenv("INVOCATION_ID") != "" {
|
if os.Getenv("INVOCATION_ID") != "" {
|
||||||
return false // Running under systemd
|
return false // Running under systemd
|
||||||
}
|
}
|
||||||
|
|
||||||
// 3. Check if running from a typical development location
|
// 3. Check if running from a typical development location
|
||||||
if exe, err := os.Executable(); err == nil {
|
if exe, err := os.Executable(); err == nil {
|
||||||
// If executable is in current directory or contains "wild-central" without being in /usr/bin
|
// If executable is in current directory or contains "wild-central" without being in /usr/bin
|
||||||
@@ -88,12 +88,12 @@ func (m *Manager) isDevelopmentMode() bool {
|
|||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 4. Check if we can write to /var/lib (if not, probably development)
|
// 4. Check if we can write to /var/lib (if not, probably development)
|
||||||
if _, err := os.Stat("/var/lib"); err != nil {
|
if _, err := os.Stat("/var/lib"); err != nil {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
// 5. Default to development if uncertain
|
// 5. Default to development if uncertain
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
@@ -127,4 +127,4 @@ func (m *Manager) GetDataDir() string {
|
|||||||
// IsDevelopment returns true if running in development mode
|
// IsDevelopment returns true if running in development mode
|
||||||
func (m *Manager) IsDevelopment() bool {
|
func (m *Manager) IsDevelopment() bool {
|
||||||
return m.isDev
|
return m.isDev
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -94,4 +94,4 @@ func (g *ConfigGenerator) RestartService() error {
|
|||||||
return fmt.Errorf("failed to restart dnsmasq: %w", err)
|
return fmt.Errorf("failed to restart dnsmasq: %w", err)
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ func (app *App) GetDnsmasqConfigHandler(w http.ResponseWriter, r *http.Request)
|
|||||||
http.Error(w, "No configuration available. Please configure the system first.", http.StatusPreconditionFailed)
|
http.Error(w, "No configuration available. Please configure the system first.", http.StatusPreconditionFailed)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
config := app.DnsmasqManager.Generate(app.Config)
|
config := app.DnsmasqManager.Generate(app.Config)
|
||||||
w.Header().Set("Content-Type", "text/plain")
|
w.Header().Set("Content-Type", "text/plain")
|
||||||
w.Write([]byte(config))
|
w.Write([]byte(config))
|
||||||
@@ -42,4 +42,4 @@ func (app *App) RestartDnsmasqHandler(w http.ResponseWriter, r *http.Request) {
|
|||||||
|
|
||||||
w.Header().Set("Content-Type", "application/json")
|
w.Header().Set("Content-Type", "application/json")
|
||||||
json.NewEncoder(w).Encode(map[string]string{"status": "restarted"})
|
json.NewEncoder(w).Encode(map[string]string{"status": "restarted"})
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ func (app *App) downloadTalosAssets() error {
|
|||||||
// Get assets directory from data paths
|
// Get assets directory from data paths
|
||||||
paths := app.DataManager.GetPaths()
|
paths := app.DataManager.GetPaths()
|
||||||
assetsDir := filepath.Join(paths.AssetsDir, "talos")
|
assetsDir := filepath.Join(paths.AssetsDir, "talos")
|
||||||
|
|
||||||
log.Printf("Downloading Talos assets to: %s", assetsDir)
|
log.Printf("Downloading Talos assets to: %s", assetsDir)
|
||||||
if err := os.MkdirAll(filepath.Join(assetsDir, "amd64"), 0755); err != nil {
|
if err := os.MkdirAll(filepath.Join(assetsDir, "amd64"), 0755); err != nil {
|
||||||
return fmt.Errorf("creating assets directory: %w", err)
|
return fmt.Errorf("creating assets directory: %w", err)
|
||||||
@@ -93,7 +93,7 @@ boot
|
|||||||
return fmt.Errorf("writing boot script: %w", err)
|
return fmt.Errorf("writing boot script: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Download iPXE bootloaders
|
// Download iPXE bootloaders
|
||||||
tftpDir := filepath.Join(paths.AssetsDir, "tftp")
|
tftpDir := filepath.Join(paths.AssetsDir, "tftp")
|
||||||
if err := os.MkdirAll(tftpDir, 0755); err != nil {
|
if err := os.MkdirAll(tftpDir, 0755); err != nil {
|
||||||
return fmt.Errorf("creating tftp directory: %w", err)
|
return fmt.Errorf("creating tftp directory: %w", err)
|
||||||
@@ -135,4 +135,4 @@ func downloadFile(url, filepath string) error {
|
|||||||
|
|
||||||
_, err = io.Copy(out, resp.Body)
|
_, err = io.Copy(out, resp.Body)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -54,7 +54,7 @@ func main() {
|
|||||||
func setupRoutes(app *handlers.App, router *mux.Router) {
|
func setupRoutes(app *handlers.App, router *mux.Router) {
|
||||||
// Add CORS middleware
|
// Add CORS middleware
|
||||||
router.Use(app.CORSMiddleware)
|
router.Use(app.CORSMiddleware)
|
||||||
|
|
||||||
// API v1 routes
|
// API v1 routes
|
||||||
router.HandleFunc("/api/v1/health", app.HealthHandler).Methods("GET")
|
router.HandleFunc("/api/v1/health", app.HealthHandler).Methods("GET")
|
||||||
router.HandleFunc("/api/v1/config", app.GetConfigHandler).Methods("GET")
|
router.HandleFunc("/api/v1/config", app.GetConfigHandler).Methods("GET")
|
||||||
@@ -65,10 +65,10 @@ func setupRoutes(app *handlers.App, router *mux.Router) {
|
|||||||
router.HandleFunc("/api/v1/dnsmasq/config", app.GetDnsmasqConfigHandler).Methods("GET")
|
router.HandleFunc("/api/v1/dnsmasq/config", app.GetDnsmasqConfigHandler).Methods("GET")
|
||||||
router.HandleFunc("/api/v1/dnsmasq/restart", app.RestartDnsmasqHandler).Methods("POST")
|
router.HandleFunc("/api/v1/dnsmasq/restart", app.RestartDnsmasqHandler).Methods("POST")
|
||||||
router.HandleFunc("/api/v1/pxe/assets", app.DownloadPXEAssetsHandler).Methods("POST")
|
router.HandleFunc("/api/v1/pxe/assets", app.DownloadPXEAssetsHandler).Methods("POST")
|
||||||
|
|
||||||
// UI-specific endpoints
|
// UI-specific endpoints
|
||||||
router.HandleFunc("/api/status", app.StatusHandler).Methods("GET")
|
router.HandleFunc("/api/status", app.StatusHandler).Methods("GET")
|
||||||
|
|
||||||
// Serve static files
|
// Serve static files
|
||||||
router.PathPrefix("/").Handler(http.FileServer(http.Dir("./static/")))
|
router.PathPrefix("/").Handler(http.FileServer(http.Dir("./static/")))
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user