Functions for common paths.

This commit is contained in:
2025-10-14 19:23:16 +00:00
parent 679ea18446
commit 67ca1b85be
19 changed files with 114 additions and 60 deletions

View File

@@ -71,8 +71,8 @@ func (api *API) UtilitiesDashboardToken(w http.ResponseWriter, r *http.Request)
return return
} }
// 3. Construct instance-specific paths // 3. Construct instance-specific paths using tools helpers
kubeconfigPath := filepath.Join(api.dataDir, "instances", instanceName, "kubeconfig") kubeconfigPath := tools.GetKubeconfigPath(api.dataDir, instanceName)
// 4. Perform instance-specific operations // 4. Perform instance-specific operations
token, err := utilities.GetDashboardToken(kubeconfigPath) token, err := utilities.GetDashboardToken(kubeconfigPath)
@@ -113,6 +113,6 @@ func GetDashboardToken(kubeconfigPath string) (*DashboardToken, error) {
1. **Instance name in URL**: Always include instance name as a path parameter (`{name}`) 1. **Instance name in URL**: Always include instance name as a path parameter (`{name}`)
2. **Extract from mux.Vars()**: Get instance name from `mux.Vars(r)["name"]`, not from context 2. **Extract from mux.Vars()**: Get instance name from `mux.Vars(r)["name"]`, not from context
3. **Validate instance**: Always validate the instance exists before operations 3. **Validate instance**: Always validate the instance exists before operations
4. **Construct paths explicitly**: Build instance-specific file paths from the instance name 4. **Use path helpers**: Use `tools.GetKubeconfigPath()`, `tools.GetInstanceConfigPath()`, etc. instead of inline `filepath.Join()` constructions
5. **Stateless handlers**: Handlers should not depend on session state or current context 5. **Stateless handlers**: Handlers should not depend on session state or current context
6. **Use tools helpers**: Use `tools.WithKubeconfig()` for kubectl/talosctl commands 6. **Use tools helpers**: Use `tools.WithKubeconfig()` for kubectl/talosctl commands

View File

@@ -7,7 +7,6 @@ import (
"log" "log"
"net/http" "net/http"
"os" "os"
"path/filepath"
"time" "time"
"github.com/gorilla/mux" "github.com/gorilla/mux"
@@ -19,6 +18,7 @@ import (
"github.com/wild-cloud/wild-central/daemon/internal/instance" "github.com/wild-cloud/wild-central/daemon/internal/instance"
"github.com/wild-cloud/wild-central/daemon/internal/operations" "github.com/wild-cloud/wild-central/daemon/internal/operations"
"github.com/wild-cloud/wild-central/daemon/internal/secrets" "github.com/wild-cloud/wild-central/daemon/internal/secrets"
"github.com/wild-cloud/wild-central/daemon/internal/tools"
) )
// API holds all dependencies for API handlers // API holds all dependencies for API handlers
@@ -37,7 +37,7 @@ type API struct {
// Note: Setup files (cluster-services, cluster-nodes, etc.) are now embedded in the binary // Note: Setup files (cluster-services, cluster-nodes, etc.) are now embedded in the binary
func NewAPI(dataDir, appsDir string) (*API, error) { func NewAPI(dataDir, appsDir string) (*API, error) {
// Ensure base directories exist // Ensure base directories exist
instancesDir := filepath.Join(dataDir, "instances") instancesDir := tools.GetInstancesPath(dataDir)
if err := os.MkdirAll(instancesDir, 0755); err != nil { if err := os.MkdirAll(instancesDir, 0755); err != nil {
return nil, fmt.Errorf("failed to create instances directory: %w", err) return nil, fmt.Errorf("failed to create instances directory: %w", err)
} }

View File

@@ -11,6 +11,7 @@ import (
"github.com/gorilla/mux" "github.com/gorilla/mux"
"github.com/wild-cloud/wild-central/daemon/internal/operations" "github.com/wild-cloud/wild-central/daemon/internal/operations"
"github.com/wild-cloud/wild-central/daemon/internal/tools"
) )
// OperationGet returns operation status // OperationGet returns operation status
@@ -110,7 +111,7 @@ func (api *API) OperationStream(w http.ResponseWriter, r *http.Request) {
} }
// Check if operation is already completed // Check if operation is already completed
statusFile := filepath.Join(api.dataDir, "instances", instanceName, "operations", opID+".json") statusFile := filepath.Join(tools.GetInstanceOperationsPath(api.dataDir, instanceName), opID+".json")
isCompleted := false isCompleted := false
if data, err := os.ReadFile(statusFile); err == nil { if data, err := os.ReadFile(statusFile); err == nil {
var op map[string]interface{} var op map[string]interface{}
@@ -122,7 +123,7 @@ func (api *API) OperationStream(w http.ResponseWriter, r *http.Request) {
} }
// Send existing log file content first (if exists) // Send existing log file content first (if exists)
logPath := filepath.Join(api.dataDir, "instances", instanceName, "operations", opID, "output.log") logPath := filepath.Join(tools.GetInstanceOperationsPath(api.dataDir, instanceName), opID, "output.log")
if _, err := os.Stat(logPath); err == nil { if _, err := os.Stat(logPath); err == nil {
file, err := os.Open(logPath) file, err := os.Open(logPath)
if err == nil { if err == nil {

View File

@@ -5,7 +5,6 @@ import (
"fmt" "fmt"
"net/http" "net/http"
"os" "os"
"path/filepath"
"strings" "strings"
"github.com/gorilla/mux" "github.com/gorilla/mux"
@@ -14,6 +13,7 @@ import (
"github.com/wild-cloud/wild-central/daemon/internal/contracts" "github.com/wild-cloud/wild-central/daemon/internal/contracts"
"github.com/wild-cloud/wild-central/daemon/internal/operations" "github.com/wild-cloud/wild-central/daemon/internal/operations"
"github.com/wild-cloud/wild-central/daemon/internal/services" "github.com/wild-cloud/wild-central/daemon/internal/services"
"github.com/wild-cloud/wild-central/daemon/internal/tools"
) )
// ServicesList lists all base services // ServicesList lists all base services
@@ -297,7 +297,7 @@ func (api *API) ServicesGetInstanceConfig(w http.ResponseWriter, r *http.Request
} }
// Load instance config as map for dynamic path extraction // Load instance config as map for dynamic path extraction
configPath := filepath.Join(api.dataDir, "instances", instanceName, "config.yaml") configPath := tools.GetInstanceConfigPath(api.dataDir, instanceName)
configData, err := os.ReadFile(configPath) configData, err := os.ReadFile(configPath)
if err != nil { if err != nil {
respondError(w, http.StatusInternalServerError, fmt.Sprintf("Failed to read instance config: %v", err)) respondError(w, http.StatusInternalServerError, fmt.Sprintf("Failed to read instance config: %v", err))

View File

@@ -4,9 +4,9 @@ import (
"encoding/json" "encoding/json"
"fmt" "fmt"
"net/http" "net/http"
"path/filepath"
"github.com/gorilla/mux" "github.com/gorilla/mux"
"github.com/wild-cloud/wild-central/daemon/internal/tools"
"github.com/wild-cloud/wild-central/daemon/internal/utilities" "github.com/wild-cloud/wild-central/daemon/internal/utilities"
) )
@@ -36,7 +36,7 @@ func (api *API) InstanceUtilitiesHealth(w http.ResponseWriter, r *http.Request)
} }
// Get kubeconfig path for this instance // Get kubeconfig path for this instance
kubeconfigPath := filepath.Join(api.dataDir, "instances", instanceName, "kubeconfig") kubeconfigPath := tools.GetKubeconfigPath(api.dataDir, instanceName)
status, err := utilities.GetClusterHealth(kubeconfigPath) status, err := utilities.GetClusterHealth(kubeconfigPath)
if err != nil { if err != nil {
@@ -62,7 +62,7 @@ func (api *API) UtilitiesDashboardToken(w http.ResponseWriter, r *http.Request)
} }
// Get kubeconfig path for the instance // Get kubeconfig path for the instance
kubeconfigPath := filepath.Join(api.dataDir, "instances", instanceName, "kubeconfig") kubeconfigPath := tools.GetKubeconfigPath(api.dataDir, instanceName)
token, err := utilities.GetDashboardToken(kubeconfigPath) token, err := utilities.GetDashboardToken(kubeconfigPath)
if err != nil { if err != nil {

View File

@@ -115,7 +115,7 @@ func (m *Manager) Get(appName string) (*App, error) {
// ListDeployed lists deployed apps for an instance // ListDeployed lists deployed apps for an instance
func (m *Manager) ListDeployed(instanceName string) ([]DeployedApp, error) { func (m *Manager) ListDeployed(instanceName string) ([]DeployedApp, error) {
kubeconfigPath := tools.GetKubeconfigPath(m.dataDir, instanceName) kubeconfigPath := tools.GetKubeconfigPath(m.dataDir, instanceName)
instancePath := filepath.Join(m.dataDir, "instances", instanceName) instancePath := tools.GetInstancePath(m.dataDir, instanceName)
appsDir := filepath.Join(instancePath, "apps") appsDir := filepath.Join(instancePath, "apps")
apps := []DeployedApp{} apps := []DeployedApp{}
@@ -190,9 +190,9 @@ func (m *Manager) Add(instanceName, appName string, config map[string]string) er
return fmt.Errorf("app %s not found at %s", appName, manifestPath) return fmt.Errorf("app %s not found at %s", appName, manifestPath)
} }
instancePath := filepath.Join(m.dataDir, "instances", instanceName) instancePath := tools.GetInstancePath(m.dataDir, instanceName)
configFile := filepath.Join(instancePath, "config.yaml") configFile := tools.GetInstanceConfigPath(m.dataDir, instanceName)
secretsFile := filepath.Join(instancePath, "secrets.yaml") secretsFile := tools.GetInstanceSecretsPath(m.dataDir, instanceName)
appDestDir := filepath.Join(instancePath, "apps", appName) appDestDir := filepath.Join(instancePath, "apps", appName)
// Check instance config exists // Check instance config exists
@@ -306,8 +306,8 @@ func (m *Manager) Add(instanceName, appName string, config map[string]string) er
// Deploy deploys an app to the cluster // Deploy deploys an app to the cluster
func (m *Manager) Deploy(instanceName, appName string) error { func (m *Manager) Deploy(instanceName, appName string) error {
kubeconfigPath := tools.GetKubeconfigPath(m.dataDir, instanceName) kubeconfigPath := tools.GetKubeconfigPath(m.dataDir, instanceName)
instancePath := filepath.Join(m.dataDir, "instances", instanceName) instancePath := tools.GetInstancePath(m.dataDir, instanceName)
secretsFile := filepath.Join(instancePath, "secrets.yaml") secretsFile := tools.GetInstanceSecretsPath(m.dataDir, instanceName)
// Get compiled app manifests from instance directory // Get compiled app manifests from instance directory
appDir := filepath.Join(instancePath, "apps", appName) appDir := filepath.Join(instancePath, "apps", appName)
@@ -369,9 +369,9 @@ func (m *Manager) Deploy(instanceName, appName string) error {
// Delete removes an app from the cluster and configuration // Delete removes an app from the cluster and configuration
func (m *Manager) Delete(instanceName, appName string) error { func (m *Manager) Delete(instanceName, appName string) error {
kubeconfigPath := tools.GetKubeconfigPath(m.dataDir, instanceName) kubeconfigPath := tools.GetKubeconfigPath(m.dataDir, instanceName)
instancePath := filepath.Join(m.dataDir, "instances", instanceName) instancePath := tools.GetInstancePath(m.dataDir, instanceName)
configFile := filepath.Join(instancePath, "config.yaml") configFile := tools.GetInstanceConfigPath(m.dataDir, instanceName)
secretsFile := filepath.Join(instancePath, "secrets.yaml") secretsFile := tools.GetInstanceSecretsPath(m.dataDir, instanceName)
// Get compiled app manifests from instance directory // Get compiled app manifests from instance directory
appDir := filepath.Join(instancePath, "apps", appName) appDir := filepath.Join(instancePath, "apps", appName)
@@ -425,7 +425,7 @@ func (m *Manager) Delete(instanceName, appName string) error {
// GetStatus returns the status of a deployed app // GetStatus returns the status of a deployed app
func (m *Manager) GetStatus(instanceName, appName string) (*DeployedApp, error) { func (m *Manager) GetStatus(instanceName, appName string) (*DeployedApp, error) {
kubeconfigPath := tools.GetKubeconfigPath(m.dataDir, instanceName) kubeconfigPath := tools.GetKubeconfigPath(m.dataDir, instanceName)
instancePath := filepath.Join(m.dataDir, "instances", instanceName) instancePath := tools.GetInstancePath(m.dataDir, instanceName)
appDir := filepath.Join(instancePath, "apps", appName) appDir := filepath.Join(instancePath, "apps", appName)
app := &DeployedApp{ app := &DeployedApp{

View File

@@ -46,7 +46,7 @@ func NewManager(dataDir string) *Manager {
// GetBackupDir returns the backup directory for an instance // GetBackupDir returns the backup directory for an instance
func (m *Manager) GetBackupDir(instanceName string) string { func (m *Manager) GetBackupDir(instanceName string) string {
return filepath.Join(m.dataDir, "instances", instanceName, "backups") return tools.GetInstanceBackupsPath(m.dataDir, instanceName)
} }
// GetStagingDir returns the staging directory for backups // GetStagingDir returns the staging directory for backups

View File

@@ -48,7 +48,7 @@ type ClusterStatus struct {
// GetTalosDir returns the talos directory for an instance // GetTalosDir returns the talos directory for an instance
func (m *Manager) GetTalosDir(instanceName string) string { func (m *Manager) GetTalosDir(instanceName string) string {
return filepath.Join(m.dataDir, "instances", instanceName, "talos") return tools.GetInstanceTalosPath(m.dataDir, instanceName)
} }
// GetGeneratedDir returns the generated config directory // GetGeneratedDir returns the generated config directory
@@ -99,8 +99,7 @@ func (m *Manager) GenerateConfig(instanceName string, config *ClusterConfig) err
// Bootstrap bootstraps the cluster on the specified node // Bootstrap bootstraps the cluster on the specified node
func (m *Manager) Bootstrap(instanceName, nodeName string) error { func (m *Manager) Bootstrap(instanceName, nodeName string) error {
// Get node configuration to find the target IP // Get node configuration to find the target IP
instancePath := filepath.Join(m.dataDir, "instances", instanceName) configPath := tools.GetInstanceConfigPath(m.dataDir, instanceName)
configPath := filepath.Join(instancePath, "config.yaml")
yq := tools.NewYQ() yq := tools.NewYQ()
@@ -183,8 +182,7 @@ func (m *Manager) retrieveKubeconfigFromCluster(instanceName, nodeIP string, tim
// RegenerateKubeconfig regenerates the kubeconfig by retrieving it from the cluster // RegenerateKubeconfig regenerates the kubeconfig by retrieving it from the cluster
func (m *Manager) RegenerateKubeconfig(instanceName string) error { func (m *Manager) RegenerateKubeconfig(instanceName string) error {
instancePath := filepath.Join(m.dataDir, "instances", instanceName) configPath := tools.GetInstanceConfigPath(m.dataDir, instanceName)
configPath := filepath.Join(instancePath, "config.yaml")
yq := tools.NewYQ() yq := tools.NewYQ()
@@ -206,8 +204,7 @@ func (m *Manager) RegenerateKubeconfig(instanceName string) error {
// ConfigureEndpoints updates talosconfig to use VIP and retrieves kubeconfig // ConfigureEndpoints updates talosconfig to use VIP and retrieves kubeconfig
func (m *Manager) ConfigureEndpoints(instanceName string, includeNodes bool) error { func (m *Manager) ConfigureEndpoints(instanceName string, includeNodes bool) error {
instancePath := filepath.Join(m.dataDir, "instances", instanceName) configPath := tools.GetInstanceConfigPath(m.dataDir, instanceName)
configPath := filepath.Join(instancePath, "config.yaml")
talosconfigPath := tools.GetTalosconfigPath(m.dataDir, instanceName) talosconfigPath := tools.GetTalosconfigPath(m.dataDir, instanceName)
yq := tools.NewYQ() yq := tools.NewYQ()

View File

@@ -152,16 +152,19 @@ func (m *Manager) CopyConfig(srcPath, dstPath string) error {
} }
// GetInstanceConfigPath returns the path to an instance's config file // GetInstanceConfigPath returns the path to an instance's config file
// Deprecated: Use tools.GetInstanceConfigPath instead
func GetInstanceConfigPath(dataDir, instanceName string) string { func GetInstanceConfigPath(dataDir, instanceName string) string {
return filepath.Join(dataDir, "instances", instanceName, "config.yaml") return tools.GetInstanceConfigPath(dataDir, instanceName)
} }
// GetInstanceSecretsPath returns the path to an instance's secrets file // GetInstanceSecretsPath returns the path to an instance's secrets file
// Deprecated: Use tools.GetInstanceSecretsPath instead
func GetInstanceSecretsPath(dataDir, instanceName string) string { func GetInstanceSecretsPath(dataDir, instanceName string) string {
return filepath.Join(dataDir, "instances", instanceName, "secrets.yaml") return tools.GetInstanceSecretsPath(dataDir, instanceName)
} }
// GetInstancePath returns the path to an instance directory // GetInstancePath returns the path to an instance directory
// Deprecated: Use tools.GetInstancePath instead
func GetInstancePath(dataDir, instanceName string) string { func GetInstancePath(dataDir, instanceName string) string {
return filepath.Join(dataDir, "instances", instanceName) return tools.GetInstancePath(dataDir, instanceName)
} }

View File

@@ -6,6 +6,7 @@ import (
"strings" "strings"
"github.com/wild-cloud/wild-central/daemon/internal/storage" "github.com/wild-cloud/wild-central/daemon/internal/storage"
"github.com/wild-cloud/wild-central/daemon/internal/tools"
) )
// Manager handles current instance context tracking // Manager handles current instance context tracking
@@ -53,7 +54,7 @@ func (m *Manager) SetCurrentContext(instanceName string) error {
} }
// Verify instance exists // Verify instance exists
instancePath := filepath.Join(m.dataDir, "instances", instanceName) instancePath := tools.GetInstancePath(m.dataDir, instanceName)
if !storage.FileExists(instancePath) { if !storage.FileExists(instancePath) {
return fmt.Errorf("instance %s does not exist", instanceName) return fmt.Errorf("instance %s does not exist", instanceName)
} }
@@ -101,7 +102,7 @@ func (m *Manager) ValidateContext() error {
return err return err
} }
instancePath := filepath.Join(m.dataDir, "instances", contextName) instancePath := tools.GetInstancePath(m.dataDir, contextName)
if !storage.FileExists(instancePath) { if !storage.FileExists(instancePath) {
return fmt.Errorf("current context %s points to non-existent instance", contextName) return fmt.Errorf("current context %s points to non-existent instance", contextName)
} }
@@ -116,7 +117,7 @@ func (m *Manager) GetCurrentInstancePath() (string, error) {
return "", err return "", err
} }
return filepath.Join(m.dataDir, "instances", contextName), nil return tools.GetInstancePath(m.dataDir, contextName), nil
} }
// GetCurrentInstanceConfigPath returns the path to the current instance's config file // GetCurrentInstanceConfigPath returns the path to the current instance's config file

View File

@@ -24,7 +24,7 @@ type Manager struct {
// NewManager creates a new discovery manager // NewManager creates a new discovery manager
func NewManager(dataDir string, instanceName string) *Manager { func NewManager(dataDir string, instanceName string) *Manager {
// Get talosconfig path for the instance // Get talosconfig path for the instance
talosconfigPath := filepath.Join(dataDir, "instances", instanceName, "setup", "cluster-nodes", "generated", "talosconfig") talosconfigPath := tools.GetTalosconfigPath(dataDir, instanceName)
return &Manager{ return &Manager{
dataDir: dataDir, dataDir: dataDir,
@@ -53,7 +53,7 @@ type DiscoveryStatus struct {
// GetDiscoveryDir returns the discovery directory for an instance // GetDiscoveryDir returns the discovery directory for an instance
func (m *Manager) GetDiscoveryDir(instanceName string) string { func (m *Manager) GetDiscoveryDir(instanceName string) string {
return filepath.Join(m.dataDir, "instances", instanceName, "discovery") return tools.GetInstanceDiscoveryPath(m.dataDir, instanceName)
} }
// GetDiscoveryStatusPath returns the path to discovery status file // GetDiscoveryStatusPath returns the path to discovery status file

View File

@@ -9,6 +9,7 @@ import (
"github.com/wild-cloud/wild-central/daemon/internal/context" "github.com/wild-cloud/wild-central/daemon/internal/context"
"github.com/wild-cloud/wild-central/daemon/internal/secrets" "github.com/wild-cloud/wild-central/daemon/internal/secrets"
"github.com/wild-cloud/wild-central/daemon/internal/storage" "github.com/wild-cloud/wild-central/daemon/internal/storage"
"github.com/wild-cloud/wild-central/daemon/internal/tools"
) )
// Manager handles instance lifecycle operations // Manager handles instance lifecycle operations
@@ -38,18 +39,21 @@ type Instance struct {
} }
// GetInstancePath returns the path to an instance directory // GetInstancePath returns the path to an instance directory
// Deprecated: Use tools.GetInstancePath instead
func (m *Manager) GetInstancePath(name string) string { func (m *Manager) GetInstancePath(name string) string {
return filepath.Join(m.dataDir, "instances", name) return tools.GetInstancePath(m.dataDir, name)
} }
// GetInstanceConfigPath returns the path to an instance's config file // GetInstanceConfigPath returns the path to an instance's config file
// Deprecated: Use tools.GetInstanceConfigPath instead
func (m *Manager) GetInstanceConfigPath(name string) string { func (m *Manager) GetInstanceConfigPath(name string) string {
return filepath.Join(m.GetInstancePath(name), "config.yaml") return tools.GetInstanceConfigPath(m.dataDir, name)
} }
// GetInstanceSecretsPath returns the path to an instance's secrets file // GetInstanceSecretsPath returns the path to an instance's secrets file
// Deprecated: Use tools.GetInstanceSecretsPath instead
func (m *Manager) GetInstanceSecretsPath(name string) string { func (m *Manager) GetInstanceSecretsPath(name string) string {
return filepath.Join(m.GetInstancePath(name), "secrets.yaml") return tools.GetInstanceSecretsPath(m.dataDir, name)
} }
// InstanceExists checks if an instance exists // InstanceExists checks if an instance exists
@@ -71,7 +75,7 @@ func (m *Manager) CreateInstance(name string) error {
} }
// Acquire lock for instance creation // Acquire lock for instance creation
lockPath := filepath.Join(m.dataDir, "instances", ".lock") lockPath := tools.GetInstancesLockPath(m.dataDir)
return storage.WithLock(lockPath, func() error { return storage.WithLock(lockPath, func() error {
// Create instance directory // Create instance directory
if err := storage.EnsureDir(instancePath, 0755); err != nil { if err := storage.EnsureDir(instancePath, 0755); err != nil {
@@ -123,7 +127,7 @@ func (m *Manager) DeleteInstance(name string) error {
} }
// Acquire lock for instance deletion // Acquire lock for instance deletion
lockPath := filepath.Join(m.dataDir, "instances", ".lock") lockPath := tools.GetInstancesLockPath(m.dataDir)
return storage.WithLock(lockPath, func() error { return storage.WithLock(lockPath, func() error {
// Remove instance directory // Remove instance directory
if err := os.RemoveAll(instancePath); err != nil { if err := os.RemoveAll(instancePath); err != nil {
@@ -136,7 +140,7 @@ func (m *Manager) DeleteInstance(name string) error {
// ListInstances returns a list of all instance names // ListInstances returns a list of all instance names
func (m *Manager) ListInstances() ([]string, error) { func (m *Manager) ListInstances() ([]string, error) {
instancesDir := filepath.Join(m.dataDir, "instances") instancesDir := tools.GetInstancesPath(m.dataDir)
// Ensure instances directory exists // Ensure instances directory exists
if !storage.FileExists(instancesDir) { if !storage.FileExists(instancesDir) {

View File

@@ -59,7 +59,7 @@ type ApplyOptions struct {
// GetInstancePath returns the path to an instance's nodes directory // GetInstancePath returns the path to an instance's nodes directory
func (m *Manager) GetInstancePath(instanceName string) string { func (m *Manager) GetInstancePath(instanceName string) string {
return filepath.Join(m.dataDir, "instances", instanceName) return tools.GetInstancePath(m.dataDir, instanceName)
} }
// List returns all nodes for an instance // List returns all nodes for an instance

View File

@@ -8,6 +8,7 @@ import (
"time" "time"
"github.com/wild-cloud/wild-central/daemon/internal/storage" "github.com/wild-cloud/wild-central/daemon/internal/storage"
"github.com/wild-cloud/wild-central/daemon/internal/tools"
) )
// Manager handles async operation tracking // Manager handles async operation tracking
@@ -38,7 +39,7 @@ type Operation struct {
// GetOperationsDir returns the operations directory for an instance // GetOperationsDir returns the operations directory for an instance
func (m *Manager) GetOperationsDir(instanceName string) string { func (m *Manager) GetOperationsDir(instanceName string) string {
return filepath.Join(m.dataDir, "instances", instanceName, "operations") return tools.GetInstanceOperationsPath(m.dataDir, instanceName)
} }
// generateID generates a unique operation ID // generateID generates a unique operation ID

View File

@@ -9,6 +9,7 @@ import (
"path/filepath" "path/filepath"
"github.com/wild-cloud/wild-central/daemon/internal/storage" "github.com/wild-cloud/wild-central/daemon/internal/storage"
"github.com/wild-cloud/wild-central/daemon/internal/tools"
) )
// Manager handles PXE boot asset management // Manager handles PXE boot asset management
@@ -35,7 +36,7 @@ type Asset struct {
// GetPXEDir returns the PXE directory for an instance // GetPXEDir returns the PXE directory for an instance
func (m *Manager) GetPXEDir(instanceName string) string { func (m *Manager) GetPXEDir(instanceName string) string {
return filepath.Join(m.dataDir, "instances", instanceName, "pxe") return tools.GetInstancePXEPath(m.dataDir, instanceName)
} }
// ListAssets returns available PXE assets for an instance // ListAssets returns available PXE assets for an instance

View File

@@ -3,7 +3,6 @@ package services
import ( import (
"fmt" "fmt"
"os" "os"
"path/filepath"
"strings" "strings"
"gopkg.in/yaml.v3" "gopkg.in/yaml.v3"
@@ -11,6 +10,7 @@ import (
"github.com/wild-cloud/wild-central/daemon/internal/contracts" "github.com/wild-cloud/wild-central/daemon/internal/contracts"
"github.com/wild-cloud/wild-central/daemon/internal/operations" "github.com/wild-cloud/wild-central/daemon/internal/operations"
"github.com/wild-cloud/wild-central/daemon/internal/storage" "github.com/wild-cloud/wild-central/daemon/internal/storage"
"github.com/wild-cloud/wild-central/daemon/internal/tools"
) )
// UpdateConfig updates service configuration and optionally redeploys // UpdateConfig updates service configuration and optionally redeploys
@@ -27,8 +27,7 @@ func (m *Manager) UpdateConfig(instanceName, serviceName string, update contract
} }
// 2. Load instance config // 2. Load instance config
instanceDir := filepath.Join(m.dataDir, "instances", instanceName) configPath := tools.GetInstanceConfigPath(m.dataDir, instanceName)
configPath := filepath.Join(instanceDir, "config.yaml")
if !storage.FileExists(configPath) { if !storage.FileExists(configPath) {
return nil, fmt.Errorf("config file not found for instance %s", instanceName) return nil, fmt.Errorf("config file not found for instance %s", instanceName)

View File

@@ -264,7 +264,7 @@ func (m *Manager) Delete(instanceName, serviceName string) error {
} }
// Get manifests file from embedded setup or instance directory // Get manifests file from embedded setup or instance directory
instanceServiceDir := filepath.Join(m.dataDir, "instances", instanceName, "setup", "cluster-services", serviceName) instanceServiceDir := filepath.Join(tools.GetInstancePath(m.dataDir, instanceName), "setup", "cluster-services", serviceName)
manifestsFile := filepath.Join(instanceServiceDir, "manifests.yaml") manifestsFile := filepath.Join(instanceServiceDir, "manifests.yaml")
if !storage.FileExists(manifestsFile) { if !storage.FileExists(manifestsFile) {
@@ -332,7 +332,7 @@ func (m *Manager) Fetch(instanceName, serviceName string) error {
} }
// 2. Create instance service directory // 2. Create instance service directory
instanceDir := filepath.Join(m.dataDir, "instances", instanceName, instanceDir := filepath.Join(tools.GetInstancePath(m.dataDir, instanceName),
"setup", "cluster-services", serviceName) "setup", "cluster-services", serviceName)
if err := os.MkdirAll(instanceDir, 0755); err != nil { if err := os.MkdirAll(instanceDir, 0755); err != nil {
return fmt.Errorf("failed to create service directory: %w", err) return fmt.Errorf("failed to create service directory: %w", err)
@@ -376,7 +376,7 @@ func (m *Manager) Fetch(instanceName, serviceName string) error {
// serviceFilesExist checks if service files exist in the instance // serviceFilesExist checks if service files exist in the instance
func (m *Manager) serviceFilesExist(instanceName, serviceName string) bool { func (m *Manager) serviceFilesExist(instanceName, serviceName string) bool {
serviceDir := filepath.Join(m.dataDir, "instances", instanceName, serviceDir := filepath.Join(tools.GetInstancePath(m.dataDir, instanceName),
"setup", "cluster-services", serviceName) "setup", "cluster-services", serviceName)
installSh := filepath.Join(serviceDir, "install.sh") installSh := filepath.Join(serviceDir, "install.sh")
return fileExists(installSh) return fileExists(installSh)
@@ -422,7 +422,7 @@ func extractFS(fsys fs.FS, dst string) error {
// Compile processes gomplate templates into final Kubernetes manifests // Compile processes gomplate templates into final Kubernetes manifests
func (m *Manager) Compile(instanceName, serviceName string) error { func (m *Manager) Compile(instanceName, serviceName string) error {
instanceDir := filepath.Join(m.dataDir, "instances", instanceName) instanceDir := tools.GetInstancePath(m.dataDir, instanceName)
serviceDir := filepath.Join(instanceDir, "setup", "cluster-services", serviceName) serviceDir := filepath.Join(instanceDir, "setup", "cluster-services", serviceName)
templateDir := filepath.Join(serviceDir, "kustomize.template") templateDir := filepath.Join(serviceDir, "kustomize.template")
outputDir := filepath.Join(serviceDir, "kustomize") outputDir := filepath.Join(serviceDir, "kustomize")
@@ -500,7 +500,7 @@ func (m *Manager) Compile(instanceName, serviceName string) error {
func (m *Manager) Deploy(instanceName, serviceName, opID string, broadcaster *operations.Broadcaster) error { func (m *Manager) Deploy(instanceName, serviceName, opID string, broadcaster *operations.Broadcaster) error {
fmt.Printf("[DEBUG] Deploy() called for service=%s instance=%s opID=%s\n", serviceName, instanceName, opID) fmt.Printf("[DEBUG] Deploy() called for service=%s instance=%s opID=%s\n", serviceName, instanceName, opID)
instanceDir := filepath.Join(m.dataDir, "instances", instanceName) instanceDir := tools.GetInstancePath(m.dataDir, instanceName)
serviceDir := filepath.Join(instanceDir, "setup", "cluster-services", serviceName) serviceDir := filepath.Join(instanceDir, "setup", "cluster-services", serviceName)
installScript := filepath.Join(serviceDir, "install.sh") installScript := filepath.Join(serviceDir, "install.sh")
@@ -596,8 +596,7 @@ func (m *Manager) validateConfig(instanceName, serviceName string) error {
} }
// Load instance config // Load instance config
instanceDir := filepath.Join(m.dataDir, "instances", instanceName) configFile := tools.GetInstanceConfigPath(m.dataDir, instanceName)
configFile := filepath.Join(instanceDir, "config.yaml")
configData, err := os.ReadFile(configFile) configData, err := os.ReadFile(configFile)
if err != nil { if err != nil {

View File

@@ -3,7 +3,6 @@ package services
import ( import (
"fmt" "fmt"
"os" "os"
"path/filepath"
"time" "time"
"gopkg.in/yaml.v3" "gopkg.in/yaml.v3"
@@ -91,8 +90,7 @@ func (m *Manager) GetDetailedStatus(instanceName, serviceName string) (*contract
} }
// 5. Load current config values // 5. Load current config values
instanceDir := filepath.Join(m.dataDir, "instances", instanceName) configPath := tools.GetInstanceConfigPath(m.dataDir, instanceName)
configPath := filepath.Join(instanceDir, "config.yaml")
configValues := make(map[string]interface{}) configValues := make(map[string]interface{})
if storage.FileExists(configPath) { if storage.FileExists(configPath) {

View File

@@ -35,3 +35,53 @@ func GetTalosconfigPath(dataDir, instanceName string) string {
func GetKubeconfigPath(dataDir, instanceName string) string { func GetKubeconfigPath(dataDir, instanceName string) string {
return filepath.Join(dataDir, "instances", instanceName, "kubeconfig") return filepath.Join(dataDir, "instances", instanceName, "kubeconfig")
} }
// GetInstancePath returns the path to an instance directory
func GetInstancePath(dataDir, instanceName string) string {
return filepath.Join(dataDir, "instances", instanceName)
}
// GetInstanceConfigPath returns the path to an instance's config file
func GetInstanceConfigPath(dataDir, instanceName string) string {
return filepath.Join(dataDir, "instances", instanceName, "config.yaml")
}
// GetInstanceSecretsPath returns the path to an instance's secrets file
func GetInstanceSecretsPath(dataDir, instanceName string) string {
return filepath.Join(dataDir, "instances", instanceName, "secrets.yaml")
}
// GetInstanceTalosPath returns the path to an instance's talos directory
func GetInstanceTalosPath(dataDir, instanceName string) string {
return filepath.Join(dataDir, "instances", instanceName, "talos")
}
// GetInstancePXEPath returns the path to an instance's PXE directory
func GetInstancePXEPath(dataDir, instanceName string) string {
return filepath.Join(dataDir, "instances", instanceName, "pxe")
}
// GetInstanceOperationsPath returns the path to an instance's operations directory
func GetInstanceOperationsPath(dataDir, instanceName string) string {
return filepath.Join(dataDir, "instances", instanceName, "operations")
}
// GetInstanceBackupsPath returns the path to an instance's backups directory
func GetInstanceBackupsPath(dataDir, instanceName string) string {
return filepath.Join(dataDir, "instances", instanceName, "backups")
}
// GetInstanceDiscoveryPath returns the path to an instance's discovery directory
func GetInstanceDiscoveryPath(dataDir, instanceName string) string {
return filepath.Join(dataDir, "instances", instanceName, "discovery")
}
// GetInstancesPath returns the path to the instances directory
func GetInstancesPath(dataDir string) string {
return filepath.Join(dataDir, "instances")
}
// GetInstancesLockPath returns the path to the instances directory lock file
func GetInstancesLockPath(dataDir string) string {
return filepath.Join(dataDir, "instances", ".lock")
}