docs: sync with code (topologies, mount scheme, CLI flags, UEFI/BIOS, fstab) and fix relative src links in docs/ to ../src/

This commit is contained in:
2025-09-29 23:24:25 +02:00
parent 7cef73368b
commit b0d8c0bc75
9 changed files with 451 additions and 373 deletions

View File

@@ -6,34 +6,34 @@ Purpose
- After approval, these will be created in the src tree in Code mode.
Index
- [src/lib.rs](src/lib.rs)
- [src/errors.rs](src/errors.rs)
- [src/main.rs](src/main.rs)
- [src/cli/args.rs](src/cli/args.rs)
- [src/logging/mod.rs](src/logging/mod.rs)
- [src/types.rs](src/types.rs)
- [src/config/loader.rs](src/config/loader.rs)
- [src/device/discovery.rs](src/device/discovery.rs)
- [src/partition/plan.rs](src/partition/plan.rs)
- [src/fs/plan.rs](src/fs/plan.rs)
- [src/mount/ops.rs](src/mount/ops.rs)
- [src/report/state.rs](src/report/state.rs)
- [src/orchestrator/run.rs](src/orchestrator/run.rs)
- [src/idempotency/mod.rs](src/idempotency/mod.rs)
- [src/util/mod.rs](src/util/mod.rs)
- [src/lib.rs](../src/lib.rs)
- [src/errors.rs](../src/errors.rs)
- [src/main.rs](../src/main.rs)
- [src/cli/args.rs](../src/cli/args.rs)
- [src/logging/mod.rs](../src/logging/mod.rs)
- [src/types.rs](../src/types.rs)
- [src/config/loader.rs](../src/config/loader.rs)
- [src/device/discovery.rs](../src/device/discovery.rs)
- [src/partition/plan.rs](../src/partition/plan.rs)
- [src/fs/plan.rs](../src/fs/plan.rs)
- [src/mount/ops.rs](../src/mount/ops.rs)
- [src/report/state.rs](../src/report/state.rs)
- [src/orchestrator/run.rs](../src/orchestrator/run.rs)
- [src/idempotency/mod.rs](../src/idempotency/mod.rs)
- [src/util/mod.rs](../src/util/mod.rs)
Conventions
- Shared [type Result<T>](src/errors.rs:1) and [enum Error](src/errors.rs:1).
- Shared [type Result<T>](../src/errors.rs:1) and [enum Error](../src/errors.rs:1).
- No stdout prints; use tracing only.
- External tools invoked via [util](src/util/mod.rs) wrappers.
- External tools invoked via [util](../src/util/mod.rs) wrappers.
---
## Crate root
References
- [src/lib.rs](src/lib.rs)
- [type Result<T> = std::result::Result<T, Error>](src/errors.rs:1)
- [src/lib.rs](../src/lib.rs)
- [type Result<T> = std::result::Result<T, Error>](../src/errors.rs:1)
Skeleton (for later implementation in code mode)
```rust
@@ -63,8 +63,8 @@ pub const VERSION: &str = env!("CARGO_PKG_VERSION");
## Errors
References
- [enum Error](src/errors.rs:1)
- [type Result<T>](src/errors.rs:1)
- [enum Error](../src/errors.rs:1)
- [type Result<T>](../src/errors.rs:1)
Skeleton
```rust
@@ -107,8 +107,8 @@ pub type Result<T> = std::result::Result<T, Error>;
## Entrypoint
References
- [fn main()](src/main.rs:1)
- [fn run(ctx: &Context) -> Result<()>](src/orchestrator/run.rs:1)
- [fn main()](../src/main.rs:1)
- [fn run(ctx: &Context) -> Result<()>](../src/orchestrator/run.rs:1)
Skeleton
```rust
@@ -143,8 +143,8 @@ fn real_main() -> Result<()> {
## CLI
References
- [struct Cli](src/cli/args.rs:1)
- [fn from_args() -> Cli](src/cli/args.rs:1)
- [struct Cli](../src/cli/args.rs:1)
- [fn from_args() -> Cli](../src/cli/args.rs:1)
Skeleton
```rust
@@ -170,6 +170,18 @@ pub struct Cli {
#[arg(long = "fstab", default_value_t = false)]
pub fstab: bool,
/// Print preview JSON to stdout (non-destructive)
#[arg(long = "show", default_value_t = false)]
pub show: bool,
/// Write preview JSON to a file (non-destructive)
#[arg(long = "report")]
pub report: Option<String>,
/// Perform partitioning, filesystem creation, and mounts (DESTRUCTIVE)
#[arg(long = "apply", default_value_t = false)]
pub apply: bool,
/// Present but non-functional; returns unimplemented error
#[arg(long = "force")]
pub force: bool,
@@ -186,8 +198,8 @@ pub fn from_args() -> Cli {
## Logging
References
- [struct LogOptions](src/logging/mod.rs:1)
- [fn init_logging(opts: &LogOptions) -> Result<()>](src/logging/mod.rs:1)
- [struct LogOptions](../src/logging/mod.rs:1)
- [fn init_logging(opts: &LogOptions) -> Result<()>](../src/logging/mod.rs:1)
Skeleton
```rust
@@ -218,13 +230,13 @@ pub fn init_logging(opts: &LogOptions) -> Result<()> {
## Configuration types
References
- [struct Config](src/types.rs:1)
- [enum Topology](src/types.rs:1)
- [struct DeviceSelection](src/types.rs:1)
- [struct Partitioning](src/types.rs:1)
- [struct FsOptions](src/types.rs:1)
- [struct MountScheme](src/types.rs:1)
- [struct ReportOptions](src/types.rs:1)
- [struct Config](../src/types.rs:1)
- [enum Topology](../src/types.rs:1)
- [struct DeviceSelection](../src/types.rs:1)
- [struct Partitioning](../src/types.rs:1)
- [struct FsOptions](../src/types.rs:1)
- [struct MountScheme](../src/types.rs:1)
- [struct ReportOptions](../src/types.rs:1)
Skeleton
```rust
@@ -247,8 +259,10 @@ pub struct DeviceSelection {
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub enum Topology {
Single,
BtrfsSingle,
BcachefsSingle,
DualIndependent,
Bcachefs2Copy,
SsdHddBcachefs,
BtrfsRaid1,
}
@@ -351,8 +365,8 @@ pub struct Config {
## Configuration I/O
References
- [fn load_and_merge(cli: &Cli) -> Result<Config>](src/config/loader.rs:1)
- [fn validate(cfg: &Config) -> Result<()>](src/config/loader.rs:1)
- [fn load_and_merge(cli: &Cli) -> Result<Config>](../src/config/loader.rs:1)
- [fn validate(cfg: &Config) -> Result<()>](../src/config/loader.rs:1)
Skeleton
```rust
@@ -374,10 +388,10 @@ pub fn validate(cfg: &crate::config::types::Config) -> Result<()> {
## Device discovery
References
- [struct Disk](src/device/discovery.rs:1)
- [struct DeviceFilter](src/device/discovery.rs:1)
- [trait DeviceProvider](src/device/discovery.rs:1)
- [fn discover(filter: &DeviceFilter) -> Result<Vec<Disk>>](src/device/discovery.rs:1)
- [struct Disk](../src/device/discovery.rs:1)
- [struct DeviceFilter](../src/device/discovery.rs:1)
- [trait DeviceProvider](../src/device/discovery.rs:1)
- [fn discover(filter: &DeviceFilter) -> Result<Vec<Disk>>](../src/device/discovery.rs:1)
Skeleton
```rust
@@ -418,12 +432,12 @@ pub fn discover(filter: &DeviceFilter) -> Result<Vec<Disk>> {
## Partitioning
References
- [enum PartRole](src/partition/plan.rs:1)
- [struct PartitionSpec](src/partition/plan.rs:1)
- [struct PartitionPlan](src/partition/plan.rs:1)
- [struct PartitionResult](src/partition/plan.rs:1)
- [fn plan_partitions(disks: &[Disk], cfg: &Config) -> Result<PartitionPlan>](src/partition/plan.rs:1)
- [fn apply_partitions(plan: &PartitionPlan) -> Result<Vec<PartitionResult>>](src/partition/plan.rs:1)
- [enum PartRole](../src/partition/plan.rs:1)
- [struct PartitionSpec](../src/partition/plan.rs:1)
- [struct PartitionPlan](../src/partition/plan.rs:1)
- [struct PartitionResult](../src/partition/plan.rs:1)
- [fn plan_partitions(disks: &[Disk], cfg: &Config) -> Result<PartitionPlan>](../src/partition/plan.rs:1)
- [fn apply_partitions(plan: &PartitionPlan) -> Result<Vec<PartitionResult>>](../src/partition/plan.rs:1)
Skeleton
```rust
@@ -485,12 +499,12 @@ pub fn apply_partitions(plan: &PartitionPlan) -> Result<Vec<PartitionResult>> {
## Filesystems
References
- [enum FsKind](src/fs/plan.rs:1)
- [struct FsSpec](src/fs/plan.rs:1)
- [struct FsPlan](src/fs/plan.rs:1)
- [struct FsResult](src/fs/plan.rs:1)
- [fn plan_filesystems(...)](src/fs/plan.rs:1)
- [fn make_filesystems(...)](src/fs/plan.rs:1)
- [enum FsKind](../src/fs/plan.rs:1)
- [struct FsSpec](../src/fs/plan.rs:1)
- [struct FsPlan](../src/fs/plan.rs:1)
- [struct FsResult](../src/fs/plan.rs:1)
- [fn plan_filesystems(...)](../src/fs/plan.rs:1)
- [fn make_filesystems(...)](../src/fs/plan.rs:1)
Skeleton
```rust
@@ -531,8 +545,8 @@ pub fn plan_filesystems(
todo!("map ESP to vfat, data to btrfs or bcachefs according to topology")
}
/// Create the filesystems and return identity info (UUIDs, labels).
pub fn make_filesystems(plan: &FsPlan) -> Result<Vec<FsResult>> {
//// Create the filesystems and return identity info (UUIDs, labels).
pub fn make_filesystems(plan: &FsPlan, cfg: &Config) -> Result<Vec<FsResult>> {
todo!("invoke mkfs tools with configured options via util::run_cmd")
}
```
@@ -542,11 +556,11 @@ pub fn make_filesystems(plan: &FsPlan) -> Result<Vec<FsResult>> {
## Mounting
References
- [struct MountPlan](src/mount/ops.rs:1)
- [struct MountResult](src/mount/ops.rs:1)
- [fn plan_mounts(...)](src/mount/ops.rs:1)
- [fn apply_mounts(...)](src/mount/ops.rs:1)
- [fn maybe_write_fstab(...)](src/mount/ops.rs:1)
- [struct MountPlan](../src/mount/ops.rs:1)
- [struct MountResult](../src/mount/ops.rs:1)
- [fn plan_mounts(...)](../src/mount/ops.rs:1)
- [fn apply_mounts(...)](../src/mount/ops.rs:1)
- [fn maybe_write_fstab(...)](../src/mount/ops.rs:1)
Skeleton
```rust
@@ -565,9 +579,13 @@ pub struct MountResult {
pub options: String,
}
/// Build mount plan under /var/cache/<UUID> by default.
//// Build mount plan:
//// - Root-mount all data filesystems under `/var/mounts/{UUID}` (runtime only)
//// - Ensure/create subvolumes on the primary data filesystem: system, etc, modules, vm-meta
//// - Plan final mounts to `/var/cache/{system,etc,modules,vm-meta}` using
//// `subvol=` for btrfs and `X-mount.subdir=` for bcachefs.
pub fn plan_mounts(fs_results: &[FsResult], cfg: &Config) -> Result<MountPlan> {
todo!("create per-UUID directories and mount mapping")
todo!("root mounts under /var/mounts/{UUID}; final subvol/subdir mounts to /var/cache/{system,etc,modules,vm-meta}")
}
/// Apply mounts using syscalls (nix), ensuring directories exist.
@@ -575,9 +593,12 @@ pub fn apply_mounts(plan: &MountPlan) -> Result<Vec<MountResult>> {
todo!("perform mount syscalls and return results")
}
/// Optionally generate /etc/fstab entries in deterministic order.
//// Optionally generate /etc/fstab entries for final subvolume/subdir mounts only.
//// - Write exactly four entries: system, etc, modules, vm-meta
//// - Use UUID= sources; deterministic order by target path
//// - Exclude runtime root mounts under `/var/mounts/{UUID}`
pub fn maybe_write_fstab(mounts: &[MountResult], cfg: &Config) -> Result<()> {
todo!("when enabled, write fstab entries")
todo!("when enabled, write only the four final subvolume/subdir entries with UUID= sources")
}
```
@@ -586,10 +607,10 @@ pub fn maybe_write_fstab(mounts: &[MountResult], cfg: &Config) -> Result<()> {
## Reporting
References
- [const REPORT_VERSION: &str](src/report/state.rs:1)
- [struct StateReport](src/report/state.rs:1)
- [fn build_report(...)](src/report/state.rs:1)
- [fn write_report(...)](src/report/state.rs:1)
- [const REPORT_VERSION: &str](../src/report/state.rs:1)
- [struct StateReport](../src/report/state.rs:1)
- [fn build_report(...)](../src/report/state.rs:1)
- [fn write_report(...)](../src/report/state.rs:1)
Skeleton
```rust
@@ -632,8 +653,8 @@ pub fn write_report(report: &StateReport, path: &str) -> Result<()> {
## Orchestrator
References
- [struct Context](src/orchestrator/run.rs:1)
- [fn run(ctx: &Context) -> Result<()>](src/orchestrator/run.rs:1)
- [struct Context](../src/orchestrator/run.rs:1)
- [fn run(ctx: &Context) -> Result<()>](../src/orchestrator/run.rs:1)
Skeleton
```rust
@@ -662,8 +683,8 @@ pub fn run(ctx: &Context) -> Result<()> {
## Idempotency
References
- [fn detect_existing_state() -> Result<Option<StateReport>>](src/idempotency/mod.rs:1)
- [fn is_empty_disk(disk: &Disk) -> Result<bool>](src/idempotency/mod.rs:1)
- [fn detect_existing_state() -> Result<Option<StateReport>>](../src/idempotency/mod.rs:1)
- [fn is_empty_disk(disk: &Disk) -> Result<bool>](../src/idempotency/mod.rs:1)
Skeleton
```rust
@@ -685,11 +706,11 @@ pub fn is_empty_disk(disk: &Disk) -> Result<bool> {
## Utilities
References
- [struct CmdOutput](src/util/mod.rs:1)
- [fn which_tool(name: &str) -> Result<Option<String>>](src/util/mod.rs:1)
- [fn run_cmd(args: &[&str]) -> Result<()>](src/util/mod.rs:1)
- [fn run_cmd_capture(args: &[&str]) -> Result<CmdOutput>](src/util/mod.rs:1)
- [fn udev_settle(timeout_ms: u64) -> Result<()>](src/util/mod.rs:1)
- [struct CmdOutput](../src/util/mod.rs:1)
- [fn which_tool(name: &str) -> Result<Option<String>>](../src/util/mod.rs:1)
- [fn run_cmd(args: &[&str]) -> Result<()>](../src/util/mod.rs:1)
- [fn run_cmd_capture(args: &[&str]) -> Result<CmdOutput>](../src/util/mod.rs:1)
- [fn udev_settle(timeout_ms: u64) -> Result<()>](../src/util/mod.rs:1)
Skeleton
```rust
@@ -722,6 +743,11 @@ pub fn run_cmd_capture(args: &[&str]) -> Result<CmdOutput> {
pub fn udev_settle(timeout_ms: u64) -> Result<()> {
todo!("invoke udevadm settle when present")
}
/// Detect UEFI environment by checking /sys/firmware/efi; used to suppress BIOS boot partition on UEFI.
pub fn is_efi_boot() -> bool {
todo!("return Path::new(\"/sys/firmware/efi\").exists()")
}
```
---
@@ -735,24 +761,24 @@ Approval gate
- Add initial tests scaffolding and example configs.
References summary
- [fn main()](src/main.rs:1)
- [fn from_args()](src/cli/args.rs:1)
- [fn init_logging(opts: &LogOptions)](src/logging/mod.rs:1)
- [fn load_and_merge(cli: &Cli)](src/config/loader.rs:1)
- [fn validate(cfg: &Config)](src/config/loader.rs:1)
- [fn discover(filter: &DeviceFilter)](src/device/discovery.rs:1)
- [fn plan_partitions(disks: &[Disk], cfg: &Config)](src/partition/plan.rs:1)
- [fn apply_partitions(plan: &PartitionPlan)](src/partition/plan.rs:1)
- [fn plan_filesystems(parts: &[PartitionResult], cfg: &Config)](src/fs/plan.rs:1)
- [fn make_filesystems(plan: &FsPlan)](src/fs/plan.rs:1)
- [fn plan_mounts(fs_results: &[FsResult], cfg: &Config)](src/mount/ops.rs:1)
- [fn apply_mounts(plan: &MountPlan)](src/mount/ops.rs:1)
- [fn maybe_write_fstab(mounts: &[MountResult], cfg: &Config)](src/mount/ops.rs:1)
- [fn build_report(...)](src/report/state.rs:1)
- [fn write_report(report: &StateReport)](src/report/state.rs:1)
- [fn detect_existing_state()](src/idempotency/mod.rs:1)
- [fn is_empty_disk(disk: &Disk)](src/idempotency/mod.rs:1)
- [fn which_tool(name: &str)](src/util/mod.rs:1)
- [fn run_cmd(args: &[&str])](src/util/mod.rs:1)
- [fn run_cmd_capture(args: &[&str])](src/util/mod.rs:1)
- [fn udev_settle(timeout_ms: u64)](src/util/mod.rs:1)
- [fn main()](../src/main.rs:1)
- [fn from_args()](../src/cli/args.rs:1)
- [fn init_logging(opts: &LogOptions)](../src/logging/mod.rs:1)
- [fn load_and_merge(cli: &Cli)](../src/config/loader.rs:1)
- [fn validate(cfg: &Config)](../src/config/loader.rs:1)
- [fn discover(filter: &DeviceFilter)](../src/device/discovery.rs:1)
- [fn plan_partitions(disks: &[Disk], cfg: &Config)](../src/partition/plan.rs:1)
- [fn apply_partitions(plan: &PartitionPlan)](../src/partition/plan.rs:1)
- [fn plan_filesystems(parts: &[PartitionResult], cfg: &Config)](../src/fs/plan.rs:1)
- [fn make_filesystems(plan: &FsPlan)](../src/fs/plan.rs:1)
- [fn plan_mounts(fs_results: &[FsResult], cfg: &Config)](../src/mount/ops.rs:1)
- [fn apply_mounts(plan: &MountPlan)](../src/mount/ops.rs:1)
- [fn maybe_write_fstab(mounts: &[MountResult], cfg: &Config)](../src/mount/ops.rs:1)
- [fn build_report(...)](../src/report/state.rs:1)
- [fn write_report(report: &StateReport)](../src/report/state.rs:1)
- [fn detect_existing_state()](../src/idempotency/mod.rs:1)
- [fn is_empty_disk(disk: &Disk)](../src/idempotency/mod.rs:1)
- [fn which_tool(name: &str)](../src/util/mod.rs:1)
- [fn run_cmd(args: &[&str])](../src/util/mod.rs:1)
- [fn run_cmd_capture(args: &[&str])](../src/util/mod.rs:1)
- [fn udev_settle(timeout_ms: u64)](../src/util/mod.rs:1)

View File

@@ -8,40 +8,40 @@ Conventions
- External tooling calls are mediated via utility wrappers.
Module index
- [src/main.rs](src/main.rs)
- [src/lib.rs](src/lib.rs)
- [src/errors.rs](src/errors.rs)
- [src/cli/args.rs](src/cli/args.rs)
- [src/logging/mod.rs](src/logging/mod.rs)
- [src/types.rs](src/types.rs)
- [src/config/loader.rs](src/config/loader.rs)
- [src/device/discovery.rs](src/device/discovery.rs)
- [src/partition/plan.rs](src/partition/plan.rs)
- [src/fs/plan.rs](src/fs/plan.rs)
- [src/mount/ops.rs](src/mount/ops.rs)
- [src/report/state.rs](src/report/state.rs)
- [src/orchestrator/run.rs](src/orchestrator/run.rs)
- [src/idempotency/mod.rs](src/idempotency/mod.rs)
- [src/util/mod.rs](src/util/mod.rs)
- [src/main.rs](../src/main.rs)
- [src/lib.rs](../src/lib.rs)
- [src/errors.rs](../src/errors.rs)
- [src/cli/args.rs](../src/cli/args.rs)
- [src/logging/mod.rs](../src/logging/mod.rs)
- [src/types.rs](../src/types.rs)
- [src/config/loader.rs](../src/config/loader.rs)
- [src/device/discovery.rs](../src/device/discovery.rs)
- [src/partition/plan.rs](../src/partition/plan.rs)
- [src/fs/plan.rs](../src/fs/plan.rs)
- [src/mount/ops.rs](../src/mount/ops.rs)
- [src/report/state.rs](../src/report/state.rs)
- [src/orchestrator/run.rs](../src/orchestrator/run.rs)
- [src/idempotency/mod.rs](../src/idempotency/mod.rs)
- [src/util/mod.rs](../src/util/mod.rs)
Common errors and result
- [enum Error](src/errors.rs:1)
- [enum Error](../src/errors.rs:1)
- Top-level error type covering parse/validation errors, device discovery errors, partitioning failures, filesystem mkfs errors, mount errors, report write errors, and external tool invocation failures with stderr capture.
- [type Result<T> = std::result::Result<T, Error>](src/errors.rs:1)
- [type Result<T> = std::result::Result<T, Error>](../src/errors.rs:1)
- Shared result alias across modules.
Crate root
- [src/lib.rs](src/lib.rs)
- [src/lib.rs](../src/lib.rs)
- Exposes crate version constants, the prelude, and re-exports common types for consumers of the library (tests/integration). No heavy logic.
Entrypoint
- [fn main()](src/main.rs:1)
- [fn main()](../src/main.rs:1)
- Initializes logging based on CLI defaults, parses CLI flags and kernel cmdline, loads and validates configuration, and invokes the orchestrator run sequence. Avoids stdout; logs via tracing only.
Orchestrator
- [struct Context](src/orchestrator/run.rs:1)
- [struct Context](../src/orchestrator/run.rs:1)
- Aggregates resolved configuration, logging options, and environment flags suited for initramfs execution.
- [fn run(ctx: &Context) -> Result<()>](src/orchestrator/run.rs:1)
- [fn run(ctx: &Context) -> Result<()>](../src/orchestrator/run.rs:1)
- High-level one-shot flow:
- Idempotency detection
- Device discovery
@@ -52,131 +52,141 @@ Orchestrator
- Aborts the entire run on any validation or execution failure. Returns Ok on successful no-op if already provisioned.
CLI
- [struct Cli](src/cli/args.rs:1)
- [struct Cli](../src/cli/args.rs:1)
- Mirrors kernel cmdline semantics with flags:
- --config PATH
- --log-level LEVEL
- --log-to-file
- --fstab
- --show
- --report PATH
- --apply
- --force (present, returns unimplemented error)
- [fn from_args() -> Cli](src/cli/args.rs:1)
- [fn from_args() -> Cli](../src/cli/args.rs:1)
- Parses argv without side effects; suitable for initramfs.
Logging
- [struct LogOptions](src/logging/mod.rs:1)
- [struct LogOptions](../src/logging/mod.rs:1)
- Holds level and optional file target (/run/zosstorage/zosstorage.log).
- [fn init_logging(opts: &LogOptions) -> Result<()>](src/logging/mod.rs:1)
- [fn init_logging(opts: &LogOptions) -> Result<()>](../src/logging/mod.rs:1)
- Configures tracing-subscriber for stderr by default and optional file layer when enabled. Must be idempotent.
Configuration types
- [struct Config](src/types.rs:1)
- [struct Config](../src/types.rs:1)
- The validated configuration used by the orchestrator, containing logging, device selection rules, topology, partitioning, filesystem options, mount scheme, and report path.
- [enum Topology](src/types.rs:1)
- Values: btrfs_single, bcachefs_single, dual_independent, bcachefs_2copy, ssd_hdd_bcachefs, btrfs_raid1 (opt-in).
- [struct DeviceSelection](src/types.rs:1)
- [enum Topology](../src/types.rs:1)
- Values: btrfs_single, bcachefs_single, dual_independent, bcachefs2_copy, ssd_hdd_bcachefs, btrfs_raid1 (opt-in).
- [struct DeviceSelection](../src/types.rs:1)
- Include and exclude regex patterns, minimum size, removable policy.
- [struct Partitioning](src/types.rs:1)
- [struct Partitioning](../src/types.rs:1)
- Alignment, emptiness requirement, bios_boot, esp, data, cache GPT names and sizes where applicable.
- [struct BtrfsOptions](src/types.rs:1)
- [struct BtrfsOptions](../src/types.rs:1)
- Compression string and raid profile (none or raid1).
- [struct BcachefsOptions](src/types.rs:1)
- [struct BcachefsOptions](../src/types.rs:1)
- Cache mode (promote or writeback), compression, checksum.
- [struct VfatOptions](src/types.rs:1)
- [struct VfatOptions](../src/types.rs:1)
- Reserved for ESP mkfs options; includes label ZOSBOOT.
- [struct FsOptions](src/types.rs:1)
- [struct FsOptions](../src/types.rs:1)
- Aggregates BtrfsOptions, BcachefsOptions, VfatOptions and shared defaults such as ZOSDATA label.
- [enum MountSchemeKind](src/types.rs:1)
- [enum MountSchemeKind](../src/types.rs:1)
- Values: per_uuid, custom (future).
- [struct MountScheme](src/types.rs:1)
- [struct MountScheme](../src/types.rs:1)
- Base directory (/var/cache), scheme kind, fstab enabled flag.
- [struct ReportOptions](src/types.rs:1)
- [struct ReportOptions](../src/types.rs:1)
- Output path (/run/zosstorage/state.json).
Configuration IO
- [fn load_and_merge(cli: &Cli) -> Result<Config>](src/config/loader.rs:1)
- [fn load_and_merge(cli: &Cli) -> Result<Config>](../src/config/loader.rs:1)
- Loads built-in defaults, optionally merges on-disk config, overlays CLI flags, and finally overlays kernel cmdline via zosstorage.config=. Validates the YAML against types and constraints.
- [fn validate(cfg: &Config) -> Result<()>](src/config/loader.rs:1)
- [fn validate(cfg: &Config) -> Result<()>](../src/config/loader.rs:1)
- Ensures structural and semantic validity (e.g., disk selection rules not empty, sizes non-zero, supported topology combinations).
Device discovery
- [struct Disk](src/device/discovery.rs:1)
- [struct Disk](../src/device/discovery.rs:1)
- Represents an eligible block device with path, size, rotational flag, and identifiers (serial, model if available).
- [struct DeviceFilter](src/device/discovery.rs:1)
- [struct DeviceFilter](../src/device/discovery.rs:1)
- Derived from DeviceSelection; compiled regexes and size thresholds for efficient filtering.
- [trait DeviceProvider](src/device/discovery.rs:1)
- [trait DeviceProvider](../src/device/discovery.rs:1)
- Abstraction for listing /dev and probing properties, enabling test doubles.
- [fn discover(filter: &DeviceFilter) -> Result<Vec<Disk>>](src/device/discovery.rs:1)
- [fn discover(filter: &DeviceFilter) -> Result<Vec<Disk>>](../src/device/discovery.rs:1)
- Returns eligible disks or a well-defined error if none are found.
Partitioning
- [enum PartRole](src/partition/plan.rs:1)
- [enum PartRole](../src/partition/plan.rs:1)
- Roles: BiosBoot, Esp, Data, Cache.
- [struct PartitionSpec](src/partition/plan.rs:1)
- [struct PartitionSpec](../src/partition/plan.rs:1)
- Declarative spec for a single partition: role, optional size_mib, gpt_name (zosboot, zosdata, zoscache), and reserved filesystem label when role is Esp (ZOSBOOT).
- [struct DiskPlan](src/partition/plan.rs:1)
- [struct DiskPlan](../src/partition/plan.rs:1)
- The planned set of PartitionSpec instances for a single Disk in the chosen topology.
- [struct PartitionPlan](src/partition/plan.rs:1)
- [struct PartitionPlan](../src/partition/plan.rs:1)
- Combined plan across all target disks, including alignment rules and safety checks.
- [struct PartitionResult](src/partition/plan.rs:1)
- [struct PartitionResult](../src/partition/plan.rs:1)
- Result of applying a DiskPlan: device path of each created partition, role, partition GUID, and gpt_name.
- [fn plan_partitions(disks: &[Disk], cfg: &Config) -> Result<PartitionPlan>](src/partition/plan.rs:1)
- [fn plan_partitions(disks: &[Disk], cfg: &Config) -> Result<PartitionPlan>](../src/partition/plan.rs:1)
- Produces a GPT-only plan with 1 MiB alignment, bios boot first (1 MiB), ESP 512 MiB, data remainder, and zoscache on SSD for ssd_hdd_bcachefs.
- [fn apply_partitions(plan: &PartitionPlan) -> Result<Vec<PartitionResult>>](src/partition/plan.rs:1)
- [fn apply_partitions(plan: &PartitionPlan) -> Result<Vec<PartitionResult>>](../src/partition/plan.rs:1)
- Executes the plan via sgdisk and related utilities. Aborts if target disks are not empty or if signatures are detected.
Filesystems
- [enum FsKind](src/fs/plan.rs:1)
- [enum FsKind](../src/fs/plan.rs:1)
- Values: Vfat, Btrfs, Bcachefs.
- [struct FsSpec](src/fs/plan.rs:1)
- [struct FsSpec](../src/fs/plan.rs:1)
- Maps PartitionResult to desired filesystem kind and label (ZOSBOOT for ESP; ZOSDATA for all data filesystems including bcachefs).
- [struct FsPlan](src/fs/plan.rs:1)
- [struct FsPlan](../src/fs/plan.rs:1)
- Plan of mkfs operations across all partitions and devices given the topology.
- [struct FsResult](src/fs/plan.rs:1)
- [struct FsResult](../src/fs/plan.rs:1)
- Output of mkfs: device path(s), fs uuid, label, and kind.
- [fn plan_filesystems(disks: &[Disk], parts: &[PartitionResult], cfg: &Config) -> Result<FsPlan>](src/fs/plan.rs:1)
- [fn plan_filesystems(disks: &[Disk], parts: &[PartitionResult], cfg: &Config) -> Result<FsPlan>](../src/fs/plan.rs:1)
- Determines which partitions receive vfat, btrfs, or bcachefs, and aggregates tuning options.
- [fn make_filesystems(plan: &FsPlan) -> Result<Vec<FsResult>>](src/fs/plan.rs:1)
- [fn make_filesystems(plan: &FsPlan, cfg: &Config) -> Result<Vec<FsResult>>](../src/fs/plan.rs:1)
- Invokes mkfs.vfat, mkfs.btrfs, mkfs.bcachefs accordingly via utility wrappers and returns filesystem identities.
Mounting
- [struct MountPlan](src/mount/ops.rs:1)
- Derived from FsResult entries: creates target directories under /var/cache/<UUID> and the mounts required for the current boot.
- [struct MountResult](src/mount/ops.rs:1)
- [struct MountPlan](../src/mount/ops.rs:1)
- Derived from FsResult entries. Plans:
- Root mounts for all data filesystems under `/var/mounts/{UUID}` (runtime only).
- btrfs root options: `rw,noatime,subvolid=5`
- bcachefs root options: `rw,noatime`
- Final subvolume/subdir mounts (from the primary data filesystem) to:
- `/var/cache/system`, `/var/cache/etc`, `/var/cache/modules`, `/var/cache/vm-meta`
- [struct MountResult](../src/mount/ops.rs:1)
- Actual mount operations performed (source, target, fstype, options).
- [fn plan_mounts(fs_results: &[FsResult], cfg: &Config) -> Result<MountPlan>](src/mount/ops.rs:1)
- Translates filesystem identities to mount targets and options.
- [fn apply_mounts(plan: &MountPlan) -> Result<Vec<MountResult>>](src/mount/ops.rs:1)
- Performs mounts using syscalls (nix crate) with minimal dependencies. Ensures directories exist.
- [fn maybe_write_fstab(mounts: &[MountResult], cfg: &Config) -> Result<()>](src/mount/ops.rs:1)
- When enabled, generates /etc/fstab entries in deterministic order. Disabled by default.
- [fn plan_mounts(fs_results: &[FsResult], cfg: &Config) -> Result<MountPlan>](../src/mount/ops.rs:1)
- Translates filesystem identities to mount targets and options, including `subvol=` for btrfs and `X-mount.subdir=` for bcachefs.
- [fn apply_mounts(plan: &MountPlan) -> Result<Vec<MountResult>>](../src/mount/ops.rs:1)
- Performs mounts using syscalls (nix crate). Ensures directories exist and creates subvolumes/subdirs if missing.
- [fn maybe_write_fstab(mounts: &[MountResult], cfg: &Config) -> Result<()>](../src/mount/ops.rs:1)
- When enabled, writes only the four subvolume/subdir mount entries to `/etc/fstab` in deterministic order using `UUID=` sources. Root mounts under `/var/mounts` are excluded.
Reporting
- [const REPORT_VERSION: &str](src/report/state.rs:1)
- [const REPORT_VERSION: &str](../src/report/state.rs:1)
- Version string for the JSON payload schema.
- [struct StateReport](src/report/state.rs:1)
- [struct StateReport](../src/report/state.rs:1)
- Machine-readable state describing discovered disks, created partitions, filesystems, labels, mountpoints, status, and timestamp.
- [fn build_report(disks: &[Disk], parts: &[PartitionResult], fs: &[FsResult], mounts: &[MountResult], status: &str) -> StateReport](src/report/state.rs:1)
- [fn build_report(disks: &[Disk], parts: &[PartitionResult], fs: &[FsResult], mounts: &[MountResult], status: &str) -> StateReport](../src/report/state.rs:1)
- Constructs a StateReport matching REPORT_VERSION.
- [fn write_report(report: &StateReport) -> Result<()>](src/report/state.rs:1)
- [fn write_report(report: &StateReport) -> Result<()>](../src/report/state.rs:1)
- Writes JSON to /run/zosstorage/state.json (configurable).
Idempotency
- [fn detect_existing_state() -> Result<Option<StateReport>>](src/idempotency/mod.rs:1)
- [fn detect_existing_state() -> Result<Option<StateReport>>](../src/idempotency/mod.rs:1)
- Probes for expected GPT names (zosboot, zosdata, zoscache where applicable) and filesystem labels (ZOSBOOT, ZOSDATA). If present and consistent, returns a StateReport; orchestrator exits success without changes.
- [fn is_empty_disk(disk: &Disk) -> Result<bool>](src/idempotency/mod.rs:1)
- [fn is_empty_disk(disk: &Disk) -> Result<bool>](../src/idempotency/mod.rs:1)
- Determines disk emptiness: absence of partitions and known filesystem signatures.
Utilities
- [struct CmdOutput](src/util/mod.rs:1)
- [struct CmdOutput](../src/util/mod.rs:1)
- Captures status, stdout, stderr from external tool invocations.
- [fn which_tool(name: &str) -> Result<Option<String>>](src/util/mod.rs:1)
- [fn which_tool(name: &str) -> Result<Option<String>>](../src/util/mod.rs:1)
- Locates a required system utility in PATH, returning its absolute path if available.
- [fn run_cmd(args: &[&str]) -> Result<()>](src/util/mod.rs:1)
- [fn run_cmd(args: &[&str]) -> Result<()>](../src/util/mod.rs:1)
- Executes a command (args[0] is binary) and returns Ok when exit status is zero; logs stderr on failure.
- [fn run_cmd_capture(args: &[&str]) -> Result<CmdOutput>](src/util/mod.rs:1)
- [fn run_cmd_capture(args: &[&str]) -> Result<CmdOutput>](../src/util/mod.rs:1)
- Executes a command and returns captured output for parsing (e.g., blkid).
- [fn udev_settle(timeout_ms: u64) -> Result<()>](src/util/mod.rs:1)
- [fn udev_settle(timeout_ms: u64) -> Result<()>](../src/util/mod.rs:1)
- Calls udevadm settle with a timeout when available; otherwise no-ops with a warning.
- [fn is_efi_boot() -> bool](../src/util/mod.rs:1)
- Detects UEFI environment by checking `/sys/firmware/efi`; used to suppress BIOS boot partition creation on UEFI systems.
Behavioral notes and contracts
- Safety and idempotency:
@@ -188,10 +198,13 @@ Behavioral notes and contracts
- Data filesystems use label ZOSDATA regardless of backend kind.
- Cache partitions in bcachefs topology use GPT name zoscache.
- Topology-specific behavior:
- single: one data filesystem (btrfs) on the sole disk.
- dual_independent: two separate btrfs filesystems, one per disk.
- btrfs_single: one data filesystem (btrfs) on the sole disk.
- bcachefs_single: one data filesystem (bcachefs) on the sole disk.
- dual_independent: independent btrfs filesystems on each eligible disk (one or more).
- bcachefs2_copy: multi-device bcachefs across two or more data partitions with `--replicas=2` (data and metadata).
- ssd_hdd_bcachefs: bcachefs spanning SSD (cache/promote) and HDD (backing), labeled ZOSDATA.
- btrfs_raid1: only when explicitly requested; otherwise default to independent btrfs.
- UEFI vs BIOS: when running under UEFI (`/sys/firmware/efi` present), the BIOS boot partition is suppressed.
Module dependency overview

View File

@@ -30,116 +30,122 @@ Top level
- [tests/integration_ssd_hdd.rs](tests/integration_ssd_hdd.rs)
Crate sources
- [src/main.rs](src/main.rs)
- [src/lib.rs](src/lib.rs)
- [src/errors.rs](src/errors.rs)
- [src/cli/args.rs](src/cli/args.rs)
- [src/logging/mod.rs](src/logging/mod.rs)
- [src/config/loader.rs](src/config/loader.rs)
- [src/types.rs](src/types.rs)
- [src/device/discovery.rs](src/device/discovery.rs)
- [src/partition/plan.rs](src/partition/plan.rs)
- [src/fs/plan.rs](src/fs/plan.rs)
- [src/mount/ops.rs](src/mount/ops.rs)
- [src/report/state.rs](src/report/state.rs)
- [src/orchestrator/run.rs](src/orchestrator/run.rs)
- [src/idempotency/mod.rs](src/idempotency/mod.rs)
- [src/util/mod.rs](src/util/mod.rs)
- [src/main.rs](../src/main.rs)
- [src/lib.rs](../src/lib.rs)
- [src/errors.rs](../src/errors.rs)
- [src/cli/args.rs](../src/cli/args.rs)
- [src/logging/mod.rs](../src/logging/mod.rs)
- [src/config/loader.rs](../src/config/loader.rs)
- [src/types.rs](../src/types.rs)
- [src/device/discovery.rs](../src/device/discovery.rs)
- [src/partition/plan.rs](../src/partition/plan.rs)
- [src/fs/plan.rs](../src/fs/plan.rs)
- [src/mount/ops.rs](../src/mount/ops.rs)
- [src/report/state.rs](../src/report/state.rs)
- [src/orchestrator/run.rs](../src/orchestrator/run.rs)
- [src/idempotency/mod.rs](../src/idempotency/mod.rs)
- [src/util/mod.rs](../src/util/mod.rs)
Module responsibilities
- [src/main.rs](src/main.rs)
- [src/main.rs](../src/main.rs)
- Entrypoint. Parse CLI, initialize logging, load and merge configuration per precedence, call orchestrator. No stdout spam.
- [src/lib.rs](src/lib.rs)
- [src/lib.rs](../src/lib.rs)
- Crate exports, prelude, version constants, Result alias.
- [src/errors.rs](src/errors.rs)
- [src/errors.rs](../src/errors.rs)
- Common error enum and Result alias via thiserror.
- [src/cli/args.rs](src/cli/args.rs)
- [src/cli/args.rs](../src/cli/args.rs)
- CLI definition mirroring kernel cmdline semantics; provide non-interactive interface. Stub --force returns unimplemented.
- [src/logging/mod.rs](src/logging/mod.rs)
- [src/logging/mod.rs](../src/logging/mod.rs)
- Initialize tracing; levels error, warn, info, debug; default to stderr; optional file target.
- [src/config/loader.rs](src/config/loader.rs) and [src/types.rs](src/types.rs)
- [src/config/loader.rs](../src/config/loader.rs) and [src/types.rs](../src/types.rs)
- YAML schema types, validation, loading, and merging with CLI and kernel cmdline.
- [src/device/discovery.rs](src/device/discovery.rs)
- [src/device/discovery.rs](../src/device/discovery.rs)
- Device discovery under /dev with filters and allowlist; probe emptiness safely.
- [src/partition/plan.rs](src/partition/plan.rs)
- [src/partition/plan.rs](../src/partition/plan.rs)
- GPT-only planning and application; 1 MiB alignment; create bios boot, ESP, data and cache partitions with strict safety checks.
- [src/fs/plan.rs](src/fs/plan.rs)
- [src/fs/plan.rs](../src/fs/plan.rs)
- Filesystem provisioning: vfat for ESP, btrfs for ZOSDATA, bcachefs for SSD+HDD mode; all data filesystems labeled ZOSDATA.
- [src/mount/ops.rs](src/mount/ops.rs)
- Mount per-UUID under /var/cache/<UUID>. Optional fstab writing, disabled by default.
- [src/report/state.rs](src/report/state.rs)
- [src/mount/ops.rs](../src/mount/ops.rs)
- Mount scheme:
- Root-mount all data filesystems under `/var/mounts/{UUID}` (runtime only)
- btrfs root: `rw,noatime,subvolid=5`
- bcachefs root: `rw,noatime`
- Create or ensure subvolumes on the primary data filesystem: `system`, `etc`, `modules`, `vm-meta`
- Mount final subvolume/subdir targets at `/var/cache/{system,etc,modules,vm-meta}`
- Optional fstab writing: only the four final targets, deterministic order, `UUID=` sources; disabled by default
- [src/report/state.rs](../src/report/state.rs)
- Build and write JSON state report with version field.
- [src/orchestrator/run.rs](src/orchestrator/run.rs)
- [src/orchestrator/run.rs](../src/orchestrator/run.rs)
- One-shot flow orchestration with abort-on-any-validation-error policy.
- [src/idempotency/mod.rs](src/idempotency/mod.rs)
- [src/idempotency/mod.rs](../src/idempotency/mod.rs)
- Detect prior provisioning via GPT names and labels; return success-without-changes.
- [src/util/mod.rs](src/util/mod.rs)
- [src/util/mod.rs](../src/util/mod.rs)
- Shell-out, udev settle, and helpers.
Public API surface (signatures; implementation to follow after approval)
Entrypoint and orchestrator
- [fn main()](src/main.rs:1)
- [struct Context](src/orchestrator/run.rs:1)
- [fn run(ctx: &Context) -> Result<()>](src/orchestrator/run.rs:1)
- [fn main()](../src/main.rs:1)
- [struct Context](../src/orchestrator/run.rs:1)
- [fn run(ctx: &Context) -> Result<()>](../src/orchestrator/run.rs:1)
CLI
- [struct Cli](src/cli/args.rs:1)
- [fn from_args() -> Cli](src/cli/args.rs:1)
- [struct Cli](../src/cli/args.rs:1)
- [fn from_args() -> Cli](../src/cli/args.rs:1)
Logging
- [struct LogOptions](src/logging/mod.rs:1)
- [fn init_logging(opts: &LogOptions) -> Result<()>](src/logging/mod.rs:1)
- [struct LogOptions](../src/logging/mod.rs:1)
- [fn init_logging(opts: &LogOptions) -> Result<()>](../src/logging/mod.rs:1)
Config
- [struct Config](src/types.rs:1)
- [enum Topology](src/types.rs:1)
- [struct DeviceSelection](src/types.rs:1)
- [struct FsOptions](src/types.rs:1)
- [struct MountScheme](src/types.rs:1)
- [fn load_and_merge(cli: &Cli) -> Result<Config>](src/config/loader.rs:1)
- [fn validate(cfg: &Config) -> Result<()>](src/config/loader.rs:1)
- [struct Config](../src/types.rs:1)
- [enum Topology](../src/types.rs:1)
- [struct DeviceSelection](../src/types.rs:1)
- [struct FsOptions](../src/types.rs:1)
- [struct MountScheme](../src/types.rs:1)
- [fn load_and_merge(cli: &Cli) -> Result<Config>](../src/config/loader.rs:1)
- [fn validate(cfg: &Config) -> Result<()>](../src/config/loader.rs:1)
Device discovery
- [struct Disk](src/device/discovery.rs:1)
- [struct DeviceFilter](src/device/discovery.rs:1)
- [trait DeviceProvider](src/device/discovery.rs:1)
- [fn discover(filter: &DeviceFilter) -> Result<Vec<Disk>>](src/device/discovery.rs:1)
- [struct Disk](../src/device/discovery.rs:1)
- [struct DeviceFilter](../src/device/discovery.rs:1)
- [trait DeviceProvider](../src/device/discovery.rs:1)
- [fn discover(filter: &DeviceFilter) -> Result<Vec<Disk>>](../src/device/discovery.rs:1)
Partitioning
- [struct PartitionSpec](src/partition/plan.rs:1)
- [struct PartitionPlan](src/partition/plan.rs:1)
- [struct PartitionResult](src/partition/plan.rs:1)
- [fn plan_partitions(disks: &[Disk], cfg: &Config) -> Result<PartitionPlan>](src/partition/plan.rs:1)
- [fn apply_partitions(plan: &PartitionPlan) -> Result<Vec<PartitionResult>>](src/partition/plan.rs:1)
- [struct PartitionSpec](../src/partition/plan.rs:1)
- [struct PartitionPlan](../src/partition/plan.rs:1)
- [struct PartitionResult](../src/partition/plan.rs:1)
- [fn plan_partitions(disks: &[Disk], cfg: &Config) -> Result<PartitionPlan>](../src/partition/plan.rs:1)
- [fn apply_partitions(plan: &PartitionPlan) -> Result<Vec<PartitionResult>>](../src/partition/plan.rs:1)
Filesystems
- [enum FsKind](src/fs/plan.rs:1)
- [struct FsSpec](src/fs/plan.rs:1)
- [struct FsPlan](src/fs/plan.rs:1)
- [struct FsResult](src/fs/plan.rs:1)
- [fn plan_filesystems(disks: &[Disk], parts: &[PartitionResult], cfg: &Config) -> Result<FsPlan>](src/fs/plan.rs:1)
- [fn make_filesystems(plan: &FsPlan) -> Result<Vec<FsResult>>](src/fs/plan.rs:1)
- [enum FsKind](../src/fs/plan.rs:1)
- [struct FsSpec](../src/fs/plan.rs:1)
- [struct FsPlan](../src/fs/plan.rs:1)
- [struct FsResult](../src/fs/plan.rs:1)
- [fn plan_filesystems(disks: &[Disk], parts: &[PartitionResult], cfg: &Config) -> Result<FsPlan>](../src/fs/plan.rs:1)
- [fn make_filesystems(plan: &FsPlan) -> Result<Vec<FsResult>>](../src/fs/plan.rs:1)
Mounting
- [struct MountPlan](src/mount/ops.rs:1)
- [struct MountResult](src/mount/ops.rs:1)
- [fn plan_mounts(fs_results: &[FsResult], cfg: &Config) -> Result<MountPlan>](src/mount/ops.rs:1)
- [fn apply_mounts(plan: &MountPlan) -> Result<Vec<MountResult>>](src/mount/ops.rs:1)
- [fn maybe_write_fstab(mounts: &[MountResult], cfg: &Config) -> Result<()>](src/mount/ops.rs:1)
- [struct MountPlan](../src/mount/ops.rs:1)
- [struct MountResult](../src/mount/ops.rs:1)
- [fn plan_mounts(fs_results: &[FsResult], cfg: &Config) -> Result<MountPlan>](../src/mount/ops.rs:1)
- [fn apply_mounts(plan: &MountPlan) -> Result<Vec<MountResult>>](../src/mount/ops.rs:1)
- [fn maybe_write_fstab(mounts: &[MountResult], cfg: &Config) -> Result<()>](../src/mount/ops.rs:1)
Reporting
- [const REPORT_VERSION: &str](src/report/state.rs:1)
- [struct StateReport](src/report/state.rs:1)
- [fn build_report(...) -> StateReport](src/report/state.rs:1)
- [fn write_report(report: &StateReport) -> Result<()>](src/report/state.rs:1)
- [const REPORT_VERSION: &str](../src/report/state.rs:1)
- [struct StateReport](../src/report/state.rs:1)
- [fn build_report(...) -> StateReport](../src/report/state.rs:1)
- [fn write_report(report: &StateReport) -> Result<()>](../src/report/state.rs:1)
Idempotency
- [fn detect_existing_state() -> Result<Option<StateReport>>](src/idempotency/mod.rs:1)
- [fn is_empty_disk(disk: &Disk) -> Result<bool>](src/idempotency/mod.rs:1)
- [fn detect_existing_state() -> Result<Option<StateReport>>](../src/idempotency/mod.rs:1)
- [fn is_empty_disk(disk: &Disk) -> Result<bool>](../src/idempotency/mod.rs:1)
Errors and Result
- [enum Error](src/errors.rs:1)
- [type Result<T> = std::result::Result<T, Error>](src/errors.rs:1)
- [enum Error](../src/errors.rs:1)
- [type Result<T> = std::result::Result<T, Error>](../src/errors.rs:1)
Execution flow
@@ -190,8 +196,15 @@ Filesystem provisioning defaults
- Filesystem tuning options configurable with sensible defaults and extension points
Mount scheme and fstab policy
- Mount under /var/cache/<UUID> using filesystem UUID to create stable subdirectories
- Optional /etc/fstab generation disabled by default; when enabled, produce deterministic order with documentation
- Runtime root mounts:
- Each data filesystem is root-mounted at `/var/mounts/{UUID}` (runtime only)
- btrfs: `rw,noatime,subvolid=5`; bcachefs: `rw,noatime`
- Final targets (from primary data filesystem only):
- `/var/cache/system`, `/var/cache/etc`, `/var/cache/modules`, `/var/cache/vm-meta`
- btrfs subvolume option: `-o subvol={name},noatime`
- bcachefs subdir option: `-o X-mount.subdir={name},noatime`
- /etc/fstab generation:
- Disabled by default. When enabled, write only the four final targets with `UUID=` sources in deterministic order. Root mounts under `/var/mounts` are excluded.
Idempotency detection
- Consider the system provisioned when expected GPT names and filesystem labels are present and consistent

View File

@@ -8,18 +8,18 @@ Goal
Core Principles
1) Contract-first per module
- API signatures and responsibilities are documented in [docs/API-SKELETONS.md](docs/API-SKELETONS.md) and mirrored by crate modules:
- [src/types.rs](src/types.rs)
- [fn load_and_merge()](src/config/loader.rs:1), [fn validate()](src/config/loader.rs:1)
- [fn from_args()](src/cli/args.rs:1)
- [struct LogOptions](src/logging/mod.rs:1), [fn init_logging()](src/logging/mod.rs:1)
- [fn discover()](src/device/discovery.rs:1)
- [fn plan_partitions()](src/partition/plan.rs:1), [fn apply_partitions()](src/partition/plan.rs:1)
- [fn plan_filesystems()](src/fs/plan.rs:1), [fn make_filesystems()](src/fs/plan.rs:1)
- [fn plan_mounts()](src/mount/ops.rs:1), [fn apply_mounts()](src/mount/ops.rs:1), [fn maybe_write_fstab()](src/mount/ops.rs:1)
- [const REPORT_VERSION](src/report/state.rs:1), [fn build_report()](src/report/state.rs:1), [fn write_report()](src/report/state.rs:1)
- [struct Context](src/orchestrator/run.rs:1), [fn run()](src/orchestrator/run.rs:1)
- [fn detect_existing_state()](src/idempotency/mod.rs:1), [fn is_empty_disk()](src/idempotency/mod.rs:1)
- [struct CmdOutput](src/util/mod.rs:1), [fn which_tool()](src/util/mod.rs:1), [fn run_cmd()](src/util/mod.rs:1), [fn run_cmd_capture()](src/util/mod.rs:1), [fn udev_settle()](src/util/mod.rs:1)
- [src/types.rs](../src/types.rs)
- [fn load_and_merge()](../src/config/loader.rs:1), [fn validate()](../src/config/loader.rs:1)
- [fn from_args()](../src/cli/args.rs:1)
- [struct LogOptions](../src/logging/mod.rs:1), [fn init_logging()](../src/logging/mod.rs:1)
- [fn discover()](../src/device/discovery.rs:1)
- [fn plan_partitions()](../src/partition/plan.rs:1), [fn apply_partitions()](../src/partition/plan.rs:1)
- [fn plan_filesystems()](../src/fs/plan.rs:1), [fn make_filesystems()](../src/fs/plan.rs:1)
- [fn plan_mounts()](../src/mount/ops.rs:1), [fn apply_mounts()](../src/mount/ops.rs:1), [fn maybe_write_fstab()](../src/mount/ops.rs:1)
- [const REPORT_VERSION](../src/report/state.rs:1), [fn build_report()](../src/report/state.rs:1), [fn write_report()](../src/report/state.rs:1)
- [struct Context](../src/orchestrator/run.rs:1), [fn run()](../src/orchestrator/run.rs:1)
- [fn detect_existing_state()](../src/idempotency/mod.rs:1), [fn is_empty_disk()](../src/idempotency/mod.rs:1)
- [struct CmdOutput](../src/util/mod.rs:1), [fn which_tool()](../src/util/mod.rs:1), [fn run_cmd()](../src/util/mod.rs:1), [fn run_cmd_capture()](../src/util/mod.rs:1), [fn udev_settle()](../src/util/mod.rs:1)
2) Grep-able region markers in code
- Every module contains the following optional annotated regions:
@@ -55,22 +55,22 @@ Core Principles
6) Module ownership and boundaries
- Add a “Module Responsibilities” section in each modules header doc comment summarizing scope and non-goals.
- Example references:
- [src/device/discovery.rs](src/device/discovery.rs)
- [src/partition/plan.rs](src/partition/plan.rs)
- [src/fs/plan.rs](src/fs/plan.rs)
- [src/mount/ops.rs](src/mount/ops.rs)
- [src/report/state.rs](src/report/state.rs)
- [src/device/discovery.rs](../src/device/discovery.rs)
- [src/partition/plan.rs](../src/partition/plan.rs)
- [src/fs/plan.rs](../src/fs/plan.rs)
- [src/mount/ops.rs](../src/mount/ops.rs)
- [src/report/state.rs](../src/report/state.rs)
7) Invariants and safety notes
- For code that must uphold safety or idempotency invariants, annotate with:
// SAFETY: explanation
// IDEMPOTENCY: explanation
- Example locations:
- [fn apply_partitions()](src/partition/plan.rs:1) must enforce empty-disks rule when configured.
- [fn make_filesystems()](src/fs/plan.rs:1) must not run if partitioning failed.
- [fn apply_partitions()](../src/partition/plan.rs:1) must enforce empty-disks rule when configured.
- [fn make_filesystems()](../src/fs/plan.rs:1) must not run if partitioning failed.
8) Error mapping consistency
- Centralize conversions to [enum Error](src/errors.rs:1). When calling external tools, wrap failures into Error::Tool with stderr captured.
- Centralize conversions to [enum Error](../src/errors.rs:1). When calling external tools, wrap failures into Error::Tool with stderr captured.
- Annotate mapping areas with:
// ERROR: mapping external failure to Error::Tool
@@ -111,7 +111,7 @@ Checklist for adding a new feature
- Add examples if config or output formats change
- Update [config/zosstorage.example.yaml](config/zosstorage.example.yaml) or add a new example file
- Keep error mapping and logging consistent:
- Ensure any external tool calls map errors to [enum Error](src/errors.rs:1)
- Ensure any external tool calls map errors to [enum Error](../src/errors.rs:1)
- Run cargo build and update any broken references
Optional automation (future)

View File

@@ -43,7 +43,7 @@ device_selection:
allow_removable: false # future option; default false
min_size_gib: 10 # ignore devices smaller than this (default 10)
topology: # desired overall layout; see values below
mode: single # single | dual_independent | ssd_hdd_bcachefs | btrfs_raid1 (optional)
mode: btrfs_single # btrfs_single | bcachefs_single | dual_independent | bcachefs2_copy | ssd_hdd_bcachefs | btrfs_raid1
partitioning:
alignment_mib: 1 # GPT alignment in MiB
require_empty_disks: true # abort if any partition or FS signatures exist
@@ -83,8 +83,8 @@ report:
Topology modes
- btrfs_single: One eligible disk. Create BIOS boot (if enabled), ESP 512 MiB, remainder as data. Create a btrfs filesystem labeled ZOSDATA on the data partition.
- bcachefs_single: One eligible disk. Create BIOS boot (if enabled), ESP 512 MiB, remainder as data. Create a bcachefs filesystem labeled ZOSDATA on the data partition.
- dual_independent: Two eligible disks. On each disk, create BIOS boot (if enabled) + ESP + data. Create an independent btrfs filesystem labeled ZOSDATA on each data partition. No RAID by default.
- bcachefs_2copy: Two eligible disks. Create data partitions on both, then create a single multi-device bcachefs labeled ZOSDATA spanning the data partitions (two-copies semantics to be tuned via mkfs options in a follow-up).
- dual_independent: One or more eligible disks. On each disk, create BIOS boot (if enabled) + ESP + data. Create an independent btrfs filesystem labeled ZOSDATA on each data partition. No RAID by default.
- bcachefs2_copy: Two or more eligible disks (minimum 2). Create data partitions and then a single multi-device bcachefs labeled ZOSDATA spanning those data partitions. The mkfs step uses `--replicas=2` (data and metadata).
- ssd_hdd_bcachefs: One SSD/NVMe and one HDD. Create BIOS boot (if enabled) + ESP on both as required. Create cache (on SSD) and data/backing (on HDD) partitions named zoscache and zosdata respectively. Create a bcachefs labeled ZOSDATA across SSD(HDD) per policy (SSD cache/promote; HDD backing).
- btrfs_raid1: Optional mode if explicitly requested. Create mirrored btrfs across two disks for the data role with raid1 profile. Not enabled by default.
@@ -119,11 +119,15 @@ Filesystem section
- vfat: label ZOSBOOT used for ESP.
Mount section
- base_dir: default /var/cache.
- scheme:
- per_uuid: mount data filesystems at /var/cache/<FS-UUID>
- custom: reserved for future mapping-by-config, not yet implemented.
- fstab.enabled: default false. When true, zosstorage will generate fstab entries in deterministic order.
- Runtime root mounts (all data filesystems):
- Each data filesystem is root-mounted at `/var/mounts/{UUID}`
- btrfs root mount options: `rw,noatime,subvolid=5`
- bcachefs root mount options: `rw,noatime`
- Subvolume mounts (from the primary data filesystem only) to final targets:
- Targets: `/var/cache/system`, `/var/cache/etc`, `/var/cache/modules`, `/var/cache/vm-meta`
- btrfs subvol options: `-o rw,noatime,subvol={name}`
- bcachefs subdir options: `-o rw,noatime,X-mount.subdir={name}`
- fstab.enabled: default false. When true, zosstorage writes only the four subvolume mount entries, in deterministic target order, using `UUID=` sources for the filesystem; root mounts under `/var/mounts` are excluded.
Report section
- path: default /run/zosstorage/state.json.
@@ -135,7 +139,7 @@ Minimal single-disk btrfs
```yaml
version: 1
topology:
mode: single
mode: btrfs_single
```
Dual independent btrfs (two disks)
@@ -186,15 +190,15 @@ Future extensions
- Multiple topology groups on multi-disk systems
Reference modules
- [src/types.rs](src/types.rs)
- [src/config/loader.rs](src/config/loader.rs)
- [src/cli/args.rs](src/cli/args.rs)
- [src/orchestrator/run.rs](src/orchestrator/run.rs)
- [src/partition/plan.rs](src/partition/plan.rs)
- [src/fs/plan.rs](src/fs/plan.rs)
- [src/mount/ops.rs](src/mount/ops.rs)
- [src/report/state.rs](src/report/state.rs)
- [src/idempotency/mod.rs](src/idempotency/mod.rs)
- [src/types.rs](../src/types.rs)
- [src/config/loader.rs](../src/config/loader.rs)
- [src/cli/args.rs](../src/cli/args.rs)
- [src/orchestrator/run.rs](../src/orchestrator/run.rs)
- [src/partition/plan.rs](../src/partition/plan.rs)
- [src/fs/plan.rs](../src/fs/plan.rs)
- [src/mount/ops.rs](../src/mount/ops.rs)
- [src/report/state.rs](../src/report/state.rs)
- [src/idempotency/mod.rs](../src/idempotency/mod.rs)
Change log
- v1: Initial draft of schema and precedence rules

View File

@@ -3,31 +3,31 @@
This document finalizes core specifications required before code skeleton implementation. It complements [docs/ARCHITECTURE.md](docs/ARCHITECTURE.md) and [docs/SCHEMA.md](docs/SCHEMA.md), and references the API declarations listed in [docs/API.md](docs/API.md).
Linked modules and functions
- Logging module: [src/logging/mod.rs](src/logging/mod.rs)
- [fn init_logging(opts: &LogOptions) -> Result<()>](src/logging/mod.rs:1)
- Report module: [src/report/state.rs](src/report/state.rs)
- [const REPORT_VERSION: &str](src/report/state.rs:1)
- [fn build_report(...) -> StateReport](src/report/state.rs:1)
- [fn write_report(report: &StateReport) -> Result<()>](src/report/state.rs:1)
- Device module: [src/device/discovery.rs](src/device/discovery.rs)
- [fn discover(filter: &DeviceFilter) -> Result<Vec<Disk>>](src/device/discovery.rs:1)
- Partitioning module: [src/partition/plan.rs](src/partition/plan.rs)
- [fn plan_partitions(disks: &[Disk], cfg: &Config) -> Result<PartitionPlan>](src/partition/plan.rs:1)
- [fn apply_partitions(plan: &PartitionPlan) -> Result<Vec<PartitionResult>>](src/partition/plan.rs:1)
- Filesystems module: [src/fs/plan.rs](src/fs/plan.rs)
- [fn plan_filesystems(disks: &[Disk], parts: &[PartitionResult], cfg: &Config) -> Result<FsPlan>](src/fs/plan.rs:1)
- [fn make_filesystems(plan: &FsPlan) -> Result<Vec<FsResult>>](src/fs/plan.rs:1)
- Mount module: [src/mount/ops.rs](src/mount/ops.rs)
- [fn plan_mounts(fs_results: &[FsResult], cfg: &Config) -> Result<MountPlan>](src/mount/ops.rs:1)
- [fn apply_mounts(plan: &MountPlan) -> Result<Vec<MountResult>>](src/mount/ops.rs:1)
- [fn maybe_write_fstab(mounts: &[MountResult], cfg: &Config) -> Result<()>](src/mount/ops.rs:1)
- Idempotency module: [src/idempotency/mod.rs](src/idempotency/mod.rs)
- [fn detect_existing_state() -> Result<Option<StateReport>>](src/idempotency/mod.rs:1)
- [fn is_empty_disk(disk: &Disk) -> Result<bool>](src/idempotency/mod.rs:1)
- CLI module: [src/cli/args.rs](src/cli/args.rs)
- [fn from_args() -> Cli](src/cli/args.rs:1)
- Orchestrator: [src/orchestrator/run.rs](src/orchestrator/run.rs)
- [fn run(ctx: &Context) -> Result<()>](src/orchestrator/run.rs:1)
- Logging module: [src/logging/mod.rs](../src/logging/mod.rs)
- [fn init_logging(opts: &LogOptions) -> Result<()>](../src/logging/mod.rs:1)
- Report module: [src/report/state.rs](../src/report/state.rs)
- [const REPORT_VERSION: &str](../src/report/state.rs:1)
- [fn build_report(...) -> StateReport](../src/report/state.rs:1)
- [fn write_report(report: &StateReport) -> Result<()>](../src/report/state.rs:1)
- Device module: [src/device/discovery.rs](../src/device/discovery.rs)
- [fn discover(filter: &DeviceFilter) -> Result<Vec<Disk>>](../src/device/discovery.rs:1)
- Partitioning module: [src/partition/plan.rs](../src/partition/plan.rs)
- [fn plan_partitions(disks: &[Disk], cfg: &Config) -> Result<PartitionPlan>](../src/partition/plan.rs:1)
- [fn apply_partitions(plan: &PartitionPlan) -> Result<Vec<PartitionResult>>](../src/partition/plan.rs:1)
- Filesystems module: [src/fs/plan.rs](../src/fs/plan.rs)
- [fn plan_filesystems(disks: &[Disk], parts: &[PartitionResult], cfg: &Config) -> Result<FsPlan>](../src/fs/plan.rs:1)
- [fn make_filesystems(plan: &FsPlan) -> Result<Vec<FsResult>>](../src/fs/plan.rs:1)
- Mount module: [src/mount/ops.rs](../src/mount/ops.rs)
- [fn plan_mounts(fs_results: &[FsResult], cfg: &Config) -> Result<MountPlan>](../src/mount/ops.rs:1)
- [fn apply_mounts(plan: &MountPlan) -> Result<Vec<MountResult>>](../src/mount/ops.rs:1)
- [fn maybe_write_fstab(mounts: &[MountResult], cfg: &Config) -> Result<()>](../src/mount/ops.rs:1)
- Idempotency module: [src/idempotency/mod.rs](../src/idempotency/mod.rs)
- [fn detect_existing_state() -> Result<Option<StateReport>>](../src/idempotency/mod.rs:1)
- [fn is_empty_disk(disk: &Disk) -> Result<bool>](../src/idempotency/mod.rs:1)
- CLI module: [src/cli/args.rs](../src/cli/args.rs)
- [fn from_args() -> Cli](../src/cli/args.rs:1)
- Orchestrator: [src/orchestrator/run.rs](../src/orchestrator/run.rs)
- [fn run(ctx: &Context) -> Result<()>](../src/orchestrator/run.rs:1)
---
@@ -39,7 +39,7 @@ Goals
Configuration
- Levels: error, warn, info, debug (default info).
- Propagation: single global initialization via [fn init_logging](src/logging/mod.rs:1). Subsequent calls must be no-ops.
- Propagation: single global initialization via [fn init_logging](../src/logging/mod.rs:1). Subsequent calls must be no-ops.
Implementation notes
- Use tracing and tracing-subscriber.
@@ -57,7 +57,7 @@ Location
- Default output: /run/zosstorage/state.json
Versioning
- Include a top-level string field version equal to [REPORT_VERSION](src/report/state.rs:1). Start with v1.
- Include a top-level string field version equal to [REPORT_VERSION](../src/report/state.rs:1). Start with v1.
Schema example
@@ -154,17 +154,17 @@ Default exclude patterns
- ^/dev/fd\\d+$
Selection policy
- Compile include and exclude regex into [DeviceFilter](src/device/discovery.rs).
- Compile include and exclude regex into [DeviceFilter](../src/device/discovery.rs).
- Enumerate device candidates and apply:
- Must match at least one include.
- Must not match any exclude.
- Must be larger than min_size_gib (default 10).
- Probing
- Gather size, rotational flag, model, serial when available.
- Expose via [struct Disk](src/device/discovery.rs:1).
- Expose via [struct Disk](../src/device/discovery.rs:1).
No eligible disks
- Return a specific error variant in [enum Error](src/errors.rs:1).
- Return a specific error variant in [enum Error](../src/errors.rs:1).
---
@@ -181,17 +181,20 @@ Layout defaults
- Cache partitions (only in ssd_hdd_bcachefs): GPT name zoscache on SSD.
Per-topology specifics
- single: All roles on the single disk.
- dual_independent: Each disk gets BIOS boot + ESP + data.
- ssd_hdd_bcachefs: SSD gets BIOS boot + ESP + zoscache, HDD gets BIOS boot + ESP + zosdata.
- btrfs_single: All roles on the single disk; data formatted as btrfs.
- bcachefs_single: All roles on the single disk; data formatted as bcachefs.
- dual_independent: On each eligible disk (one or more), create BIOS boot (if applicable), ESP, and data.
- bcachefs_2copy: Create data partitions on two or more disks; later formatted as one multi-device bcachefs spanning all data partitions.
- ssd_hdd_bcachefs: SSD gets BIOS boot + ESP + zoscache; HDD gets BIOS boot + ESP + zosdata; combined later into one bcachefs.
- btrfs_raid1: Two disks minimum; data partitions mirrored via btrfs RAID1.
Safety checks
- Ensure unique partition UUIDs.
- Verify no pre-existing partitions or signatures. Use blkid or similar via [run_cmd_capture](src/util/mod.rs:1).
- After partition creation, run udev settle via [udev_settle](src/util/mod.rs:1).
- Verify no pre-existing partitions or signatures. Use blkid or similar via [run_cmd_capture](../src/util/mod.rs:1).
- After partition creation, run udev settle via [udev_settle](../src/util/mod.rs:1).
Application
- Utilize sgdisk helpers in [apply_partitions](src/partition/plan.rs:1).
- Utilize sgdisk helpers in [apply_partitions](../src/partition/plan.rs:1).
---
@@ -199,34 +202,38 @@ Application
Kinds
- Vfat for ESP, label ZOSBOOT.
- Btrfs for data on single and dual_independent.
- Bcachefs for ssd_hdd_bcachefs (SSD cache, HDD backing).
- Btrfs for data in btrfs_single, dual_independent, and btrfs_raid1 (with RAID1 profile).
- Bcachefs for data in bcachefs_single, ssd_hdd_bcachefs (SSD cache + HDD backing), and bcachefs_2copy (multi-device).
- All data filesystems use label ZOSDATA.
Defaults
- btrfs: compression zstd:3, raid_profile none unless explicitly set to raid1 in btrfs_raid1 mode.
- bcachefs: cache_mode promote, compression zstd, checksum crc32c.
- btrfs: compression zstd:3, raid_profile none unless explicitly set; for btrfs_raid1 use -m raid1 -d raid1.
- bcachefs: cache_mode promote, compression zstd, checksum crc32c; for bcachefs_2copy use `--replicas=2` (data and metadata).
- vfat: ESP label ZOSBOOT.
Planning and execution
- Decide mapping of [PartitionResult](src/partition/plan.rs:1) to [FsSpec](src/fs/plan.rs:1) in [plan_filesystems](src/fs/plan.rs:1).
- Create filesystems in [make_filesystems](src/fs/plan.rs:1) through wrapped mkfs tools.
- Capture resulting identifiers (fs uuid, label) in [FsResult](src/fs/plan.rs:1).
- Decide mapping of [PartitionResult](../src/partition/plan.rs:1) to [FsSpec](../src/fs/plan.rs:1) in [plan_filesystems](../src/fs/plan.rs:1).
- Create filesystems in [make_filesystems](../src/fs/plan.rs:1) through wrapped mkfs tools.
- Capture resulting identifiers (fs uuid, label) in [FsResult](../src/fs/plan.rs:1).
---
## 6. Mount scheme and fstab policy
Scheme
- per_uuid under /var/cache: directories named as filesystem UUIDs.
Runtime root mounts (all data filesystems)
- Each data filesystem is root-mounted at `/var/mounts/{UUID}` (runtime only).
- btrfs root mount options: `rw,noatime,subvolid=5`
- bcachefs root mount options: `rw,noatime`
Mount options
- btrfs: ssd when non-rotational underlying device, compress from config, defaults otherwise.
- vfat: defaults, utf8.
Final subvolume/subdir mounts (from the primary data filesystem)
- Create or ensure subvolumes named: `system`, `etc`, `modules`, `vm-meta`
- Mount targets: `/var/cache/system`, `/var/cache/etc`, `/var/cache/modules`, `/var/cache/vm-meta`
- btrfs options: `-o rw,noatime,subvol={name}`
- bcachefs options: `-o rw,noatime,X-mount.subdir={name}`
fstab
fstab policy
- Disabled by default.
- When enabled, [maybe_write_fstab](src/mount/ops.rs:1) writes deterministic entries sorted by target path.
- When enabled, [maybe_write_fstab](../src/mount/ops.rs:1) writes only the four final subvolume/subdir entries using `UUID=` sources, in deterministic target order. Root mounts under `/var/mounts` are excluded.
---
@@ -235,20 +242,23 @@ fstab
Signals for already-provisioned system
- Expected GPT names found: zosboot, zosdata, and zoscache when applicable.
- Filesystems with labels ZOSBOOT for ESP and ZOSDATA for all data filesystems.
- When consistent with selected topology, [detect_existing_state](src/idempotency/mod.rs:1) returns a StateReport and orchestrator exits success without changes.
- When consistent with selected topology, [detect_existing_state](../src/idempotency/mod.rs:1) returns a StateReport and orchestrator exits success without changes.
Disk emptiness
- [is_empty_disk](src/idempotency/mod.rs:1) checks for absence of partitions and FS signatures before any modification.
- [is_empty_disk](../src/idempotency/mod.rs:1) checks for absence of partitions and FS signatures before any modification.
---
## 8. CLI flags and help text outline
Flags mirrored by [struct Cli](src/cli/args.rs:1) parsed via [from_args](src/cli/args.rs:1)
Flags mirrored by [struct Cli](../src/cli/args.rs:1) parsed via [from_args](../src/cli/args.rs:1)
- --config PATH
- --log-level LEVEL error | warn | info | debug
- --log-to-file
- --fstab enable fstab generation
- --show print preview JSON to stdout (non-destructive)
- --report PATH write preview JSON to file (non-destructive)
- --apply perform partitioning, filesystem creation, and mounts (DESTRUCTIVE)
- --force present but returns unimplemented error
Kernel cmdline
@@ -257,7 +267,7 @@ Kernel cmdline
Help text sections
- NAME, SYNOPSIS, DESCRIPTION
- CONFIG PRECEDENCE
- TOPOLOGIES: single, dual_independent, ssd_hdd_bcachefs, btrfs_raid1
- TOPOLOGIES: btrfs_single, bcachefs_single, dual_independent, bcachefs_2copy, ssd_hdd_bcachefs, btrfs_raid1
- SAFETY AND IDEMPOTENCY
- REPORTS
- EXIT CODES: 0 success or already_provisioned, non-zero on error
@@ -267,9 +277,10 @@ Help text sections
## 9. Integration testing plan (QEMU KVM)
Scenarios to scaffold in [tests/](tests/)
- Single disk 40 GiB virtio: validates single topology end-to-end smoke.
- Dual NVMe 40 GiB each: validates dual_independent topology.
- SSD NVMe + HDD virtio: validates ssd_hdd_bcachefs topology.
- Single disk 40 GiB virtio: validates btrfs_single topology end-to-end smoke.
- Dual NVMe 40 GiB each: validates dual_independent topology (independent btrfs per disk).
- SSD NVMe + HDD virtio: validates ssd_hdd_bcachefs topology (bcachefs with SSD cache/promote, HDD backing).
- Three disks: validates bcachefs_2copy across data partitions using `--replicas=2`.
- Negative: no eligible disks, or non-empty disk should abort.
Test strategy
@@ -281,7 +292,7 @@ Test strategy
Artifacts to validate
- Presence of expected partition GPT names.
- Filesystems created with correct labels.
- Mountpoints under /var/cache/<UUID> when running in a VM.
- Runtime root mounts under `/var/mounts/{UUID}` and final subvolume targets at `/var/cache/{system,etc,modules,vm-meta}`.
- JSON report validates against v1 schema.
---

View File

@@ -47,14 +47,14 @@ Consequences
Implementation Notes
- Region markers have been added to key modules:
- [src/config/loader.rs](src/config/loader.rs)
- [src/orchestrator/run.rs](src/orchestrator/run.rs)
- [src/cli/args.rs](src/cli/args.rs)
- [src/device/discovery.rs](src/device/discovery.rs)
- [src/partition/plan.rs](src/partition/plan.rs)
- [src/fs/plan.rs](src/fs/plan.rs)
- [src/mount/ops.rs](src/mount/ops.rs)
- [src/report/state.rs](src/report/state.rs)
- [src/config/loader.rs](../src/config/loader.rs)
- [src/orchestrator/run.rs](../src/orchestrator/run.rs)
- [src/cli/args.rs](../src/cli/args.rs)
- [src/device/discovery.rs](../src/device/discovery.rs)
- [src/partition/plan.rs](../src/partition/plan.rs)
- [src/fs/plan.rs](../src/fs/plan.rs)
- [src/mount/ops.rs](../src/mount/ops.rs)
- [src/report/state.rs](../src/report/state.rs)
- Remaining modules will follow the same pattern as needed (e.g., util, idempotency, main/lib if helpful).
Related Documents