diff --git a/CLAUDE.md b/CLAUDE.md new file mode 100644 index 0000000..52651da --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1,100 @@ +# CLAUDE.md + +This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. + +## Project Overview + +Debi is a Debian Network Reinstall Script that allows reinstalling any VPS or physical machine to minimal Debian via network boot. It's a single POSIX-compliant shell script that automates the entire Debian installation process. + +## Commands + +### Running the Script +```bash +# Basic execution (requires root) +sudo ./debi.sh + +# With options +sudo ./debi.sh --user debian --timezone UTC --cloudflare + +# Dry run (generate config without installing) +sudo ./debi.sh --dry-run + +# With cloud-init configuration +sudo ./debi.sh --cidata ./cidata-example/ +``` + +### Testing Changes +```bash +# Check shell script syntax +sh -n debi.sh + +# Run shellcheck for linting (if available) +shellcheck debi.sh + +# Test in a VM environment (recommended) +# No automated test suite exists - manual testing required +``` + +## Architecture + +The script operates in distinct phases: + +1. **Configuration Phase**: Parses command-line arguments and validates environment +2. **Download Phase**: Fetches Debian installer components to `/boot/debian-$VERSION/` +3. **Preseed Generation**: Creates automated installation configuration +4. **GRUB Modification**: Adds installer entry to bootloader menu +5. **Initramfs Injection**: Embeds preseed and network configuration into installer +6. **Execution**: Updates GRUB and prepares for reboot + +Key architectural decisions: +- Single-file design for easy distribution +- POSIX compliance for maximum compatibility +- No external dependencies beyond standard Linux utilities +- Modular function design with clear separation of concerns +- Extensive error handling with rollback capabilities + +## Key Functions and Their Purposes + +- `download()`: Handles file downloads with proxy support and multiple backend options (wget/curl/busybox) +- `set_debian_version()` / `set_suite()`: Manages Debian version selection and mirror URLs +- `configure_sshd()`: Sets up SSH access during installation for remote monitoring +- `in_target()`: Executes commands within the target installation environment +- `prompt_password()`: Securely handles password input with validation + +## Important Configuration Variables + +The script uses 80+ configuration options. Key ones include: +- `$suite`: Debian version (bookworm, bullseye, etc.) +- `$mirror_protocol` / `$mirror_host`: APT repository configuration +- `$disk`: Target installation disk +- `$authorized_keys_url`: SSH key provisioning +- `$cidata`: Cloud-init configuration directory + +## Development Guidelines + +1. **Maintain POSIX compliance** - Script must work with dash/sh, not just bash +2. **Test on real systems** - No test suite exists; changes require VM or physical testing +3. **Preserve backward compatibility** - Many users rely on specific option behaviors +4. **Document all options** - Update README.md for any new configuration options +5. **Handle errors gracefully** - Always provide rollback paths for critical operations + +## Common Development Tasks + +### Adding New Configuration Options +1. Add option to the case statement in the argument parsing section +2. Define corresponding variable with sensible default +3. Implement logic in appropriate phase function +4. Update README.md documentation + +### Debugging Installation Issues +1. Use `--dry-run` to generate and inspect preseed configuration +2. Enable network console with `--ssh` for remote debugging +3. Check `/boot/debian-$VERSION/` for downloaded components +4. Review GRUB configuration changes in `/boot/grub/grub.cfg` + +### Testing Platform Compatibility +Focus areas for testing: +- Network configuration (static IP vs DHCP) +- Disk detection and partitioning +- GRUB installation and boot entries +- Architecture-specific installer components \ No newline at end of file diff --git a/README.ja-JP.md b/README.ja-JP.md index 8bf8943..6c5ad1e 100644 --- a/README.ja-JP.md +++ b/README.ja-JP.md @@ -30,7 +30,7 @@ sudo ./debi.sh --user root sudo reboot ```` -**デフォルト設定:** Debian 12 (bookworm)、DHCPによるネットワーク設定、sudo権限を持つ`debian`ユーザーが作成され、パスワードの入力を求められます。 +**デフォルト設定:** Debian 13 (trixie)、DHCPによるネットワーク設定、sudo権限を持つ`debian`ユーザーが作成され、パスワードの入力を求められます。 ## プラットフォームサポート @@ -65,8 +65,8 @@ sudo reboot | オプション | デフォルト値 | 説明 | |---|---|---| -| `--version 12` | `12` | Debianのバージョン: `10`, `11`, `12`, `13` | -| `--suite bookworm` | `bookworm` | Debianのスイート: `stable`, `testing`, `sid` など | +| `--version 13` | `13` | Debianのバージョン: `10`, `11`, `12`, `13`, `14` | +| `--suite trixie` | `trixie` | Debianのスイート: `stable`, `testing`, `sid` など | | `--user debian` | `debian` | ユーザー名 (`root`を指定するとrootユーザーのみ) | | `--password PASSWORD` | *プロンプト* | ユーザーのパスワード(指定しない場合はプロンプト表示) | | `--authorized-keys-url URL` | *パスワード認証* | URLからSSH公開鍵を設定 (例: `https://github.com/user.keys`) | @@ -267,7 +267,7 @@ sudo ./debi.sh --ip 192.168.1.100/24 --gateway 192.168.1.1 --cidata ./cloud-conf ```bash sudo ./debi.sh \ - --version 12 \ + --version 13 \ --user admin \ --timezone Europe/London \ --disk /dev/nvme0n1 \ diff --git a/README.md b/README.md index 1bfcef3..129dcfd 100644 --- a/README.md +++ b/README.md @@ -31,7 +31,7 @@ sudo ./debi.sh --user root sudo reboot ``` -**Default settings:** Debian 12 (bookworm), DHCP networking, user `debian` with sudo access, you'll be prompted for password. +**Default settings:** Debian 13 (trixie), DHCP networking, user `debian` with sudo access, you'll be prompted for password. ## Platform Support @@ -64,8 +64,8 @@ sudo reboot ### System & User Configuration | Option | Default | Description | |--------|---------|-------------| -| `--version 12` | `12` | Debian version: `10`, `11`, `12`, `13` | -| `--suite bookworm` | `bookworm` | Debian suite: `stable`, `testing`, `sid`, etc. | +| `--version 13` | `13` | Debian version: `10`, `11`, `12`, `13`, `14` | +| `--suite trixie` | `trixie` | Debian suite: `stable`, `testing`, `sid`, etc. | | `--user debian` | `debian` | Username (use `root` for root-only) | | `--password PASSWORD` | *prompt* | User password (prompted if not specified) | | `--authorized-keys-url URL` | *password auth* | SSH keys from URL (e.g., `https://github.com/user.keys`) | @@ -245,7 +245,7 @@ sudo ./debi.sh --ip 192.168.1.100/24 --gateway 192.168.1.1 --cidata ./cloud-conf ### Advanced Custom Configuration ```bash sudo ./debi.sh \ - --version 12 \ + --version 13 \ --user admin \ --timezone Europe/London \ --disk /dev/nvme0n1 \ diff --git a/README.zh-CN.md b/README.zh-CN.md index 2fc85d0..f9c9709 100644 --- a/README.zh-CN.md +++ b/README.zh-CN.md @@ -31,7 +31,7 @@ sudo ./debi.sh --user root sudo reboot ``` -**默认设置:** Debian 12 (bookworm),DHCP 网络,创建一个名为 `debian` 并拥有 sudo 权限的用户,脚本会提示你为该用户设置密码。 +**默认设置:** Debian 13 (trixie),DHCP 网络,创建一个名为 `debian` 并拥有 sudo 权限的用户,脚本会提示你为该用户设置密码。 ## 平台支持 @@ -66,8 +66,8 @@ sudo reboot | 选项 | 默认值 | 描述 | | :--- | :--- | :--- | -| `--version 12` | `12` | Debian 版本:`10`, `11`, `12`, `13` | -| `--suite bookworm` | `bookworm` | Debian 发行代号:`stable`, `testing`, `sid` 等 | +| `--version 13` | `13` | Debian 版本:`10`, `11`, `12`, `13`, `14` | +| `--suite trixie` | `trixie` | Debian 发行代号:`stable`, `testing`, `sid` 等 | | `--user debian` | `debian` | 用户名 (使用 `root` 则只创建 root 用户) | | `--password PASSWORD` | *交互式提示* | 用户密码 (如果未指定,则会提示输入) | | `--authorized-keys-url URL` | *密码认证* | 从 URL 加载 SSH 公钥 (例如 `https://github.com/user.keys`) | @@ -269,7 +269,7 @@ sudo ./debi.sh --ip 192.168.1.100/24 --gateway 192.168.1.1 --cidata ./cloud-conf ```bash sudo ./debi.sh \ - --version 12 \ + --version 13 \ --user admin \ --timezone Europe/London \ --disk /dev/nvme0n1 \ diff --git a/debi.sh b/debi.sh index 9c241b7..ca2987f 100755 --- a/debi.sh +++ b/debi.sh @@ -109,12 +109,16 @@ set_mirror_proxy() { esac } +# Determines the security repository path format based on Debian suite +# - Buster (Debian 10): Uses old format "buster/updates" +# - Bullseye onwards and testing: Uses new format "suite-security" +# - Sid/unstable: No security repository (fixes go directly to unstable) set_security_archive() { case $suite in - buster|oldoldstable) + buster) security_archive="$suite/updates" ;; - bullseye|oldstable|bookworm|stable|trixie|testing) + bullseye|oldoldstable|bookworm|oldstable|trixie|stable|forky|testing) security_archive="$suite-security" ;; sid|unstable) @@ -125,12 +129,16 @@ set_security_archive() { esac } +# Determines whether to use daily or stable installer builds +# - Stable/oldstable releases: Use stable installer builds (thoroughly tested) +# - Testing/unstable: Use daily installer builds (latest changes, may be less stable) +# Daily builds are necessary for testing/unstable as they need the latest kernel and packages set_daily_d_i() { case $suite in - buster|oldoldstable|bullseye|oldstable|bookworm|stable) + buster|bullseye|oldoldstable|bookworm|oldstable|trixie|stable) daily_d_i=false ;; - trixie|testing|sid|unstable) + forky|testing|sid|unstable) daily_d_i=true ;; *) @@ -144,20 +152,32 @@ set_suite() { set_security_archive } +# Maps version numbers and release aliases to actual suite names +# Accepts: version number (10-14), suite name (buster, bullseye, etc.), or alias (stable, testing, etc.) +# Current mapping: +# - 10/buster: No longer supported as oldoldstable (archived) +# - 11/bullseye/oldoldstable: LTS support +# - 12/bookworm/oldstable: Previous stable +# - 13/trixie/stable: Current stable release +# - 14/forky/testing: Next release in development +# - sid/unstable: Rolling development branch set_debian_version() { case $1 in - 10|buster|oldoldstable) + 10|buster) set_suite buster ;; - 11|bullseye|oldstable) + 11|bullseye|oldoldstable) set_suite bullseye ;; - 12|bookworm|stable) + 12|bookworm|oldstable) set_suite bookworm ;; - 13|trixie|testing) + 13|trixie|stable) set_suite trixie ;; + 14|forky|testing) + set_suite forky + ;; sid|unstable) set_suite sid ;; @@ -166,13 +186,19 @@ set_debian_version() { esac } +# Checks if cloud-optimized kernels are available for the current architecture and suite +# Cloud kernels are minimal kernels optimized for cloud/virtual environments +# - Buster: Only amd64 has cloud kernel, arm64 requires backports +# - Bullseye onwards: Both amd64 and arm64 have cloud kernels +# - Other architectures (i386, etc.): No cloud kernels available +# Returns 0 if available, 1 if not has_cloud_kernel() { case $suite in - buster|oldoldstable) + buster) [ "$architecture" = amd64 ] && return [ "$architecture" = arm64 ] && [ "$bpo_kernel" = true ] && return ;; - bullseye|oldstable|bookworm|stable|trixie|testing|sid|unstable) + bullseye|oldoldstable|bookworm|oldstable|trixie|stable|forky|testing|sid|unstable) [ "$architecture" = amd64 ] || [ "$architecture" = arm64 ] && return esac @@ -182,9 +208,14 @@ has_cloud_kernel() { return 1 } +# Checks if backports repository is available for the current suite +# Backports provide newer versions of packages from testing/unstable rebuilt for stable releases +# - All stable releases and testing: Have backports available +# - Sid/unstable: No backports (already has the latest packages) +# Returns 0 if available, 1 if not has_backports() { case $suite in - buster|oldoldstable|bullseye|oldstable|bookworm|stable|trixie|testing) return + buster|bullseye|oldoldstable|bookworm|oldstable|trixie|stable|forky|testing) return esac warn "No backports kernel is available for $suite" @@ -201,7 +232,7 @@ dns6='2606:4700:4700::1111 2606:4700:4700::1001' dns10='1.1.1.1 2606:4700:4700::1111' hostname= network_console=false -set_debian_version 12 +set_debian_version 13 mirror_protocol=https mirror_host=deb.debian.org mirror_directory=/debian @@ -540,9 +571,14 @@ done [ -n "$authorized_keys_url" ] && ! download "$authorized_keys_url" /dev/null && err "Failed to download SSH authorized public keys from \"$authorized_keys_url\"" +# Determines if the non-free-firmware repository component is available +# Starting from Debian 12 (Bookworm), firmware was split into a separate component +# to make it easier to include necessary firmware while keeping main free +# - Bookworm onwards: non-free-firmware component available +# - Bullseye and earlier: Firmware is in non-free component non_free_firmware_available=false case $suite in - bookworm|stable|trixie|testing|sid|unstable) + bookworm|oldstable|trixie|stable|forky|testing|sid|unstable) non_free_firmware_available=true ;; *)