225 lines
8.9 KiB
Markdown
Executable File
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.
|