DriveStage/README.md

225 lines
8.9 KiB
Markdown
Executable File

# DriveStage
> A Linux-native toolkit for building multi-payload USB drives. Clean ext4 + GRUB2 architecture, boot-time auto-discovery, and an optional Rust GUI. Inspired by Easy2Boot and RMPrepUSB; built from scratch for the modern Linux era.
**Author:** Jeremy Anderson <info@dcos.net> — [dcos.net](https://dcos.net)
## Project naming
DriveStage is the public project name. BlkStage is the internal backend
that ships as `scripts/blkstage.sh` and installs on PATH as the `drivestage`
CLI command. The GUI binary is `drivestage-gui`. The previous codename was
retired to remove a trademark conflict; the rename is deliberate and
complete across source, docs, paths, partition labels, and GRUB cfg
identifiers.
```
┌──────────────────────────────────────────────────────────────────────┐
│ blkstage.sh → the engine (BlkStage, single bash script) │
│ drivestage-gui → optional Rust + Iced companion app │
└──────────────────────────────────────────────────────────────────────┘
```
## What this is
A two-part toolkit for building multi-payload USB drives on Linux. Drop a
dozen distro ISOs onto a single stick and boot any of them on demand.
Designed as a clean-slate Linux-native implementation — inspired by the
drop-and-boot workflow of Easy2Boot and RMPrepUSB, with no shared code or
heritage. The previous Bash + NTFS + FAT32 + grub4dos pipeline is not
carried forward; every layer is replaced with a Linux-native equivalent.
### The architecture
The drive layout is minimal, standard-compliant, and deterministic:
```
[ Drive: /dev/sdX or /dev/nvmeXn1 ]
├─ Partition 1: ESP (FAT32, 512MB) → /boot/efi (UEFI GRUB binaries)
├─ Partition 2: BIOS Boot (unformatted, 1MB) (GRUB GPT embedding)
└─ Partition 3: Payloads (ext4, remainder) → /payloads (ISOs, rootfs tars, images)
```
**Ext4 for payloads by decision.** GRUB2 ships built-in ext2/ext3/ext4
drivers. UEFI loads GRUB from the FAT32 ESP; GRUB loads its drivers and
reads menu entries and kernels directly from the ext4 partition. This
removes the FAT32 4 GB file size limit, eliminates the need for NTFS
drivers, and avoids contiguous-file defragmentation passes entirely.
Files on ext4 are files — no allocation tricks, no partition-table
patching.
### Boot-time auto-discovery
The defining feature. Drop files into `payloads/` and boot — no
host-side menu generation, no `scan` command for ISOs, no config file
editing. GRUB's `grub.cfg` contains `for` loops that scan
`payloads/{isos,rootfs,images}/` at boot time and emit menu entries
with distro-specific kernel arguments selected by filename pattern
matching.
Supported distros (30+): Ubuntu, Debian, Arch, Manjaro, Fedora, CentOS
Stream, Rocky, Alma, openSUSE, Kali, Parrot, Tails, Knoppix,
SystemRescue, Alpine, Void, Gentoo, Slax, TinyCore, Clonezilla, GParted,
Mint, elementary, Pop!_OS. Unrecognized ISOs chainload via GRUB's
standard `loopback.cfg` mechanism — no special-case handling required.
## Repository layout
```
drivestage/
├── README.md ← this document
├── QUICKSTART.md ← 5-minute getting started guide
├── BLOG.md ← design rationale and architecture deep-dive
├── LICENSE ← MIT
├── CONTRIBUTING.md ← development setup, conventions
├── SECURITY.md ← threat model, disclosure process
├── CHANGELOG.md ← release history
├── QA_REPORT.md ← MoE production-readiness review
├── Makefile ← build / test / install / dist targets
│
├── scripts/
│ ├── blkstage.sh ← the engine (BlkStage, single bash file)
│ ├── test_distro_detection.sh ← 30 distro-pattern unit tests
│ └── test_loop_device.sh ← end-to-end loop-device smoke test
│
└── gui/ ← optional Rust + Iced companion app
├── README.md ← GUI-specific documentation
├── Cargo.toml
├── Cargo.lock
├── assets/
│ └── blkstage.sh ← bundled copy of the engine
└── src/
├── main.rs ← bootstrap
├── app.rs ← top-level state, Message enum
├── theme.rs ← dark tech utility palette
├── core/ ← disk, sudo, bootloader, payload modules
└── ui/ ← 5 page modules + widget helpers
```
## Two interfaces, one engine
### CLI — the bash engine (BlkStage)
The minimal path. No Rust toolchain required. The engine is a single
self-contained file.
```bash
# Provision a USB drive (one-time)
sudo ./scripts/blkstage.sh setup /dev/sdX
# Drop ISOs into the mounted payloads directory — no scan command required
cp ubuntu-24.04.iso /mnt/drivestage/payload/payloads/isos/
cp archlinux-2026.08.01-x86_64.iso /mnt/drivestage/payload/payloads/isos/
# Eject and boot — GRUB auto-discovers
sudo umount /mnt/drivestage/payload
sudo eject /dev/sdX
```
Six subcommands: `setup`, `deploy`, `scan`, `list`, `shell`, `clean`.
Run `./scripts/blkstage.sh --help` for the full reference.
### GUI — the Rust companion (drivestage-gui)
A native desktop application for users who want a visual interface.
Wraps the bash engine with a dark-tech-utility themed UI featuring a
setup wizard, payload manager, bootloader switcher, menu editor, and
diagnostics.
```bash
cd gui
cargo build --release
./target/release/drivestage-gui
```
See [`gui/README.md`](gui/README.md) for build and usage instructions.
## Design principles
1. **Linux-native.** Ext4, GRUB2, bash, systemd-aware. No cross-platform shims.
2. **Drop-and-boot.** GRUB discovers payloads at boot time. No host-side menu generation for ISOs.
3. **Safe by default.** The engine refuses to touch the OS disk and requires typed confirmation for destructive operations.
4. **Single-file engine.** The bash script is one self-contained file. Dependencies are standard Linux utilities.
5. **Optional GUI.** The Rust app is a thin wrapper. The engine operates standalone.
6. **Multiple bootloader support.** GRUB2 by default; systemd-boot, Limine, and rEFInd available via the GUI.
## Requirements
### Bash engine
Standard Linux utilities present on any modern distribution:
```
bash 4+, parted, sfdisk, mkfs.fat, mkfs.ext4, blkid, findmnt,
grub-install (with x86_64-efi and i386-pc modules), tar, rsync, wipefs
```
Optional: `smartctl` for diagnostics; `bootctl`, `limine`, `refind-install` for non-GRUB2 bootloaders.
### GUI
- Rust 1.75+ ([rustup](https://rustup.rs))
- All bash engine dependencies
- Linux desktop (Wayland or X11)
## Installation
### From source
```bash
git clone https://git.dcos.net/dcosnet/DriveStage.git
cd drivestage
# CLI — install the engine on PATH as the `drivestage` command
sudo cp scripts/blkstage.sh /usr/local/bin/drivestage
sudo chmod +x /usr/local/bin/drivestage
# GUI — build with cargo
cd gui
cargo build --release
sudo cp target/release/drivestage-gui /usr/local/bin/
sudo mkdir -p /usr/local/lib/drivestage
sudo cp assets/blkstage.sh /usr/local/lib/drivestage/
```
### Via cargo install (GUI)
```bash
cargo install --git https://git.dcos.net/dcosnet/DriveStage
```
## Documentation
- [`QUICKSTART.md`](QUICKSTART.md) — 5-minute getting started guide
- [`BLOG.md`](BLOG.md) — design rationale and architecture deep-dive
- `./scripts/blkstage.sh --help` — full CLI reference
- [`gui/README.md`](gui/README.md) — GUI build, install, and usage
- [`CONTRIBUTING.md`](CONTRIBUTING.md) — development setup and conventions
- [`SECURITY.md`](SECURITY.md) — threat model and disclosure process
- [`CHANGELOG.md`](CHANGELOG.md) — release history
- [`QA_REPORT.md`](QA_REPORT.md) — MoE production-readiness review
## License
MIT — see [`LICENSE`](LICENSE).
## Attribution
Inspired by Easy2Boot and RMPrepUSB by Steve Si. Independent implementation; no derived code.
## Contributing
Pull requests welcome. The codebase prioritizes readability:
- The bash engine is a single file — direct to read, direct to modify.
- The Rust GUI separates core logic from UI pages.
- Distro boot parameters live in one location: the `ds_iso_entry` function
in the auto-scan `grub.cfg`, mirrored by the `detect_distro_profile`
function in the bash engine.
Adding support for a new distro requires a single `case` clause in
`detect_distro_profile` (in `scripts/blkstage.sh`) and a matching
`regexp` clause in the GRUB `grub.cfg` template generated by
`generate_grub_main_cfg`. The test suite at
`scripts/test_distro_detection.sh` verifies 30+ patterns.