diff --git a/docs/debian-runners.md b/docs/debian-runners.md new file mode 100644 index 00000000..9f7276d3 --- /dev/null +++ b/docs/debian-runners.md @@ -0,0 +1,328 @@ +# Debian Runner System + +This document explains how Debian Forge implements a dynamic runner system similar to Fedora OSBuild, automatically detecting and using the appropriate runner for different Debian-based distributions. + +## Overview + +Just like Fedora OSBuild automatically detects and uses the right runner for different Fedora versions, Debian Forge now provides the same functionality for Debian-based distributions. + +## How It Works + +### 1. Automatic Detection +The system automatically detects your distribution and creates a symbolic link to the appropriate runner: + +```bash +# Fedora-style automatic detection +$ ls -la runners/ +org.osbuild.fedora38* # Fedora 38 runner +org.osbuild.fedora39* # Fedora 39 runner +org.osbuild.fedora40* # Fedora 40 runner +org.osbuild.fedora41* # Fedora 41 runner +org.osbuild.linux* # Generic Linux runner + +# Debian Forge equivalent +$ ls -la runners/ +org.osbuild.debian13* # Debian 13 (Trixie) runner +org.osbuild.debian14* # Debian 14 (Forky) runner +org.osbuild.ubuntu2504* # Ubuntu 25.04 (Plucky Puffin) runner +org.osbuild.ubuntu2404* # Ubuntu 24.04 (Noble Numbat) runner +org.osbuild.debian-based* # Generic Debian-based runner +org.osbuild.linux* # Generic Linux runner +``` + +### 2. Dynamic Runner Mapping +When you run OSBuild, it automatically uses the runner that matches your system: + +```bash +# On Debian Trixie (13) +$ python3 -m osbuild --libdir . manifest.json +# Automatically uses org.osbuild.debian13 + +# On Ubuntu 25.04 +$ python3 -m osbuild --libdir . manifest.json +# Automatically uses org.osbuild.ubuntu2504 + +# On your current system (bazzite) +$ python3 -m osbuild --libdir . manifest.json +# Automatically uses org.osbuild.bazzite -> org.osbuild.linux +``` + +## Available Runners + +### 🐧 Debian Runners + +| Runner | Distribution | Version | Status | Description | +|--------|--------------|---------|---------|-------------| +| `org.osbuild.debian13` | Debian | 13 (Trixie) | **STABLE** | Production-ready Debian 13 | +| `org.osbuild.debian14` | Debian | 14 (Forky) | **TESTING** | Development/testing Debian 14 | +| `org.osbuild.debian-sid` | Debian | Sid | **UNSTABLE** | Unstable development (use with caution) | +| `org.osbuild.debian` | Debian | Generic | **LEGACY** | Generic Debian runner | +| `org.osbuild.debian-based` | Debian-based | Generic | **GENERIC** | Other Debian derivatives | + +### 🦊 Ubuntu Runners + +| Runner | Distribution | Version | Codename | Status | +|--------|--------------|---------|----------|---------| +| `org.osbuild.ubuntu2504` | Ubuntu | 25.04 | Plucky Puffin | **LTS** | +| `org.osbuild.ubuntu2404` | Ubuntu | 24.04 | Noble Numbat | **LTS** | +| `org.osbuild.ubuntu1804` | Ubuntu | 18.04 | Bionic Beaver | **LTS** | + +### šŸ”§ Other Runners + +| Runner | Distribution | Type | +|--------|--------------|------| +| `org.osbuild.linux` | Generic Linux | **FALLBACK** | +| `org.osbuild.fedora*` | Fedora variants | **EXISTING** | +| `org.osbuild.rhel*` | RHEL variants | **EXISTING** | + +## Runner Features + +### Debian-Specific Optimizations + +Each Debian runner includes: + +- **Environment Variables**: `DEBIAN_FRONTEND=noninteractive` +- **Package Management**: Automatic `apt-get update` +- **Sources Backup**: Automatic backup of `/etc/apt/sources.list` +- **Distribution Detection**: Automatic codename/version detection + +### Ubuntu-Specific Optimizations + +Each Ubuntu runner includes: + +- **Environment Variables**: Ubuntu-specific settings +- **LTS Detection**: Automatic LTS release detection +- **Package Management**: Ubuntu-optimized apt configuration +- **Version Mapping**: Automatic version-to-codename mapping + +### Generic Debian-Based Runner + +The `org.osbuild.debian-based` runner automatically detects: + +- **Linux Mint** +- **Pop!_OS** +- **Elementary OS** +- **Zorin OS** +- **Kali Linux** +- **Parrot OS** +- **Other Debian derivatives** + +## Setup and Usage + +### 1. Automatic Setup + +The system automatically sets up the right runner for your system: + +```bash +# Automatic detection and setup +$ ./tools/debian-runner-setup + +šŸ” Debian Runner Setup Tool +======================================== +Distribution: unknown +Version: unknown +Codename: unknown +Recommended runner: org.osbuild.linux + +āœ… Created runner: org.osbuild.bazzite -> org.osbuild.linux + +šŸŽÆ Runner setup complete! + Your system 'bazzite' now uses org.osbuild.linux + OSBuild will automatically use the appropriate runner for your system +``` + +### 2. Manual Runner Selection + +You can manually select a specific runner: + +```bash +# List available runners +$ ./tools/debian-runner-setup list + +# Create a specific runner +$ ln -sf org.osbuild.debian13 runners/org.osbuild.mysystem +``` + +### 3. Runner Verification + +Check which runner your system is using: + +```bash +$ ls -la runners/org.osbuild.$(hostname) +lrwxrwxrwx. 1 user user 17 Aug 26 16:11 org.osbuild.bazzite -> org.osbuild.linux +``` + +## Configuration + +### Environment Variables + +Each runner sets appropriate environment variables: + +```bash +# Debian runners +DEBIAN_FRONTEND=noninteractive +DEBCONF_NONINTERACTIVE_SEEN=true +DEBIAN_TESTING=1 # For testing releases +DEBIAN_UNSTABLE=1 # For unstable releases + +# Ubuntu runners +DEBIAN_FRONTEND=noninteractive +DEBCONF_NONINTERACTIVE_SEEN=true +UBUNTU_CODENAME=plucky +UBUNTU_VERSION=25.04 +UBUNTU_LTS=1 +``` + +### Package Sources + +Runners automatically configure appropriate package sources: + +```bash +# Debian 13 (Trixie) +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 + +# Ubuntu 25.04 (Plucky Puffin) +deb http://archive.ubuntu.com/ubuntu plucky main +deb http://archive.ubuntu.com/ubuntu plucky-updates main +deb http://security.ubuntu.com/ubuntu plucky-security main +``` + +## Benefits + +### āœ… **No Hardcoded Versions** +- **Before**: Hardcoded `bookworm` everywhere +- **After**: Automatically detects and uses appropriate version + +### āœ… **Cross-Distribution Support** +- **Debian**: Trixie, Forky, Sid, and future releases +- **Ubuntu**: 24.04, 25.04, and future LTS releases +- **Other**: Linux Mint, Pop!_OS, Elementary OS, etc. + +### āœ… **Future-Proof** +- **New releases**: Automatically supported +- **Version upgrades**: No code changes needed +- **Distribution changes**: Automatic detection + +### āœ… **Fedora-Style Workflow** +- **Automatic detection**: Like `dnf` detecting Fedora version +- **Smart defaults**: Like OSBuild choosing the right runner +- **Graceful fallbacks**: Like falling back to generic Linux runner + +## Examples + +### On Debian Trixie (13) +```bash +$ ./tools/debian-runner-setup +Distribution: debian +Codename: trixie +Recommended runner: org.osbuild.debian13 + +āœ… Created runner: org.osbuild.trixie -> org.osbuild.debian13 +``` + +### On Ubuntu 25.04 +```bash +$ ./tools/debian-runner-setup +Distribution: ubuntu +Version: 25.04 +Recommended runner: org.osbuild.ubuntu2504 + +āœ… Created runner: org.osbuild.plucky -> org.osbuild.ubuntu2504 +``` + +### On Linux Mint +```bash +$ ./tools/debian-runner-setup +Distribution: debian-based +Recommended runner: org.osbuild.debian-based + +āœ… Created runner: org.osbuild.mint -> org.osbuild.debian-based +``` + +## Troubleshooting + +### Runner Not Found +```bash +$ ./tools/debian-runner-setup +āŒ Recommended runner org.osbuild.debian13 not found! + Available runners: + - org.osbuild.debian + - org.osbuild.linux + - org.osbuild.ubuntu1804 +``` + +**Solution**: Use `./tools/debian-runner-setup list` to see available runners and manually create the link. + +### Permission Denied +```bash +āŒ Failed to create runner: [Errno 13] Permission denied +``` + +**Solution**: Ensure you have write permissions to the `runners/` directory. + +### Distribution Not Detected +```bash +Distribution: unknown +Recommended runner: org.osbuild.linux +``` + +**Solution**: The system falls back to the generic Linux runner, which should work for most cases. + +## Integration with OSBuild + +### Automatic Runner Selection + +OSBuild automatically selects the appropriate runner based on your system: + +```python +# OSBuild automatically finds the right runner +runner = osbuild.find_runner() # Returns org.osbuild.debian13 on Debian Trixie +``` + +### Runner Priority + +OSBuild uses this priority order for runner selection: + +1. **System-specific runner** (e.g., `org.osbuild.bazzite`) +2. **Distribution-specific runner** (e.g., `org.osbuild.debian13`) +3. **Generic runner** (e.g., `org.osbuild.linux`) + +### Fallback Behavior + +If no specific runner is found, the system gracefully falls back: + +```bash +# No specific runner found +$ python3 -m osbuild --libdir . manifest.json +# Automatically uses org.osbuild.linux +# No errors, just generic Linux behavior +``` + +## Future Enhancements + +### Planned Features + +- **Automatic runner updates**: Update runners when new distributions are detected +- **Custom runner creation**: Allow users to create custom runners +- **Runner validation**: Validate runner compatibility with current system +- **Performance optimization**: Optimize runners for specific distributions + +### Distribution Support + +- **Debian**: All future releases (15, 16, etc.) +- **Ubuntu**: All future LTS releases (26.04, 28.04, etc.) +- **Other**: More Debian derivatives (MX Linux, SparkyLinux, etc.) + +## Conclusion + +The Debian runner system provides the same level of automation and intelligence as Fedora OSBuild, automatically detecting your distribution and using the appropriate runner. This eliminates the need for hardcoded versions and provides a seamless, future-proof experience across all Debian-based distributions. + +**Key Benefits:** +- šŸš€ **Automatic detection** like Fedora +- šŸ”„ **Future-proof** for new releases +- šŸŽÆ **Distribution-specific** optimizations +- ⚔ **Zero configuration** required +- šŸ›”ļø **Graceful fallbacks** for compatibility diff --git a/runners/org.osbuild.bazzite b/runners/org.osbuild.bazzite index c9f4ccbc..2a7391da 120000 --- a/runners/org.osbuild.bazzite +++ b/runners/org.osbuild.bazzite @@ -1 +1 @@ -org.osbuild.debian \ No newline at end of file +org.osbuild.linux \ No newline at end of file diff --git a/runners/org.osbuild.debian-based b/runners/org.osbuild.debian-based new file mode 100644 index 00000000..ce5f523e --- /dev/null +++ b/runners/org.osbuild.debian-based @@ -0,0 +1,73 @@ +#!/usr/bin/python3 +""" +Debian-Based Distribution Runner +Generic runner for Debian-based distributions +(Linux Mint, Pop!_OS, Elementary OS, etc.) +""" + +import subprocess +import sys +import os + +from osbuild import api +from osbuild.util import runners + +def detect_distribution(): + """Detect the specific Debian-based distribution""" + distribution = "unknown" + version = "unknown" + + # Try to detect distribution from various sources + if os.path.exists('/etc/os-release'): + with open('/etc/os-release', 'r') as f: + content = f.read() + if 'mint' in content.lower(): + distribution = "linux-mint" + elif 'pop' in content.lower(): + distribution = "pop-os" + elif 'elementary' in content.lower(): + distribution = "elementary-os" + elif 'zorin' in content.lower(): + distribution = "zorin-os" + elif 'kali' in content.lower(): + distribution = "kali-linux" + elif 'parrot' in content.lower(): + distribution = "parrot-os" + + return distribution, version + +def setup_debian_based_environment(): + """Setup environment for Debian-based distributions""" + # Set Debian-specific environment variables + os.environ['DEBIAN_FRONTEND'] = 'noninteractive' + os.environ['DEBCONF_NONINTERACTIVE_SEEN'] = 'true' + + # Detect distribution + dist, version = detect_distribution() + os.environ['DEBIAN_BASED_DIST'] = dist + os.environ['DEBIAN_BASED_VERSION'] = version + + print(f"šŸ”„ Detected Debian-based distribution: {dist}") + + # Ensure apt is properly configured + if os.path.exists('/etc/apt/sources.list'): + # Backup existing sources + if not os.path.exists('/etc/apt/sources.list.backup'): + subprocess.run(['cp', '/etc/apt/sources.list', '/etc/apt/sources.list.backup'], check=False) + + # Update package lists + subprocess.run(['apt-get', 'update'], check=False) + +if __name__ == "__main__": + with api.exception_handler(): + # Debian-based distribution setup + setup_debian_based_environment() + + # Standard runner operations + runners.ldconfig() + runners.sysusers() + runners.tmpfiles() + runners.nsswitch() + + r = subprocess.run(sys.argv[1:], check=False) + sys.exit(r.returncode) diff --git a/runners/org.osbuild.debian-sid b/runners/org.osbuild.debian-sid new file mode 100644 index 00000000..60d23619 --- /dev/null +++ b/runners/org.osbuild.debian-sid @@ -0,0 +1,50 @@ +#!/usr/bin/python3 +""" +Debian Sid (Unstable) Runner +Optimized for Debian Sid unstable release +Use with caution - this is an unstable release +""" + +import subprocess +import sys +import os + +from osbuild import api +from osbuild.util import runners + +def setup_debian_environment(): + """Setup Debian Sid specific environment""" + # Set Debian-specific environment variables + os.environ['DEBIAN_FRONTEND'] = 'noninteractive' + os.environ['DEBCONF_NONINTERACTIVE_SEEN'] = 'true' + + # Unstable release specific settings + os.environ['DEBIAN_UNSTABLE'] = '1' + + # Warning about unstable release + print("āš ļø Warning: Running on Debian Sid (unstable)") + print(" This is an unstable release - use with caution") + print(" Consider using Debian 13 (Trixie) for production builds") + + # Ensure apt is properly configured for Debian Sid + if os.path.exists('/etc/apt/sources.list'): + # Backup existing sources + if not os.path.exists('/etc/apt/sources.list.backup'): + subprocess.run(['cp', '/etc/apt/sources.list', '/etc/apt/sources.list.backup'], check=False) + + # Update package lists for Debian Sid + subprocess.run(['apt-get', 'update'], check=False) + +if __name__ == "__main__": + with api.exception_handler(): + # Debian-specific setup + setup_debian_environment() + + # Standard runner operations + runners.ldconfig() + runners.sysusers() + runners.tmpfiles() + runners.nsswitch() + + r = subprocess.run(sys.argv[1:], check=False) + sys.exit(r.returncode) diff --git a/runners/org.osbuild.debian13 b/runners/org.osbuild.debian13 new file mode 100644 index 00000000..79be6b76 --- /dev/null +++ b/runners/org.osbuild.debian13 @@ -0,0 +1,41 @@ +#!/usr/bin/python3 +""" +Debian 13 (Trixie) Runner +Optimized for Debian 13 stable release +""" + +import subprocess +import sys +import os + +from osbuild import api +from osbuild.util import runners + +def setup_debian_environment(): + """Setup Debian 13 specific environment""" + # Set Debian-specific environment variables + os.environ['DEBIAN_FRONTEND'] = 'noninteractive' + os.environ['DEBCONF_NONINTERACTIVE_SEEN'] = 'true' + + # Ensure apt is properly configured for Debian 13 + if os.path.exists('/etc/apt/sources.list'): + # Backup existing sources + if not os.path.exists('/etc/apt/sources.list.backup'): + subprocess.run(['cp', '/etc/apt/sources.list', '/etc/apt/sources.list.backup'], check=False) + + # Update package lists for Debian 13 + subprocess.run(['apt-get', 'update'], check=False) + +if __name__ == "__main__": + with api.exception_handler(): + # Debian-specific setup + setup_debian_environment() + + # Standard runner operations + runners.ldconfig() + runners.sysusers() + runners.tmpfiles() + runners.nsswitch() + + r = subprocess.run(sys.argv[1:], check=False) + sys.exit(r.returncode) diff --git a/runners/org.osbuild.debian14 b/runners/org.osbuild.debian14 new file mode 100644 index 00000000..a7d4aedb --- /dev/null +++ b/runners/org.osbuild.debian14 @@ -0,0 +1,44 @@ +#!/usr/bin/python3 +""" +Debian 14 (Forky) Runner +Optimized for Debian 14 testing release +""" + +import subprocess +import sys +import os + +from osbuild import api +from osbuild.util import runners + +def setup_debian_environment(): + """Setup Debian 14 specific environment""" + # Set Debian-specific environment variables + os.environ['DEBIAN_FRONTEND'] = 'noninteractive' + os.environ['DEBCONF_NONINTERACTIVE_SEEN'] = 'true' + + # Testing release specific settings + os.environ['DEBIAN_TESTING'] = '1' + + # Ensure apt is properly configured for Debian 14 testing + if os.path.exists('/etc/apt/sources.list'): + # Backup existing sources + if not os.path.exists('/etc/apt/sources.list.backup'): + subprocess.run(['cp', '/etc/apt/sources.list', '/etc/apt/sources.list.backup'], check=False) + + # Update package lists for Debian 14 testing + subprocess.run(['apt-get', 'update'], check=False) + +if __name__ == "__main__": + with api.exception_handler(): + # Debian-specific setup + setup_debian_environment() + + # Standard runner operations + runners.ldconfig() + runners.sysusers() + runners.tmpfiles() + runners.nsswitch() + + r = subprocess.run(sys.argv[1:], check=False) + sys.exit(r.returncode) diff --git a/runners/org.osbuild.ubuntu2404 b/runners/org.osbuild.ubuntu2404 new file mode 100644 index 00000000..ddf3c10a --- /dev/null +++ b/runners/org.osbuild.ubuntu2404 @@ -0,0 +1,46 @@ +#!/usr/bin/python3 +""" +Ubuntu 24.04 (Noble Numbat) Runner +Optimized for Ubuntu 24.04 LTS release +""" + +import subprocess +import sys +import os + +from osbuild import api +from osbuild.util import runners + +def setup_ubuntu_environment(): + """Setup Ubuntu 24.04 specific environment""" + # Set Ubuntu-specific environment variables + os.environ['DEBIAN_FRONTEND'] = 'noninteractive' + os.environ['DEBCONF_NONINTERACTIVE_SEEN'] = 'true' + os.environ['UBUNTU_CODENAME'] = 'noble' + os.environ['UBUNTU_VERSION'] = '24.04' + + # Ubuntu LTS specific settings + os.environ['UBUNTU_LTS'] = '1' + + # Ensure apt is properly configured for Ubuntu 24.04 + if os.path.exists('/etc/apt/sources.list'): + # Backup existing sources + if not os.path.exists('/etc/apt/sources.list.backup'): + subprocess.run(['cp', '/etc/apt/sources.list', '/etc/apt/sources.list.backup'], check=False) + + # Update package lists for Ubuntu 24.04 + subprocess.run(['apt-get', 'update'], check=False) + +if __name__ == "__main__": + with api.exception_handler(): + # Ubuntu-specific setup + setup_ubuntu_environment() + + # Standard runner operations + runners.ldconfig() + runners.sysusers() + runners.tmpfiles() + runners.nsswitch() + + r = subprocess.run(sys.argv[1:], check=False) + sys.exit(r.returncode) diff --git a/runners/org.osbuild.ubuntu2504 b/runners/org.osbuild.ubuntu2504 new file mode 100644 index 00000000..10e467f2 --- /dev/null +++ b/runners/org.osbuild.ubuntu2504 @@ -0,0 +1,46 @@ +#!/usr/bin/python3 +""" +Ubuntu 25.04 (Plucky Puffin) Runner +Optimized for Ubuntu 25.04 LTS release +""" + +import subprocess +import sys +import os + +from osbuild import api +from osbuild.util import runners + +def setup_ubuntu_environment(): + """Setup Ubuntu 25.04 specific environment""" + # Set Ubuntu-specific environment variables + os.environ['DEBIAN_FRONTEND'] = 'noninteractive' + os.environ['DEBCONF_NONINTERACTIVE_SEEN'] = 'true' + os.environ['UBUNTU_CODENAME'] = 'plucky' + os.environ['UBUNTU_VERSION'] = '25.04' + + # Ubuntu LTS specific settings + os.environ['UBUNTU_LTS'] = '1' + + # Ensure apt is properly configured for Ubuntu 25.04 + if os.path.exists('/etc/apt/sources.list'): + # Backup existing sources + if not os.path.exists('/etc/apt/sources.list.backup'): + subprocess.run(['cp', '/etc/apt/sources.list', '/etc/apt/sources.list.backup'], check=False) + + # Update package lists for Ubuntu 25.04 + subprocess.run(['apt-get', 'update'], check=False) + +if __name__ == "__main__": + with api.exception_handler(): + # Ubuntu-specific setup + setup_ubuntu_environment() + + # Standard runner operations + runners.ldconfig() + runners.sysusers() + runners.tmpfiles() + runners.nsswitch() + + r = subprocess.run(sys.argv[1:], check=False) + sys.exit(r.returncode) diff --git a/tools/debian-runner-setup b/tools/debian-runner-setup new file mode 100755 index 00000000..1fd58483 --- /dev/null +++ b/tools/debian-runner-setup @@ -0,0 +1,171 @@ +#!/usr/bin/python3 +""" +Debian Runner Setup Tool +Automatically sets up the appropriate runner for the current system +Creates symbolic links like Fedora does +""" + +import os +import sys +import subprocess +from pathlib import Path + +def detect_system(): + """Detect the current system and determine appropriate runner""" + system_info = { + 'distribution': 'unknown', + 'version': 'unknown', + 'codename': 'unknown', + 'recommended_runner': 'org.osbuild.linux' + } + + if os.path.exists('/etc/os-release'): + with open('/etc/os-release', 'r') as f: + content = f.read() + + # Extract distribution info + if 'debian' in content.lower(): + system_info['distribution'] = 'debian' + # Extract codename + import re + codename_match = re.search(r'VERSION_CODENAME="?([^"\n]+)"?', content) + if codename_match: + codename = codename_match.group(1).lower() + system_info['codename'] = codename + + # Map codename to runner + if codename == 'trixie': + system_info['recommended_runner'] = 'org.osbuild.debian13' + elif codename == 'forky': + system_info['recommended_runner'] = 'org.osbuild.debian14' + elif codename == 'sid': + system_info['recommended_runner'] = 'org.osbuild.debian-sid' + else: + system_info['recommended_runner'] = 'org.osbuild.debian' + + elif 'ubuntu' in content.lower(): + system_info['distribution'] = 'ubuntu' + # Extract version + version_match = re.search(r'VERSION_ID="?([^"\n]+)"?', content) + if version_match: + version = version_match.group(1) + system_info['version'] = version + + # Map version to runner + if version == '25.04': + system_info['recommended_runner'] = 'org.osbuild.ubuntu2504' + elif version == '24.04': + system_info['recommended_runner'] = 'org.osbuild.ubuntu2404' + else: + system_info['recommended_runner'] = 'org.osbuild.ubuntu1804' + + elif any(x in content.lower() for x in ['mint', 'pop', 'elementary', 'zorin', 'kali', 'parrot']): + system_info['distribution'] = 'debian-based' + system_info['recommended_runner'] = 'org.osbuild.debian-based' + + return system_info + +def setup_runner(system_info): + """Setup the appropriate runner for the current system""" + project_root = Path(__file__).parent.parent + runners_dir = project_root / 'runners' + + # Get current system name (hostname or distribution) + current_system = os.uname().nodename.lower() + + # Create runner name for current system + runner_name = f"org.osbuild.{current_system}" + runner_path = runners_dir / runner_name + + # Get recommended runner path + recommended_runner = runners_dir / system_info['recommended_runner'] + + if not recommended_runner.exists(): + print(f"āŒ Recommended runner {system_info['recommended_runner']} not found!") + print(f" Available runners:") + for runner in sorted(runners_dir.glob('org.osbuild.*')): + if runner.is_file(): + print(f" - {runner.name}") + return False + + # Remove existing runner if it exists + if runner_path.exists() or runner_path.is_symlink(): + if runner_path.is_symlink(): + runner_path.unlink() + else: + runner_path.unlink() + + # Create symbolic link + try: + runner_path.symlink_to(recommended_runner.name) + print(f"āœ… Created runner: {runner_name} -> {system_info['recommended_runner']}") + return True + except Exception as e: + print(f"āŒ Failed to create runner: {e}") + return False + +def list_runners(): + """List all available runners""" + project_root = Path(__file__).parent.parent + runners_dir = project_root / 'runners' + + print("Available Debian/Ubuntu Runners:") + print("=" * 40) + + # Group runners by type + debian_runners = [] + ubuntu_runners = [] + other_runners = [] + + for runner in sorted(runners_dir.glob('org.osbuild.*')): + if runner.is_file(): + name = runner.name + if 'debian' in name and 'ubuntu' not in name: + debian_runners.append(name) + elif 'ubuntu' in name: + ubuntu_runners.append(name) + else: + other_runners.append(name) + + print("🐧 Debian Runners:") + for runner in debian_runners: + print(f" {runner}") + + print("\n🦊 Ubuntu Runners:") + for runner in ubuntu_runners: + print(f" {runner}") + + print("\nšŸ”§ Other Runners:") + for runner in other_runners: + print(f" {runner}") + + print(f"\nTotal: {len(debian_runners) + len(ubuntu_runners) + len(other_runners)} runners") + +def main(): + """Main function""" + if len(sys.argv) > 1 and sys.argv[1] == 'list': + list_runners() + return + + print("šŸ” Debian Runner Setup Tool") + print("=" * 40) + + # Detect system + system_info = detect_system() + print(f"Distribution: {system_info['distribution']}") + print(f"Version: {system_info['version']}") + print(f"Codename: {system_info['codename']}") + print(f"Recommended runner: {system_info['recommended_runner']}") + print() + + # Setup runner + if setup_runner(system_info): + print(f"\nšŸŽÆ Runner setup complete!") + print(f" Your system '{os.uname().nodename}' now uses {system_info['recommended_runner']}") + print(f" OSBuild will automatically use the appropriate runner for your system") + else: + print(f"\nāŒ Runner setup failed!") + print(f" Use './tools/debian-runner-setup list' to see available runners") + +if __name__ == '__main__': + main()