@calltelemetry/cli 0.6.12 → 0.7.1
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/commands/appliance.d.ts +3 -0
- package/dist/commands/appliance.d.ts.map +1 -0
- package/dist/commands/appliance.js +99 -0
- package/dist/commands/appliance.js.map +1 -0
- package/dist/commands/config.d.ts.map +1 -1
- package/dist/commands/config.js +0 -42
- package/dist/commands/config.js.map +1 -1
- package/dist/commands/loadtest.d.ts.map +1 -1
- package/dist/commands/loadtest.js +214 -1
- package/dist/commands/loadtest.js.map +1 -1
- package/dist/commands/otel.d.ts +3 -0
- package/dist/commands/otel.d.ts.map +1 -0
- package/dist/commands/otel.js +89 -0
- package/dist/commands/otel.js.map +1 -0
- package/dist/commands/seed.d.ts +3 -0
- package/dist/commands/seed.d.ts.map +1 -0
- package/dist/commands/seed.js +106 -0
- package/dist/commands/seed.js.map +1 -0
- package/dist/commands/storage.d.ts +3 -0
- package/dist/commands/storage.d.ts.map +1 -0
- package/dist/commands/storage.js +66 -0
- package/dist/commands/storage.js.map +1 -0
- package/dist/commands/update.d.ts.map +1 -1
- package/dist/commands/update.js +19 -17
- package/dist/commands/update.js.map +1 -1
- package/dist/index.js +8 -0
- package/dist/index.js.map +1 -1
- package/dist/lib/migration-001-cgnat.d.ts +2 -0
- package/dist/lib/migration-001-cgnat.d.ts.map +1 -0
- package/dist/lib/migration-001-cgnat.js +59 -0
- package/dist/lib/migration-001-cgnat.js.map +1 -0
- package/dist/lib/migration-002-swap.d.ts +12 -0
- package/dist/lib/migration-002-swap.d.ts.map +1 -0
- package/dist/lib/migration-002-swap.js +103 -0
- package/dist/lib/migration-002-swap.js.map +1 -0
- package/dist/lib/migration-003-nm-heal.d.ts +12 -0
- package/dist/lib/migration-003-nm-heal.d.ts.map +1 -0
- package/dist/lib/migration-003-nm-heal.js +75 -0
- package/dist/lib/migration-003-nm-heal.js.map +1 -0
- package/dist/lib/migration-004-systemd-docker.d.ts +13 -0
- package/dist/lib/migration-004-systemd-docker.d.ts.map +1 -0
- package/dist/lib/migration-004-systemd-docker.js +48 -0
- package/dist/lib/migration-004-systemd-docker.js.map +1 -0
- package/dist/lib/migration-005-ssh-keys.d.ts +13 -0
- package/dist/lib/migration-005-ssh-keys.d.ts.map +1 -0
- package/dist/lib/migration-005-ssh-keys.js +49 -0
- package/dist/lib/migration-005-ssh-keys.js.map +1 -0
- package/dist/lib/migration-006-console-loglevel.d.ts +10 -0
- package/dist/lib/migration-006-console-loglevel.d.ts.map +1 -0
- package/dist/lib/migration-006-console-loglevel.js +27 -0
- package/dist/lib/migration-006-console-loglevel.js.map +1 -0
- package/dist/lib/migration-007-nm-keyfile.d.ts +10 -0
- package/dist/lib/migration-007-nm-keyfile.d.ts.map +1 -0
- package/dist/lib/migration-007-nm-keyfile.js +30 -0
- package/dist/lib/migration-007-nm-keyfile.js.map +1 -0
- package/dist/lib/migration-008-systemd-restart.d.ts +13 -0
- package/dist/lib/migration-008-systemd-restart.d.ts.map +1 -0
- package/dist/lib/migration-008-systemd-restart.js +41 -0
- package/dist/lib/migration-008-systemd-restart.js.map +1 -0
- package/dist/lib/migration-009-bind-mount-files.d.ts +11 -0
- package/dist/lib/migration-009-bind-mount-files.d.ts.map +1 -0
- package/dist/lib/migration-009-bind-mount-files.js +86 -0
- package/dist/lib/migration-009-bind-mount-files.js.map +1 -0
- package/dist/lib/migration-010-jtapi-state.d.ts +11 -0
- package/dist/lib/migration-010-jtapi-state.d.ts.map +1 -0
- package/dist/lib/migration-010-jtapi-state.js +61 -0
- package/dist/lib/migration-010-jtapi-state.js.map +1 -0
- package/dist/lib/migration-011-docker-memory-limit.d.ts +13 -0
- package/dist/lib/migration-011-docker-memory-limit.d.ts.map +1 -0
- package/dist/lib/migration-011-docker-memory-limit.js +45 -0
- package/dist/lib/migration-011-docker-memory-limit.js.map +1 -0
- package/dist/lib/migration-012-db-pool-sizes.d.ts +12 -0
- package/dist/lib/migration-012-db-pool-sizes.d.ts.map +1 -0
- package/dist/lib/migration-012-db-pool-sizes.js +64 -0
- package/dist/lib/migration-012-db-pool-sizes.js.map +1 -0
- package/dist/lib/migration-013-grafana-password.d.ts +15 -0
- package/dist/lib/migration-013-grafana-password.d.ts.map +1 -0
- package/dist/lib/migration-013-grafana-password.js +80 -0
- package/dist/lib/migration-013-grafana-password.js.map +1 -0
- package/dist/lib/migration-014-docker-firewall-backend.d.ts +16 -0
- package/dist/lib/migration-014-docker-firewall-backend.d.ts.map +1 -0
- package/dist/lib/migration-014-docker-firewall-backend.js +72 -0
- package/dist/lib/migration-014-docker-firewall-backend.js.map +1 -0
- package/dist/lib/migrations.d.ts +42 -0
- package/dist/lib/migrations.d.ts.map +1 -0
- package/dist/lib/migrations.js +231 -0
- package/dist/lib/migrations.js.map +1 -0
- package/dist/lib/otel.d.ts +7 -7
- package/dist/lib/otel.d.ts.map +1 -1
- package/dist/lib/otel.js +18 -25
- package/dist/lib/otel.js.map +1 -1
- package/dist/lib/prefs.d.ts +1 -0
- package/dist/lib/prefs.d.ts.map +1 -1
- package/dist/lib/prefs.js +1 -0
- package/dist/lib/prefs.js.map +1 -1
- package/dist/lib/prompts.d.ts +3 -0
- package/dist/lib/prompts.d.ts.map +1 -0
- package/dist/lib/prompts.js +39 -0
- package/dist/lib/prompts.js.map +1 -0
- package/dist/lib/rpc-scripts.d.ts +4 -0
- package/dist/lib/rpc-scripts.d.ts.map +1 -1
- package/dist/lib/rpc-scripts.js +235 -0
- package/dist/lib/rpc-scripts.js.map +1 -1
- package/dist/lib/secrets.d.ts +2 -2
- package/dist/lib/secrets.d.ts.map +1 -1
- package/dist/lib/secrets.js +2 -1
- package/dist/lib/secrets.js.map +1 -1
- package/dist/lib/seed/connection.d.ts +5 -0
- package/dist/lib/seed/connection.d.ts.map +1 -0
- package/dist/lib/seed/connection.js +168 -0
- package/dist/lib/seed/connection.js.map +1 -0
- package/dist/lib/seed/copy.d.ts +4 -0
- package/dist/lib/seed/copy.d.ts.map +1 -0
- package/dist/lib/seed/copy.js +74 -0
- package/dist/lib/seed/copy.js.map +1 -0
- package/dist/lib/seed/dashboard-templates.d.ts +22 -0
- package/dist/lib/seed/dashboard-templates.d.ts.map +1 -0
- package/dist/lib/seed/dashboard-templates.js +268 -0
- package/dist/lib/seed/dashboard-templates.js.map +1 -0
- package/dist/lib/seed/families.d.ts +5 -0
- package/dist/lib/seed/families.d.ts.map +1 -0
- package/dist/lib/seed/families.js +1541 -0
- package/dist/lib/seed/families.js.map +1 -0
- package/dist/lib/seed/index.d.ts +12 -0
- package/dist/lib/seed/index.d.ts.map +1 -0
- package/dist/lib/seed/index.js +327 -0
- package/dist/lib/seed/index.js.map +1 -0
- package/dist/lib/seed/presets.d.ts +5 -0
- package/dist/lib/seed/presets.d.ts.map +1 -0
- package/dist/lib/seed/presets.js +114 -0
- package/dist/lib/seed/presets.js.map +1 -0
- package/dist/lib/seed/schema/columns.d.ts +35 -0
- package/dist/lib/seed/schema/columns.d.ts.map +1 -0
- package/dist/lib/seed/schema/columns.js +497 -0
- package/dist/lib/seed/schema/columns.js.map +1 -0
- package/dist/lib/seed/schema/fingerprint.d.ts +2 -0
- package/dist/lib/seed/schema/fingerprint.d.ts.map +1 -0
- package/dist/lib/seed/schema/fingerprint.js +4 -0
- package/dist/lib/seed/schema/fingerprint.js.map +1 -0
- package/dist/lib/seed/schema/index.d.ts +4 -0
- package/dist/lib/seed/schema/index.d.ts.map +1 -0
- package/dist/lib/seed/schema/index.js +6 -0
- package/dist/lib/seed/schema/index.js.map +1 -0
- package/dist/lib/seed/schema/spec.d.ts +8 -0
- package/dist/lib/seed/schema/spec.d.ts.map +1 -0
- package/dist/lib/seed/schema/spec.js +655 -0
- package/dist/lib/seed/schema/spec.js.map +1 -0
- package/dist/lib/seed/schema/tables.d.ts +132 -0
- package/dist/lib/seed/schema/tables.d.ts.map +1 -0
- package/dist/lib/seed/schema/tables.js +37 -0
- package/dist/lib/seed/schema/tables.js.map +1 -0
- package/dist/lib/seed/store.d.ts +26 -0
- package/dist/lib/seed/store.d.ts.map +1 -0
- package/dist/lib/seed/store.js +111 -0
- package/dist/lib/seed/store.js.map +1 -0
- package/dist/lib/seed/types.d.ts +71 -0
- package/dist/lib/seed/types.d.ts.map +1 -0
- package/dist/lib/seed/types.js +2 -0
- package/dist/lib/seed/types.js.map +1 -0
- package/dist/lib/storage.d.ts +4 -0
- package/dist/lib/storage.d.ts.map +1 -0
- package/dist/lib/storage.js +36 -0
- package/dist/lib/storage.js.map +1 -0
- package/dist/lib/update-steps.d.ts.map +1 -1
- package/dist/lib/update-steps.js +27 -0
- package/dist/lib/update-steps.js.map +1 -1
- package/dist/lib/update.d.ts.map +1 -1
- package/dist/lib/update.js +28 -2
- package/dist/lib/update.js.map +1 -1
- package/dist/lib/version.d.ts +1 -1
- package/dist/lib/version.d.ts.map +1 -1
- package/dist/lib/version.js +1 -1
- package/dist/lib/version.js.map +1 -1
- package/dist/lib/xcc-loadtest-types.d.ts +232 -0
- package/dist/lib/xcc-loadtest-types.d.ts.map +1 -0
- package/dist/lib/xcc-loadtest-types.js +2 -0
- package/dist/lib/xcc-loadtest-types.js.map +1 -0
- package/dist/lib/xcc-loadtest.d.ts +4 -0
- package/dist/lib/xcc-loadtest.d.ts.map +1 -0
- package/dist/lib/xcc-loadtest.js +616 -0
- package/dist/lib/xcc-loadtest.js.map +1 -0
- package/dist/lib/xcc-overlay.d.ts +3 -0
- package/dist/lib/xcc-overlay.d.ts.map +1 -0
- package/dist/lib/xcc-overlay.js +74 -0
- package/dist/lib/xcc-overlay.js.map +1 -0
- package/dist/lib/xcc-scenarios.d.ts +8 -0
- package/dist/lib/xcc-scenarios.d.ts.map +1 -0
- package/dist/lib/xcc-scenarios.js +129 -0
- package/dist/lib/xcc-scenarios.js.map +1 -0
- package/dist/lib/xcc-xml.d.ts +18 -0
- package/dist/lib/xcc-xml.d.ts.map +1 -0
- package/dist/lib/xcc-xml.js +210 -0
- package/dist/lib/xcc-xml.js.map +1 -0
- package/dist/shell/commands/appliance-migrations.d.ts +7 -0
- package/dist/shell/commands/appliance-migrations.d.ts.map +1 -0
- package/dist/shell/commands/appliance-migrations.js +128 -0
- package/dist/shell/commands/appliance-migrations.js.map +1 -0
- package/dist/shell/commands/appliance-performance.d.ts +36 -0
- package/dist/shell/commands/appliance-performance.d.ts.map +1 -0
- package/dist/shell/commands/appliance-performance.js +221 -0
- package/dist/shell/commands/appliance-performance.js.map +1 -0
- package/dist/shell/commands/config.d.ts.map +1 -1
- package/dist/shell/commands/config.js +6 -5
- package/dist/shell/commands/config.js.map +1 -1
- package/dist/shell/commands/connect.d.ts.map +1 -1
- package/dist/shell/commands/connect.js +3 -2
- package/dist/shell/commands/connect.js.map +1 -1
- package/dist/shell/commands/db.d.ts.map +1 -1
- package/dist/shell/commands/db.js +5 -4
- package/dist/shell/commands/db.js.map +1 -1
- package/dist/shell/commands/debug.d.ts.map +1 -1
- package/dist/shell/commands/debug.js +5 -4
- package/dist/shell/commands/debug.js.map +1 -1
- package/dist/shell/commands/diag.js +10 -10
- package/dist/shell/commands/diag.js.map +1 -1
- package/dist/shell/commands/registry.d.ts.map +1 -1
- package/dist/shell/commands/registry.js +74 -0
- package/dist/shell/commands/registry.js.map +1 -1
- package/dist/shell/commands/secrets.d.ts.map +1 -1
- package/dist/shell/commands/secrets.js +2 -1
- package/dist/shell/commands/secrets.js.map +1 -1
- package/dist/shell/commands/seed.d.ts +9 -0
- package/dist/shell/commands/seed.d.ts.map +1 -0
- package/dist/shell/commands/seed.js +197 -0
- package/dist/shell/commands/seed.js.map +1 -0
- package/dist/shell/commands/services.d.ts.map +1 -1
- package/dist/shell/commands/services.js +5 -4
- package/dist/shell/commands/services.js.map +1 -1
- package/dist/shell/commands/test.d.ts.map +1 -1
- package/dist/shell/commands/test.js +3 -2
- package/dist/shell/commands/test.js.map +1 -1
- package/dist/shell/commands/users.d.ts.map +1 -1
- package/dist/shell/commands/users.js +9 -2
- package/dist/shell/commands/users.js.map +1 -1
- package/dist/shell/network-onboarding.d.ts +29 -7
- package/dist/shell/network-onboarding.d.ts.map +1 -1
- package/dist/shell/network-onboarding.js +305 -88
- package/dist/shell/network-onboarding.js.map +1 -1
- package/dist/ui/components/ActionBar.d.ts +13 -0
- package/dist/ui/components/ActionBar.d.ts.map +1 -0
- package/dist/ui/components/ActionBar.js +7 -0
- package/dist/ui/components/ActionBar.js.map +1 -0
- package/dist/ui/components/AppShell.d.ts +6 -1
- package/dist/ui/components/AppShell.d.ts.map +1 -1
- package/dist/ui/components/AppShell.js +32 -10
- package/dist/ui/components/AppShell.js.map +1 -1
- package/dist/ui/components/DashboardBlock.d.ts +11 -0
- package/dist/ui/components/DashboardBlock.d.ts.map +1 -0
- package/dist/ui/components/DashboardBlock.js +6 -0
- package/dist/ui/components/DashboardBlock.js.map +1 -0
- package/dist/ui/components/DataTable.d.ts +6 -1
- package/dist/ui/components/DataTable.d.ts.map +1 -1
- package/dist/ui/components/DataTable.js +71 -7
- package/dist/ui/components/DataTable.js.map +1 -1
- package/dist/ui/components/ErrorBoundary.d.ts +1 -1
- package/dist/ui/components/FieldList.d.ts +24 -0
- package/dist/ui/components/FieldList.d.ts.map +1 -0
- package/dist/ui/components/FieldList.js +67 -0
- package/dist/ui/components/FieldList.js.map +1 -0
- package/dist/ui/components/KeyValue.d.ts +4 -2
- package/dist/ui/components/KeyValue.d.ts.map +1 -1
- package/dist/ui/components/KeyValue.js +4 -2
- package/dist/ui/components/KeyValue.js.map +1 -1
- package/dist/ui/components/KeyboardHint.d.ts +10 -0
- package/dist/ui/components/KeyboardHint.d.ts.map +1 -0
- package/dist/ui/components/KeyboardHint.js +6 -0
- package/dist/ui/components/KeyboardHint.js.map +1 -0
- package/dist/ui/components/MenuList.d.ts +10 -0
- package/dist/ui/components/MenuList.d.ts.map +1 -0
- package/dist/ui/components/MenuList.js +7 -0
- package/dist/ui/components/MenuList.js.map +1 -0
- package/dist/ui/components/MetricsFooter.d.ts +10 -7
- package/dist/ui/components/MetricsFooter.d.ts.map +1 -1
- package/dist/ui/components/MetricsFooter.js +16 -3
- package/dist/ui/components/MetricsFooter.js.map +1 -1
- package/dist/ui/components/PaneSection.d.ts +9 -0
- package/dist/ui/components/PaneSection.d.ts.map +1 -0
- package/dist/ui/components/PaneSection.js +6 -0
- package/dist/ui/components/PaneSection.js.map +1 -0
- package/dist/ui/components/PanelState.d.ts +8 -0
- package/dist/ui/components/PanelState.d.ts.map +1 -0
- package/dist/ui/components/PanelState.js +7 -0
- package/dist/ui/components/PanelState.js.map +1 -0
- package/dist/ui/components/ScrollViewport.d.ts +16 -0
- package/dist/ui/components/ScrollViewport.d.ts.map +1 -0
- package/dist/ui/components/ScrollViewport.js +54 -0
- package/dist/ui/components/ScrollViewport.js.map +1 -0
- package/dist/ui/components/Section.js +1 -1
- package/dist/ui/components/Section.js.map +1 -1
- package/dist/ui/components/SelectMenu.d.ts.map +1 -1
- package/dist/ui/components/SelectMenu.js +3 -3
- package/dist/ui/components/SelectMenu.js.map +1 -1
- package/dist/ui/components/ShellOutput.d.ts +2 -1
- package/dist/ui/components/ShellOutput.d.ts.map +1 -1
- package/dist/ui/components/ShellOutput.js +6 -2
- package/dist/ui/components/ShellOutput.js.map +1 -1
- package/dist/ui/components/SplitPane.d.ts +18 -0
- package/dist/ui/components/SplitPane.d.ts.map +1 -0
- package/dist/ui/components/SplitPane.js +9 -0
- package/dist/ui/components/SplitPane.js.map +1 -0
- package/dist/ui/components/StatusList.d.ts +18 -0
- package/dist/ui/components/StatusList.d.ts.map +1 -0
- package/dist/ui/components/StatusList.js +13 -0
- package/dist/ui/components/StatusList.js.map +1 -0
- package/dist/ui/components/SummaryStrip.d.ts +9 -0
- package/dist/ui/components/SummaryStrip.d.ts.map +1 -0
- package/dist/ui/components/SummaryStrip.js +6 -0
- package/dist/ui/components/SummaryStrip.js.map +1 -0
- package/dist/ui/components/app-shell-viewport.d.ts +7 -0
- package/dist/ui/components/app-shell-viewport.d.ts.map +1 -0
- package/dist/ui/components/app-shell-viewport.js +6 -0
- package/dist/ui/components/app-shell-viewport.js.map +1 -0
- package/dist/ui/components/index.d.ts +14 -0
- package/dist/ui/components/index.d.ts.map +1 -1
- package/dist/ui/components/index.js +12 -0
- package/dist/ui/components/index.js.map +1 -1
- package/dist/ui/context/MetricsContext.d.ts.map +1 -1
- package/dist/ui/context/MetricsContext.js +15 -12
- package/dist/ui/context/MetricsContext.js.map +1 -1
- package/dist/ui/hooks/index.d.ts +9 -1
- package/dist/ui/hooks/index.d.ts.map +1 -1
- package/dist/ui/hooks/index.js +7 -0
- package/dist/ui/hooks/index.js.map +1 -1
- package/dist/ui/hooks/useAsyncTask.d.ts +7 -1
- package/dist/ui/hooks/useAsyncTask.d.ts.map +1 -1
- package/dist/ui/hooks/useAsyncTask.js +30 -6
- package/dist/ui/hooks/useAsyncTask.js.map +1 -1
- package/dist/ui/hooks/useBoundedCursor.d.ts +7 -0
- package/dist/ui/hooks/useBoundedCursor.d.ts.map +1 -0
- package/dist/ui/hooks/useBoundedCursor.js +19 -0
- package/dist/ui/hooks/useBoundedCursor.js.map +1 -0
- package/dist/ui/hooks/useConfirmBackNav.d.ts +7 -0
- package/dist/ui/hooks/useConfirmBackNav.d.ts.map +1 -0
- package/dist/ui/hooks/useConfirmBackNav.js +10 -0
- package/dist/ui/hooks/useConfirmBackNav.js.map +1 -0
- package/dist/ui/hooks/useDismissKeys.d.ts +10 -0
- package/dist/ui/hooks/useDismissKeys.d.ts.map +1 -0
- package/dist/ui/hooks/useDismissKeys.js +17 -0
- package/dist/ui/hooks/useDismissKeys.js.map +1 -0
- package/dist/ui/hooks/useListCursor.d.ts +7 -0
- package/dist/ui/hooks/useListCursor.d.ts.map +1 -0
- package/dist/ui/hooks/useListCursor.js +29 -0
- package/dist/ui/hooks/useListCursor.js.map +1 -0
- package/dist/ui/hooks/useTwoPaneCursor.d.ts +12 -0
- package/dist/ui/hooks/useTwoPaneCursor.d.ts.map +1 -0
- package/dist/ui/hooks/useTwoPaneCursor.js +36 -0
- package/dist/ui/hooks/useTwoPaneCursor.js.map +1 -0
- package/dist/ui/hooks/useXccBackendOverlay.d.ts +9 -0
- package/dist/ui/hooks/useXccBackendOverlay.d.ts.map +1 -0
- package/dist/ui/hooks/useXccBackendOverlay.js +14 -0
- package/dist/ui/hooks/useXccBackendOverlay.js.map +1 -0
- package/dist/ui/hooks/useXccLoadTest.d.ts +11 -0
- package/dist/ui/hooks/useXccLoadTest.d.ts.map +1 -0
- package/dist/ui/hooks/useXccLoadTest.js +37 -0
- package/dist/ui/hooks/useXccLoadTest.js.map +1 -0
- package/dist/ui/palette.d.ts +23 -0
- package/dist/ui/palette.d.ts.map +1 -0
- package/dist/ui/palette.js +22 -0
- package/dist/ui/palette.js.map +1 -0
- package/dist/ui/views/DbHealthView.js +4 -4
- package/dist/ui/views/DbHealthView.js.map +1 -1
- package/dist/ui/views/DbSizeView.d.ts.map +1 -1
- package/dist/ui/views/DbSizeView.js +2 -2
- package/dist/ui/views/DbSizeView.js.map +1 -1
- package/dist/ui/views/DbTablesView.d.ts.map +1 -1
- package/dist/ui/views/DbTablesView.js +2 -2
- package/dist/ui/views/DbTablesView.js.map +1 -1
- package/dist/ui/views/DiagDatabaseView.d.ts.map +1 -1
- package/dist/ui/views/DiagDatabaseView.js +4 -3
- package/dist/ui/views/DiagDatabaseView.js.map +1 -1
- package/dist/ui/views/DiagNetworkView.js +2 -2
- package/dist/ui/views/DiagNetworkView.js.map +1 -1
- package/dist/ui/views/DiagServiceView.js +1 -1
- package/dist/ui/views/DiagServiceView.js.map +1 -1
- package/dist/ui/views/DockerPruneView.d.ts.map +1 -1
- package/dist/ui/views/DockerPruneView.js +4 -8
- package/dist/ui/views/DockerPruneView.js.map +1 -1
- package/dist/ui/views/K8sDeployView.d.ts.map +1 -1
- package/dist/ui/views/K8sDeployView.js +5 -5
- package/dist/ui/views/K8sDeployView.js.map +1 -1
- package/dist/ui/views/K8sServicesView.d.ts.map +1 -1
- package/dist/ui/views/K8sServicesView.js +6 -11
- package/dist/ui/views/K8sServicesView.js.map +1 -1
- package/dist/ui/views/K8sStatusView.d.ts.map +1 -1
- package/dist/ui/views/K8sStatusView.js +14 -19
- package/dist/ui/views/K8sStatusView.js.map +1 -1
- package/dist/ui/views/LoadTestConfigView.d.ts.map +1 -1
- package/dist/ui/views/LoadTestConfigView.js +45 -43
- package/dist/ui/views/LoadTestConfigView.js.map +1 -1
- package/dist/ui/views/LoadTestSummaryView.d.ts.map +1 -1
- package/dist/ui/views/LoadTestSummaryView.js +7 -2
- package/dist/ui/views/LoadTestSummaryView.js.map +1 -1
- package/dist/ui/views/MainMenu.d.ts.map +1 -1
- package/dist/ui/views/MainMenu.js +265 -55
- package/dist/ui/views/MainMenu.js.map +1 -1
- package/dist/ui/views/MigrateHistoryView.d.ts.map +1 -1
- package/dist/ui/views/MigrateHistoryView.js +11 -2
- package/dist/ui/views/MigrateHistoryView.js.map +1 -1
- package/dist/ui/views/MigrateRollbackView.d.ts.map +1 -1
- package/dist/ui/views/MigrateRollbackView.js +4 -8
- package/dist/ui/views/MigrateRollbackView.js.map +1 -1
- package/dist/ui/views/MigrateRunView.d.ts.map +1 -1
- package/dist/ui/views/MigrateRunView.js +4 -8
- package/dist/ui/views/MigrateRunView.js.map +1 -1
- package/dist/ui/views/MigrateStatusView.js +1 -1
- package/dist/ui/views/MigrateStatusView.js.map +1 -1
- package/dist/ui/views/MigrateWatchView.js +1 -1
- package/dist/ui/views/MigrateWatchView.js.map +1 -1
- package/dist/ui/views/OfflineApplyView.d.ts.map +1 -1
- package/dist/ui/views/OfflineApplyView.js +17 -7
- package/dist/ui/views/OfflineApplyView.js.map +1 -1
- package/dist/ui/views/OfflineDownloadView.d.ts.map +1 -1
- package/dist/ui/views/OfflineDownloadView.js +17 -7
- package/dist/ui/views/OfflineDownloadView.js.map +1 -1
- package/dist/ui/views/OfflineFetchView.d.ts.map +1 -1
- package/dist/ui/views/OfflineFetchView.js +17 -7
- package/dist/ui/views/OfflineFetchView.js.map +1 -1
- package/dist/ui/views/OfflineInspectView.d.ts.map +1 -1
- package/dist/ui/views/OfflineInspectView.js +17 -7
- package/dist/ui/views/OfflineInspectView.js.map +1 -1
- package/dist/ui/views/OsUpdatesEnableView.js +4 -4
- package/dist/ui/views/OsUpdatesEnableView.js.map +1 -1
- package/dist/ui/views/OsUpdatesLogView.js +1 -1
- package/dist/ui/views/OsUpdatesLogView.js.map +1 -1
- package/dist/ui/views/OsUpdatesStatusView.d.ts.map +1 -1
- package/dist/ui/views/OsUpdatesStatusView.js +12 -12
- package/dist/ui/views/OsUpdatesStatusView.js.map +1 -1
- package/dist/ui/views/PowerActionView.d.ts.map +1 -1
- package/dist/ui/views/PowerActionView.js +3 -8
- package/dist/ui/views/PowerActionView.js.map +1 -1
- package/dist/ui/views/SecretsResetPasswordView.d.ts.map +1 -1
- package/dist/ui/views/SecretsResetPasswordView.js +23 -7
- package/dist/ui/views/SecretsResetPasswordView.js.map +1 -1
- package/dist/ui/views/SecretsSetupView.d.ts.map +1 -1
- package/dist/ui/views/SecretsSetupView.js +39 -22
- package/dist/ui/views/SecretsSetupView.js.map +1 -1
- package/dist/ui/views/ServiceLogsView.d.ts.map +1 -1
- package/dist/ui/views/ServiceLogsView.js +9 -9
- package/dist/ui/views/ServiceLogsView.js.map +1 -1
- package/dist/ui/views/ServicesView.d.ts.map +1 -1
- package/dist/ui/views/ServicesView.js +51 -28
- package/dist/ui/views/ServicesView.js.map +1 -1
- package/dist/ui/views/SettingsView.d.ts.map +1 -1
- package/dist/ui/views/SettingsView.js +5 -4
- package/dist/ui/views/SettingsView.js.map +1 -1
- package/dist/ui/views/SetupWizardView.d.ts.map +1 -1
- package/dist/ui/views/SetupWizardView.js +37 -32
- package/dist/ui/views/SetupWizardView.js.map +1 -1
- package/dist/ui/views/StatusView.d.ts.map +1 -1
- package/dist/ui/views/StatusView.js +44 -31
- package/dist/ui/views/StatusView.js.map +1 -1
- package/dist/ui/views/UpdateView.d.ts.map +1 -1
- package/dist/ui/views/UpdateView.js +28 -14
- package/dist/ui/views/UpdateView.js.map +1 -1
- package/dist/ui/views/UserResetPasswordView.d.ts.map +1 -1
- package/dist/ui/views/UserResetPasswordView.js +26 -8
- package/dist/ui/views/UserResetPasswordView.js.map +1 -1
- package/dist/ui/views/XccLoadTestConfigView.d.ts +29 -0
- package/dist/ui/views/XccLoadTestConfigView.d.ts.map +1 -0
- package/dist/ui/views/XccLoadTestConfigView.js +210 -0
- package/dist/ui/views/XccLoadTestConfigView.js.map +1 -0
- package/dist/ui/views/XccLoadTestRunView.d.ts +9 -0
- package/dist/ui/views/XccLoadTestRunView.d.ts.map +1 -0
- package/dist/ui/views/XccLoadTestRunView.js +154 -0
- package/dist/ui/views/XccLoadTestRunView.js.map +1 -0
- package/dist/ui/views/XccLoadTestSummaryView.d.ts +9 -0
- package/dist/ui/views/XccLoadTestSummaryView.d.ts.map +1 -0
- package/dist/ui/views/XccLoadTestSummaryView.js +63 -0
- package/dist/ui/views/XccLoadTestSummaryView.js.map +1 -0
- package/dist/ui/views/XccLoadTestView.d.ts +8 -0
- package/dist/ui/views/XccLoadTestView.d.ts.map +1 -0
- package/dist/ui/views/XccLoadTestView.js +40 -0
- package/dist/ui/views/XccLoadTestView.js.map +1 -0
- package/package.json +6 -1
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Migration 011: Cap Docker daemon memory at 90% of system RAM.
|
|
3
|
+
*
|
|
4
|
+
* On a single-purpose Docker Compose appliance, containers can consume
|
|
5
|
+
* all available RAM, starving the OS (kernel, systemd, sshd, NM) and
|
|
6
|
+
* triggering the OOM killer. This migration creates a systemd drop-in
|
|
7
|
+
* that limits the Docker daemon + all containers to 90% of total RAM,
|
|
8
|
+
* guaranteeing 10% for the OS.
|
|
9
|
+
*
|
|
10
|
+
* Also updates existing 80% limit to 90% (previous default was too conservative).
|
|
11
|
+
*/
|
|
12
|
+
import { existsSync, writeFileSync, readFileSync } from 'node:fs';
|
|
13
|
+
import { spawnSync } from 'node:child_process';
|
|
14
|
+
const DROPIN_DIR = '/etc/systemd/system/docker.service.d';
|
|
15
|
+
const DROPIN_FILE = `${DROPIN_DIR}/memory-limit.conf`;
|
|
16
|
+
export async function migrateDockerMemoryLimit() {
|
|
17
|
+
// Skip if already at 90%
|
|
18
|
+
if (existsSync(DROPIN_FILE)) {
|
|
19
|
+
const content = readFileSync(DROPIN_FILE, 'utf-8');
|
|
20
|
+
if (content.includes('MemoryMax=90%')) {
|
|
21
|
+
return false;
|
|
22
|
+
}
|
|
23
|
+
// Exists but wrong value (80%) — update to 90%
|
|
24
|
+
}
|
|
25
|
+
const content = `[Service]\nMemoryMax=90%\n`;
|
|
26
|
+
const tmp = `/tmp/ct-docker-memory-${Date.now()}`;
|
|
27
|
+
writeFileSync(tmp, content);
|
|
28
|
+
spawnSync('sudo', ['mkdir', '-p', DROPIN_DIR], { stdio: 'pipe' });
|
|
29
|
+
spawnSync('sudo', ['cp', tmp, DROPIN_FILE], { stdio: 'pipe' });
|
|
30
|
+
try {
|
|
31
|
+
require('node:fs').unlinkSync(tmp);
|
|
32
|
+
}
|
|
33
|
+
catch { /* ignore */ }
|
|
34
|
+
const reload = spawnSync('sudo', ['systemctl', 'daemon-reload'], { stdio: 'pipe' });
|
|
35
|
+
if (reload.status !== 0) {
|
|
36
|
+
throw new Error('systemctl daemon-reload failed');
|
|
37
|
+
}
|
|
38
|
+
// Restart Docker to apply the memory limit
|
|
39
|
+
const restart = spawnSync('sudo', ['systemctl', 'restart', 'docker'], { stdio: 'pipe' });
|
|
40
|
+
if (restart.status !== 0) {
|
|
41
|
+
throw new Error('systemctl restart docker failed');
|
|
42
|
+
}
|
|
43
|
+
return true;
|
|
44
|
+
}
|
|
45
|
+
//# sourceMappingURL=migration-011-docker-memory-limit.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"migration-011-docker-memory-limit.js","sourceRoot":"","sources":["../../src/lib/migration-011-docker-memory-limit.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,EAAE,UAAU,EAAa,aAAa,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAC7E,OAAO,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAE/C,MAAM,UAAU,GAAG,sCAAsC,CAAC;AAC1D,MAAM,WAAW,GAAG,GAAG,UAAU,oBAAoB,CAAC;AAEtD,MAAM,CAAC,KAAK,UAAU,wBAAwB;IAC5C,yBAAyB;IACzB,IAAI,UAAU,CAAC,WAAW,CAAC,EAAE,CAAC;QAC5B,MAAM,OAAO,GAAG,YAAY,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC;QACnD,IAAI,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAC,EAAE,CAAC;YACtC,OAAO,KAAK,CAAC;QACf,CAAC;QACD,+CAA+C;IACjD,CAAC;IAED,MAAM,OAAO,GAAG,4BAA4B,CAAC;IAC7C,MAAM,GAAG,GAAG,yBAAyB,IAAI,CAAC,GAAG,EAAE,EAAE,CAAC;IAClD,aAAa,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC;IAE5B,SAAS,CAAC,MAAM,EAAE,CAAC,OAAO,EAAE,IAAI,EAAE,UAAU,CAAC,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC,CAAC;IAClE,SAAS,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,GAAG,EAAE,WAAW,CAAC,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC,CAAC;IAC/D,IAAI,CAAC;QAAC,OAAO,CAAC,SAAS,CAAC,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC;IAAC,CAAC;IAAC,MAAM,CAAC,CAAC,YAAY,CAAC,CAAC;IAElE,MAAM,MAAM,GAAG,SAAS,CAAC,MAAM,EAAE,CAAC,WAAW,EAAE,eAAe,CAAC,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC,CAAC;IACpF,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACxB,MAAM,IAAI,KAAK,CAAC,gCAAgC,CAAC,CAAC;IACpD,CAAC;IAED,2CAA2C;IAC3C,MAAM,OAAO,GAAG,SAAS,CAAC,MAAM,EAAE,CAAC,WAAW,EAAE,SAAS,EAAE,QAAQ,CAAC,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC,CAAC;IACzF,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACzB,MAAM,IAAI,KAAK,CAAC,iCAAiC,CAAC,CAAC;IACrD,CAAC;IAED,OAAO,IAAI,CAAC;AACd,CAAC"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Migration 012: Set default DB pool sizes if no profile is configured.
|
|
3
|
+
*
|
|
4
|
+
* Existing appliances run with 95 total DB connections (45+18+18+14)
|
|
5
|
+
* which is excessive for 8GB appliances and wastes memory. If no
|
|
6
|
+
* PG_PROFILE is set in .env, apply the 'small' profile defaults:
|
|
7
|
+
* 44 total connections (20+8+8+8).
|
|
8
|
+
*
|
|
9
|
+
* Does NOT override if a profile is already set — respects user choice.
|
|
10
|
+
*/
|
|
11
|
+
export declare function migrateDbPoolSizes(): Promise<boolean>;
|
|
12
|
+
//# sourceMappingURL=migration-012-db-pool-sizes.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"migration-012-db-pool-sizes.d.ts","sourceRoot":"","sources":["../../src/lib/migration-012-db-pool-sizes.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAgBH,wBAAsB,kBAAkB,IAAI,OAAO,CAAC,OAAO,CAAC,CA2C3D"}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Migration 012: Set default DB pool sizes if no profile is configured.
|
|
3
|
+
*
|
|
4
|
+
* Existing appliances run with 95 total DB connections (45+18+18+14)
|
|
5
|
+
* which is excessive for 8GB appliances and wastes memory. If no
|
|
6
|
+
* PG_PROFILE is set in .env, apply the 'small' profile defaults:
|
|
7
|
+
* 44 total connections (20+8+8+8).
|
|
8
|
+
*
|
|
9
|
+
* Does NOT override if a profile is already set — respects user choice.
|
|
10
|
+
*/
|
|
11
|
+
import { existsSync, readFileSync } from 'node:fs';
|
|
12
|
+
import { spawnSync } from 'node:child_process';
|
|
13
|
+
import { homedir } from 'node:os';
|
|
14
|
+
import { join } from 'node:path';
|
|
15
|
+
// Detect install dir (same logic as ct-cli paths.ts)
|
|
16
|
+
function getInstallDir() {
|
|
17
|
+
const known = ['/home/calltelemetry', '/opt/calltelemetry'];
|
|
18
|
+
for (const p of known) {
|
|
19
|
+
if (existsSync(join(p, 'docker-compose.yml')))
|
|
20
|
+
return p;
|
|
21
|
+
}
|
|
22
|
+
return homedir();
|
|
23
|
+
}
|
|
24
|
+
export async function migrateDbPoolSizes() {
|
|
25
|
+
const installDir = getInstallDir();
|
|
26
|
+
const envFile = join(installDir, '.env');
|
|
27
|
+
// If PG_PROFILE is already set, user has chosen a profile — don't override
|
|
28
|
+
if (existsSync(envFile)) {
|
|
29
|
+
const content = readFileSync(envFile, 'utf-8');
|
|
30
|
+
if (content.includes('PG_PROFILE=')) {
|
|
31
|
+
return false; // Already configured
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
// No profile set — apply small defaults
|
|
35
|
+
const settings = [
|
|
36
|
+
'PG_PROFILE=small',
|
|
37
|
+
'PG_SHM_SIZE=1gb',
|
|
38
|
+
'PG_SHARED_BUFFERS=512MB',
|
|
39
|
+
'PG_EFFECTIVE_CACHE_SIZE=1536MB',
|
|
40
|
+
'PG_WORK_MEM=8MB',
|
|
41
|
+
'PG_MAINTENANCE_WORK_MEM=128MB',
|
|
42
|
+
'PG_MAX_CONNECTIONS=60',
|
|
43
|
+
'DB_POOL_SIZE=20',
|
|
44
|
+
'DB_BACKGROUND_POOL_SIZE=8',
|
|
45
|
+
'DB_DISCOVERY_POOL_SIZE=8',
|
|
46
|
+
'DB_OBAN_POOL_SIZE=8',
|
|
47
|
+
];
|
|
48
|
+
// Append to .env (or create it)
|
|
49
|
+
const block = '\n# PostgreSQL profile: small (auto-applied by migration 012)\n' +
|
|
50
|
+
settings.join('\n') + '\n';
|
|
51
|
+
const tmp = `/tmp/ct-env-append-${Date.now()}`;
|
|
52
|
+
require('node:fs').writeFileSync(tmp, block);
|
|
53
|
+
// Append via sudo
|
|
54
|
+
const result = spawnSync('sudo', ['bash', '-c', `cat ${tmp} >> ${envFile}`], { stdio: 'pipe' });
|
|
55
|
+
try {
|
|
56
|
+
require('node:fs').unlinkSync(tmp);
|
|
57
|
+
}
|
|
58
|
+
catch { /* ignore */ }
|
|
59
|
+
if (result.status !== 0) {
|
|
60
|
+
throw new Error(`Failed to write pool sizes to ${envFile}`);
|
|
61
|
+
}
|
|
62
|
+
return true;
|
|
63
|
+
}
|
|
64
|
+
//# sourceMappingURL=migration-012-db-pool-sizes.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"migration-012-db-pool-sizes.js","sourceRoot":"","sources":["../../src/lib/migration-012-db-pool-sizes.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACnD,OAAO,EAAE,SAAS,EAAY,MAAM,oBAAoB,CAAC;AACzD,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAClC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAEjC,qDAAqD;AACrD,SAAS,aAAa;IACpB,MAAM,KAAK,GAAG,CAAC,qBAAqB,EAAE,oBAAoB,CAAC,CAAC;IAC5D,KAAK,MAAM,CAAC,IAAI,KAAK,EAAE,CAAC;QACtB,IAAI,UAAU,CAAC,IAAI,CAAC,CAAC,EAAE,oBAAoB,CAAC,CAAC;YAAE,OAAO,CAAC,CAAC;IAC1D,CAAC;IACD,OAAO,OAAO,EAAE,CAAC;AACnB,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,kBAAkB;IACtC,MAAM,UAAU,GAAG,aAAa,EAAE,CAAC;IACnC,MAAM,OAAO,GAAG,IAAI,CAAC,UAAU,EAAE,MAAM,CAAC,CAAC;IAEzC,2EAA2E;IAC3E,IAAI,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC;QACxB,MAAM,OAAO,GAAG,YAAY,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;QAC/C,IAAI,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAC,EAAE,CAAC;YACpC,OAAO,KAAK,CAAC,CAAC,qBAAqB;QACrC,CAAC;IACH,CAAC;IAED,wCAAwC;IACxC,MAAM,QAAQ,GAAG;QACf,kBAAkB;QAClB,iBAAiB;QACjB,yBAAyB;QACzB,gCAAgC;QAChC,iBAAiB;QACjB,+BAA+B;QAC/B,uBAAuB;QACvB,iBAAiB;QACjB,2BAA2B;QAC3B,0BAA0B;QAC1B,qBAAqB;KACtB,CAAC;IAEF,gCAAgC;IAChC,MAAM,KAAK,GAAG,iEAAiE;QAC7E,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;IAE7B,MAAM,GAAG,GAAG,sBAAsB,IAAI,CAAC,GAAG,EAAE,EAAE,CAAC;IAC/C,OAAO,CAAC,SAAS,CAAC,CAAC,aAAa,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;IAE7C,kBAAkB;IAClB,MAAM,MAAM,GAAG,SAAS,CAAC,MAAM,EAAE,CAAC,MAAM,EAAE,IAAI,EAAE,OAAO,GAAG,OAAO,OAAO,EAAE,CAAC,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC,CAAC;IAChG,IAAI,CAAC;QAAC,OAAO,CAAC,SAAS,CAAC,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC;IAAC,CAAC;IAAC,MAAM,CAAC,CAAC,YAAY,CAAC,CAAC;IAElE,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACxB,MAAM,IAAI,KAAK,CAAC,iCAAiC,OAAO,EAAE,CAAC,CAAC;IAC9D,CAAC;IAED,OAAO,IAAI,CAAC;AACd,CAAC"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Migration 013: Generate GRAFANA_PASSWORD for deterministic Grafana auth.
|
|
3
|
+
*
|
|
4
|
+
* The BootProvisioner (Elixir) uses GRAFANA_PASSWORD for basic auth to push
|
|
5
|
+
* dashboards to Grafana. Both the web container and grafana container read
|
|
6
|
+
* this from .env. If it's missing, dashboard provisioning fails.
|
|
7
|
+
*
|
|
8
|
+
* This migration:
|
|
9
|
+
* 1. Generates a random 32-char hex password
|
|
10
|
+
* 2. Writes GRAFANA_PASSWORD=<password> to .env
|
|
11
|
+
* 3. Removes stale GRAFANA_TOKEN if present
|
|
12
|
+
* 4. Resets Grafana admin password via grafana-cli (for existing volumes)
|
|
13
|
+
*/
|
|
14
|
+
export declare function migrateGrafanaPassword(): Promise<boolean>;
|
|
15
|
+
//# sourceMappingURL=migration-013-grafana-password.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"migration-013-grafana-password.d.ts","sourceRoot":"","sources":["../../src/lib/migration-013-grafana-password.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAgBH,wBAAsB,sBAAsB,IAAI,OAAO,CAAC,OAAO,CAAC,CAoE/D"}
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Migration 013: Generate GRAFANA_PASSWORD for deterministic Grafana auth.
|
|
3
|
+
*
|
|
4
|
+
* The BootProvisioner (Elixir) uses GRAFANA_PASSWORD for basic auth to push
|
|
5
|
+
* dashboards to Grafana. Both the web container and grafana container read
|
|
6
|
+
* this from .env. If it's missing, dashboard provisioning fails.
|
|
7
|
+
*
|
|
8
|
+
* This migration:
|
|
9
|
+
* 1. Generates a random 32-char hex password
|
|
10
|
+
* 2. Writes GRAFANA_PASSWORD=<password> to .env
|
|
11
|
+
* 3. Removes stale GRAFANA_TOKEN if present
|
|
12
|
+
* 4. Resets Grafana admin password via grafana-cli (for existing volumes)
|
|
13
|
+
*/
|
|
14
|
+
import { existsSync, readFileSync } from 'node:fs';
|
|
15
|
+
import { randomBytes } from 'node:crypto';
|
|
16
|
+
import { spawnSync } from 'node:child_process';
|
|
17
|
+
import { homedir } from 'node:os';
|
|
18
|
+
import { join } from 'node:path';
|
|
19
|
+
function getInstallDir() {
|
|
20
|
+
const known = ['/home/calltelemetry', '/opt/calltelemetry'];
|
|
21
|
+
for (const p of known) {
|
|
22
|
+
if (existsSync(join(p, 'docker-compose.yml')))
|
|
23
|
+
return p;
|
|
24
|
+
}
|
|
25
|
+
return homedir();
|
|
26
|
+
}
|
|
27
|
+
export async function migrateGrafanaPassword() {
|
|
28
|
+
const installDir = getInstallDir();
|
|
29
|
+
const envFile = join(installDir, '.env');
|
|
30
|
+
// If GRAFANA_PASSWORD is already set, nothing to do
|
|
31
|
+
if (existsSync(envFile)) {
|
|
32
|
+
const content = readFileSync(envFile, 'utf-8');
|
|
33
|
+
if (content.includes('GRAFANA_PASSWORD=')) {
|
|
34
|
+
return false; // Already configured
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
// Generate random password
|
|
38
|
+
const password = randomBytes(16).toString('hex');
|
|
39
|
+
// Build .env block
|
|
40
|
+
const block = '\n# Grafana auth password (auto-generated by migration 013)\n' +
|
|
41
|
+
`GRAFANA_PASSWORD=${password}\n`;
|
|
42
|
+
const tmp = `/tmp/ct-grafana-pw-${Date.now()}`;
|
|
43
|
+
require('node:fs').writeFileSync(tmp, block);
|
|
44
|
+
// Append to .env
|
|
45
|
+
const appendResult = spawnSync('sudo', ['bash', '-c', `cat ${tmp} >> ${envFile}`], {
|
|
46
|
+
stdio: 'pipe',
|
|
47
|
+
});
|
|
48
|
+
try {
|
|
49
|
+
require('node:fs').unlinkSync(tmp);
|
|
50
|
+
}
|
|
51
|
+
catch {
|
|
52
|
+
/* ignore */
|
|
53
|
+
}
|
|
54
|
+
if (appendResult.status !== 0) {
|
|
55
|
+
throw new Error(`Failed to write GRAFANA_PASSWORD to ${envFile}`);
|
|
56
|
+
}
|
|
57
|
+
// Remove stale GRAFANA_TOKEN lines from .env (replaced by GRAFANA_PASSWORD)
|
|
58
|
+
if (existsSync(envFile)) {
|
|
59
|
+
const content = readFileSync(envFile, 'utf-8');
|
|
60
|
+
if (content.includes('GRAFANA_TOKEN=')) {
|
|
61
|
+
spawnSync('sudo', ['sed', '-i', '/^GRAFANA_TOKEN=/d', envFile], { stdio: 'pipe' });
|
|
62
|
+
spawnSync('sudo', ['sed', '-i', '/^# .*GRAFANA_TOKEN/d', envFile], { stdio: 'pipe' });
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
// Reset Grafana admin password for existing volumes.
|
|
66
|
+
// grafana-cli stores the new password in the SQLite DB, overriding whatever
|
|
67
|
+
// was set previously (even if changed via the UI).
|
|
68
|
+
const resetResult = spawnSync('docker', ['compose', 'exec', '-T', 'grafana', 'grafana-cli', 'admin', 'reset-admin-password', password], { cwd: installDir, stdio: 'pipe', timeout: 30_000 });
|
|
69
|
+
if (resetResult.status !== 0) {
|
|
70
|
+
// Grafana container might not be running — that's OK.
|
|
71
|
+
// On next start, GF_SECURITY_ADMIN_PASSWORD from .env will be used
|
|
72
|
+
// (only applies on first start of a fresh volume, but that covers new installs).
|
|
73
|
+
const stderr = resetResult.stderr?.toString() ?? '';
|
|
74
|
+
if (!stderr.includes('No such container') && !stderr.includes('not running')) {
|
|
75
|
+
console.warn(`[migration-013] grafana-cli reset failed (non-fatal): ${stderr.slice(0, 200)}`);
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
return true;
|
|
79
|
+
}
|
|
80
|
+
//# sourceMappingURL=migration-013-grafana-password.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"migration-013-grafana-password.js","sourceRoot":"","sources":["../../src/lib/migration-013-grafana-password.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Migration 014: Remove firewall-backend from daemon.json on Docker < 29.
|
|
3
|
+
*
|
|
4
|
+
* The `firewall-backend` option was added in Docker 29.0.0. Appliances that
|
|
5
|
+
* were provisioned with a daemon.json written for Docker 29 but then received
|
|
6
|
+
* Docker 28.x (e.g. dnf resolving to an older version) will fail to start
|
|
7
|
+
* dockerd with:
|
|
8
|
+
*
|
|
9
|
+
* unable to configure the Docker daemon with file /etc/docker/daemon.json:
|
|
10
|
+
* the following directives don't match any configuration option: firewall-backend
|
|
11
|
+
*
|
|
12
|
+
* This migration detects that condition and removes the unsupported key so
|
|
13
|
+
* Docker can start. The option is left in place on Docker 29+ where it is valid.
|
|
14
|
+
*/
|
|
15
|
+
export declare function migrateDockerFirewallBackend(): Promise<boolean>;
|
|
16
|
+
//# sourceMappingURL=migration-014-docker-firewall-backend.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"migration-014-docker-firewall-backend.d.ts","sourceRoot":"","sources":["../../src/lib/migration-014-docker-firewall-backend.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAkBH,wBAAsB,4BAA4B,IAAI,OAAO,CAAC,OAAO,CAAC,CAgDrE"}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Migration 014: Remove firewall-backend from daemon.json on Docker < 29.
|
|
3
|
+
*
|
|
4
|
+
* The `firewall-backend` option was added in Docker 29.0.0. Appliances that
|
|
5
|
+
* were provisioned with a daemon.json written for Docker 29 but then received
|
|
6
|
+
* Docker 28.x (e.g. dnf resolving to an older version) will fail to start
|
|
7
|
+
* dockerd with:
|
|
8
|
+
*
|
|
9
|
+
* unable to configure the Docker daemon with file /etc/docker/daemon.json:
|
|
10
|
+
* the following directives don't match any configuration option: firewall-backend
|
|
11
|
+
*
|
|
12
|
+
* This migration detects that condition and removes the unsupported key so
|
|
13
|
+
* Docker can start. The option is left in place on Docker 29+ where it is valid.
|
|
14
|
+
*/
|
|
15
|
+
import { existsSync, readFileSync, writeFileSync, unlinkSync } from 'node:fs';
|
|
16
|
+
import { spawnSync } from 'node:child_process';
|
|
17
|
+
const DAEMON_JSON = '/etc/docker/daemon.json';
|
|
18
|
+
function getDockerMajorVersion() {
|
|
19
|
+
const result = spawnSync('docker', ['version', '--format', '{{.Server.Version}}'], {
|
|
20
|
+
stdio: 'pipe',
|
|
21
|
+
timeout: 10_000,
|
|
22
|
+
});
|
|
23
|
+
if (result.status !== 0)
|
|
24
|
+
return 0;
|
|
25
|
+
const version = result.stdout?.toString().trim() ?? '';
|
|
26
|
+
const major = parseInt(version.split('.')[0] ?? '0', 10);
|
|
27
|
+
return isNaN(major) ? 0 : major;
|
|
28
|
+
}
|
|
29
|
+
export async function migrateDockerFirewallBackend() {
|
|
30
|
+
// Only relevant if daemon.json exists and contains firewall-backend
|
|
31
|
+
if (!existsSync(DAEMON_JSON))
|
|
32
|
+
return false;
|
|
33
|
+
const raw = readFileSync(DAEMON_JSON, 'utf-8');
|
|
34
|
+
if (!raw.includes('"firewall-backend"'))
|
|
35
|
+
return false;
|
|
36
|
+
// firewall-backend is valid on Docker 29+ — leave it alone
|
|
37
|
+
const major = getDockerMajorVersion();
|
|
38
|
+
if (major >= 29)
|
|
39
|
+
return false;
|
|
40
|
+
// Docker < 29 (or version undetectable): remove the key
|
|
41
|
+
let config;
|
|
42
|
+
try {
|
|
43
|
+
config = JSON.parse(raw);
|
|
44
|
+
}
|
|
45
|
+
catch {
|
|
46
|
+
throw new Error(`Cannot parse ${DAEMON_JSON}: invalid JSON`);
|
|
47
|
+
}
|
|
48
|
+
delete config['firewall-backend'];
|
|
49
|
+
const updated = JSON.stringify(config, null, 2) + '\n';
|
|
50
|
+
const tmp = `/tmp/ct-daemon-json-${Date.now()}`;
|
|
51
|
+
writeFileSync(tmp, updated, 'utf-8');
|
|
52
|
+
const result = spawnSync('sudo', ['cp', tmp, DAEMON_JSON], { stdio: 'pipe' });
|
|
53
|
+
try {
|
|
54
|
+
unlinkSync(tmp);
|
|
55
|
+
}
|
|
56
|
+
catch {
|
|
57
|
+
/* ignore */
|
|
58
|
+
}
|
|
59
|
+
if (result.status !== 0) {
|
|
60
|
+
throw new Error(`Failed to write ${DAEMON_JSON}: ${result.stderr?.toString().trim()}`);
|
|
61
|
+
}
|
|
62
|
+
// Restart Docker so the corrected config takes effect
|
|
63
|
+
const restart = spawnSync('sudo', ['systemctl', 'restart', 'docker'], {
|
|
64
|
+
stdio: 'pipe',
|
|
65
|
+
timeout: 30_000,
|
|
66
|
+
});
|
|
67
|
+
if (restart.status !== 0) {
|
|
68
|
+
throw new Error(`daemon.json fixed but Docker restart failed: ${restart.stderr?.toString().trim()}`);
|
|
69
|
+
}
|
|
70
|
+
return true;
|
|
71
|
+
}
|
|
72
|
+
//# sourceMappingURL=migration-014-docker-firewall-backend.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"migration-014-docker-firewall-backend.js","sourceRoot":"","sources":["../../src/lib/migration-014-docker-firewall-backend.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
export interface Migration {
|
|
2
|
+
id: string;
|
|
3
|
+
description: string;
|
|
4
|
+
run: () => Promise<boolean>;
|
|
5
|
+
}
|
|
6
|
+
interface MigrationRecord {
|
|
7
|
+
at: string;
|
|
8
|
+
result: 'applied' | 'skipped';
|
|
9
|
+
}
|
|
10
|
+
interface ErrorRecord {
|
|
11
|
+
at: string;
|
|
12
|
+
error: string;
|
|
13
|
+
}
|
|
14
|
+
interface MigrationState {
|
|
15
|
+
completed: Record<string, MigrationRecord>;
|
|
16
|
+
errors: Record<string, ErrorRecord>;
|
|
17
|
+
}
|
|
18
|
+
export declare const MIGRATIONS: Migration[];
|
|
19
|
+
export declare function loadMigrationState(): MigrationState;
|
|
20
|
+
export declare function saveMigrationState(state: MigrationState): void;
|
|
21
|
+
export declare function isMigrationCompleted(id: string): boolean;
|
|
22
|
+
export declare function runPendingMigrations(log?: (msg: string) => void): Promise<{
|
|
23
|
+
ran: string[];
|
|
24
|
+
skipped: string[];
|
|
25
|
+
}>;
|
|
26
|
+
/**
|
|
27
|
+
* Run a single migration by ID, regardless of whether it has already completed.
|
|
28
|
+
* Useful for re-running a migration that errored or needs to be re-applied.
|
|
29
|
+
*/
|
|
30
|
+
export declare function runSingleMigration(id: string, log?: (msg: string) => void): Promise<{
|
|
31
|
+
result: 'applied' | 'skipped' | 'not_found';
|
|
32
|
+
error?: string;
|
|
33
|
+
}>;
|
|
34
|
+
export declare function getMigrationStatus(): Array<{
|
|
35
|
+
id: string;
|
|
36
|
+
description: string;
|
|
37
|
+
status: 'applied' | 'skipped' | 'pending' | 'error';
|
|
38
|
+
at?: string;
|
|
39
|
+
error?: string;
|
|
40
|
+
}>;
|
|
41
|
+
export {};
|
|
42
|
+
//# sourceMappingURL=migrations.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"migrations.d.ts","sourceRoot":"","sources":["../../src/lib/migrations.ts"],"names":[],"mappings":"AAUA,MAAM,WAAW,SAAS;IACxB,EAAE,EAAE,MAAM,CAAC;IACX,WAAW,EAAE,MAAM,CAAC;IACpB,GAAG,EAAE,MAAM,OAAO,CAAC,OAAO,CAAC,CAAC;CAC7B;AAED,UAAU,eAAe;IACvB,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,SAAS,GAAG,SAAS,CAAC;CAC/B;AAED,UAAU,WAAW;IACnB,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;CACf;AAED,UAAU,cAAc;IACtB,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,eAAe,CAAC,CAAC;IAC3C,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC;CACrC;AAqBD,eAAO,MAAM,UAAU,EAAE,SAAS,EAuEjC,CAAC;AAEF,wBAAgB,kBAAkB,IAAI,cAAc,CAcnD;AAED,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,cAAc,GAAG,IAAI,CAG9D;AAED,wBAAgB,oBAAoB,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAGxD;AAED,wBAAsB,oBAAoB,CACxC,GAAG,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,GAC1B,OAAO,CAAC;IAAE,GAAG,EAAE,MAAM,EAAE,CAAC;IAAC,OAAO,EAAE,MAAM,EAAE,CAAA;CAAE,CAAC,CA4C/C;AAED;;;GAGG;AACH,wBAAsB,kBAAkB,CACtC,EAAE,EAAE,MAAM,EACV,GAAG,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,GAC1B,OAAO,CAAC;IAAE,MAAM,EAAE,SAAS,GAAG,SAAS,GAAG,WAAW,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,CAwC1E;AAED,wBAAgB,kBAAkB,IAAI,KAAK,CAAC;IAC1C,EAAE,EAAE,MAAM,CAAC;IACX,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,SAAS,GAAG,SAAS,GAAG,SAAS,GAAG,OAAO,CAAC;IACpD,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,CAAC,CAgCD"}
|
|
@@ -0,0 +1,231 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Appliance migration framework.
|
|
3
|
+
*
|
|
4
|
+
* Tracks which system-level migrations have been applied on this appliance
|
|
5
|
+
* and runs any pending ones. State is persisted in ~/.ct/migrations.json.
|
|
6
|
+
*/
|
|
7
|
+
import { join } from 'node:path';
|
|
8
|
+
import { homedir } from 'node:os';
|
|
9
|
+
import { existsSync, readFileSync, writeFileSync, mkdirSync } from 'node:fs';
|
|
10
|
+
const CT_DIR = join(homedir(), '.ct');
|
|
11
|
+
const MIGRATIONS_FILE = join(CT_DIR, 'migrations.json');
|
|
12
|
+
// Import migrations
|
|
13
|
+
import { migrateCgnatSubnets } from './migration-001-cgnat.js';
|
|
14
|
+
import { migrateSwapFile } from './migration-002-swap.js';
|
|
15
|
+
import { migrateNmHeal } from './migration-003-nm-heal.js';
|
|
16
|
+
import { migrateSystemdDocker } from './migration-004-systemd-docker.js';
|
|
17
|
+
import { migrateSshKeys } from './migration-005-ssh-keys.js';
|
|
18
|
+
import { migrateConsoleLoglevel } from './migration-006-console-loglevel.js';
|
|
19
|
+
import { migrateNmKeyfile } from './migration-007-nm-keyfile.js';
|
|
20
|
+
import { migrateSystemdRestart } from './migration-008-systemd-restart.js';
|
|
21
|
+
import { migrateBindMountFiles } from './migration-009-bind-mount-files.js';
|
|
22
|
+
import { migrateDockerMemoryLimit } from './migration-011-docker-memory-limit.js';
|
|
23
|
+
import { migrateJtapiState } from './migration-010-jtapi-state.js';
|
|
24
|
+
import { migrateDbPoolSizes } from './migration-012-db-pool-sizes.js';
|
|
25
|
+
import { migrateGrafanaPassword } from './migration-013-grafana-password.js';
|
|
26
|
+
import { migrateDockerFirewallBackend } from './migration-014-docker-firewall-backend.js';
|
|
27
|
+
export const MIGRATIONS = [
|
|
28
|
+
{
|
|
29
|
+
id: '001_cgnat_docker_subnets',
|
|
30
|
+
description: 'Move Docker subnets to CGNAT space (100.64.x)',
|
|
31
|
+
run: migrateCgnatSubnets,
|
|
32
|
+
},
|
|
33
|
+
{
|
|
34
|
+
id: '002_swap_file',
|
|
35
|
+
description: 'Configure swap file (50% of RAM)',
|
|
36
|
+
run: migrateSwapFile,
|
|
37
|
+
},
|
|
38
|
+
{
|
|
39
|
+
id: '003_nm_connection_heal',
|
|
40
|
+
description: 'Fix NetworkManager connection profiles (autoconnect, Docker bridges)',
|
|
41
|
+
run: migrateNmHeal,
|
|
42
|
+
},
|
|
43
|
+
{
|
|
44
|
+
id: '004_systemd_docker_boot',
|
|
45
|
+
description: 'Docker boot ordering (After=firewalld)',
|
|
46
|
+
run: migrateSystemdDocker,
|
|
47
|
+
},
|
|
48
|
+
{
|
|
49
|
+
id: '005_ssh_host_keys',
|
|
50
|
+
description: 'Regenerate SSH host keys (OVA clone safety)',
|
|
51
|
+
run: migrateSshKeys,
|
|
52
|
+
},
|
|
53
|
+
{
|
|
54
|
+
id: '006_console_loglevel',
|
|
55
|
+
description: 'Suppress nft_compat/ip_set kernel console warnings',
|
|
56
|
+
run: migrateConsoleLoglevel,
|
|
57
|
+
},
|
|
58
|
+
{
|
|
59
|
+
id: '007_nm_keyfile_migration',
|
|
60
|
+
description: 'Migrate legacy ifcfg network configs to NM keyfile format',
|
|
61
|
+
run: migrateNmKeyfile,
|
|
62
|
+
},
|
|
63
|
+
{
|
|
64
|
+
id: '008_systemd_restart_policy',
|
|
65
|
+
description: 'Add restart-on-failure and network-online.target to systemd service',
|
|
66
|
+
run: migrateSystemdRestart,
|
|
67
|
+
},
|
|
68
|
+
{
|
|
69
|
+
id: '009_bind_mount_files',
|
|
70
|
+
description: 'Fix alertmanager.yml and tempo.yaml created as directories by Docker',
|
|
71
|
+
run: migrateBindMountFiles,
|
|
72
|
+
},
|
|
73
|
+
{
|
|
74
|
+
id: '010_jtapi_state_to_env',
|
|
75
|
+
description: 'Migrate .jtapi-enabled sentinel to .env COMPOSE_PROFILES=jtapi',
|
|
76
|
+
run: migrateJtapiState,
|
|
77
|
+
},
|
|
78
|
+
{
|
|
79
|
+
id: '011_docker_memory_limit',
|
|
80
|
+
description: 'Cap Docker daemon at 90% RAM (reserve 10% for OS)',
|
|
81
|
+
run: migrateDockerMemoryLimit,
|
|
82
|
+
},
|
|
83
|
+
{
|
|
84
|
+
id: '012_db_pool_sizes',
|
|
85
|
+
description: 'Set small DB pool profile (44 connections instead of 95)',
|
|
86
|
+
run: migrateDbPoolSizes,
|
|
87
|
+
},
|
|
88
|
+
{
|
|
89
|
+
id: '013_grafana_password',
|
|
90
|
+
description: 'Generate GRAFANA_PASSWORD for deterministic Grafana auth',
|
|
91
|
+
run: migrateGrafanaPassword,
|
|
92
|
+
},
|
|
93
|
+
{
|
|
94
|
+
id: '014_docker_firewall_backend',
|
|
95
|
+
description: 'Remove firewall-backend from daemon.json on Docker < 29 (prevents dockerd startup failure)',
|
|
96
|
+
run: migrateDockerFirewallBackend,
|
|
97
|
+
},
|
|
98
|
+
];
|
|
99
|
+
export function loadMigrationState() {
|
|
100
|
+
try {
|
|
101
|
+
if (!existsSync(MIGRATIONS_FILE)) {
|
|
102
|
+
return { completed: {}, errors: {} };
|
|
103
|
+
}
|
|
104
|
+
const raw = readFileSync(MIGRATIONS_FILE, 'utf-8');
|
|
105
|
+
const parsed = JSON.parse(raw);
|
|
106
|
+
return {
|
|
107
|
+
completed: parsed.completed ?? {},
|
|
108
|
+
errors: parsed.errors ?? {},
|
|
109
|
+
};
|
|
110
|
+
}
|
|
111
|
+
catch {
|
|
112
|
+
return { completed: {}, errors: {} };
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
export function saveMigrationState(state) {
|
|
116
|
+
mkdirSync(CT_DIR, { recursive: true });
|
|
117
|
+
writeFileSync(MIGRATIONS_FILE, JSON.stringify(state, null, 2) + '\n', 'utf-8');
|
|
118
|
+
}
|
|
119
|
+
export function isMigrationCompleted(id) {
|
|
120
|
+
const state = loadMigrationState();
|
|
121
|
+
return id in state.completed;
|
|
122
|
+
}
|
|
123
|
+
export async function runPendingMigrations(log) {
|
|
124
|
+
const state = loadMigrationState();
|
|
125
|
+
const ran = [];
|
|
126
|
+
const skipped = [];
|
|
127
|
+
for (const migration of MIGRATIONS) {
|
|
128
|
+
if (migration.id in state.completed) {
|
|
129
|
+
skipped.push(migration.id);
|
|
130
|
+
continue;
|
|
131
|
+
}
|
|
132
|
+
log?.(`Running migration: ${migration.description}`);
|
|
133
|
+
try {
|
|
134
|
+
const changed = await migration.run();
|
|
135
|
+
state.completed[migration.id] = {
|
|
136
|
+
at: new Date().toISOString(),
|
|
137
|
+
result: changed ? 'applied' : 'skipped',
|
|
138
|
+
};
|
|
139
|
+
// Clear any previous error for this migration
|
|
140
|
+
delete state.errors[migration.id];
|
|
141
|
+
if (changed) {
|
|
142
|
+
ran.push(migration.id);
|
|
143
|
+
log?.(` Applied: ${migration.id}`);
|
|
144
|
+
}
|
|
145
|
+
else {
|
|
146
|
+
skipped.push(migration.id);
|
|
147
|
+
log?.(` Skipped (already correct): ${migration.id}`);
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
catch (err) {
|
|
151
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
152
|
+
state.errors[migration.id] = {
|
|
153
|
+
at: new Date().toISOString(),
|
|
154
|
+
error: message,
|
|
155
|
+
};
|
|
156
|
+
log?.(` Error: ${migration.id} — ${message}`);
|
|
157
|
+
}
|
|
158
|
+
saveMigrationState(state);
|
|
159
|
+
}
|
|
160
|
+
return { ran, skipped };
|
|
161
|
+
}
|
|
162
|
+
/**
|
|
163
|
+
* Run a single migration by ID, regardless of whether it has already completed.
|
|
164
|
+
* Useful for re-running a migration that errored or needs to be re-applied.
|
|
165
|
+
*/
|
|
166
|
+
export async function runSingleMigration(id, log) {
|
|
167
|
+
const migration = MIGRATIONS.find((m) => m.id === id);
|
|
168
|
+
if (!migration) {
|
|
169
|
+
return { result: 'not_found' };
|
|
170
|
+
}
|
|
171
|
+
const state = loadMigrationState();
|
|
172
|
+
log?.(`Running migration: ${migration.description}`);
|
|
173
|
+
try {
|
|
174
|
+
const changed = await migration.run();
|
|
175
|
+
state.completed[migration.id] = {
|
|
176
|
+
at: new Date().toISOString(),
|
|
177
|
+
result: changed ? 'applied' : 'skipped',
|
|
178
|
+
};
|
|
179
|
+
// Clear any previous error for this migration
|
|
180
|
+
delete state.errors[migration.id];
|
|
181
|
+
saveMigrationState(state);
|
|
182
|
+
if (changed) {
|
|
183
|
+
log?.(` Applied: ${migration.id}`);
|
|
184
|
+
return { result: 'applied' };
|
|
185
|
+
}
|
|
186
|
+
else {
|
|
187
|
+
log?.(` Skipped (already correct): ${migration.id}`);
|
|
188
|
+
return { result: 'skipped' };
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
catch (err) {
|
|
192
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
193
|
+
state.errors[migration.id] = {
|
|
194
|
+
at: new Date().toISOString(),
|
|
195
|
+
error: message,
|
|
196
|
+
};
|
|
197
|
+
saveMigrationState(state);
|
|
198
|
+
log?.(` Error: ${migration.id} — ${message}`);
|
|
199
|
+
return { result: 'applied', error: message };
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
export function getMigrationStatus() {
|
|
203
|
+
const state = loadMigrationState();
|
|
204
|
+
return MIGRATIONS.map((m) => {
|
|
205
|
+
const completed = state.completed[m.id];
|
|
206
|
+
const errRecord = state.errors[m.id];
|
|
207
|
+
if (completed) {
|
|
208
|
+
return {
|
|
209
|
+
id: m.id,
|
|
210
|
+
description: m.description,
|
|
211
|
+
status: completed.result,
|
|
212
|
+
at: completed.at,
|
|
213
|
+
};
|
|
214
|
+
}
|
|
215
|
+
if (errRecord) {
|
|
216
|
+
return {
|
|
217
|
+
id: m.id,
|
|
218
|
+
description: m.description,
|
|
219
|
+
status: 'error',
|
|
220
|
+
at: errRecord.at,
|
|
221
|
+
error: errRecord.error,
|
|
222
|
+
};
|
|
223
|
+
}
|
|
224
|
+
return {
|
|
225
|
+
id: m.id,
|
|
226
|
+
description: m.description,
|
|
227
|
+
status: 'pending',
|
|
228
|
+
};
|
|
229
|
+
});
|
|
230
|
+
}
|
|
231
|
+
//# sourceMappingURL=migrations.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"migrations.js","sourceRoot":"","sources":["../../src/lib/migrations.ts"],"names":[],"mappings":"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"}
|