Restore

Restore a backup bundle from storage into a live data directory. b.restore.create binds a storage backend, the backup passphrase and the data directory; the engine it returns lists and inspects bundles, restores one, and reverses a restore through b.restoreRollback.

A restore runs in four steps. The engine pulls the bundle out of storage, decrypts it with b.restoreBundle.extract (checking each file's size and SHA3-512 checksum and the manifest signature), renames the live data directory into the rollback root, and renames the decrypted directory onto the data directory. Both renames stay on one filesystem: the pulled and decrypted copies are written under stagingRoot, which defaults to the parent directory of the rollback root, and run() refuses a layout the renames cannot complete before it decrypts anything.

The framework keeps its files open, so a restore runs as stop framework -> run() -> start framework, the same shape as a database restore. Every outcome lands on b.audit as restore.success or restore.failure unless audit: false.

b.restore.create(opts) #

stable0.1.89hipaapci-dssgdprsoc2dora
{
  dataDir:             string,           // required; the live data directory
  storage:             StorageBackend,   // required; b.backup.diskStorage() or custom
  passphrase:          Buffer | string,  // required; the backup passphrase
  rollbackRoot:        string,           // default: .rollbacks
  stagingRoot:         string,           // default: the parent directory of rollbackRoot
  audit:               boolean,          // default true
  maxPulledBytes:      number,           // default 4 GiB
  maxPulledFiles:      number,           // default 100000
  requireSignature:    boolean,          // refuse a bundle whose manifest is unsigned
  expectedFingerprint: string,           // trust only the key with this fingerprint
  verifySignature:     boolean,          // default true
  mountInfoPath:       string,           // default null — read mount points from this file instead of
                                         // the platform's own, for the cross-device and
                                         // mount-point checks above
}

Build a restore engine bound to a data directory, a storage backend and the backup passphrase. The returned object carries list, inspect, run, rollback, listRollbacks, purgeRollbacks, the wired storage and the resolved rollbackRoot. Building it throws restore/no-datadir when dataDir is absent or empty, and restore/no-passphrase when passphrase is neither a Buffer nor a string.

run({ bundleId }) pulls that bundle, decrypts it, renames the live data directory into the rollback root and renames the decrypted copy onto the data directory. It resolves with { bundleId, fileCount, totalBytes, rollbackPath, vaultKeyJson, durationMs }. A signed manifest is trusted only under expectedFingerprint or an active or rotated b.auditSign key, so a process that does not hold the signing key passes expectedFingerprint. requireSignature: true refuses a bundle with no signature, and combining it with verifySignature: false throws restore/bad-opts.

Both renames must stay on one filesystem. Before pulling anything, run() throws restore/datadir-is-mount-point for a data directory that is a mount point, restore/cross-device for a stagingRoot or rollbackRoot on another filesystem, restore/bad-staging-root or restore/bad-rollback-root for one inside the data directory by either its written path or its canonical one, and restore/datadir-is-symlink for a data directory that is a symbolic link. A failure after decryption removes the decrypted staging directory and rejects with restore/swap-failed; the bundle in storage can be restored again. Every restore-bundle/ failure is reported as restore/.

A storage missing any of readBundle, listBundles and hasBundle throws restore/bad-storage.

var fs   = require("node:fs");
var path = require("node:path");
var os   = require("node:os");

var root = fs.mkdtempSync(path.join(os.tmpdir(), "restore-store-"));
var engine = b.restore.create({
  dataDir:    path.join(root, "data"),
  storage:    b.backup.diskStorage({ root: root }),
  passphrase: Buffer.from("operator backup passphrase"),
});

typeof engine.run;        // → "function"
typeof engine.rollback;   // → "function"

Last updated 2026-10-12T14:21:56.879Z by seeder.