|
root / README.md
README.md markdown 119 lines 3.8 KB

repoman

Per-project Incus containers + opinionated NFS/ZFS backup. v0.1.

Build

reefc build

Produces ./build/repoman.

Test

for t in tests/test_*.reef; do
    echo "== $t =="
    reefc run "$t" || exit 1
done

Install

System-wide via Makefile (uses reefc build under the hood):

make
sudo make install        # installs to /usr/local/bin/repoman

Quickstart

# First run creates ~/.config/repoman/repoman.toml with sane defaults.
repoman --help
repoman new isurus --repo isurus-project
repoman sync --dry-run
repoman list

Subcommands

Subcommand Description
new <name> [--repo <dirname>] [--image <image>] Launch an Incus container and bind a local repo into it.
sync [name] [--no-delete] [--dry-run] Mirror local repos to NFS backup via rsync.
list Print a table of all registered projects (read-only).
status [name] Show project state from registry + live incus query.
remove <name> --yes [--keep-incus] Delete the incus container and registry entry. --yes required.
shell <name> [--cwd <path>] Open a bash login shell inside the project's container (replaces repoman).
--help / -h / help Show usage and subcommand list.
--version / -V Print version string.

Smoke test (requires Incus + NFS)

# In an existing repo dir under ~/repos:
repoman new test-foo
repoman sync test-foo --dry-run
incus delete --project repoman test-foo

Output and logging

By default repoman runs quietly — only its own ==> ... markers and any errors reach the terminal. Subprocess probes (e.g. incus project show, stat /nfs/repos, findmnt) have their stdout/stderr suppressed to /dev/null. The actual user-facing operations (launch, rsync) pass their stdio through.

To see the suppressed probe output for troubleshooting, run with --verbose (or -v). Pass --quiet (or -q) to force quiet mode if your config defaults to verbose.

Every invocation also writes a log file at <logdir>/<project>-<verb>.log, truncated each run. So if a repoman new veemarker fails, the log lives at ~/.local/state/repoman/veemarker-new.log until the next run with the same name+verb. Whole-tree sync uses all-sync.log.

Configuration

Central registry: ~/.config/repoman/repoman.toml (managed; do not edit while repoman is running).

Tool-level settings under [repoman]:

Field Values Default Effect
output "quiet" | "verbose" "quiet" Default output mode (CLI flags override).

Defaults under [defaults]:

Field Default Effect
repos_root ~/repos Local NVMe canonical location.
backup_root /nfs/repos NFS-mounted backup destination.
logdir ~/.local/state/repoman Per-invocation log files written here.
incus_project repoman Incus project containers are created in.
default_image images:ubuntu/26.04/cloud Image used when no --image flag and no override.
profiles ["default", "claude-share"] Profiles applied when creating containers.

Per-project overrides: ~/.config/repoman/repos.d/<container-name>.toml (user-authored). Example:

[container]
image    = "images:debian/12/cloud"
profiles = ["default", "claude-share", "node-dev"]

[[mount]]
source = "~/.npm"
path   = "/home/ctusa/.npm"

[env]
NODE_ENV = "development"

For the agent-friendly setup repoman is built around, create a shared profile that exposes the user's Claude state:

# (one-time)
incus profile create claude-share
incus profile edit claude-share  # add your bind-mounts for ~/.claude, etc.

repoman uses profiles default and claude-share by default; override per-project in repos.d/<name>.toml.