app

package
v0.7.2 Latest Latest
Warning

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

Go to latest
Published: Jun 17, 2026 License: Apache-2.0 Imports: 25 Imported by: 0

Documentation

Overview

Package app provides application bootstrap, lifecycle management, and configuration management for muster.

This package implements the central application lifecycle control following the API Service Locator Pattern and clean separation of concerns. It handles initialization, configuration loading and management, service setup, API adapter registration, and execution mode determination.

Architecture Overview

The app package serves as the application's bootstrap layer and configuration bridge, with five core components:

1. **Bootstrap (`bootstrap.go`)**: Application initialization and lifecycle management 2. **Configuration (`config.go`)**: Application runtime configuration structure 3. **Configuration Adapter (`config_adapter.go`)**: API integration and MCP configuration tools 4. **Services (`services.go`)**: Service initialization, registration, and dependency management 5. **Modes (`modes.go`)**: Execution mode handlers

Core Components

## Bootstrap (bootstrap.go)

The bootstrap component handles the complete application initialization sequence:

  • **Logging Configuration**: Sets up logging based on debug flags and execution mode
  • **Configuration Loading**: Supports both layered and single-path configuration strategies
  • **Service Initialization**: Creates and initializes all required services and API adapters
  • **Mode Selection**: Determines and executes appropriate execution mode based on configuration

### Configuration Loading Strategies

**Layered Configuration (Default)**:

  1. Default configuration (embedded in binary)
  2. User configuration (~/.config/muster/config.yaml)
  3. Project configuration (./.muster/config.yaml)

**Single Path Configuration**:

  • Loads from specified directory only
  • Useful for testing and deployment scenarios

## Configuration Management (config.go & config_adapter.go)

The configuration system has two layers:

**Application Configuration (`config.go`)**:

  • Runtime settings: debug flags, safety settings
  • Configuration loading behavior control
  • Bootstrap args and preferences

**Configuration Adapter (`config_adapter.go`)**:

  • Implements `api.ConfigHandler` interface
  • Provides thread-safe configuration access and updates
  • Exposes MCP tools for external configuration management
  • Handles configuration persistence and reloading
  • Supports both project-local and user-global configuration files

### MCP Configuration Tools

The ConfigAdapter exposes the following MCP tools for external clients:

  • `config_get`: Retrieve complete muster configuration
  • `config_get_aggregator`: Get aggregator-specific settings
  • `config_get_global_settings`: Get global configuration settings
  • `config_update_aggregator`: Update aggregator configuration
  • `config_update_global_settings`: Update global settings
  • `config_save`: Persist current configuration to disk
  • `config_reload`: Reload configuration from disk and trigger component reloads

## Service Management (services.go)

The Services component implements comprehensive service initialization following the API Service Locator Pattern:

### Initialization Sequence

  1. **Storage Creation**: Shared configuration storage for persistence
  2. **API Interfaces**: Tool checker and caller for service integration
  3. **Orchestrator Setup**: Core service lifecycle manager initialization
  4. **Service Registry**: Dependency injection and service discovery setup
  5. **API Adapter Registration**: Register all service adapters with API layer (CRITICAL)
  6. **Manager Creation**: Workflow and MCPServer managers
  7. **Definition Loading**: Load component definitions from configuration directories
  8. **Service Instantiation**: Create concrete service instances from definitions
  9. **Aggregator Service**: MCP aggregator for external tool access (when enabled)

### Service Dependencies and Registration

**Critical Ordering**: API adapters MUST be registered before API interfaces are created. This ensures handlers are available when APIs attempt to locate them.

**Auto-Start Services**: Services with `AutoStart=true` are automatically registered with the orchestrator and started during application launch.

**Service Types Managed**:

  • MCP Server services (external MCP protocol servers)
  • Aggregator service (tool aggregation and MCP endpoint)
  • Workflow execution services

## Execution Modes (modes.go)

### Server Mode Activated by default:

  • **Purpose**: Separation of concerns between client integration and actual application logic
  • **Logging**: Text-based output to stdout/stderr
  • **Lifecycle**: Start services → Wait for signals → Graceful shutdown
  • **Signals**: SIGINT (Ctrl+C), SIGTERM handled for graceful shutdown
  • **Use Cases**: systemd services, run in a Kubernetes cluster

Configuration Persistence Strategy

The ConfigAdapter implements intelligent configuration file management:

**Path Resolution Priority**:

  1. Custom path (if specified via `ConfigPath`)
  2. Project configuration (`./.muster/config.yaml`)
  3. User configuration (`~/.config/muster/config.yaml`)

**Automatic Directory Creation**: Creates necessary directories when saving configuration

**Thread Safety**: All configuration access is protected with read-write mutex

Usage Patterns

## Standard Application Startup

cfg := app.NewConfig(true, false, "")  // debug enabled
application, err := app.NewApplication(cfg)
if err != nil {
    return fmt.Errorf("bootstrap failed: %w", err)
}
return application.Run(ctx)

## Custom Configuration Path

cfg := app.NewConfig(false, false, "/opt/muster/config")
application, err := app.NewApplication(cfg)
if err != nil {
    return fmt.Errorf("bootstrap failed: %w", err)
}
return application.Run(ctx)

## Debug Mode for Development

cfg := app.NewConfig(true, true, "")  // debug, yolo mode
application, err := app.NewApplication(cfg)
if err != nil {
    return fmt.Errorf("bootstrap failed: %w", err)
}
return application.Run(ctx)

API Service Locator Pattern Compliance

The app package strictly follows the architectural principle that all inter-package communication goes through the central API layer:

**Adapter Registration**: Each service creates an API adapter that implements the corresponding handler interface and registers itself with the API layer.

**Service Discovery**: Components retrieve other services through `api.GetXXX()` methods rather than direct package imports.

**Dependency Flow**: app → api ← other packages (one-way dependency)

Error Handling and Resilience

**Fail-Fast Approach**: Critical components (storage, orchestrator, API registration) cause immediate initialization failure if they cannot be set up properly.

**Graceful Degradation**: Optional components (Workflow definitions) log warnings but don't halt initialization.

**Configuration Recovery**: Config reload functionality allows recovery from configuration errors without application restart.

**Signal Handling**: Proper SIGINT/SIGTERM handling ensures graceful shutdown with service cleanup.

Testing Strategy

The package includes comprehensive test coverage with patterns for:

**Unit Testing**: Configuration validation, mode selection, service structure validation

**Integration Testing**: Service initialization sequences, API adapter registration

**Mock-Friendly Design**: Pre-populated configurations in tests to avoid global dependencies

**Test Coverage Focus**: Configuration handling, service creation, mode selection logic

Dependencies and Integration

**Core Dependencies**:

  • `internal/config`: Environment configuration and entity persistence
  • `internal/orchestrator`: Service lifecycle management
  • `internal/api`: Central API layer and service locator
  • `internal/aggregator`: MCP tool aggregation service
  • `internal/services`: Service abstractions and registry
  • `pkg/logging`: Logging system initialization

**Service Components**:

  • `internal/workflow`: Workflow definition and execution
  • `internal/mcpserver`: MCP server process management

**API Integration**: All service interactions use the API layer interfaces, maintaining clean architectural boundaries and enabling independent testing.

Benefits of This Architecture

**Separation of Concerns**: Clear boundaries between bootstrap, configuration, services, and execution

**Testability**: Each component can be tested independently with mocked dependencies

**Flexibility**: Easy to add new services, modify behavior, or change execution modes

**Configuration Management**: Comprehensive configuration handling with persistence and MCP integration

**Service Isolation**: Services are loosely coupled through the API layer

**Operational Readiness**: Proper signal handling, logging, and error management for production use

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Application

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

Application represents the main application structure that bootstraps and runs muster. It encapsulates all necessary configuration and services required for the application's lifecycle, including initialization, service management, and execution mode handling.

The Application follows a two-phase initialization pattern:

  1. Bootstrap phase: Load configuration, initialize logging, setup services
  2. Execution phase: Run the orchestrator

Example usage:

cfg := app.NewConfig(true, false, "")  // debug enabled
app, err := app.NewApplication(cfg)
if err != nil {
    return fmt.Errorf("failed to create application: %w", err)
}
return app.Run(ctx)

func NewApplication

func NewApplication(cfg *Config) (*Application, error)

NewApplication creates and initializes a new application instance with the provided configuration. This function performs the complete bootstrap sequence:

  1. Configures logging based on debug settings
  2. Loads muster configuration (layered or single-path)
  3. Initializes all required services and API handlers
  4. Sets up service dependencies and registrations

Configuration Loading Behavior:

  • If cfg.ConfigPath is set: loads from the specified directory only
  • If cfg.ConfigPath is empty: uses layered loading (defaults + user + project)

The function returns an error if any critical initialization step fails, including configuration loading or service initialization failures.

Example:

cfg := app.NewConfig(true, false, "/custom/config")  // CLI mode, custom config
app, err := app.NewApplication(cfg)
if err != nil {
    log.Fatalf("Bootstrap failed: %v", err)
}

func (*Application) Run

func (a *Application) Run(ctx context.Context) error

Run executes the application

Handles graceful shutdown via context cancellation and system signals. The method blocks until the application is terminated or encounters an error.

Returns an error if the selected execution mode fails to start or encounters a runtime error during execution.

type Config

type Config struct {
	// Version is the muster build version (e.g., "v0.1.0").
	// This is passed to the aggregator to report in the MCP protocol handshake.
	Version string

	// Debug settings
	Debug bool

	// Yolo enables "you only live once" mode with relaxed safety checks.
	// This setting reduces confirmation prompts and safety validations.
	// Use with caution in production environments.
	Yolo bool

	// ConfigPath specifies a custom configuration directory path.
	// When set, disables layered configuration loading and loads from this path only.
	// When empty, uses standard layered configuration loading strategy.
	ConfigPath string

	// MusterConfig holds the loaded muster environment configuration.
	// This field is populated during application bootstrap after configuration loading.
	MusterConfig *config.MusterConfig

	// OAuth MCP Client/Proxy settings (ADR 004 - for authenticating TO remote MCP servers)
	OAuthMCPClientEnabled   bool   // Enable OAuth MCP client/proxy for remote MCP server authentication
	OAuthMCPClientPublicURL string // Publicly accessible URL of the Muster Server
	OAuthMCPClientID        string // OAuth client identifier (CIMD URL)

	// OAuth Server settings (ADR 005 - for protecting the Muster Server ITSELF)
	OAuthServerEnabled bool   // Enable OAuth 2.1 protection for Muster Server
	OAuthServerBaseURL string // Base URL of the Muster Server for OAuth issuer

	// Events settings
	EnableEvents bool // Enable Kubernetes event emission (alpha, disabled by default)

	// ExtraCAFile is the path to a PEM file whose certificates are appended to
	// the system trust pool at startup. The augmented pool becomes the default
	// for outbound HTTP (MCP backends, token exchange, OAuth proxy) by
	// overriding http.DefaultTransport.TLSClientConfig.RootCAs.
	//
	// Use this when muster talks to internal services served behind a private
	// CA — e.g. tunnelport's SPIFFE-issued certificates on tunnel pods.
	ExtraCAFile string
}

Config holds the application configuration that controls bootstrap behavior and execution modes. This struct encapsulates all settings needed during application initialization and runtime, including debugging options, safety settings, and configuration loading behavior.

The configuration supports both layered and single-path configuration loading strategies:

  • Layered: Merges configuration from defaults, user config, and project config
  • Single-path: Loads configuration from a specific directory only

Field descriptions:

  • Debug: Enables debug-level logging and additional diagnostic output
  • Yolo: Enables "you only live once" mode with relaxed safety checks
  • ConfigPath: Optional custom configuration directory path
  • MusterConfig: Loaded muster configuration (populated during bootstrap)

func NewConfig

func NewConfig(debug, yolo bool, configPath string) *Config

NewConfig creates a new application configuration with the specified settings. This is the primary constructor for application configuration, taking all essential runtime args needed for application bootstrap and execution.

Args:

  • debug: enables debug logging and verbose output
  • yolo: enables relaxed safety checks and reduced confirmations
  • configPath: custom config directory (empty string for default layered loading)

Returns a fully initialized Config struct ready for use with NewApplication.

Example:

// Standard mode with debug enabled
cfg := app.NewConfig(true, false, "")

// Custom configuration path
cfg := app.NewConfig(false, false, "/opt/muster/config")

func (*Config) WithEvents added in v0.0.233

func (c *Config) WithEvents(enabled bool) *Config

WithEvents enables or disables Kubernetes event emission. Events are an alpha feature and disabled by default. When enabled, muster emits Kubernetes Events for CRD lifecycle operations and service management.

Args:

  • enabled: whether event emission is enabled

Returns the modified Config for method chaining.

func (*Config) WithExtraCAFile added in v0.1.198

func (c *Config) WithExtraCAFile(path string) *Config

WithExtraCAFile sets the path to a PEM file appended to the system trust pool at startup. See Config.ExtraCAFile for the rationale.

func (*Config) WithOAuthMCPClient

func (c *Config) WithOAuthMCPClient(enabled bool, publicURL, clientID string) *Config

WithOAuthMCPClient adds OAuth MCP client/proxy configuration to the Config. This method enables OAuth MCP client/proxy functionality for authenticating TO remote MCP servers.

Args:

  • enabled: whether OAuth MCP client/proxy is enabled
  • publicURL: the publicly accessible URL of the Muster Server
  • clientID: the OAuth client identifier (CIMD URL)

Returns the modified Config for method chaining.

func (*Config) WithOAuthServer

func (c *Config) WithOAuthServer(enabled bool, baseURL string) *Config

WithOAuthServer adds OAuth server protection configuration to the Config. This method enables OAuth 2.1 protection for the Muster Server itself (ADR 005). When enabled, clients (like muster agent) must authenticate with OAuth before accessing MCP endpoints.

Note: Full OAuth server configuration (provider, storage, etc.) should be done via the config file. These flags provide convenience overrides for enabling the feature and setting the base URL.

Args:

  • enabled: whether OAuth server protection is enabled
  • baseURL: the base URL of the Muster Server (used as OAuth issuer)

Returns the modified Config for method chaining.

func (*Config) WithVersion

func (c *Config) WithVersion(version string) *Config

WithVersion sets the muster build version on the Config. This version is passed to the aggregator to report in the MCP protocol handshake, allowing clients to discover the server version during initialization.

Args:

  • version: the build version string (e.g., "v0.1.0", "dev")

Returns the modified Config for method chaining.

type ConfigAdapter

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

ConfigAdapter adapts the config system to implement api.ConfigHandler. It provides a thread-safe interface for reading and updating muster configuration and serves as the bridge between the application layer and the API system.

func NewConfigAdapter

func NewConfigAdapter(cfg *config.MusterConfig, configPath string) *ConfigAdapter

NewConfigAdapter creates a new config adapter instance. The configPath arg specifies where to save configuration changes. If empty, the adapter will auto-detect an appropriate path.

func (*ConfigAdapter) ExecuteTool

func (a *ConfigAdapter) ExecuteTool(ctx context.Context, toolName string, args map[string]interface{}) (*api.CallToolResult, error)

ExecuteTool executes a configuration management tool by name with the provided arguments. This is the main entry point for MCP clients to interact with configuration.

func (*ConfigAdapter) GetAggregatorConfig

func (a *ConfigAdapter) GetAggregatorConfig(ctx context.Context) (*config.AggregatorConfig, error)

GetAggregatorConfig returns the aggregator-specific configuration section.

func (*ConfigAdapter) GetConfig

func (a *ConfigAdapter) GetConfig(ctx context.Context) (*config.MusterConfig, error)

GetConfig returns the current muster configuration. This method is thread-safe and returns a copy of the configuration.

func (*ConfigAdapter) GetTools

func (a *ConfigAdapter) GetTools() []api.ToolMetadata

GetTools returns metadata for all configuration management tools provided by this adapter. These tools are exposed through the MCP aggregator for external clients.

func (*ConfigAdapter) Register

func (a *ConfigAdapter) Register()

Register registers the adapter with the API layer. This must be called during application initialization to make the config handler available to other components through the API system.

func (*ConfigAdapter) ReloadConfig

func (a *ConfigAdapter) ReloadConfig(ctx context.Context) error

ReloadConfig reloads the configuration from disk using the centralized loader. This replaces the current in-memory configuration with the version from disk.

func (*ConfigAdapter) SaveConfig

func (a *ConfigAdapter) SaveConfig(ctx context.Context) error

SaveConfig persists the current configuration to disk. If no config path was specified during creation, it attempts to auto-detect an appropriate location (project directory first, then user directory).

func (*ConfigAdapter) UpdateAggregatorConfig

func (a *ConfigAdapter) UpdateAggregatorConfig(ctx context.Context, aggregator config.AggregatorConfig) error

UpdateAggregatorConfig updates the aggregator configuration section. Changes are immediately saved to disk if a valid config path is available.

type Services

type Services struct {
	// Orchestrator manages the lifecycle of all registered services.
	// It handles service startup, shutdown, dependency resolution, and health monitoring.
	Orchestrator *orchestrator.Orchestrator

	// OrchestratorAPI provides programmatic access to orchestrator operations.
	// This interface allows other components to interact with service management
	// functionality through the central API layer.
	OrchestratorAPI api.OrchestratorAPI

	// ConfigAPI provides programmatic access to configuration management.
	// This interface enables runtime configuration updates, persistence,
	// and retrieval through the central API layer.
	ConfigAPI api.ConfigAPI

	// AggregatorPort specifies the port number for the MCP aggregator service.
	// This port is used by external MCP clients to connect to the aggregator
	// for tool discovery and execution.
	AggregatorPort int

	// ReconcileManager handles automatic detection and reconciliation of
	// configuration changes for MCPServers and Workflows.
	// This enables automatic synchronization between desired state (YAML/CRDs)
	// and actual state (running services).
	ReconcileManager *reconciler.Manager

	// StateChangeBridge bridges service state changes from the orchestrator to
	// the reconciliation system. This enables status sync when services change
	// state at runtime (e.g., crash, health check failure, restart).
	StateChangeBridge *reconciler.StateChangeBridge
}

Services holds all initialized services and APIs used by the application. This struct serves as the central registry for all core application components, providing access to service management, API interfaces, and runtime configuration.

The Services struct follows the dependency injection pattern, ensuring that all components are properly initialized and registered before being made available to the application runtime.

Field descriptions:

  • Orchestrator: Core service orchestrator responsible for service lifecycle management
  • OrchestratorAPI: API interface for orchestrator operations (start, stop, status)
  • AggregatorPort: Port number where the MCP aggregator service is listening
  • ReconcileManager: Reconciliation manager for automatic change detection

Service Dependencies: The services are initialized in a specific order to handle dependencies:

  1. Storage and tool interfaces (shared dependencies)
  2. Service adapters and API registrations
  3. Manager instances (Workflow, MCPServer)
  4. Concrete service instances
  5. Aggregator service (when enabled)
  6. Reconciliation manager (for automatic change detection)

func InitializeServices

func InitializeServices(cfg *Config) (*Services, error)

InitializeServices creates and registers all required services for the application. This function implements the complete service initialization sequence, following the API Service Locator Pattern for clean separation of concerns.

Initialization Sequence:

  1. **Storage Setup**: Creates shared configuration storage for persistence
  2. **API Interfaces**: Creates tool checker and caller for service integration
  3. **Orchestrator**: Initializes the core service orchestrator
  4. **Service Registry**: Sets up the service registry for dependency injection
  5. **API Adapters**: Creates and registers all service adapters with the API layer
  6. **Manager Initialization**: Creates managers for Workflow, MCPServer
  7. **Definition Loading**: Loads component definitions from configuration directories
  8. **Service Creation**: Creates concrete service instances based on definitions
  9. **Aggregator Setup**: Initializes MCP aggregator service (when enabled)

Configuration Handling:

  • If cfg.ConfigPath is set: uses single-directory configuration loading
  • If cfg.ConfigPath is empty: uses layered configuration approach

Service Auto-registration: Services marked with AutoStart=true in their definitions are automatically registered with the orchestrator and will be started when the orchestrator starts.

Error Handling: The function uses a fail-fast approach for critical components but continues initialization for optional components (logging warnings for failures). Critical failures include storage creation, orchestrator setup, and API registration.

Aggregator Service: The MCP aggregator is enabled by default unless explicitly disabled in configuration. It provides MCP protocol support for external tool integration and discovery.

Returns a fully initialized Services struct or an error if critical initialization fails.

Jump to

Keyboard shortcuts

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