From 00114caa00cc7f107cde26e7949ff8aa97c90e78 Mon Sep 17 00:00:00 2001 From: LordMathis Date: Mon, 1 Dec 2025 20:48:17 +0100 Subject: [PATCH] Add db config and move data dir config --- README.md | 13 ++++-- cmd/server/main.go | 11 ++++- docs/configuration.md | 85 +++++++++++++++++++++++++++------------ pkg/config/config.go | 56 +++++++++++++------------- webui/src/types/config.ts | 10 ++++- 5 files changed, 117 insertions(+), 58 deletions(-) diff --git a/README.md b/README.md index 9f2039b..13d9b8e 100644 --- a/README.md +++ b/README.md @@ -179,11 +179,12 @@ backends: args: [] environment: {} # Environment variables for the backend process +data_dir: ~/.local/share/llamactl # Main data directory (database, instances, logs), default varies by OS + instances: port_range: [8000, 9000] # Port range for instances - data_dir: ~/.local/share/llamactl # Data directory (platform-specific, see below) - configs_dir: ~/.local/share/llamactl/instances # Instance configs directory - logs_dir: ~/.local/share/llamactl/logs # Logs directory + configs_dir: instances # Instance configs directory (relative to data_dir) + logs_dir: logs # Logs directory (relative to data_dir) auto_create_dirs: true # Auto-create data/config/logs dirs if missing max_instances: -1 # Max instances (-1 = unlimited) max_running_instances: -1 # Max running instances (-1 = unlimited) @@ -195,6 +196,12 @@ instances: on_demand_start_timeout: 120 # Default on-demand start timeout in seconds timeout_check_interval: 5 # Idle instance timeout check in minutes +database: + path: llamactl.db # Database file path (relative to data_dir) + max_open_connections: 25 # Maximum open database connections + max_idle_connections: 5 # Maximum idle database connections + connection_max_lifetime: 5m # Connection max lifetime + auth: require_inference_auth: true # Require auth for inference endpoints inference_keys: [] # Keys for inference endpoints diff --git a/cmd/server/main.go b/cmd/server/main.go index ffa0c27..0eeca45 100644 --- a/cmd/server/main.go +++ b/cmd/server/main.go @@ -50,10 +50,17 @@ func main() { // Create the data directory if it doesn't exist if cfg.Instances.AutoCreateDirs { - if err := os.MkdirAll(cfg.Instances.InstancesDir, 0755); err != nil { - log.Printf("Error creating config directory %s: %v\nPersistence will not be available.", cfg.Instances.InstancesDir, err) + // Create the main data directory + if err := os.MkdirAll(cfg.DataDir, 0755); err != nil { + log.Printf("Error creating data directory %s: %v\nData persistence may not be available.", cfg.DataDir, err) } + // Create instances directory + if err := os.MkdirAll(cfg.Instances.InstancesDir, 0755); err != nil { + log.Printf("Error creating instances directory %s: %v\nPersistence will not be available.", cfg.Instances.InstancesDir, err) + } + + // Create logs directory if err := os.MkdirAll(cfg.Instances.LogsDir, 0755); err != nil { log.Printf("Error creating log directory %s: %v\nInstance logs will not be available.", cfg.Instances.LogsDir, err) } diff --git a/docs/configuration.md b/docs/configuration.md index c271f29..1455cdd 100644 --- a/docs/configuration.md +++ b/docs/configuration.md @@ -49,11 +49,12 @@ backends: environment: {} # Environment variables for the backend process response_headers: {} # Additional response headers to send with responses +data_dir: ~/.local/share/llamactl # Main data directory (database, instances, logs), default varies by OS + instances: port_range: [8000, 9000] # Port range for instances - data_dir: ~/.local/share/llamactl # Data directory (platform-specific, see below) - configs_dir: ~/.local/share/llamactl/instances # Instance configs directory - logs_dir: ~/.local/share/llamactl/logs # Logs directory + configs_dir: data_dir/instances # Instance configs directory + logs_dir: data_dir/logs # Logs directory auto_create_dirs: true # Auto-create data/config/logs dirs if missing max_instances: -1 # Max instances (-1 = unlimited) max_running_instances: -1 # Max running instances (-1 = unlimited) @@ -65,6 +66,12 @@ instances: on_demand_start_timeout: 120 # Default on-demand start timeout in seconds timeout_check_interval: 5 # Idle instance timeout check in minutes +database: + path: data_dir/llamactl.db # Database file path + max_open_connections: 25 # Maximum open database connections + max_idle_connections: 5 # Maximum idle database connections + connection_max_lifetime: 5m # Connection max lifetime + auth: require_inference_auth: true # Require auth for inference endpoints inference_keys: [] # Keys for inference endpoints @@ -193,32 +200,44 @@ backends: - `LLAMACTL_MLX_ENV` - Environment variables in format "KEY1=value1,KEY2=value2" - `LLAMACTL_MLX_RESPONSE_HEADERS` - Response headers in format "KEY1=value1;KEY2=value2" +### Data Directory Configuration + +```yaml +data_dir: "~/.local/share/llamactl" # Main data directory for database, instances, and logs (default varies by OS) +``` + +**Environment Variables:** +- `LLAMACTL_DATA_DIRECTORY` - Main data directory path + +**Default Data Directory by Platform:** +- **Linux**: `~/.local/share/llamactl` +- **macOS**: `~/Library/Application Support/llamactl` +- **Windows**: `%LOCALAPPDATA%\llamactl` or `%PROGRAMDATA%\llamactl` + ### Instance Configuration ```yaml instances: - port_range: [8000, 9000] # Port range for instances (default: [8000, 9000]) - data_dir: "~/.local/share/llamactl" # Directory for all llamactl data (default varies by OS) - configs_dir: "~/.local/share/llamactl/instances" # Directory for instance configs (default: data_dir/instances) - logs_dir: "~/.local/share/llamactl/logs" # Directory for instance logs (default: data_dir/logs) - auto_create_dirs: true # Automatically create data/config/logs directories (default: true) - max_instances: -1 # Maximum instances (-1 = unlimited) - max_running_instances: -1 # Maximum running instances (-1 = unlimited) - enable_lru_eviction: true # Enable LRU eviction for idle instances - default_auto_restart: true # Default auto-restart setting - default_max_restarts: 3 # Default maximum restart attempts - default_restart_delay: 5 # Default restart delay in seconds - default_on_demand_start: true # Default on-demand start setting - on_demand_start_timeout: 120 # Default on-demand start timeout in seconds - timeout_check_interval: 5 # Default instance timeout check interval in minutes + port_range: [8000, 9000] # Port range for instances (default: [8000, 9000]) + configs_dir: "instances" # Directory for instance configs, default: data_dir/instances + logs_dir: "logs" # Directory for instance logs, default: data_dir/logs + auto_create_dirs: true # Automatically create data/config/logs directories (default: true) + max_instances: -1 # Maximum instances (-1 = unlimited) + max_running_instances: -1 # Maximum running instances (-1 = unlimited) + enable_lru_eviction: true # Enable LRU eviction for idle instances + default_auto_restart: true # Default auto-restart setting + default_max_restarts: 3 # Default maximum restart attempts + default_restart_delay: 5 # Default restart delay in seconds + default_on_demand_start: true # Default on-demand start setting + on_demand_start_timeout: 120 # Default on-demand start timeout in seconds + timeout_check_interval: 5 # Default instance timeout check interval in minutes ``` -**Environment Variables:** -- `LLAMACTL_INSTANCE_PORT_RANGE` - Port range (format: "8000-9000" or "8000,9000") -- `LLAMACTL_DATA_DIRECTORY` - Data directory path -- `LLAMACTL_INSTANCES_DIR` - Instance configs directory path -- `LLAMACTL_LOGS_DIR` - Log directory path -- `LLAMACTL_AUTO_CREATE_DATA_DIR` - Auto-create data/config/logs directories (true/false) +**Environment Variables:** +- `LLAMACTL_INSTANCE_PORT_RANGE` - Port range (format: "8000-9000" or "8000,9000") +- `LLAMACTL_INSTANCES_DIR` - Instance configs directory path +- `LLAMACTL_LOGS_DIR` - Log directory path +- `LLAMACTL_AUTO_CREATE_DATA_DIR` - Auto-create data/config/logs directories (true/false) - `LLAMACTL_MAX_INSTANCES` - Maximum number of instances - `LLAMACTL_MAX_RUNNING_INSTANCES` - Maximum number of running instances - `LLAMACTL_ENABLE_LRU_EVICTION` - Enable LRU eviction for idle instances @@ -226,8 +245,24 @@ instances: - `LLAMACTL_DEFAULT_MAX_RESTARTS` - Default maximum restarts - `LLAMACTL_DEFAULT_RESTART_DELAY` - Default restart delay in seconds - `LLAMACTL_DEFAULT_ON_DEMAND_START` - Default on-demand start setting (true/false) -- `LLAMACTL_ON_DEMAND_START_TIMEOUT` - Default on-demand start timeout in seconds -- `LLAMACTL_TIMEOUT_CHECK_INTERVAL` - Default instance timeout check interval in minutes +- `LLAMACTL_ON_DEMAND_START_TIMEOUT` - Default on-demand start timeout in seconds +- `LLAMACTL_TIMEOUT_CHECK_INTERVAL` - Default instance timeout check interval in minutes + +### Database Configuration + +```yaml +database: + path: "llamactl.db" # Database file path, default: data_dir/llamactl.db + max_open_connections: 25 # Maximum open database connections (default: 25) + max_idle_connections: 5 # Maximum idle database connections (default: 5) + connection_max_lifetime: 5m # Connection max lifetime (default: 5m) +``` + +**Environment Variables:** +- `LLAMACTL_DATABASE_PATH` - Database file path (relative to data_dir or absolute) +- `LLAMACTL_DATABASE_MAX_OPEN_CONNECTIONS` - Maximum open database connections +- `LLAMACTL_DATABASE_MAX_IDLE_CONNECTIONS` - Maximum idle database connections +- `LLAMACTL_DATABASE_CONN_MAX_LIFETIME` - Connection max lifetime (e.g., "5m", "1h") ### Authentication Configuration diff --git a/pkg/config/config.go b/pkg/config/config.go index b9b9ec8..1c53c17 100644 --- a/pkg/config/config.go +++ b/pkg/config/config.go @@ -40,16 +40,20 @@ type BackendConfig struct { // AppConfig represents the configuration for llamactl type AppConfig struct { - Server ServerConfig `yaml:"server" json:"server"` - Backends BackendConfig `yaml:"backends" json:"backends"` - Instances InstancesConfig `yaml:"instances" json:"instances"` - Database DatabaseConfig `yaml:"database" json:"database"` - Auth AuthConfig `yaml:"auth" json:"auth"` - LocalNode string `yaml:"local_node,omitempty" json:"local_node,omitempty"` - Nodes map[string]NodeConfig `yaml:"nodes,omitempty" json:"nodes,omitempty"` - Version string `yaml:"-" json:"version"` - CommitHash string `yaml:"-" json:"commit_hash"` - BuildTime string `yaml:"-" json:"build_time"` + Server ServerConfig `yaml:"server" json:"server"` + Backends BackendConfig `yaml:"backends" json:"backends"` + Instances InstancesConfig `yaml:"instances" json:"instances"` + Database DatabaseConfig `yaml:"database" json:"database"` + Auth AuthConfig `yaml:"auth" json:"auth"` + LocalNode string `yaml:"local_node,omitempty" json:"local_node,omitempty"` + Nodes map[string]NodeConfig `yaml:"nodes,omitempty" json:"nodes,omitempty"` + + // Directory where all llamactl data will be stored (database, instances, logs, etc.) + DataDir string `yaml:"data_dir" json:"data_dir"` + + Version string `yaml:"-" json:"version"` + CommitHash string `yaml:"-" json:"commit_hash"` + BuildTime string `yaml:"-" json:"build_time"` } // ServerConfig contains HTTP server configuration @@ -75,7 +79,7 @@ type ServerConfig struct { // DatabaseConfig contains database configuration settings type DatabaseConfig struct { - // Database file path (relative to data_dir or absolute) + // Database file path (relative to the top-level data_dir or absolute) Path string `yaml:"path" json:"path"` // Connection settings @@ -89,13 +93,11 @@ type InstancesConfig struct { // Port range for instances (e.g., 8000,9000) PortRange [2]int `yaml:"port_range" json:"port_range"` - // Directory where all llamactl data will be stored (instances.json, logs, etc.) - DataDir string `yaml:"data_dir" json:"data_dir"` - // Instance config directory override + // Instance config directory override (relative to data_dir if not absolute) InstancesDir string `yaml:"configs_dir" json:"configs_dir"` - // Logs directory override + // Logs directory override (relative to data_dir if not absolute) LogsDir string `yaml:"logs_dir" json:"logs_dir"` // Automatically create the data directory if it doesn't exist @@ -156,6 +158,8 @@ type NodeConfig struct { // 3. Environment variables func LoadConfig(configPath string) (AppConfig, error) { // 1. Start with defaults + defaultDataDir := getDefaultDataDirectory() + cfg := AppConfig{ Server: ServerConfig{ Host: "0.0.0.0", @@ -166,6 +170,7 @@ func LoadConfig(configPath string) (AppConfig, error) { }, LocalNode: "main", Nodes: map[string]NodeConfig{}, + DataDir: defaultDataDir, Backends: BackendConfig{ LlamaCpp: BackendSettings{ Command: "llama-server", @@ -176,7 +181,7 @@ func LoadConfig(configPath string) (AppConfig, error) { Image: "ghcr.io/ggml-org/llama.cpp:server", Args: []string{ "run", "--rm", "--network", "host", "--gpus", "all", - "-v", filepath.Join(getDefaultDataDirectory(), "llama.cpp") + ":/root/.cache/llama.cpp"}, + "-v", filepath.Join(defaultDataDir, "llama.cpp") + ":/root/.cache/llama.cpp"}, Environment: map[string]string{}, }, }, @@ -188,7 +193,7 @@ func LoadConfig(configPath string) (AppConfig, error) { Image: "vllm/vllm-openai:latest", Args: []string{ "run", "--rm", "--network", "host", "--gpus", "all", "--shm-size", "1g", - "-v", filepath.Join(getDefaultDataDirectory(), "huggingface") + ":/root/.cache/huggingface", + "-v", filepath.Join(defaultDataDir, "huggingface") + ":/root/.cache/huggingface", }, Environment: map[string]string{}, }, @@ -201,7 +206,6 @@ func LoadConfig(configPath string) (AppConfig, error) { }, Instances: InstancesConfig{ PortRange: [2]int{8000, 9000}, - DataDir: getDefaultDataDirectory(), // NOTE: empty strings are set as placeholder values since InstancesDir and LogsDir // should be relative path to DataDir if not explicitly set. InstancesDir: "", @@ -218,7 +222,7 @@ func LoadConfig(configPath string) (AppConfig, error) { TimeoutCheckInterval: 5, // Check timeouts every 5 minutes }, Database: DatabaseConfig{ - Path: "llamactl.db", // Relative to data_dir + Path: "", // Will be set to data_dir/llamactl.db if empty MaxOpenConnections: 25, MaxIdleConnections: 5, ConnMaxLifetime: 5 * time.Minute, @@ -244,17 +248,15 @@ func LoadConfig(configPath string) (AppConfig, error) { // 3. Override with environment variables loadEnvVars(&cfg) - // If InstancesDir or LogsDir is not set, set it to relative path of DataDir + // Set default directories if not specified if cfg.Instances.InstancesDir == "" { - cfg.Instances.InstancesDir = filepath.Join(cfg.Instances.DataDir, "instances") + cfg.Instances.InstancesDir = filepath.Join(cfg.DataDir, "instances") } if cfg.Instances.LogsDir == "" { - cfg.Instances.LogsDir = filepath.Join(cfg.Instances.DataDir, "logs") + cfg.Instances.LogsDir = filepath.Join(cfg.DataDir, "logs") } - - // Resolve database path relative to DataDir if it's not absolute - if cfg.Database.Path != "" && !filepath.IsAbs(cfg.Database.Path) { - cfg.Database.Path = filepath.Join(cfg.Instances.DataDir, cfg.Database.Path) + if cfg.Database.Path == "" { + cfg.Database.Path = filepath.Join(cfg.DataDir, "llamactl.db") } // Validate port range @@ -312,7 +314,7 @@ func loadEnvVars(cfg *AppConfig) { // Data config if dataDir := os.Getenv("LLAMACTL_DATA_DIRECTORY"); dataDir != "" { - cfg.Instances.DataDir = dataDir + cfg.DataDir = dataDir } if instancesDir := os.Getenv("LLAMACTL_INSTANCES_DIR"); instancesDir != "" { cfg.Instances.InstancesDir = instancesDir diff --git a/webui/src/types/config.ts b/webui/src/types/config.ts index 21f15fa..8a99a47 100644 --- a/webui/src/types/config.ts +++ b/webui/src/types/config.ts @@ -30,7 +30,6 @@ export interface ServerConfig { export interface InstancesConfig { port_range: [number, number] - data_dir: string configs_dir: string logs_dir: string auto_create_dirs: boolean @@ -45,6 +44,13 @@ export interface InstancesConfig { timeout_check_interval: number } +export interface DatabaseConfig { + path: string + max_open_connections: number + max_idle_connections: number + connection_max_lifetime: number +} + export interface AuthConfig { require_inference_auth: boolean inference_keys: string[] // Will be empty in sanitized response @@ -61,9 +67,11 @@ export interface AppConfig { server: ServerConfig backends: BackendConfig instances: InstancesConfig + database: DatabaseConfig auth: AuthConfig local_node: string nodes: Record + data_dir: string version?: string commit_hash?: string build_time?: string