Skip to main content
Version: Development

Preserve and restore local node state

Keep a node's complete durable state and protected configuration together. This guide covers the node-owned local Linux container layout from Run a node in a Linux container. It uses UID/GID 10001 and a local ext4 or XFS mount. The maintained drill records the actual filesystem; qualifying one observed filesystem does not qualify every mount of its type.

Azure Files, NFS and SMB remain unqualified. There are no Azure resources in this delivery, and local results do not establish remote storage durability. Use a host-controlled Linux filesystem for the supported deployment alternative.

What must survive together​

RootContents and recovery rule
configNode identity, operator credentials, current admission policy/revocations, protected native key when used. Restore the reviewed set; do not generate replacement keys during recovery.
dataPublications, shared immutable blobs, lifecycle/evidence history, trigger/deployment state, operation receipts, audit and supply-chain clock floor. Restore the whole root.
cacheCached artifacts and authenticated native receipts. Some caches can be rebuilt under their documented admission rules; this conservative snapshot preserves all of them.

The filesystem must support same-filesystem hard links, stable open-file readers, atomic replacement, successful file and parent-directory synchronization, reliable exclusive locks between processes, ownership/mode checks and no-follow access. It must not bypass those checks with shared write permissions or unsupported extended ACLs. A failed durable operation can have an unknown result: retain its operation ID and resolve its receipt/current state after recovery. Never remove an intent, lock, format marker or catalog row to force startup.

Stop and take a complete snapshot​

The container entrypoint holds .container-owner.lock in the data root for its process lifetime, including across native exec. The snapshot helper acquires the same nonblocking lock. It rejects a running owner before creating a destination. The lock file stays in place; stopping the owner releases the lock. Native catalog locks continue to apply as well.

Use an administrative Linux session with UID/GID 10001. Make the source available at Installation/config, Installation/data and Installation/cache, with the same mounts as the container. Configuration in this helper's supported profile is node-owned and private, rather than root-owned. Keep the node and all other writers stopped throughout the operation, including policy editors:

docker stop --time 10 lsf-node
python3 tools/container_runtime/storage.py snapshot --source "$Installation" --output "$Backup"

Backup must be a new directory under a private directory you own. It must be outside the source. The helper rejects symlinks, special files, external hard links, foreign ownership, writable-by-others paths and extended ACLs. It preserves hard-link relationships and modes, checks content before and after copying, and syncs completed files and directories. Its bounds are 16,384 entries, 1 GiB of logical file bytes and two minutes. A larger installation needs a separately reviewed stopped filesystem snapshot procedure; never drop files to fit.

Only a complete verified copy receives SNAPSHOT-COMPLETE.json. A failed partial directory remains for inspection and is not a restorable backup. Keep snapshots private: they contain credentials and trust material. Store the authenticated runtime image identity separately with your recovery records.

Restore into a new installation​

Keep the original stopped. Restore to a fresh directory; this tool never merges rows into an existing installation or overwrites one:

python3 tools/container_runtime/storage.py restore --source "$Backup" --output "$RestoredInstallation"

It verifies the snapshot's complete manifest, bytes, permissions and hard links. Mount the restored config, data and cache roots at the original container locations, using the same approved runtime image. Wait for the retained supply-chain clock lease, run the image's check, then start one owner and verify authenticated readiness. Recheck current route targets, exact content and original operation receipts before directing traffic to it.

An eligible earlier publication is selected through new explicit route operations and current admission checks. Replaying an old receipt is a recovery query, not permission to restore a revoked publication. Follow the route-set workflow for coordinated GET/HEAD reconciliation. A runtime downgrade is separate and must obey the release compatibility policy.

What the maintained test establishes​

The real local-volume drill performs hard-link, held-reader/atomic-replacement, file/directory sync, no-follow and separate-process lock checks as UID 10001. A separate writer exits after syncing a pending file but before replacement; the current file remains intact. The application drill publishes two signed sites, restarts, updates only one, restarts again, and verifies the unchanged site and exact operation receipt. It rejects a live backup, copies and restores the stopped coupled roots, reopens their actual native catalogs, and selects an eligible earlier publication while preserving the other site.

This covers orderly restart, interrupted local file replacement, native reopen, stopped backup/restore and publication rollback. It does not inject a host power failure or establish a storage service's physical write guarantees. Source-level catalog interruption tests complement this drill; they do not convert it into a managed-storage qualification. See the storage decision.