135 lines
3.7 KiB
Python
135 lines
3.7 KiB
Python
"""Configuration management"""
|
|
import os
|
|
from typing import List, Optional
|
|
from pydantic import BaseModel, Field
|
|
import yaml
|
|
|
|
SANDBOX_USER_ID = 1000
|
|
SANDBOX_GROUP_ID = 1000
|
|
|
|
DEFAULT_PYTHON_LIB_REQUIREMENTS_AMD = [
|
|
"/usr/local/lib/python3.12",
|
|
"/usr/lib/python3",
|
|
"/usr/lib/x86_64-linux-gnu",
|
|
"/etc/ssl/certs/ca-certificates.crt",
|
|
"/etc/nsswitch.conf",
|
|
"/etc/hosts",
|
|
"/etc/resolv.conf",
|
|
"/run/systemd/resolve/stub-resolv.conf",
|
|
"/run/resolvconf/resolv.conf",
|
|
"/etc/localtime",
|
|
"/usr/share/zoneinfo",
|
|
"/etc/timezone",
|
|
]
|
|
|
|
|
|
class AppConfig(BaseModel):
|
|
"""Application configuration"""
|
|
port: int = 8194
|
|
debug: bool = True
|
|
key: str = "redbear-sandbox"
|
|
|
|
|
|
class ProxyConfig(BaseModel):
|
|
"""Proxy configuration"""
|
|
socks5: str = ""
|
|
http: str = ""
|
|
https: str = ""
|
|
|
|
|
|
class Config(BaseModel):
|
|
"""Global configuration"""
|
|
app: AppConfig = Field(default_factory=AppConfig)
|
|
max_workers: int = 4
|
|
max_requests: int = 50
|
|
worker_timeout: int = 30
|
|
nodejs_path: str = "node"
|
|
enable_network: bool = True
|
|
enable_preload: bool = False
|
|
|
|
python_path: str = ""
|
|
python_lib_paths: list = Field(default=DEFAULT_PYTHON_LIB_REQUIREMENTS_AMD)
|
|
python_deps_update_interval: str = "30m"
|
|
allowed_syscalls: List[int] = Field(default_factory=list)
|
|
proxy: ProxyConfig = Field(default_factory=ProxyConfig)
|
|
|
|
|
|
# Global configuration instance
|
|
_config: Optional[Config] = None
|
|
|
|
|
|
def load_config(config_path: str) -> Config:
|
|
"""Load configuration from YAML file"""
|
|
global _config
|
|
|
|
# Load from file
|
|
if os.path.exists(config_path):
|
|
with open(config_path, 'r') as f:
|
|
data = yaml.safe_load(f)
|
|
_config = Config(**data)
|
|
else:
|
|
_config = Config()
|
|
|
|
# Override with environment variables
|
|
if os.getenv("DEBUG"):
|
|
_config.app.debug = os.getenv("DEBUG").lower() in ("true", "1", "yes")
|
|
|
|
if os.getenv("MAX_WORKERS"):
|
|
_config.max_workers = int(os.getenv("MAX_WORKERS"))
|
|
|
|
if os.getenv("MAX_REQUESTS"):
|
|
_config.max_requests = int(os.getenv("MAX_REQUESTS"))
|
|
|
|
if os.getenv("SANDBOX_PORT"):
|
|
_config.app.port = int(os.getenv("SANDBOX_PORT"))
|
|
|
|
if os.getenv("WORKER_TIMEOUT"):
|
|
_config.worker_timeout = int(os.getenv("WORKER_TIMEOUT"))
|
|
|
|
if os.getenv("API_KEY"):
|
|
_config.app.key = os.getenv("API_KEY")
|
|
|
|
if os.getenv("NODEJS_PATH"):
|
|
_config.nodejs_path = os.getenv("NODEJS_PATH")
|
|
|
|
if os.getenv("ENABLE_NETWORK"):
|
|
_config.enable_network = os.getenv("ENABLE_NETWORK").lower() in ("true", "1", "yes")
|
|
|
|
if os.getenv("ENABLE_PRELOAD"):
|
|
_config.enable_preload = os.getenv("ENABLE_PRELOAD").lower() in ("true", "1", "yes")
|
|
|
|
if os.getenv("ALLOWED_SYSCALLS"):
|
|
_config.allowed_syscalls = [int(x) for x in os.getenv("ALLOWED_SYSCALLS").split(",")]
|
|
|
|
if os.getenv("SOCKS5_PROXY"):
|
|
_config.proxy.socks5 = os.getenv("SOCKS5_PROXY")
|
|
|
|
if os.getenv("HTTP_PROXY"):
|
|
_config.proxy.http = os.getenv("HTTP_PROXY")
|
|
|
|
if os.getenv("HTTPS_PROXY"):
|
|
_config.proxy.https = os.getenv("HTTPS_PROXY")
|
|
|
|
# python
|
|
if os.getenv("PYTHON_PATH"):
|
|
_config.python_path = os.getenv("PYTHON_PATH")
|
|
|
|
if os.getenv("PYTHON_LIB_PATH"):
|
|
_config.python_lib_paths = os.getenv("PYTHON_LIB_PATH").split(',')
|
|
|
|
if os.getenv("PYTHON_DEPS_UPDATE_INTERVAL"):
|
|
_config.python_deps_update_interval = os.getenv("PYTHON_DEPS_UPDATE_INTERVAL")
|
|
|
|
return _config
|
|
|
|
|
|
config_path = os.getenv("CONFIG_PATH", "config.yaml")
|
|
load_config(config_path)
|
|
|
|
|
|
def get_config() -> Config:
|
|
"""Get global configuration"""
|
|
if _config is None:
|
|
raise RuntimeError("Configuration not loaded. Call load_config() first.")
|
|
return _config
|