Commands
migrate-state
Move legacy __loose__ state into per-manifest project directories.
A manifest that declares no project: is a loose manifest. Loose manifests
used to share a single project called __loose__ — one directory, one slot. So
starting a second loose manifest looked to the supervisor like an edit of the
first: it reconciled the difference by stopping the service already running
there. Every loose manifest now owns a project derived from its own path, and
they coexist.
migrate-state places the state the old shared layout left behind.
$ sysg migrate-state --dry-run
Why it is a command and not automatic
The migration moves state and logs you cannot reconstruct, and the supervisor
loads state before it takes its lock — so a migration running at boot could be
observed half-finished by a second sysg invocation. Running it explicitly means
it happens once, with no supervisor alive, with the report in front of you.
It refuses with SG0602 while a supervisor
is running. --dry-run is always allowed.
What it will not do
Legacy state records a service name. The new layout keys by project. When several manifests declare the same service name, nothing in the old state says which one owned it:
Cannot be attributed (archived, not assigned):
[service] gamecast-tunnel: declared by 3 manifests: ...
[cron] de98291cbf657443: no manifest declares it
Those artifacts are archived and reported rather than assigned to a guess. The archive is a faithful, checksum-verified copy, so nothing is lost — place them by hand if you want them, or leave them.
Options
| Short | Long | Description |
|---|---|---|
- | --units <DIR> | Directory of manifests to attribute state to (defaults to the state root's units/) |
- | --dry-run | Report what would move without changing anything |
-v | --verbose | Print operation progress |
- | --sys | Opt into privileged system mode. Requires running as root |
- | --plain | Disable terminal decoration for automation |
- | --log-level | Set logging verbosity for this invocation |
Usage
Review first — this is the recommended path, since the report tells you exactly what can and cannot be attributed:
$ sysg migrate-state --dry-run
Then stop the supervisor and run it:
$ sysg stop --supervisor
$ sysg migrate-state
Safety
Nothing is deleted. Every source is copied into a timestamped archive beside the
state root and checksum-verified before the migration proceeds, and the legacy
projects/__loose__/ tree is left in place. A run records its progress in a
journal, so an interrupted migration resumes where it stopped rather than leaving
a layout that is part old and part new
(SG0604).
The journal and archive live outside the state root, so
purge cannot destroy the record of a migration
still in progress.