#!/usr/bin/env python3 """ Configuration Manager for Debian Forge Handles reading configuration from multiple sources with priority order """ import os import configparser from pathlib import Path from typing import Optional, Dict, Any # Import version detector try: from .version_detector import ( get_recommended_suite as _get_recommended_suite, get_mirror_url as _get_mirror_url, is_version_supported as _is_version_supported, print_version_info as _print_version_info ) except ImportError: # Fallback if version detector is not available def _get_recommended_suite(): return "trixie" def _get_mirror_url(): return "http://deb.debian.org/debian" def _is_version_supported(): return True def _print_version_info(): print("Version detector not available") class DebianForgeConfig: """Configuration manager for Debian Forge settings""" def __init__(self, config_dir: str = "config"): self.config_dir = Path(config_dir) self.config = configparser.ConfigParser() self._load_config() self._apply_version_detection() def _load_config(self): """Load configuration from multiple sources with priority order""" # Priority order (highest to lowest): # 1. Environment variables # 2. Local config file (debian-forge.local.conf) # 3. Default config file (debian-forge.conf) # Load default config default_config = self.config_dir / "debian-forge.conf" if default_config.exists(): self.config.read(default_config) # Load local config (overrides defaults) local_config = self.config_dir / "debian-forge.local.conf" if local_config.exists(): self.config.read(local_config) # Environment variables override everything self._apply_environment_overrides() def _apply_environment_overrides(self): """Apply environment variable overrides""" # apt-cacher-ng proxy env_proxy = os.environ.get("DEBIAN_FORGE_APT_PROXY") if env_proxy is not None: if "apt-cacher-ng" not in self.config: self.config.add_section("apt-cacher-ng") self.config["apt-cacher-ng"]["url"] = env_proxy # Build settings env_suite = os.environ.get("DEBIAN_FORGE_DEFAULT_SUITE") if env_suite is not None: if "build" not in self.config: self.config.add_section("build") self.config["build"]["default_suite"] = env_suite env_arch = os.environ.get("DEBIAN_FORGE_DEFAULT_ARCH") if env_arch is not None: if "build" not in self.config: self.config.add_section("build") self.config["build"]["default_arch"] = env_arch def _apply_version_detection(self): """Apply automatic version detection like Fedora does""" # Check if version detection is available if not _is_version_supported(): print("⚠️ Warning: Current Debian version is not officially supported") print(" Debian Forge supports Debian 13+ (Trixie and newer)") print(" Consider upgrading or using a supported version") # Auto-detect recommended suite if not explicitly set try: current_suite = self.get_build_setting("default_suite") if not current_suite or current_suite == "bookworm": # Legacy default recommended_suite = _get_recommended_suite() if "build" not in self.config: self.config.add_section("build") self.config["build"]["default_suite"] = recommended_suite print(f"🔄 Auto-detected recommended suite: {recommended_suite}") except Exception: pass def get_apt_proxy(self) -> Optional[str]: """Get apt-cacher-ng proxy URL if configured""" try: url = self.config.get("apt-cacher-ng", "url", fallback="") return url.strip() if url.strip() else None except (configparser.NoSectionError, configparser.NoOptionError): return None def get_build_setting(self, key: str, default: Any = None) -> Any: """Get a build setting value""" try: return self.config.get("build", key, fallback=default) except (configparser.NoSectionError, configparser.NoOptionError): return default def get_stage_setting(self, key: str, default: Any = None) -> Any: """Get a stage setting value""" try: return self.config.get("stages", key, fallback=default) except (configparser.NoSectionError, configparser.NoOptionError): return default def get_logging_setting(self, key: str, default: Any = None) -> Any: """Get a logging setting value""" try: return self.config.get("logging", key, fallback=default) except (configparser.NoSectionError, configparser.NoOptionError): return default def is_apt_proxy_enabled(self) -> bool: """Check if apt-cacher-ng proxy is enabled""" return self.get_apt_proxy() is not None def get_recommended_suite(self) -> str: """Get the recommended Debian suite for this system""" return _get_recommended_suite() def get_mirror_url(self) -> str: """Get appropriate Debian mirror URL""" return _get_mirror_url() def is_version_supported(self) -> bool: """Check if current Debian version is supported""" return _is_version_supported() def get_all_settings(self) -> Dict[str, Dict[str, Any]]: """Get all configuration settings as a dictionary""" result = {} for section in self.config.sections(): result[section] = dict(self.config[section]) return result def print_config(self): """Print current configuration for debugging""" print("Debian Forge Configuration:") print("=" * 40) # Show version detection info _print_version_info() print() # Show configuration settings for section, settings in self.get_all_settings().items(): print(f"\n[{section}]") for key, value in settings.items(): print(f" {key} = {value}") # Show environment overrides env_proxy = os.environ.get("DEBIAN_FORGE_APT_PROXY") if env_proxy: print(f"\nEnvironment Override:") print(f" DEBIAN_FORGE_APT_PROXY = {env_proxy}") # Show auto-detected values print(f"\nAuto-detected:") print(f" Recommended suite = {self.get_recommended_suite()}") print(f" Mirror URL = {self.get_mirror_url()}") print(f" Version supported = {self.is_version_supported()}") # Global configuration instance config = DebianForgeConfig() def get_apt_proxy() -> Optional[str]: """Get apt-cacher-ng proxy URL (convenience function)""" return config.get_apt_proxy() def is_apt_proxy_enabled() -> bool: """Check if apt-cacher-ng proxy is enabled (convenience function)""" return config.is_apt_proxy_enabled() def get_build_setting(key: str, default: Any = None) -> Any: """Get a build setting (convenience function)""" return config.get_build_setting(key, default) def get_stage_setting(key: str, default: Any = None) -> Any: """Get a stage setting (convenience function)""" return config.get_stage_setting(key, default) def get_recommended_suite() -> str: """Get recommended Debian suite (convenience function)""" return config.get_recommended_suite() def get_mirror_url() -> str: """Get appropriate Debian mirror URL (convenience function)""" return config.get_mirror_url() def is_version_supported() -> bool: """Check if current Debian version is supported (convenience function)""" return config.is_version_supported()