Snapshot manager for the installed package set handled by prt-get on CRUX.
prt-snapshot stores the list returned by prt-get listinst and can later
inspect a stored snapshot, compare it with the current package set, or restore
package membership to that snapshot.
A typical use case is to capture a known minimal CRUX installation, install a port and its dependencies for testing, and then return the installed package set to the captured baseline.
- bash
- prt-get
- standard CRUX userland tools used by the script (
diff,find,grep,mktemp,stat, and related core utilities)
Create the snapshot store before using operational commands:
sudo mkdir -p /var/lib/pkg/snapshots
sudo chown root:root /var/lib/pkg/snapshots
sudo chmod 755 /var/lib/pkg/snapshotsThe directory must:
- be owned by root;
- not be a symbolic link;
- not be writable by group or others.
Operational commands require root. help and version do not require an
initialized snapshot store.
prt-snapshot <command> [options]
Commands:
clean Remove all stored snapshots
store msg Take a snapshot of installed ports
restore num [--dry-run [--json]|--yes]
Restore membership or preview the restore plan
diff num [--json] Show differences or emit a machine-readable restore plan
show num [--packages|--json] Show snapshot details, package names, or JSON
list [--json] List stored snapshots or emit JSON
help Show usage information
version Show version information
Examples:
sudo prt-snapshot store "clean base"
sudo prt-snapshot list
sudo prt-snapshot list --json
sudo prt-snapshot show 1
sudo prt-snapshot show 1 --packages
sudo prt-snapshot show 1 --json
sudo prt-snapshot diff 1
sudo prt-snapshot diff 1 --json
sudo prt-snapshot restore 1 --dry-run
sudo prt-snapshot restore 1 --dry-run --json
sudo prt-snapshot restore 1For non-interactive restore:
sudo prt-snapshot restore 1 --yesA snapshot represents the set of installed package names reported by
prt-get listinst.
It is not a full system snapshot. In particular, it does not capture:
- package versions;
- files outside package ownership;
- configuration changes;
- users or groups created by package hooks;
- caches, databases, or other runtime state;
- the historical state of the ports tree.
Restoring a snapshot therefore means restoring package membership as closely as possible with the currently available ports tree.
show <num> displays:
- snapshot ID;
- creation timestamp;
- stored message;
- package count;
- package names.
For scripting, show <num> --packages emits only validated package names, one
per line.
show <num> --json emits a machine-readable schema 1 object containing:
schema;id;created;message;packages.
On successful JSON output, stdout contains only the JSON document and stderr is empty. On failure, no partial JSON is written to stdout and diagnostics are written to stderr.
Snapshot data is validated before output is produced.
list --json emits a schema 1 object with a snapshots array. Each entry
contains id, created, and message, in numeric snapshot order. An empty
snapshot store is represented by an empty array.
As with show --json, successful machine-readable output contains only JSON on
stdout and diagnostics are reserved for stderr.
diff <num> --json emits a schema 1 restore-plan object with remove and
install arrays. The install array uses the same dependency-aware ordering
logic as restore and dependency discovery never expands snapshot membership.
An identical current package set is a successful result with both arrays empty.
restore <num> --dry-run --json emits the same schema 1 restore-plan object as
diff <num> --json. The payload is intentionally identical, including
dependency-aware install ordering. JSON output is available only with
--dry-run; applied restores remain human-oriented.
All JSON documents currently use schema 1.
Within schema 1:
- existing fields keep their meaning;
- array order is part of the contract where it is semantically relevant,
especially dependency-aware
installorder; - compatible new fields may be added;
- consumers should ignore unknown fields;
- incompatible changes require a new schema number.
During restore, packages present in the current system but absent from the
snapshot are removed. Packages present in the snapshot but absent from the
current system are installed with prt-get install.
Before the first package operation, prt-snapshot:
- calculates the complete restore plan;
- validates every package name and operation;
- resolves an installation order for missing packages with
prt-get quickdep; - filters that dependency information strictly to packages already present in the target snapshot.
prt-get depinst is intentionally not used. Dependency discovery is used only
for ordering: it never expands snapshot membership.
If the current ports tree reports a dependency that was not part of the target snapshot, that package is not added to the restore.
restore <num> --dry-run prints the exact removal and dependency-aware
installation plan without changing package state or pruning snapshot history.
Interactive restore <num> prints the same plan and asks for confirmation
before applying it.
Non-interactive restore requires explicit opt-in with --yes or --dry-run.
A cancelled restore does not modify package state or snapshot history.
Restore ordering is resolved before any destructive package operation begins.
If plan validation or prt-get quickdep fails, restore aborts before package
state is changed.
If a package removal or installation later fails, restore aborts immediately and does not prune snapshots newer than the requested target.
Newer snapshot history is removed only after a completely successful applied restore.
The safety baseline introduced in 0.4 remains in place:
- existing snapshots are never overwritten by index reuse;
- snapshot IDs and package names are validated;
- snapshots are published only after successful capture;
- temporary files are kept outside the numbered snapshot namespace;
- interrupted or failed operations clean temporary state when possible;
- a failed restore does not delete newer snapshots;
cleanonly removes numeric snapshot files managed byprt-snapshot;- concurrent operations are serialized with a root-owned lock;
- the snapshot directory owner and permissions are validated before use;
- snapshots are created with restrictive permissions.
Version 0.5 adds:
- complete restore-plan validation before mutation;
--dry-runrestore preview;- explicit interactive confirmation and
--yesfor automation; - dependency-aware installation order with
prt-get quickdep; - strict filtering so dependency resolution cannot expand snapshot membership;
showandshow --packages;- correct non-zero exit status for invalid CLI usage;
helpandversionindependent of snapshot-store initialization.
Version 0.5.1 fixes:
- restrictive caller or process umasks leaking into
prt-get/pkgutils; - package-database files recreated with permissions that could block normal unprivileged tools;
- snapshot privacy using explicit file permissions rather than a global umask.
Version 0.6 adds:
- versioned schema 1 JSON output for automation;
show <num> --json;list --json;diff <num> --json;restore <num> --dry-run --json;- dependency-aware machine-readable restore plans;
- byte-for-byte parity between JSON diff and JSON restore preview;
- a stdout/stderr contract that prevents partial JSON on failures;
- documented schema compatibility rules.
The regression suite currently contains 41 tests and can be run with:
sudo ./tests/run.shCI also runs Bash syntax checks, ShellCheck, and the regression suite.
Please contact:
- Victor Martinez:
pitillo at crux-arm dot nu - Jose V Beneyto:
sepen at crux dot nu