@camstack/system 1.2.424 → 1.2.425
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/builtins/addon-pages-aggregator/addon-pages-aggregator.addon.js +1 -1
- package/dist/builtins/addon-pages-aggregator/addon-pages-aggregator.addon.mjs +1 -1
- package/dist/builtins/addon-widgets-aggregator/addon-widgets-aggregator.addon.js +1 -1
- package/dist/builtins/addon-widgets-aggregator/addon-widgets-aggregator.addon.mjs +1 -1
- package/dist/builtins/alerts/alerts.addon.js +1 -1
- package/dist/builtins/alerts/alerts.addon.mjs +1 -1
- package/dist/builtins/autotrack/index.js +1 -1
- package/dist/builtins/autotrack/index.mjs +1 -1
- package/dist/builtins/backup-orchestrator/backup-databases.d.ts +51 -0
- package/dist/builtins/backup-orchestrator/backup-orchestrator.addon.d.ts +13 -0
- package/dist/builtins/backup-orchestrator/backup-orchestrator.addon.js +248 -17
- package/dist/builtins/backup-orchestrator/backup-orchestrator.addon.mjs +248 -17
- package/dist/builtins/backup-orchestrator/manifest-store.d.ts +23 -3
- package/dist/builtins/backup-orchestrator/run-queue.d.ts +3 -0
- package/dist/builtins/backup-orchestrator/schedule-store.d.ts +7 -1
- package/dist/builtins/backup-orchestrator/seed-marker-store.d.ts +34 -0
- package/dist/builtins/calendars/calendars.addon.js +1 -1
- package/dist/builtins/calendars/calendars.addon.mjs +1 -1
- package/dist/builtins/camera-grid/index.js +1 -1
- package/dist/builtins/camera-grid/index.mjs +1 -1
- package/dist/builtins/composer/composer.addon.js +2 -2
- package/dist/builtins/composer/composer.addon.mjs +2 -2
- package/dist/builtins/console-logging/index.js +1 -1
- package/dist/builtins/console-logging/index.mjs +1 -1
- package/dist/builtins/core-blocks/core-blocks.addon.js +2 -2
- package/dist/builtins/core-blocks/core-blocks.addon.mjs +2 -2
- package/dist/builtins/device-manager/device-manager.addon.js +2 -2
- package/dist/builtins/device-manager/device-manager.addon.mjs +2 -2
- package/dist/builtins/hub-forwarder/index.js +1 -1
- package/dist/builtins/hub-forwarder/index.mjs +1 -1
- package/dist/builtins/keychain/index.js +3 -3
- package/dist/builtins/keychain/index.mjs +3 -3
- package/dist/builtins/liveness-monitor/liveness-monitor.addon.js +1 -1
- package/dist/builtins/liveness-monitor/liveness-monitor.addon.mjs +1 -1
- package/dist/builtins/local-auth/local-auth.addon.js +2 -2
- package/dist/builtins/local-auth/local-auth.addon.mjs +2 -2
- package/dist/builtins/local-network/local-network.addon.js +1 -1
- package/dist/builtins/local-network/local-network.addon.mjs +1 -1
- package/dist/builtins/loki-logging/index.js +1 -1
- package/dist/builtins/loki-logging/index.mjs +1 -1
- package/dist/builtins/native-metrics/native-metrics.addon.js +1 -1
- package/dist/builtins/native-metrics/native-metrics.addon.mjs +1 -1
- package/dist/builtins/platform-probe/index.js +1 -1
- package/dist/builtins/platform-probe/index.mjs +1 -1
- package/dist/builtins/remote-access-orchestrator/remote-access-orchestrator.addon.js +1 -1
- package/dist/builtins/remote-access-orchestrator/remote-access-orchestrator.addon.mjs +1 -1
- package/dist/builtins/snapshot/index.js +1 -1
- package/dist/builtins/snapshot/index.mjs +1 -1
- package/dist/builtins/sqlite-storage/database-snapshot-provider.d.ts +18 -0
- package/dist/builtins/sqlite-storage/filesystem-storage.addon.js +1 -1
- package/dist/builtins/sqlite-storage/filesystem-storage.addon.mjs +1 -1
- package/dist/builtins/sqlite-storage/index.js +1 -1
- package/dist/builtins/sqlite-storage/index.mjs +1 -1
- package/dist/builtins/sqlite-storage/sqlite-settings.addon.js +49 -7
- package/dist/builtins/sqlite-storage/sqlite-settings.addon.mjs +49 -7
- package/dist/builtins/storage-orchestrator/storage-orchestrator.addon.js +1 -1
- package/dist/builtins/storage-orchestrator/storage-orchestrator.addon.mjs +1 -1
- package/dist/builtins/system-backup/system-backup.service.d.ts +48 -15
- package/dist/builtins/system-config/system-config.addon.js +2 -2
- package/dist/builtins/system-config/system-config.addon.mjs +2 -2
- package/dist/builtins/winston-logging/index.js +1 -1
- package/dist/builtins/winston-logging/index.mjs +1 -1
- package/dist/{composition-sources-BWNs-ZeH.js → composition-sources-197keifF.js} +1 -1
- package/dist/{composition-sources-tRG7nKWK.mjs → composition-sources-DmzTSy26.mjs} +1 -1
- package/dist/{constants-BBWZlnpQ.js → constants-B5Jd8Zch.js} +1 -1
- package/dist/{constants-DHhhVjkt.mjs → constants-CkNLi-XW.mjs} +1 -1
- package/dist/{dist-B-NmfvVC.mjs → dist-DMWeqeTF.mjs} +4341 -4308
- package/dist/{dist-CiUKtVkX.js → dist-DnALrQF-.js} +4341 -4308
- package/dist/file-host-worker.js +1 -1
- package/dist/file-host-worker.mjs +1 -1
- package/dist/index.js +5 -5
- package/dist/index.mjs +5 -5
- package/dist/{jwt-signing-key-CUpweD22.mjs → jwt-signing-key-CCHXAtrs.mjs} +1 -1
- package/dist/{jwt-signing-key-nwRpRgf_.js → jwt-signing-key-DeqG7LD9.js} +1 -1
- package/dist/{restore-archive-DA-aJtg7.js → restore-archive-C4UhQOsg.js} +156 -65
- package/dist/{restore-archive-CFmPVlWQ.mjs → restore-archive-GevpOHw8.mjs} +151 -66
- package/dist/{retired-settings-keys-D62kN_hT.js → retired-settings-keys-0FOsnzIE.js} +1 -1
- package/dist/{retired-settings-keys-DCGEI4Vi.mjs → retired-settings-keys-CdVFl7m2.mjs} +1 -1
- package/dist/{wal-maintenance-BlqNqaQ3.mjs → wal-maintenance-BtfyfuT5.mjs} +0 -0
- package/dist/{wal-maintenance-BzdCQGjH.js → wal-maintenance-DJV1rde2.js} +0 -0
- package/package.json +1 -1
package/dist/file-host-worker.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
require("./chunk-Cek0wNdY.js");
|
|
2
|
-
const require_wal_maintenance = require("./wal-maintenance-
|
|
2
|
+
const require_wal_maintenance = require("./wal-maintenance-DJV1rde2.js");
|
|
3
3
|
let node_worker_threads = require("node:worker_threads");
|
|
4
4
|
//#region src/builtins/sqlite-storage/file-host-worker.ts
|
|
5
5
|
/**
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { C as callControl, E as controlTargetOf, T as callVector, _ as collectTransferables, a as WalMaintenance, b as isFileHostWorkerData, c as SqliteSettingsBackend, h as serializeError, o as createVectorIndex, s as vectorProviderOf, w as callData, x as trustInput, y as isFileHostRequest } from "./wal-maintenance-
|
|
1
|
+
import { C as callControl, E as controlTargetOf, T as callVector, _ as collectTransferables, a as WalMaintenance, b as isFileHostWorkerData, c as SqliteSettingsBackend, h as serializeError, o as createVectorIndex, s as vectorProviderOf, w as callData, x as trustInput, y as isFileHostRequest } from "./wal-maintenance-BtfyfuT5.mjs";
|
|
2
2
|
import { parentPort, threadId, workerData } from "node:worker_threads";
|
|
3
3
|
//#region src/builtins/sqlite-storage/file-host-worker.ts
|
|
4
4
|
/**
|
package/dist/index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
2
|
const require_chunk = require("./chunk-Cek0wNdY.js");
|
|
3
|
-
const require_dist = require("./dist-
|
|
4
|
-
const require_jwt_signing_key = require("./jwt-signing-key-
|
|
3
|
+
const require_dist = require("./dist-DnALrQF-.js");
|
|
4
|
+
const require_jwt_signing_key = require("./jwt-signing-key-DeqG7LD9.js");
|
|
5
5
|
const require_builtins_alerts_alerts_addon = require("./builtins/alerts/alerts.addon.js");
|
|
6
6
|
require("./builtins/alerts/index.js");
|
|
7
7
|
const require_builtins_calendars_calendars_addon = require("./builtins/calendars/calendars.addon.js");
|
|
@@ -22,12 +22,12 @@ require("./builtins/local-auth/index.js");
|
|
|
22
22
|
const require_builtins_loki_logging_index = require("./builtins/loki-logging/index.js");
|
|
23
23
|
const require_builtins_native_metrics_native_metrics_addon = require("./builtins/native-metrics/native-metrics.addon.js");
|
|
24
24
|
const require_builtins_sqlite_storage_filesystem_storage_addon = require("./builtins/sqlite-storage/filesystem-storage.addon.js");
|
|
25
|
-
const require_wal_maintenance = require("./wal-maintenance-
|
|
25
|
+
const require_wal_maintenance = require("./wal-maintenance-DJV1rde2.js");
|
|
26
26
|
const require_builtins_sqlite_storage_sqlite_settings_addon = require("./builtins/sqlite-storage/sqlite-settings.addon.js");
|
|
27
27
|
const require_builtins_sqlite_storage_index = require("./builtins/sqlite-storage/index.js");
|
|
28
28
|
const require_builtins_storage_orchestrator_storage_orchestrator_addon = require("./builtins/storage-orchestrator/storage-orchestrator.addon.js");
|
|
29
29
|
require("./builtins/storage-orchestrator/index.js");
|
|
30
|
-
const require_constants = require("./constants-
|
|
30
|
+
const require_constants = require("./constants-B5Jd8Zch.js");
|
|
31
31
|
const require_builtins_system_config_system_config_addon = require("./builtins/system-config/system-config.addon.js");
|
|
32
32
|
require("./builtins/system-config/index.js");
|
|
33
33
|
const require_builtins_winston_logging_index = require("./builtins/winston-logging/index.js");
|
|
@@ -35,7 +35,7 @@ const require_custom_action_registry = require("./custom-action-registry-Bf_Ynag
|
|
|
35
35
|
const require_tls = require("./tls-BgImdxCO.js");
|
|
36
36
|
const require_platform_key_source = require("./platform-key-source-Di7HrlGR.js");
|
|
37
37
|
const require_resource_monitor = require("./resource-monitor-mio9dSCT.js");
|
|
38
|
-
const require_restore_archive = require("./restore-archive-
|
|
38
|
+
const require_restore_archive = require("./restore-archive-C4UhQOsg.js");
|
|
39
39
|
let zod = require("zod");
|
|
40
40
|
let node_crypto = require("node:crypto");
|
|
41
41
|
node_crypto = require_chunk.__toESM(node_crypto);
|
package/dist/index.mjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { i as __require } from "./chunk-CNf5ZN-e.mjs";
|
|
2
|
-
import { $t as looseSchema, Ar as expandCapMethods, Dn as scopesAllowAddon, Gr as readinessKey, Hr as parseJsonObject, Ht as isVoidInput, Jr as scopeKey, Jt as lifecycleJobSchema, K as addonSettingsCapability, Kr as resolveCapMount, Lt as isArrayOutputSchema, M as METHOD_ACCESS_MAP, On as scopesAllowDeviceCap, Or as emitDownForOwnedCaps, Qt as logLevelAtMost, Rt as isCollectionArrayMethod, Tr as createEvent$1, Ur as parseJsonUnknown, Ut as kebabToCamel$1, Vt as isObjectInput, br as asNumber, cn as objectInputDeclaresAddonId, cr as errMsg$1, dr as DEVICE_SETTINGS_CONTRIBUTION_METHODS, fr as DEVICE_STATUS_METHOD, gr as ReadinessTimeoutError, hr as ReadinessRegistry, jt as extractNestedAddonId, k as LOG_LEVEL_RANK, ln as objectInputDeclaresRequiredDeviceId, mn as procedureAuthKey, mr as RUNTIME_DEFAULTS, t as ALL_CAPABILITY_DEFINITIONS, ti as EventCategory$1, ur as DATAPLANE_SECRET_HEADER$1, wn as resolveMethodAuth, xr as asString$1, yr as asJsonObject$1, zn as supportedRuntimes } from "./dist-
|
|
3
|
-
import { c as staticJwtSigningKey, i as getProcessJwtSigningKeyState, n as JwtSigningKeyUnavailableError, o as processJwtSigningKey, r as SYSTEM_SECRET_OWNER, t as JWT_SIGNING_KEY_REF } from "./jwt-signing-key-
|
|
2
|
+
import { $t as looseSchema, Ar as expandCapMethods, Dn as scopesAllowAddon, Gr as readinessKey, Hr as parseJsonObject, Ht as isVoidInput, Jr as scopeKey, Jt as lifecycleJobSchema, K as addonSettingsCapability, Kr as resolveCapMount, Lt as isArrayOutputSchema, M as METHOD_ACCESS_MAP, On as scopesAllowDeviceCap, Or as emitDownForOwnedCaps, Qt as logLevelAtMost, Rt as isCollectionArrayMethod, Tr as createEvent$1, Ur as parseJsonUnknown, Ut as kebabToCamel$1, Vt as isObjectInput, br as asNumber, cn as objectInputDeclaresAddonId, cr as errMsg$1, dr as DEVICE_SETTINGS_CONTRIBUTION_METHODS, fr as DEVICE_STATUS_METHOD, gr as ReadinessTimeoutError, hr as ReadinessRegistry, jt as extractNestedAddonId, k as LOG_LEVEL_RANK, ln as objectInputDeclaresRequiredDeviceId, mn as procedureAuthKey, mr as RUNTIME_DEFAULTS, t as ALL_CAPABILITY_DEFINITIONS, ti as EventCategory$1, ur as DATAPLANE_SECRET_HEADER$1, wn as resolveMethodAuth, xr as asString$1, yr as asJsonObject$1, zn as supportedRuntimes } from "./dist-DMWeqeTF.mjs";
|
|
3
|
+
import { c as staticJwtSigningKey, i as getProcessJwtSigningKeyState, n as JwtSigningKeyUnavailableError, o as processJwtSigningKey, r as SYSTEM_SECRET_OWNER, t as JWT_SIGNING_KEY_REF } from "./jwt-signing-key-CCHXAtrs.mjs";
|
|
4
4
|
import { AlertCenterAddon } from "./builtins/alerts/alerts.addon.mjs";
|
|
5
5
|
import "./builtins/alerts/index.mjs";
|
|
6
6
|
import { CalendarsAddon } from "./builtins/calendars/calendars.addon.mjs";
|
|
@@ -21,12 +21,12 @@ import "./builtins/local-auth/index.mjs";
|
|
|
21
21
|
import { LokiDestination, LokiLoggingAddon } from "./builtins/loki-logging/index.mjs";
|
|
22
22
|
import NativeMetricsAddon, { a as NativeMetricsProvider, n as nodeProcReader, r as parseProcStat } from "./builtins/native-metrics/native-metrics.addon.mjs";
|
|
23
23
|
import { FilesystemStorageAddon, t as FilesystemStorageProvider } from "./builtins/sqlite-storage/filesystem-storage.addon.mjs";
|
|
24
|
-
import { c as SqliteSettingsBackend, l as prefixRange } from "./wal-maintenance-
|
|
24
|
+
import { c as SqliteSettingsBackend, l as prefixRange } from "./wal-maintenance-BtfyfuT5.mjs";
|
|
25
25
|
import { SqliteSettingsAddon } from "./builtins/sqlite-storage/sqlite-settings.addon.mjs";
|
|
26
26
|
import { ConfigStore, DeviceStore } from "./builtins/sqlite-storage/index.mjs";
|
|
27
27
|
import { StorageOrchestratorAddon, a as stripForwardedCaller, i as createHubCapForwardService, n as HUB_CAP_FWD_ACTION, o as buildStorageLocationRegistry, r as HUB_CAP_FWD_SERVICE, t as StorageOrchestratorService } from "./builtins/storage-orchestrator/storage-orchestrator.addon.mjs";
|
|
28
28
|
import "./builtins/storage-orchestrator/index.mjs";
|
|
29
|
-
import { _ as getProcessClusterSecretGate, a as MESH_CA_KEY_REF, b as setProcessClusterSecretGate, d as CLUSTER_SECRET_REF, f as CLUSTER_SECRET_REJECTED_EXIT_CODE, g as clusterSecretMatches, h as checkClusterSecret, i as MESH_CA_FIELD, m as CLUSTER_SECRET_UNAVAILABLE_TYPE, n as DEFAULT_HUB_TLS_TCP_PORT, o as MESH_CA_SETTINGS_KEY, p as CLUSTER_SECRET_SETTINGS_KEY, u as CLUSTER_SECRET_MISMATCH_TYPE, v as hashClusterSecret, y as isClusterSecretMismatchError } from "./constants-
|
|
29
|
+
import { _ as getProcessClusterSecretGate, a as MESH_CA_KEY_REF, b as setProcessClusterSecretGate, d as CLUSTER_SECRET_REF, f as CLUSTER_SECRET_REJECTED_EXIT_CODE, g as clusterSecretMatches, h as checkClusterSecret, i as MESH_CA_FIELD, m as CLUSTER_SECRET_UNAVAILABLE_TYPE, n as DEFAULT_HUB_TLS_TCP_PORT, o as MESH_CA_SETTINGS_KEY, p as CLUSTER_SECRET_SETTINGS_KEY, u as CLUSTER_SECRET_MISMATCH_TYPE, v as hashClusterSecret, y as isClusterSecretMismatchError } from "./constants-CkNLi-XW.mjs";
|
|
30
30
|
import { A as AGENT_UI_UNLOCK_TTL_MS, B as isMeshAuthMode, C as generateMeshCa, D as loadMeshCa, E as issueMeshLeafFromCsr, F as parseAgentDashboardOrigins, G as setProcessMeshEnforcer, H as requestProcessMeshEnforcement, I as verifyAgentUiUnlockTicket, J as parseCidrList, K as createCidrMatcher, L as MESH_AUTH_MODE_FIELD, M as UnlockTicketJtiStore, N as isAllowedAgentDashboardReturnTo, O as AGENT_DASHBOARD_ORIGINS_FIELD, P as mintAgentUiUnlockTicket, R as getProcessMeshAuthMode, S as exportMeshPrivateKeyPem, SystemConfigAddon, T as issueMeshLeafForNode, U as setProcessMeshAuthMode, V as parseMeshAuthMode, W as setProcessMeshAuthStatusSource, Y as readCidrSetting, _ as getProcessMeshCaState, a as ServiceBroker, b as caFingerprintCompact, c as JoinTokenJtiStore, d as verifyMeshJoinToken, f as getProcessNodeMeshTransport, g as MeshCaKeeper, h as processMeshCrl, i as Errors, j as AGENT_UI_UNLOCK_VERSION, k as AGENT_UI_UNLOCK_DOMAIN, l as mintMeshJoinToken, m as MeshCrl, n as MESH_TLS_PORT_HELLO_FIELD, o as setProcessMeshTlsEnabler, p as setProcessMeshPeerTransportLookup, q as normalizeIp, r as TlsTcpTransporter, s as enrollMeshNode, u as processJoinTokenJtiStore, v as requireProcessMeshCa, w as generateMeshKeyPair, x as createMeshCsrPem, y as caFingerprint, z as getProcessMeshAuthStatus } from "./builtins/system-config/system-config.addon.mjs";
|
|
31
31
|
import "./builtins/system-config/index.mjs";
|
|
32
32
|
import { WinstonDestination, WinstonLoggingAddon } from "./builtins/winston-logging/index.mjs";
|
|
@@ -34,7 +34,7 @@ import { C as isModelDownloaded, T as revisionWeightUrl, _ as downloadFile, a as
|
|
|
34
34
|
import { A as allFamiliesListenHost, C as collectCertIdentity, D as SERVER_AUTH_OID, E as MAX_LEAF_VALIDITY_DAYS, F as registerLanHttpHandler, M as bindPendingLanHttp, N as closeLanHttp, O as evaluateExistingCert, P as readLanHttpState, S as CA_COMMON_NAME, T as LEAF_RENEWAL_WINDOW_DAYS, _ as writeExtraSans, a as validateUploadedTls, b as loadTlsCert, c as registerHttpsListener, d as prepareBootTls, f as UPLOADED_CA_FILE, g as splitPemCertificates, h as readTlsMode, i as storeUploadedCertificate, j as applyLanHttp, k as DEFAULT_LAN_HTTP_PORT, l as reloadHttpsListener, m as readTlsAccessStatus, n as regenerateCertificate, o as clearHttpsListener, p as readExtraSans, r as revertToGeneratedCertificate, s as leafFingerprintOf, t as applyCertificateToListener, u as servedHttpsLeafFingerprint, v as writeTlsMode, w as CA_VALIDITY_DAYS, x as reissueTlsLeaf, y as ensureTlsCert } from "./tls-CaOLZ09W.mjs";
|
|
35
35
|
import { n as getPlatformKeychainKey, r as setPlatformKeychainKey, t as clearPlatformKeychainKey } from "./platform-key-source-BWlq0jjn.mjs";
|
|
36
36
|
import { n as getSinglePidStats, t as getPidStats } from "./resource-monitor-Di9daRwI.mjs";
|
|
37
|
-
import { c as
|
|
37
|
+
import { c as BackupDecryptError, f as generateBackupKeyPair, h as readBackupEncryptionHeader, l as BackupKeyFormatError, r as prepareRestoreArchive, s as SystemBackupService, t as BackupKeyRequiredError, u as BackupKeyMismatchError } from "./restore-archive-GevpOHw8.mjs";
|
|
38
38
|
import { z } from "zod";
|
|
39
39
|
import * as crypto$1 from "node:crypto";
|
|
40
40
|
import { createHash, createHmac, randomBytes, randomUUID, timingSafeEqual } from "node:crypto";
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
const require_chunk = require("./chunk-Cek0wNdY.js");
|
|
2
|
-
const require_dist = require("./dist-
|
|
2
|
+
const require_dist = require("./dist-DnALrQF-.js");
|
|
3
3
|
let node_crypto = require("node:crypto");
|
|
4
4
|
let buffer = require("buffer");
|
|
5
5
|
let node_fs_promises = require("node:fs/promises");
|
|
@@ -3508,6 +3508,11 @@ function isSqlitePath(relPath) {
|
|
|
3508
3508
|
const db = databaseOfSidecar(relPath) ?? relPath;
|
|
3509
3509
|
return SQLITE_DATABASE_SUFFIXES.some((suffix) => db.endsWith(suffix));
|
|
3510
3510
|
}
|
|
3511
|
+
/**
|
|
3512
|
+
* The databases a run carries when it states none: the minimum (D382). A
|
|
3513
|
+
* schedule, a manual run and `createArchive` all fall back to this one value.
|
|
3514
|
+
*/
|
|
3515
|
+
var DEFAULT_BACKUP_DATABASES = ["settings"];
|
|
3511
3516
|
/** Path of the manifest file embedded inside every archive. */
|
|
3512
3517
|
var ARCHIVE_MANIFEST_NAME = ".camstack-backup-manifest.json";
|
|
3513
3518
|
var DEFAULT_STAT_CACHE_TTL_MS = 6e4;
|
|
@@ -3596,6 +3601,8 @@ var SystemBackupService = class {
|
|
|
3596
3601
|
throwIfCancelled(opts.signal);
|
|
3597
3602
|
const recipient = opts.encryptTo !== void 0 ? parseBackupPublicKey(opts.encryptTo) : null;
|
|
3598
3603
|
const requested = opts.locations ?? DEFAULT_BACKUP_LOCATIONS;
|
|
3604
|
+
const selection = new Set(opts.databases ?? DEFAULT_BACKUP_DATABASES);
|
|
3605
|
+
if (!selection.has("settings")) return this.createSnapshotsOnlyArchive(opts, selection, recipient);
|
|
3599
3606
|
const present = [];
|
|
3600
3607
|
for (const loc of requested) {
|
|
3601
3608
|
const abs = node_path.isAbsolute(loc) ? loc : node_path.join(this.dataDir, loc);
|
|
@@ -3613,7 +3620,12 @@ var SystemBackupService = class {
|
|
|
3613
3620
|
else if (!isExcludedFromBackup(node_path.relative(this.dataDir, abs))) walked.push(toArchiveEntry(abs, this.dataDir, stat));
|
|
3614
3621
|
}
|
|
3615
3622
|
const walkedPaths = new Set(walked.map((e) => e.path));
|
|
3616
|
-
const
|
|
3623
|
+
const ownedById = walked.some((e) => isSqlitePath(e.path)) ? await this.ownedDatabasesInScope(opts.owner, walkedPaths) : /* @__PURE__ */ new Map();
|
|
3624
|
+
const owned = new Set(ownedById.keys());
|
|
3625
|
+
const selected = /* @__PURE__ */ new Map();
|
|
3626
|
+
const omitted = /* @__PURE__ */ new Set();
|
|
3627
|
+
for (const [rel, databaseId] of ownedById) if (selection.has(databaseId)) selected.set(rel, databaseId);
|
|
3628
|
+
else omitted.add(databaseId);
|
|
3617
3629
|
const unowned = /* @__PURE__ */ new Set();
|
|
3618
3630
|
for (const e of walked) {
|
|
3619
3631
|
const db = databaseOfSidecar(e.path);
|
|
@@ -3627,7 +3639,7 @@ var SystemBackupService = class {
|
|
|
3627
3639
|
} });
|
|
3628
3640
|
throw new BackupSnapshotRefusedError(`live SQLite database ${databases.join(", ")} has no owner that can snapshot it — a copy of its files would be torn; remove its stale -wal/-shm/-journal if nothing has it open, or leave its location out of the backup`);
|
|
3629
3641
|
}
|
|
3630
|
-
const
|
|
3642
|
+
const snapshots = selected.size > 0 && opts.owner ? await this.takeOwnerSnapshots(opts.owner, selected, opts.signal) : [];
|
|
3631
3643
|
try {
|
|
3632
3644
|
const liveFiles = /* @__PURE__ */ new Set();
|
|
3633
3645
|
for (const db of owned) {
|
|
@@ -3635,7 +3647,7 @@ var SystemBackupService = class {
|
|
|
3635
3647
|
for (const suffix of SQLITE_SIDECAR_SUFFIXES) liveFiles.add(db + suffix);
|
|
3636
3648
|
}
|
|
3637
3649
|
const entries = walked.filter((e) => !liveFiles.has(e.path));
|
|
3638
|
-
|
|
3650
|
+
for (const snapshot of snapshots) entries.push(snapshot.entry);
|
|
3639
3651
|
const manifest = {
|
|
3640
3652
|
archiveVersion: 1,
|
|
3641
3653
|
createdAt: Date.now(),
|
|
@@ -3644,15 +3656,20 @@ var SystemBackupService = class {
|
|
|
3644
3656
|
entries,
|
|
3645
3657
|
totalBytes: entries.reduce((acc, e) => acc + e.sizeBytes, 0),
|
|
3646
3658
|
totalFiles: entries.filter((e) => e.kind === "file").length,
|
|
3647
|
-
...
|
|
3659
|
+
...snapshots.length > 0 ? { sqliteSnapshots: snapshots.map((snapshot) => snapshot.archived) } : {},
|
|
3660
|
+
...omitted.size > 0 ? { omittedDatabases: [...omitted].toSorted() } : {}
|
|
3648
3661
|
};
|
|
3649
|
-
|
|
3662
|
+
if (omitted.size > 0) this.logger.info("createArchive: owned databases left out of this run", { meta: {
|
|
3663
|
+
omitted: [...omitted].toSorted(),
|
|
3664
|
+
carried: [...selected.values()]
|
|
3665
|
+
} });
|
|
3666
|
+
const carriedSnapshots = new Set(snapshots.map((snapshot) => snapshot.archived.snapshotPath));
|
|
3650
3667
|
return await this.writeArchive({
|
|
3651
3668
|
archivePath: opts.archivePath,
|
|
3652
3669
|
present,
|
|
3653
3670
|
manifest,
|
|
3654
3671
|
excluded: (rel) => {
|
|
3655
|
-
if (rel
|
|
3672
|
+
if (carriedSnapshots.has(rel)) return false;
|
|
3656
3673
|
return liveFiles.has(rel) || isExcludedFromBackup(rel);
|
|
3657
3674
|
},
|
|
3658
3675
|
...opts.signal ? { signal: opts.signal } : {},
|
|
@@ -3666,7 +3683,62 @@ var SystemBackupService = class {
|
|
|
3666
3683
|
}
|
|
3667
3684
|
});
|
|
3668
3685
|
} finally {
|
|
3669
|
-
|
|
3686
|
+
for (const snapshot of snapshots) await this.removeSnapshot(snapshot.absPath);
|
|
3687
|
+
}
|
|
3688
|
+
}
|
|
3689
|
+
/**
|
|
3690
|
+
* An archive of the selected databases' owner snapshots and the manifest —
|
|
3691
|
+
* no data-root walk, no location, no settings (D852). Refused when the owner
|
|
3692
|
+
* has none of the selected files: an archive of nothing must reach no
|
|
3693
|
+
* destination, because its upload prunes an older archive that has them.
|
|
3694
|
+
*/
|
|
3695
|
+
async createSnapshotsOnlyArchive(opts, selection, recipient) {
|
|
3696
|
+
if (opts.owner === void 0) throw new BackupSnapshotRefusedError("a snapshots-only archive needs the database owner, and none was given");
|
|
3697
|
+
node_fs.mkdirSync(node_path.dirname(opts.archivePath), { recursive: true });
|
|
3698
|
+
const ownedById = await this.ownedDatabasesInScope(opts.owner, null);
|
|
3699
|
+
const selected = /* @__PURE__ */ new Map();
|
|
3700
|
+
for (const [rel, databaseId] of ownedById) if (selection.has(databaseId)) selected.set(rel, databaseId);
|
|
3701
|
+
if (selected.size === 0) {
|
|
3702
|
+
this.logger.warn("createArchive: the owner has none of the selected databases — no archive built", { meta: {
|
|
3703
|
+
requested: [...selection].toSorted(),
|
|
3704
|
+
archivePath: opts.archivePath
|
|
3705
|
+
} });
|
|
3706
|
+
throw new BackupSnapshotRefusedError(`the owner has none of the selected databases (${[...selection].toSorted().join(", ")})`);
|
|
3707
|
+
}
|
|
3708
|
+
const snapshots = await this.takeOwnerSnapshots(opts.owner, selected, opts.signal);
|
|
3709
|
+
try {
|
|
3710
|
+
const entries = snapshots.map((snapshot) => snapshot.entry);
|
|
3711
|
+
const manifest = {
|
|
3712
|
+
archiveVersion: 1,
|
|
3713
|
+
createdAt: Date.now(),
|
|
3714
|
+
dataDir: this.dataDir,
|
|
3715
|
+
locations: [],
|
|
3716
|
+
entries,
|
|
3717
|
+
totalBytes: entries.reduce((acc, e) => acc + e.sizeBytes, 0),
|
|
3718
|
+
totalFiles: entries.length,
|
|
3719
|
+
sqliteSnapshots: snapshots.map((snapshot) => snapshot.archived)
|
|
3720
|
+
};
|
|
3721
|
+
const carried = snapshots.map((snapshot) => snapshot.archived.snapshotPath);
|
|
3722
|
+
const carriedSet = new Set(carried);
|
|
3723
|
+
const result = await this.writeArchive({
|
|
3724
|
+
archivePath: opts.archivePath,
|
|
3725
|
+
present: [],
|
|
3726
|
+
tarRoots: carried,
|
|
3727
|
+
manifest,
|
|
3728
|
+
excluded: (rel) => rel !== ".camstack-backup-manifest.json" && !carriedSet.has(rel),
|
|
3729
|
+
...opts.signal ? { signal: opts.signal } : {},
|
|
3730
|
+
...opts.onArchiveBytes ? { onArchiveBytes: opts.onArchiveBytes } : {},
|
|
3731
|
+
...opts.encryptTo !== void 0 ? { encryptTo: opts.encryptTo } : {}
|
|
3732
|
+
});
|
|
3733
|
+
return recipient === null ? result : {
|
|
3734
|
+
...result,
|
|
3735
|
+
encryption: {
|
|
3736
|
+
scheme: BACKUP_ENCRYPTION_SCHEME,
|
|
3737
|
+
keyId: recipient.keyId
|
|
3738
|
+
}
|
|
3739
|
+
};
|
|
3740
|
+
} finally {
|
|
3741
|
+
for (const snapshot of snapshots) await this.removeSnapshot(snapshot.absPath);
|
|
3670
3742
|
}
|
|
3671
3743
|
}
|
|
3672
3744
|
/**
|
|
@@ -3700,7 +3772,7 @@ var SystemBackupService = class {
|
|
|
3700
3772
|
if (!excludePrefix) return true;
|
|
3701
3773
|
return norm !== excludePrefix && !norm.startsWith(`${excludePrefix}/`);
|
|
3702
3774
|
}
|
|
3703
|
-
}, [ARCHIVE_MANIFEST_NAME, ...present]);
|
|
3775
|
+
}, [ARCHIVE_MANIFEST_NAME, ...opts.tarRoots ?? present]);
|
|
3704
3776
|
const sink = node_fs.createWriteStream(opts.archivePath, { mode: 384 });
|
|
3705
3777
|
try {
|
|
3706
3778
|
const streamOpts = opts.signal ? { signal: opts.signal } : {};
|
|
@@ -3817,12 +3889,13 @@ var SystemBackupService = class {
|
|
|
3817
3889
|
if (node_fs.existsSync(markerPath)) node_fs.rmSync(markerPath, { force: true });
|
|
3818
3890
|
}
|
|
3819
3891
|
/**
|
|
3820
|
-
* The databases the owner declares, archive-relative, that this walk found
|
|
3821
|
-
* One outside this data root is not in scope. An owner
|
|
3822
|
-
* stops the archive: without the answer, nothing says
|
|
3892
|
+
* The databases the owner declares, archive-relative, that this walk found,
|
|
3893
|
+
* with the id of each. One outside this data root is not in scope. An owner
|
|
3894
|
+
* that cannot answer stops the archive: without the answer, nothing says
|
|
3895
|
+
* which file is live.
|
|
3823
3896
|
*/
|
|
3824
3897
|
async ownedDatabasesInScope(owner, walked) {
|
|
3825
|
-
if (owner === void 0) return /* @__PURE__ */ new
|
|
3898
|
+
if (owner === void 0) return /* @__PURE__ */ new Map();
|
|
3826
3899
|
let declared;
|
|
3827
3900
|
try {
|
|
3828
3901
|
declared = await owner.listDatabases();
|
|
@@ -3831,22 +3904,23 @@ var SystemBackupService = class {
|
|
|
3831
3904
|
this.logger.error("createArchive: the database owner did not say what it owns — no archive built", { meta: { error: reason } });
|
|
3832
3905
|
throw new BackupSnapshotRefusedError(`the database owner could not be asked: ${reason}`);
|
|
3833
3906
|
}
|
|
3834
|
-
const inScope = /* @__PURE__ */ new
|
|
3835
|
-
for (const
|
|
3836
|
-
const rel = this.archiveRelative(
|
|
3837
|
-
if (rel !== null && walked.has(rel)) inScope.
|
|
3907
|
+
const inScope = /* @__PURE__ */ new Map();
|
|
3908
|
+
for (const db of declared) {
|
|
3909
|
+
const rel = this.archiveRelative(db.livePath);
|
|
3910
|
+
if (rel !== null && (walked === null || walked.has(rel))) inScope.set(rel, db.databaseId);
|
|
3838
3911
|
}
|
|
3839
3912
|
return inScope;
|
|
3840
3913
|
}
|
|
3841
3914
|
/**
|
|
3842
|
-
* Ask the owner for
|
|
3843
|
-
*
|
|
3844
|
-
*
|
|
3845
|
-
*
|
|
3846
|
-
* database
|
|
3915
|
+
* Ask the owner for one verified snapshot per SELECTED database, one after
|
|
3916
|
+
* the other, and place each in this archive. A snapshot must sit on THIS data
|
|
3917
|
+
* root — the call is pinned to this node, so a path elsewhere means it
|
|
3918
|
+
* reached another host, and that file is not ours to read — beside the very
|
|
3919
|
+
* database it was asked for. Anything else is refused, and the run builds
|
|
3920
|
+
* nothing: the copies already taken are removed.
|
|
3847
3921
|
*
|
|
3848
|
-
* Only ever DELETED here: `<
|
|
3849
|
-
* a name this process derives itself. A path the owner ANSWERS is never
|
|
3922
|
+
* Only ever DELETED here: `<selected db>.backup-snapshot` under this data
|
|
3923
|
+
* root, a name this process derives itself. A path the owner ANSWERS is never
|
|
3850
3924
|
* deleted on its word — answering the live database as the snapshot would
|
|
3851
3925
|
* otherwise delete the live database. A file at any other path is left to
|
|
3852
3926
|
* the owner's own sweep.
|
|
@@ -3854,62 +3928,73 @@ var SystemBackupService = class {
|
|
|
3854
3928
|
* A cancel is honoured while the owner is still copying; the copy it may
|
|
3855
3929
|
* finish afterwards is removed when that call settles.
|
|
3856
3930
|
*/
|
|
3857
|
-
async
|
|
3931
|
+
async takeOwnerSnapshots(owner, selected, signal) {
|
|
3858
3932
|
const removeOwnedSnapshots = async () => {
|
|
3859
|
-
for (const db of
|
|
3933
|
+
for (const db of selected.keys()) await this.removeSnapshot(node_path.join(this.dataDir, db + require_dist.DATABASE_SNAPSHOT_SUFFIX));
|
|
3860
3934
|
};
|
|
3935
|
+
const taken = [];
|
|
3936
|
+
try {
|
|
3937
|
+
for (const [expectedLive, databaseId] of selected) {
|
|
3938
|
+
throwIfCancelled(signal);
|
|
3939
|
+
taken.push(await this.takeOneSnapshot(owner, databaseId, expectedLive, signal, selected, removeOwnedSnapshots));
|
|
3940
|
+
}
|
|
3941
|
+
} catch (err) {
|
|
3942
|
+
await removeOwnedSnapshots();
|
|
3943
|
+
throw err;
|
|
3944
|
+
}
|
|
3945
|
+
return taken;
|
|
3946
|
+
}
|
|
3947
|
+
async takeOneSnapshot(owner, databaseId, expectedLive, signal, selected, removeOwnedSnapshots) {
|
|
3861
3948
|
let result;
|
|
3862
3949
|
try {
|
|
3863
|
-
result = await raceAbort(owner.writeSnapshot(), signal, () => {
|
|
3864
|
-
this.logger.info("createArchive: run cancelled while the owner copied — its copy is removed when it lands", { meta: {
|
|
3950
|
+
result = await raceAbort(owner.writeSnapshot(databaseId), signal, () => {
|
|
3951
|
+
this.logger.info("createArchive: run cancelled while the owner copied — its copy is removed when it lands", { meta: {
|
|
3952
|
+
databases: [...selected.values()],
|
|
3953
|
+
database: databaseId
|
|
3954
|
+
} });
|
|
3865
3955
|
return removeOwnedSnapshots();
|
|
3866
3956
|
});
|
|
3867
3957
|
} catch (err) {
|
|
3868
3958
|
if (err instanceof BackupCancelledError) throw err;
|
|
3869
3959
|
const reason = err instanceof Error ? err.message : String(err);
|
|
3870
3960
|
this.logger.error("createArchive: the owner could not snapshot its live database — no archive built", { meta: {
|
|
3871
|
-
databases: [...
|
|
3961
|
+
databases: [...selected.values()],
|
|
3962
|
+
database: databaseId,
|
|
3872
3963
|
error: reason
|
|
3873
3964
|
} });
|
|
3874
|
-
|
|
3875
|
-
throw new BackupSnapshotRefusedError(reason);
|
|
3965
|
+
throw new BackupSnapshotRefusedError(`${databaseId}: ${reason}`);
|
|
3876
3966
|
}
|
|
3877
|
-
|
|
3878
|
-
|
|
3879
|
-
|
|
3880
|
-
|
|
3881
|
-
|
|
3882
|
-
|
|
3883
|
-
dataDir: this.dataDir
|
|
3884
|
-
} });
|
|
3885
|
-
throw new BackupSnapshotRefusedError(`snapshot ${result.snapshotPath} is not under this archive's data root ${this.dataDir}`);
|
|
3886
|
-
}
|
|
3887
|
-
if (snapshotPath !== livePath + ".backup-snapshot") throw new BackupSnapshotRefusedError(`snapshot ${snapshotPath} does not sit beside the database ${livePath} it copies`);
|
|
3888
|
-
const uncovered = [...owned].filter((db) => db !== livePath);
|
|
3889
|
-
if (!owned.has(livePath) || uncovered.length > 0) throw new BackupSnapshotRefusedError(`snapshot copies ${livePath}, but the owned database(s) in this archive are ${[...owned].join(", ")}`);
|
|
3890
|
-
const absPath = node_path.join(this.dataDir, snapshotPath);
|
|
3891
|
-
const stat = await node_fs_promises.stat(absPath);
|
|
3892
|
-
this.logger.info("createArchive: carrying the owner snapshot in place of the live database", { meta: {
|
|
3893
|
-
database: livePath,
|
|
3894
|
-
snapshot: snapshotPath,
|
|
3895
|
-
sizeBytes: stat.size,
|
|
3896
|
-
tables: result.tables.length,
|
|
3897
|
-
copyMs: result.copyMs,
|
|
3898
|
-
verifyMs: result.verifyMs
|
|
3967
|
+
const livePath = this.archiveRelative(result.livePath);
|
|
3968
|
+
const snapshotPath = this.archiveRelative(result.snapshotPath);
|
|
3969
|
+
if (livePath === null || snapshotPath === null) {
|
|
3970
|
+
this.logger.warn("createArchive: the owner answered a snapshot outside this data root — not touched, left to its sweep", { meta: {
|
|
3971
|
+
snapshot: result.snapshotPath,
|
|
3972
|
+
dataDir: this.dataDir
|
|
3899
3973
|
} });
|
|
3900
|
-
|
|
3901
|
-
absPath,
|
|
3902
|
-
archived: {
|
|
3903
|
-
...result,
|
|
3904
|
-
livePath,
|
|
3905
|
-
snapshotPath
|
|
3906
|
-
},
|
|
3907
|
-
entry: toArchiveEntry(absPath, this.dataDir, stat)
|
|
3908
|
-
};
|
|
3909
|
-
} catch (err) {
|
|
3910
|
-
await removeOwnedSnapshots();
|
|
3911
|
-
throw err;
|
|
3974
|
+
throw new BackupSnapshotRefusedError(`snapshot ${result.snapshotPath} is not under this archive's data root ${this.dataDir}`);
|
|
3912
3975
|
}
|
|
3976
|
+
if (snapshotPath !== livePath + ".backup-snapshot") throw new BackupSnapshotRefusedError(`snapshot ${snapshotPath} does not sit beside the database ${livePath} it copies`);
|
|
3977
|
+
if (livePath !== expectedLive || result.databaseId !== databaseId) throw new BackupSnapshotRefusedError(`snapshot copies ${livePath} (${result.databaseId}), but ${databaseId} (${expectedLive}) was asked for`);
|
|
3978
|
+
const absPath = node_path.join(this.dataDir, snapshotPath);
|
|
3979
|
+
const stat = await node_fs_promises.stat(absPath);
|
|
3980
|
+
this.logger.info("createArchive: carrying the owner snapshot in place of the live database", { meta: {
|
|
3981
|
+
database: livePath,
|
|
3982
|
+
databaseId,
|
|
3983
|
+
snapshot: snapshotPath,
|
|
3984
|
+
sizeBytes: stat.size,
|
|
3985
|
+
tables: result.tables.length,
|
|
3986
|
+
copyMs: result.copyMs,
|
|
3987
|
+
verifyMs: result.verifyMs
|
|
3988
|
+
} });
|
|
3989
|
+
return {
|
|
3990
|
+
absPath,
|
|
3991
|
+
archived: {
|
|
3992
|
+
...result,
|
|
3993
|
+
livePath,
|
|
3994
|
+
snapshotPath
|
|
3995
|
+
},
|
|
3996
|
+
entry: toArchiveEntry(absPath, this.dataDir, stat)
|
|
3997
|
+
};
|
|
3913
3998
|
}
|
|
3914
3999
|
async removeSnapshot(absPath) {
|
|
3915
4000
|
try {
|
|
@@ -4089,6 +4174,12 @@ Object.defineProperty(exports, "BackupSnapshotRefusedError", {
|
|
|
4089
4174
|
return BackupSnapshotRefusedError;
|
|
4090
4175
|
}
|
|
4091
4176
|
});
|
|
4177
|
+
Object.defineProperty(exports, "DEFAULT_BACKUP_DATABASES", {
|
|
4178
|
+
enumerable: true,
|
|
4179
|
+
get: function() {
|
|
4180
|
+
return DEFAULT_BACKUP_DATABASES;
|
|
4181
|
+
}
|
|
4182
|
+
});
|
|
4092
4183
|
Object.defineProperty(exports, "ENCRYPTED_BACKUP_SUFFIX", {
|
|
4093
4184
|
enumerable: true,
|
|
4094
4185
|
get: function() {
|