4.3 KiB
4.3 KiB
Project Log: Rostyr
Date: 2026-03-08
Context
- Original project: styr (https://gitea.rowanbrook.net/jakob/styr) - Shell scripts for configuring FreeBSD workstations, servers, VMs, and jails
- Rewrite target: rostyr (https://gitea.rowanbrook.net/jakob/rostyr) - Rust rewrite
Requirements Decided
| Requirement | Decision | Rationale |
|---|---|---|
| Scope | Minimal first, then expand | User preference - start lean, add incrementally |
| Platform | FreeBSD-focused | Keep aligned with styr's FreeBSD focus |
| Config format | TOML | Structured config vs shell scripts |
| Idempotency | All commands re-runnable | Critical requirement - run anytime without side effects |
| Testing | Snapshot-based | User preference - run apply twice, verify no changes second time |
| Test infrastructure | VMs | User preference - bhyve VMs for testing |
| Rollback | Automatic ZFS snapshots | User preference - prominent ZFS usage |
| apply command | Actually applies | User preference - not dry-run by default |
Architecture
Platform Strategy
- Hosts: FreeBSD only
- Jails: Primary service isolation (FreeBSD-native)
- bhyve VMs: For Linux-incompatible services
- ZFS: Snapshot-based backup/rollback (prominent usage)
CLI Commands
rostyr init <hostname> # Scaffold new host config
rostyr validate # Validate all TOML configs
rostyr diff [--host H] # Show pending changes (dry-run)
rostyr check [--host H] # Detect current system state
rostyr apply [--host H] # Apply changes (creates ZFS snapshot first)
rostyr rollback # Revert to last ZFS snapshot
Idempotency Strategy
- Detect current state (jails, VMs, ZFS, users, packages)
- Diff desired vs actual state
- Plan minimal changes needed
- Execute only when state differs
- Snapshot ZFS before any apply
Testing Strategy
- Unit tests: Config parsing, state detection, diff logic
- Integration tests: CLI commands against isolated test VMs
- Idempotency tests: Run apply twice, verify no changes on second run (snapshot comparison)
- VMs for testing: All tests run in isolated bhyve VMs before production deployment
Project Created
Branch
draft/initial-setup(created from main)
Files
README.md- Project documentation with overview, architecture, roadmapCargo.toml- Rust dependencies: clap, toml, serde, thiserror, tracing, anyhowsrc/main.rs- CLI with 6 commands scaffoldedsrc/lib.rs- Module declarationssrc/{config,state,planner,executor,jail,vm,zfs,commands}/mod.rs- Placeholder modules
Directory Structure
rostyr/
├── README.md
├── Cargo.toml
├── configs/
│ ├── hosts/
│ ├── users/
│ └── services/
├── src/
│ ├── main.rs
│ ├── lib.rs
│ ├── config/
│ ├── state/
│ ├── planner/
│ ├── executor/
│ ├── jail/
│ ├── vm/
│ ├── zfs/
│ └── commands/
└── tests/
├── unit/
├── integration/
└── idempotency/
Status
- Project compiles successfully
- Ready for review/merge to main
Phased Roadmap
Phase 1 - Core Foundation
- Project scaffolding (Rust, CLI framework)
- Config parsing (TOML)
- Basic state detection (host info, ZFS)
- init, validate commands
Phase 2 - Idempotent Apply
- Diff/planner logic
- Apply command with ZFS snapshot
- Rollback command
- check command
Phase 3 - Jails
- Jail creation/management
- Basic service jail templates
- User management inside jails
Phase 4 - bhyve VMs
- VM lifecycle management
- Linux VM templates
- Service deployment to VMs
Phase 5+ - Services
- Individual service implementations (from styr)
- Full port of styr functionality
styr Reference (for porting)
Structure (from API)
Core/- Core initialization scripts (freebsd.zsh, init/*.sh, functions.zsh, settings.zsh)Host/- Host configurations: borgen, london, madrid, rackett, templateUser/- User configurations: elisabet, jakob, root, stefanService/- Service definitions: arr, bhyve, bitcoind, fah, gitea, iocage, iperf, joinmarket, mariadb, matrix, nfs, specter, tor, transmission, zabScripts/- Helper scripts: jmc.zsh, vml, vms
Description (from repo)
"Set of scripts to configure workstations, servers, virtual machines, and jails"