Some checks are pending
Checks / Spelling (push) Waiting to run
Checks / Python Linters (push) Waiting to run
Checks / Shell Linters (push) Waiting to run
Checks / 📦 Packit config lint (push) Waiting to run
Checks / 🔍 Check for valid snapshot urls (push) Waiting to run
Checks / 🔍 Check JSON files for formatting consistency (push) Waiting to run
Generate / Documentation (push) Waiting to run
Generate / Test Data (push) Waiting to run
Tests / Unittest (push) Waiting to run
Tests / Assembler test (legacy) (push) Waiting to run
Tests / Smoke run: unittest as normal user on default runner (push) Waiting to run
253 lines
9.6 KiB
Python
253 lines
9.6 KiB
Python
#!/usr/bin/env python3
|
|
"""
|
|
Debian Version Detector
|
|
Automatically detects Debian version and provides appropriate configuration
|
|
Similar to how Fedora/RHEL handle version detection in OSBuild
|
|
"""
|
|
|
|
import os
|
|
import subprocess
|
|
import re
|
|
from pathlib import Path
|
|
from typing import Optional, Dict, Any, Tuple
|
|
|
|
|
|
class DebianVersionDetector:
|
|
"""Detects Debian version and provides appropriate configuration"""
|
|
|
|
def __init__(self):
|
|
self.version_info = self._detect_debian_version()
|
|
|
|
def _detect_debian_version(self) -> Dict[str, Any]:
|
|
"""Detect Debian version from multiple sources"""
|
|
version_info = {
|
|
'codename': None,
|
|
'version': None,
|
|
'release': None,
|
|
'is_debian': False,
|
|
'is_supported': False,
|
|
'support_status': 'unknown'
|
|
}
|
|
|
|
# Method 1: Check /etc/os-release
|
|
if os.path.exists('/etc/os-release'):
|
|
with open('/etc/os-release', 'r') as f:
|
|
content = f.read()
|
|
# Check if this is actually Debian
|
|
if 'debian' in content.lower():
|
|
version_info['is_debian'] = True
|
|
# Extract version info
|
|
version_match = re.search(r'VERSION_ID="?([^"\n]+)"?', content)
|
|
codename_match = re.search(r'VERSION_CODENAME="?([^"\n]+)"?', content)
|
|
|
|
if version_match:
|
|
version_info['version'] = version_match.group(1)
|
|
if codename_match:
|
|
version_info['codename'] = codename_match.group(1)
|
|
|
|
# Method 2: Check /etc/debian_version
|
|
if os.path.exists('/etc/debian_version'):
|
|
version_info['is_debian'] = True
|
|
with open('/etc/debian_version', 'r') as f:
|
|
version_info['release'] = f.read().strip()
|
|
|
|
# Method 3: Check lsb_release command
|
|
try:
|
|
result = subprocess.run(['lsb_release', '-a'],
|
|
capture_output=True, text=True, check=True)
|
|
for line in result.stdout.split('\n'):
|
|
if 'Distributor ID:' in line and 'debian' in line.lower():
|
|
version_info['is_debian'] = True
|
|
elif 'Codename:' in line and version_info['is_debian']:
|
|
version_info['codename'] = line.split(':', 1)[1].strip()
|
|
elif 'Release:' in line and version_info['is_debian']:
|
|
version_info['version'] = line.split(':', 1)[1].strip()
|
|
except (subprocess.CalledProcessError, FileNotFoundError):
|
|
pass
|
|
|
|
# If not Debian, return early
|
|
if not version_info['is_debian']:
|
|
return {
|
|
'codename': None,
|
|
'version': None,
|
|
'release': None,
|
|
'is_debian': False,
|
|
'is_supported': False,
|
|
'support_status': 'not_debian',
|
|
'support_level': 'none',
|
|
'debian_version': 'unknown'
|
|
}
|
|
|
|
# Determine support status for Debian systems
|
|
version_info.update(self._determine_support_status(version_info))
|
|
|
|
return version_info
|
|
|
|
def _determine_support_status(self, version_info: Dict[str, Any]) -> Dict[str, Any]:
|
|
"""Determine if the detected version is supported"""
|
|
codename = version_info.get('codename', '').lower()
|
|
version = version_info.get('version', '')
|
|
|
|
# Debian 13+ support policy
|
|
supported_codenames = {
|
|
'trixie': {'version': '13', 'status': 'stable', 'support': 'full'},
|
|
'forky': {'version': '14', 'status': 'testing', 'support': 'development'},
|
|
'sid': {'version': 'unstable', 'status': 'unstable', 'support': 'experimental'}
|
|
}
|
|
|
|
# Check if codename is supported
|
|
if codename in supported_codenames:
|
|
return {
|
|
'is_supported': True,
|
|
'support_status': supported_codenames[codename]['status'],
|
|
'support_level': supported_codenames[codename]['support'],
|
|
'debian_version': supported_codenames[codename]['version']
|
|
}
|
|
|
|
# Check version number if codename not found
|
|
try:
|
|
version_num = int(version.split('.')[0])
|
|
if version_num >= 13:
|
|
return {
|
|
'is_supported': True,
|
|
'support_status': 'stable',
|
|
'support_level': 'full',
|
|
'debian_version': str(version_num)
|
|
}
|
|
except (ValueError, IndexError):
|
|
pass
|
|
|
|
# Not supported
|
|
return {
|
|
'is_supported': False,
|
|
'support_status': 'unsupported',
|
|
'support_level': 'none',
|
|
'debian_version': 'unknown'
|
|
}
|
|
|
|
def get_recommended_suite(self) -> str:
|
|
"""Get the recommended Debian suite for this system"""
|
|
if not self.version_info['is_debian']:
|
|
return 'trixie' # Default for non-Debian systems
|
|
|
|
if self.version_info['is_supported']:
|
|
return self.version_info['codename'] or 'trixie'
|
|
return 'trixie' # Default to supported version
|
|
|
|
def get_mirror_url(self) -> str:
|
|
"""Get appropriate Debian mirror URL"""
|
|
if not self.version_info['is_debian']:
|
|
return 'http://deb.debian.org/debian' # Default for non-Debian systems
|
|
|
|
codename = self.version_info.get('codename', 'trixie')
|
|
|
|
# Use official Debian mirrors
|
|
mirrors = {
|
|
'trixie': 'http://deb.debian.org/debian',
|
|
'forky': 'http://deb.debian.org/debian',
|
|
'sid': 'http://deb.debian.org/debian'
|
|
}
|
|
|
|
return mirrors.get(codename, 'http://deb.debian.org/debian')
|
|
|
|
def get_apt_sources(self) -> str:
|
|
"""Generate appropriate apt sources.list content"""
|
|
if not self.version_info['is_debian']:
|
|
# Return default sources for non-Debian systems
|
|
return """deb http://deb.debian.org/debian trixie main
|
|
deb http://deb.debian.org/debian trixie-updates main
|
|
deb http://deb.debian.org/debian trixie-security main
|
|
deb http://deb.debian.org/debian trixie-backports main
|
|
"""
|
|
|
|
codename = self.version_info.get('codename', 'trixie')
|
|
mirror = self.get_mirror_url()
|
|
|
|
sources = f"""deb {mirror} {codename} main
|
|
deb {mirror} {codename}-updates main
|
|
deb {mirror} {codename}-security main
|
|
"""
|
|
|
|
# Add backports for stable releases
|
|
if codename == 'trixie':
|
|
sources += f"deb {mirror} {codename}-backports main\n"
|
|
|
|
return sources
|
|
|
|
def get_support_warning(self) -> Optional[str]:
|
|
"""Get warning message if version is not fully supported"""
|
|
if not self.version_info['is_debian']:
|
|
return "Note: This is not a Debian system. Debian Forge will use default Debian settings."
|
|
|
|
if not self.version_info['is_supported']:
|
|
return f"Warning: Debian {self.version_info.get('version', 'unknown')} ({self.version_info.get('codename', 'unknown')}) is not officially supported. Debian Forge supports Debian 13+ (Trixie and newer)."
|
|
|
|
if self.version_info['support_level'] == 'experimental':
|
|
return f"Warning: {self.version_info['codename']} is unstable. Use with caution for production builds."
|
|
|
|
return None
|
|
|
|
def print_version_info(self):
|
|
"""Print detailed version information"""
|
|
print("Debian Version Detection:")
|
|
print("=" * 40)
|
|
|
|
if not self.version_info['is_debian']:
|
|
print("System: Non-Debian system detected")
|
|
print("Status: Using default Debian Forge settings")
|
|
print(f"Recommended suite: {self.get_recommended_suite()}")
|
|
print(f"Mirror URL: {self.get_mirror_url()}")
|
|
return
|
|
|
|
print(f"System: Debian")
|
|
print(f"Codename: {self.version_info.get('codename', 'unknown')}")
|
|
print(f"Version: {self.version_info.get('version', 'unknown')}")
|
|
print(f"Release: {self.version_info.get('release', 'unknown')}")
|
|
print(f"Supported: {self.version_info['is_supported']}")
|
|
print(f"Status: {self.version_info['support_status']}")
|
|
print(f"Support Level: {self.version_info['support_level']}")
|
|
|
|
warning = self.get_support_warning()
|
|
if warning:
|
|
print(f"\n⚠️ {warning}")
|
|
|
|
print(f"\nRecommended suite: {self.get_recommended_suite()}")
|
|
print(f"Mirror URL: {self.get_mirror_url()}")
|
|
|
|
|
|
# Global instance
|
|
version_detector = DebianVersionDetector()
|
|
|
|
|
|
def get_recommended_suite() -> str:
|
|
"""Get recommended Debian suite (convenience function)"""
|
|
return version_detector.get_recommended_suite()
|
|
|
|
|
|
def get_mirror_url() -> str:
|
|
"""Get appropriate Debian mirror URL (convenience function)"""
|
|
return version_detector.get_mirror_url()
|
|
|
|
|
|
def get_apt_sources() -> str:
|
|
"""Get appropriate apt sources (convenience function)"""
|
|
return version_detector.get_apt_sources()
|
|
|
|
|
|
def is_version_supported() -> bool:
|
|
"""Check if current Debian version is supported (convenience function)"""
|
|
return version_detector.version_info['is_supported']
|
|
|
|
|
|
def is_debian_system() -> bool:
|
|
"""Check if this is a Debian system (convenience function)"""
|
|
return version_detector.version_info['is_debian']
|
|
|
|
|
|
def print_version_info():
|
|
"""Print version information (convenience function)"""
|
|
version_detector.print_version_info()
|
|
|
|
|
|
if __name__ == '__main__':
|
|
print_version_info()
|