diff options
Diffstat (limited to 'docs/PLAN.md')
| -rw-r--r-- | docs/PLAN.md | 78 |
1 files changed, 78 insertions, 0 deletions
diff --git a/docs/PLAN.md b/docs/PLAN.md new file mode 100644 index 0000000..81a4b81 --- /dev/null +++ b/docs/PLAN.md @@ -0,0 +1,78 @@ +# jprov Plan + +Date: 2026-02-14 + +## Goal +Build `jprov`, a FreeBSD jail provisioning tool that treats jails as nearly stateless, recreating them from a template, copying a filesystem overlay, and running a provisioning command inside the jail. If provisioning fails, the run fails. If the jail already exists, it is deleted and recreated. `-y` skips confirmation. + +## Current Understanding +- Primary command: `jprov [jailname]`. +- Reads a main config from `/etc/jprov.conf` (or `/usr/local/etc/jprov.conf`) which defines where per-jail configs live. +- Per-jail config is TOML and includes at least: template, provisioning command, and nullfs mounts. +- Creates a new thin jail as a ZFS clone of the template dataset. +- Deep-copies a tree into the jail filesystem (e.g. `jailname/usr/local/bin/foo` -> `/usr/local/bin/foo`). +- Runs a provisioning command inside the jail; provisioning success depends on this command's exit status. +- If jail already exists, delete it and recreate it. `-y` skips all confirmations. +- Backend is plain `jail(8)` + ZFS (potentially via `jail.conf.d` emission). +- Volume mounts are `nullfs` from host ZFS datasets mounted on the host. +- Example directory layout under a configurable base (e.g., `/usr/local/jails/`): + - `templates/RELEASE-15.0-p3/` + - `defs/<jailname>/jprov.conf` + - `defs/<jailname>/overlay/usr/...` +- `jprov` is intended to be run after system/template upgrades, not on every jail restart. +- Implementation language: Python 3. +- Destructive operations should be delayed as late as possible; validate configs and paths first to avoid tearing down a working jail on config errors. +- N+1 provisioning is not used; jprov stops and destroys the existing jail before creating and provisioning the new jail. +- Provide clear, informative progress output so the user can see each step at a glance. +- Capture all script output to log files in a configurable log dir (default `/var/log/jprov/`); on fatal error, print: "script logs written to <logpath>.log". + +## Open Questions (Need Confirmation) +None. + +## Milestones +1. Confirm requirements and config schema. +2. Define operational workflow and backend commands. +3. Implement config parsing and validation. +4. Implement jail lifecycle (delete, create, overlay copy). +5. Implement provisioning execution and failure handling. +6. Add CLI flags, confirmations, and logging. +7. Add tests and documentation. + +## Architecture (Proposed) +Files and purposes: +- `bin/jprov` (entrypoint): CLI argument parsing, `-y` handling, top-level orchestration. +- `jprov/main.py`: main flow controller; calls config loading, validation, and provisioning steps. +- `jprov/config.py`: parse and validate main config and per-jail TOML; resolve paths; normalize defaults. +- `jprov/jailconf.py`: generate `jail.conf.d/<name>.conf` from config, including `extra_jail_conf`. +- `jprov/zfs.py`: ZFS operations (clone, destroy, dataset existence checks). +- `jprov/mounts.py`: nullfs mount/unmount operations and validation of host paths. +- `jprov/overlay.py`: deep copy overlay into jail root. +- `jprov/provision.py`: run provisioning command via `jexec <name> <cmd>` with env vars. +- `jprov/runner.py`: subprocess wrapper (stdout logging, error handling, and uniform exit code behavior). +- `docs/PLAN.md`: evolving plan and decisions. +- `docs/CONFIG.md`: user-facing config reference (main and per-jail TOML). +- `docs/USAGE.md`: CLI usage and examples. + +Notes: +- Keep module boundaries small and testable; all shell commands go through `runner.py`. +- Provide a dry-run mode later if desired (not in v1 unless requested). + +## Next Actions +1. Finalize main config schema and defaults. +2. Draft per-jail TOML schema and document in `docs/CONFIG.md`. +3. Scaffold Python package and CLI entrypoint. + +## Main Config (Proposed) +```toml +base_dir = "/usr/local/jails" + +[datasets] +templates_prefix = "zroot/jails/templates/" +containers_prefix = "zroot/jails/containers/" + +jail_conf_dir = "/etc/jail.conf.d" +log_dir = "/var/log/jprov" +``` + +Notes: +- `assume_yes` is CLI-only via `-y`. |
