@oneuptime/common 11.7.2 → 11.7.4
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/Models/AnalyticsModels/KubernetesCostAllocation.ts +103 -0
- package/Models/DatabaseModels/AlertEpisodeStateTimeline.ts +1 -0
- package/Models/DatabaseModels/AlertStateTimeline.ts +1 -0
- package/Models/DatabaseModels/IncidentEpisodeStateTimeline.ts +1 -0
- package/Models/DatabaseModels/IncidentStateTimeline.ts +1 -0
- package/Models/DatabaseModels/Index.ts +5 -0
- package/Models/DatabaseModels/LogDropFilter.ts +89 -0
- package/Models/DatabaseModels/NetworkDeviceDiscoveryScan.ts +13 -3
- package/Models/DatabaseModels/RecommendationDismissal.ts +463 -0
- package/Models/DatabaseModels/ScheduledMaintenanceStateTimeline.ts +1 -0
- package/Models/DatabaseModels/StatusPageGroup.ts +95 -0
- package/Models/DatabaseModels/TableView.ts +40 -0
- package/Models/DatabaseModels/TraceDropFilter.ts +89 -0
- package/Models/DatabaseModels/WorkflowVariable.ts +5 -1
- package/Server/API/AlertAPI.ts +32 -17
- package/Server/API/BaseAPI.ts +31 -2
- package/Server/API/BaseAnalyticsAPI.ts +36 -2
- package/Server/API/CommonAPI.ts +57 -0
- package/Server/API/IncidentAPI.ts +60 -33
- package/Server/API/IncidentEpisodeAPI.ts +31 -16
- package/Server/API/MonitorAPI.ts +30 -0
- package/Server/API/MonitorTemplateAPI.ts +8 -0
- package/Server/API/ProbeAPI.ts +196 -15
- package/Server/API/ProjectAPI.ts +79 -1
- package/Server/API/ScheduledMaintenanceAPI.ts +33 -18
- package/Server/API/StatusPageAPI.ts +74 -37
- package/Server/API/WorkspaceNotificationRuleAPI.ts +34 -4
- package/Server/Infrastructure/Postgres/SchemaMigrations/1785241000000-AddColumnsToTableView.ts +13 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1785320000000-RepairCrossProjectIncidentReferences.ts +527 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1785329453269-AddParentGroupToStatusPageGroup.ts +31 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1785397674289-AddRecommendationDismissalTable.ts +55 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1785405581596-AddDroppedCountersToDropFilters.ts +53 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/Index.ts +10 -0
- package/Server/Services/AlertEpisodeService.ts +47 -0
- package/Server/Services/AlertService.ts +125 -0
- package/Server/Services/BillingService.ts +98 -0
- package/Server/Services/DatabaseService.ts +184 -20
- package/Server/Services/IncidentEpisodeService.ts +47 -0
- package/Server/Services/IncidentService.ts +123 -0
- package/Server/Services/IncidentTemplateService.ts +123 -1
- package/Server/Services/Index.ts +2 -0
- package/Server/Services/LogDropFilterService.ts +133 -0
- package/Server/Services/MonitorProbeService.ts +94 -4
- package/Server/Services/MonitorService.ts +48 -43
- package/Server/Services/NetworkDeviceDiscoveryScanService.ts +70 -0
- package/Server/Services/ProbeService.ts +66 -0
- package/Server/Services/ProjectService.ts +131 -7
- package/Server/Services/RecommendationDismissalService.ts +52 -0
- package/Server/Services/RunbookAgentJobService.ts +68 -7
- package/Server/Services/ScheduledMaintenanceService.ts +103 -0
- package/Server/Services/ScheduledMaintenanceTemplateService.ts +90 -0
- package/Server/Services/StatusPageGroupService.ts +186 -0
- package/Server/Services/TraceDropFilterService.ts +133 -0
- package/Server/Types/Workflow/Components/API/Delete.ts +12 -0
- package/Server/Types/Workflow/Components/API/Get.ts +12 -0
- package/Server/Types/Workflow/Components/API/Patch.ts +12 -0
- package/Server/Types/Workflow/Components/API/Post.ts +12 -0
- package/Server/Types/Workflow/Components/API/Put.ts +13 -0
- package/Server/Utils/Database/ProjectScopedReferenceValidator.ts +212 -0
- package/Server/Utils/DropFilterValidation.ts +127 -0
- package/Server/Utils/Errors.ts +5 -0
- package/Server/Utils/Monitor/MonitorAlert.ts +28 -1
- package/Server/Utils/Monitor/MonitorIncident.ts +31 -2
- package/Server/Utils/Telemetry/AppMetrics.ts +31 -0
- package/Tests/Models/AnalyticsModels/KubernetesCostAllocation.test.ts +16 -0
- package/Tests/Models/DatabaseModels/MonitorProbeColumnAccessControl.test.ts +196 -0
- package/Tests/Models/RecommendationDismissalModel.test.ts +269 -0
- package/Tests/Server/API/BaseAPIUpdatePayloadValidation.test.ts +320 -0
- package/Tests/Server/API/BaseAnalyticsAPIUpdatePayloadValidation.test.ts +293 -0
- package/Tests/Server/API/CommonAPIAuthGuard.test.ts +164 -0
- package/Tests/Server/API/ProbeAPI.test.ts +422 -53
- package/Tests/Server/API/ProjectAPI.test.ts +180 -0
- package/Tests/Server/API/ProjectAPIExtendTrialBillingDisabled.test.ts +138 -0
- package/Tests/Server/API/ProjectScopedCustomRouteAuth.test.ts +458 -0
- package/Tests/Server/Infrastructure/ContainerBootConfiguration.test.ts +359 -0
- package/Tests/Server/Infrastructure/ProcessSignalDelivery.test.ts +427 -0
- package/Tests/Server/Services/BillingServiceExtendTrial.test.ts +439 -0
- package/Tests/Server/Services/CrossProjectReferenceWriteGuard.test.ts +810 -0
- package/Tests/Server/Services/DatabaseServiceAtomicAddToColumns.test.ts +269 -0
- package/Tests/Server/Services/DatabaseServiceEmptyUpdate.test.ts +277 -0
- package/Tests/Server/Services/DatabaseServiceSortColumnSelect.test.ts +201 -0
- package/Tests/Server/Services/DiscoveryScanClaimHookFreeSafety.test.ts +81 -23
- package/Tests/Server/Services/DropFilterSaveValidation.test.ts +398 -0
- package/Tests/Server/Services/MonitorProbeDeleteHooks.test.ts +280 -0
- package/Tests/Server/Services/MonitorProbeServiceProbeTenancy.test.ts +304 -0
- package/Tests/Server/Services/NetworkDeviceDiscoveryScanService.test.ts +262 -0
- package/Tests/Server/Services/ProjectServiceExtendTrial.test.ts +614 -0
- package/Tests/Server/Services/RecommendationDismissalService.test.ts +306 -0
- package/Tests/Server/Services/RepairCrossProjectIncidentReferencesMigration.test.ts +528 -0
- package/Tests/Server/Services/StatusPageGroupNesting.test.ts +395 -0
- package/Tests/Server/TestingUtils/Services/BillingServiceHelper.ts +26 -21
- package/Tests/Server/Types/Database/Permissions/WorkflowVariableColumnPermission.test.ts +227 -0
- package/Tests/Server/Types/Workflow/Components/ApiComponentErrorPort.test.ts +285 -0
- package/Tests/Server/Utils/Database/ProjectScopedReferenceValidator.test.ts +463 -0
- package/Tests/Server/Utils/DropFilterValidation.test.ts +269 -0
- package/Tests/Server/Utils/Telemetry/SpanUtil.test.ts +94 -0
- package/Tests/Types/DateUserTimezone.test.ts +52 -0
- package/Tests/Types/JSONFunctions.test.ts +103 -1
- package/Tests/Types/Monitor/KubernetesAlertTemplates.test.ts +177 -9
- package/Tests/Types/Monitor/MonitorStepDnsMonitor.test.ts +105 -0
- package/Tests/Types/Monitor/MonitorStepDnssecMonitor.test.ts +131 -0
- package/Tests/Types/Monitor/MonitorStepDomainMonitor.test.ts +60 -0
- package/Tests/Types/Monitor/MonitorStepExternalStatusPageMonitor.test.ts +82 -0
- package/Tests/Types/Monitor/MonitorStepInfrastructureMonitors.test.ts +268 -0
- package/Tests/Types/Monitor/MonitorStepMetricMonitor.test.ts +386 -0
- package/Tests/Types/Monitor/MonitorStepProfileMonitor.test.ts +185 -0
- package/Tests/Types/Monitor/MonitorStepSnmpMonitor.test.ts +156 -0
- package/Tests/Types/Monitor/Recommendation/MonitorRecommendationCatalog.test.ts +371 -0
- package/Tests/Types/Monitor/Recommendation/MonitorRecommendationCoverage.test.ts +901 -0
- package/Tests/Types/Monitor/Recommendation/MonitorRecommendationNotificationMode.test.ts +607 -0
- package/Tests/Types/Monitor/Recommendation/MonitorRecommendationSeverityMapper.test.ts +754 -0
- package/Tests/Types/Monitor/Recommendation/MonitorRecommendationUtil.test.ts +960 -0
- package/Tests/Types/RollingTime/RollingTimeUtil.test.ts +186 -0
- package/Tests/Types/Runbook/RunbookStepTimeout.test.ts +410 -0
- package/Tests/Types/Telemetry/DropFilterSampling.test.ts +241 -0
- package/Tests/Types/Workspace/NotificationRuleConditionUtil.test.ts +353 -0
- package/Tests/Types/Workspace/NotificationRuleUtil.test.ts +566 -0
- package/Tests/UI/Components/CodeEditor.test.tsx +174 -0
- package/Tests/UI/Components/ErrorBoundary.test.tsx +555 -24
- package/Tests/UI/Components/InfoCard.test.tsx +358 -0
- package/Tests/UI/Components/LogTimeRangePicker.test.tsx +138 -0
- package/Tests/UI/Components/Modal.test.tsx +43 -5
- package/Tests/UI/Components/ModelTable/BaseModelTableColumnCustomization.test.tsx +679 -0
- package/Tests/UI/Components/ModelTable/BaseModelTableSearchLabels.test.tsx +397 -0
- package/Tests/UI/Components/ModelTable/ColumnCustomizationModal.test.tsx +999 -0
- package/Tests/UI/Components/ModelTable/ColumnPreference.test.ts +1678 -0
- package/Tests/UI/Components/ModelTable/CustomFieldColumns.test.tsx +1094 -0
- package/Tests/UI/Components/Runbook/StepTimeoutInput.test.tsx +386 -0
- package/Tests/UI/Components/StatusPage/ResourceGroupSection.test.tsx +671 -0
- package/Tests/UI/Components/TelemetryTimeRangePicker.test.tsx +404 -0
- package/Tests/UI/Utils/DropdownAlignment.test.ts +306 -0
- package/Tests/UI/Utils/TableFilterUrlState.test.ts +292 -0
- package/Tests/Utils/Monitor/MonitorSummaryProbeUtil.test.ts +263 -0
- package/Tests/Utils/NetworkDiscovery/ScanTargetUtil.test.ts +583 -0
- package/Tests/Utils/StatusPage/GroupNestingLayout.test.ts +1072 -0
- package/Tests/Utils/StatusPage/GroupTree.test.ts +583 -0
- package/Tests/Utils/StatusPage/ResourceUptime.test.ts +411 -0
- package/Tests/Utils/UserPreferences.test.ts +563 -0
- package/Types/Date.ts +15 -6
- package/Types/JSONFunctions.ts +7 -2
- package/Types/Kubernetes/KubernetesCostIngest.ts +37 -1
- package/Types/Monitor/KubernetesAlertTemplates.ts +205 -0
- package/Types/Monitor/MonitorStep.ts +10 -1
- package/Types/Monitor/MonitorStepMetricMonitor.ts +46 -1
- package/Types/Monitor/Recommendation/MonitorRecommendationCatalog.ts +413 -0
- package/Types/Monitor/Recommendation/MonitorRecommendationSeverityMapper.ts +168 -0
- package/Types/Monitor/Recommendation/MonitorRecommendationTypes.ts +175 -0
- package/Types/Monitor/Recommendation/MonitorRecommendationUtil.ts +743 -0
- package/Types/Permission.ts +45 -0
- package/Types/Recommendation/RecommendationType.ts +20 -0
- package/Types/Runbook/RunbookExecutionDeadline.ts +129 -0
- package/Types/Runbook/RunbookStepTimeout.ts +202 -0
- package/Types/Telemetry/DropFilterSampling.ts +92 -0
- package/UI/Components/AI/GenerateFromAIModal.tsx +0 -2
- package/UI/Components/Accordion/Accordion.tsx +10 -2
- package/UI/Components/BulkUpdate/BulkLabelActions.tsx +0 -1
- package/UI/Components/CodeEditor/CodeEditor.tsx +34 -20
- package/UI/Components/Date/RangeStartAndEndDateView.tsx +0 -1
- package/UI/Components/EditionLabel/EditionLabel.tsx +1 -27
- package/UI/Components/Error/PageError.tsx +0 -4
- package/UI/Components/ErrorBoundary.tsx +252 -15
- package/UI/Components/InfoCard/InfoCard.tsx +58 -1
- package/UI/Components/LogsViewer/components/LogTimeRangePicker.tsx +34 -1
- package/UI/Components/MasterPage/MasterPage.tsx +65 -0
- package/UI/Components/Modal/Modal.tsx +16 -60
- package/UI/Components/ModelFormModal/ModelFormModal.tsx +0 -8
- package/UI/Components/ModelTable/BaseModelTable.tsx +503 -71
- package/UI/Components/ModelTable/Column.ts +17 -0
- package/UI/Components/ModelTable/ColumnCustomizationModal.tsx +523 -0
- package/UI/Components/ModelTable/ColumnPreference.ts +482 -0
- package/UI/Components/ModelTable/CustomFieldColumns.tsx +326 -0
- package/UI/Components/ModelTable/TableView.tsx +24 -2
- package/UI/Components/ModelTable/useCustomFieldColumns.ts +150 -0
- package/UI/Components/Runbook/StepTimeoutInput.tsx +173 -0
- package/UI/Components/SideMenu/SideMenu.tsx +24 -4
- package/UI/Components/StatusPage/ResourceGroupSection.tsx +231 -0
- package/UI/Components/Table/Table.tsx +14 -1
- package/UI/Components/Table/TableRow.tsx +180 -175
- package/UI/Components/Table/Types/Column.ts +2 -0
- package/UI/Components/TelemetryViewer/components/TelemetryTimeRangePicker.tsx +34 -1
- package/UI/Utils/DropdownAlignment.ts +162 -0
- package/UI/Utils/TableFilterUrlState.ts +59 -20
- package/Utils/API.ts +106 -2
- package/Utils/Monitor/MonitorSummaryProbeUtil.ts +130 -0
- package/Utils/NetworkDiscovery/ScanTargetUtil.ts +434 -0
- package/Utils/StatusPage/GroupNestingLayout.ts +343 -0
- package/Utils/StatusPage/GroupTree.ts +307 -0
- package/Utils/StatusPage/ResourceUptime.ts +90 -17
- package/Utils/UserPreferences.ts +53 -0
- package/build/dist/Models/AnalyticsModels/KubernetesCostAllocation.js +86 -0
- package/build/dist/Models/AnalyticsModels/KubernetesCostAllocation.js.map +1 -1
- package/build/dist/Models/DatabaseModels/AlertEpisodeStateTimeline.js +1 -0
- package/build/dist/Models/DatabaseModels/AlertEpisodeStateTimeline.js.map +1 -1
- package/build/dist/Models/DatabaseModels/AlertStateTimeline.js +1 -0
- package/build/dist/Models/DatabaseModels/AlertStateTimeline.js.map +1 -1
- package/build/dist/Models/DatabaseModels/IncidentEpisodeStateTimeline.js +1 -0
- package/build/dist/Models/DatabaseModels/IncidentEpisodeStateTimeline.js.map +1 -1
- package/build/dist/Models/DatabaseModels/IncidentStateTimeline.js +1 -0
- package/build/dist/Models/DatabaseModels/IncidentStateTimeline.js.map +1 -1
- package/build/dist/Models/DatabaseModels/Index.js +2 -0
- package/build/dist/Models/DatabaseModels/Index.js.map +1 -1
- package/build/dist/Models/DatabaseModels/LogDropFilter.js +91 -0
- package/build/dist/Models/DatabaseModels/LogDropFilter.js.map +1 -1
- package/build/dist/Models/DatabaseModels/NetworkDeviceDiscoveryScan.js +14 -4
- package/build/dist/Models/DatabaseModels/NetworkDeviceDiscoveryScan.js.map +1 -1
- package/build/dist/Models/DatabaseModels/RecommendationDismissal.js +484 -0
- package/build/dist/Models/DatabaseModels/RecommendationDismissal.js.map +1 -0
- package/build/dist/Models/DatabaseModels/ScheduledMaintenanceStateTimeline.js +1 -0
- package/build/dist/Models/DatabaseModels/ScheduledMaintenanceStateTimeline.js.map +1 -1
- package/build/dist/Models/DatabaseModels/StatusPageGroup.js +94 -0
- package/build/dist/Models/DatabaseModels/StatusPageGroup.js.map +1 -1
- package/build/dist/Models/DatabaseModels/TableView.js +40 -0
- package/build/dist/Models/DatabaseModels/TableView.js.map +1 -1
- package/build/dist/Models/DatabaseModels/TraceDropFilter.js +91 -0
- package/build/dist/Models/DatabaseModels/TraceDropFilter.js.map +1 -1
- package/build/dist/Models/DatabaseModels/WorkflowVariable.js +5 -1
- package/build/dist/Models/DatabaseModels/WorkflowVariable.js.map +1 -1
- package/build/dist/Server/API/AlertAPI.js +22 -13
- package/build/dist/Server/API/AlertAPI.js.map +1 -1
- package/build/dist/Server/API/BaseAPI.js +22 -1
- package/build/dist/Server/API/BaseAPI.js.map +1 -1
- package/build/dist/Server/API/BaseAnalyticsAPI.js +24 -1
- package/build/dist/Server/API/BaseAnalyticsAPI.js.map +1 -1
- package/build/dist/Server/API/CommonAPI.js +42 -0
- package/build/dist/Server/API/CommonAPI.js.map +1 -1
- package/build/dist/Server/API/IncidentAPI.js +43 -26
- package/build/dist/Server/API/IncidentAPI.js.map +1 -1
- package/build/dist/Server/API/IncidentEpisodeAPI.js +21 -12
- package/build/dist/Server/API/IncidentEpisodeAPI.js.map +1 -1
- package/build/dist/Server/API/MonitorAPI.js +23 -0
- package/build/dist/Server/API/MonitorAPI.js.map +1 -1
- package/build/dist/Server/API/MonitorTemplateAPI.js +4 -0
- package/build/dist/Server/API/MonitorTemplateAPI.js.map +1 -1
- package/build/dist/Server/API/ProbeAPI.js +131 -15
- package/build/dist/Server/API/ProbeAPI.js.map +1 -1
- package/build/dist/Server/API/ProjectAPI.js +62 -3
- package/build/dist/Server/API/ProjectAPI.js.map +1 -1
- package/build/dist/Server/API/ScheduledMaintenanceAPI.js +23 -14
- package/build/dist/Server/API/ScheduledMaintenanceAPI.js.map +1 -1
- package/build/dist/Server/API/StatusPageAPI.js +61 -33
- package/build/dist/Server/API/StatusPageAPI.js.map +1 -1
- package/build/dist/Server/API/WorkspaceNotificationRuleAPI.js +26 -2
- package/build/dist/Server/API/WorkspaceNotificationRuleAPI.js.map +1 -1
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1785241000000-AddColumnsToTableView.js +12 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1785241000000-AddColumnsToTableView.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1785320000000-RepairCrossProjectIncidentReferences.js +397 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1785320000000-RepairCrossProjectIncidentReferences.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1785329453269-AddParentGroupToStatusPageGroup.js +16 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1785329453269-AddParentGroupToStatusPageGroup.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1785397674289-AddRecommendationDismissalTable.js +30 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1785397674289-AddRecommendationDismissalTable.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1785405581596-AddDroppedCountersToDropFilters.js +34 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1785405581596-AddDroppedCountersToDropFilters.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js +10 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js.map +1 -1
- package/build/dist/Server/Services/AlertEpisodeService.js +39 -0
- package/build/dist/Server/Services/AlertEpisodeService.js.map +1 -1
- package/build/dist/Server/Services/AlertService.js +95 -0
- package/build/dist/Server/Services/AlertService.js.map +1 -1
- package/build/dist/Server/Services/BillingService.js +71 -0
- package/build/dist/Server/Services/BillingService.js.map +1 -1
- package/build/dist/Server/Services/DatabaseService.js +140 -17
- package/build/dist/Server/Services/DatabaseService.js.map +1 -1
- package/build/dist/Server/Services/IncidentEpisodeService.js +39 -0
- package/build/dist/Server/Services/IncidentEpisodeService.js.map +1 -1
- package/build/dist/Server/Services/IncidentService.js +100 -0
- package/build/dist/Server/Services/IncidentService.js.map +1 -1
- package/build/dist/Server/Services/IncidentTemplateService.js +97 -0
- package/build/dist/Server/Services/IncidentTemplateService.js.map +1 -1
- package/build/dist/Server/Services/Index.js +2 -0
- package/build/dist/Server/Services/Index.js.map +1 -1
- package/build/dist/Server/Services/LogDropFilterService.js +93 -0
- package/build/dist/Server/Services/LogDropFilterService.js.map +1 -1
- package/build/dist/Server/Services/MonitorProbeService.js +73 -5
- package/build/dist/Server/Services/MonitorProbeService.js.map +1 -1
- package/build/dist/Server/Services/MonitorService.js +34 -39
- package/build/dist/Server/Services/MonitorService.js.map +1 -1
- package/build/dist/Server/Services/NetworkDeviceDiscoveryScanService.js +71 -0
- package/build/dist/Server/Services/NetworkDeviceDiscoveryScanService.js.map +1 -1
- package/build/dist/Server/Services/ProbeService.js +64 -0
- package/build/dist/Server/Services/ProbeService.js.map +1 -1
- package/build/dist/Server/Services/ProjectService.js +103 -7
- package/build/dist/Server/Services/ProjectService.js.map +1 -1
- package/build/dist/Server/Services/RecommendationDismissalService.js +50 -0
- package/build/dist/Server/Services/RecommendationDismissalService.js.map +1 -0
- package/build/dist/Server/Services/RunbookAgentJobService.js +63 -5
- package/build/dist/Server/Services/RunbookAgentJobService.js.map +1 -1
- package/build/dist/Server/Services/ScheduledMaintenanceService.js +83 -0
- package/build/dist/Server/Services/ScheduledMaintenanceService.js.map +1 -1
- package/build/dist/Server/Services/ScheduledMaintenanceTemplateService.js +65 -0
- package/build/dist/Server/Services/ScheduledMaintenanceTemplateService.js.map +1 -1
- package/build/dist/Server/Services/StatusPageGroupService.js +136 -0
- package/build/dist/Server/Services/StatusPageGroupService.js.map +1 -1
- package/build/dist/Server/Services/TraceDropFilterService.js +93 -0
- package/build/dist/Server/Services/TraceDropFilterService.js.map +1 -1
- package/build/dist/Server/Types/Workflow/Components/API/Delete.js +11 -0
- package/build/dist/Server/Types/Workflow/Components/API/Delete.js.map +1 -1
- package/build/dist/Server/Types/Workflow/Components/API/Get.js +11 -0
- package/build/dist/Server/Types/Workflow/Components/API/Get.js.map +1 -1
- package/build/dist/Server/Types/Workflow/Components/API/Patch.js +11 -0
- package/build/dist/Server/Types/Workflow/Components/API/Patch.js.map +1 -1
- package/build/dist/Server/Types/Workflow/Components/API/Post.js +11 -0
- package/build/dist/Server/Types/Workflow/Components/API/Post.js.map +1 -1
- package/build/dist/Server/Types/Workflow/Components/API/Put.js +12 -0
- package/build/dist/Server/Types/Workflow/Components/API/Put.js.map +1 -1
- package/build/dist/Server/Utils/Database/ProjectScopedReferenceValidator.js +132 -0
- package/build/dist/Server/Utils/Database/ProjectScopedReferenceValidator.js.map +1 -0
- package/build/dist/Server/Utils/DropFilterValidation.js +80 -0
- package/build/dist/Server/Utils/DropFilterValidation.js.map +1 -0
- package/build/dist/Server/Utils/Errors.js +3 -0
- package/build/dist/Server/Utils/Errors.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/MonitorAlert.js +30 -12
- package/build/dist/Server/Utils/Monitor/MonitorAlert.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/MonitorIncident.js +38 -18
- package/build/dist/Server/Utils/Monitor/MonitorIncident.js.map +1 -1
- package/build/dist/Server/Utils/Telemetry/AppMetrics.js +26 -0
- package/build/dist/Server/Utils/Telemetry/AppMetrics.js.map +1 -1
- package/build/dist/Types/Date.js +14 -4
- package/build/dist/Types/Date.js.map +1 -1
- package/build/dist/Types/JSONFunctions.js +8 -3
- package/build/dist/Types/JSONFunctions.js.map +1 -1
- package/build/dist/Types/Kubernetes/KubernetesCostIngest.js.map +1 -1
- package/build/dist/Types/Monitor/KubernetesAlertTemplates.js +192 -0
- package/build/dist/Types/Monitor/KubernetesAlertTemplates.js.map +1 -1
- package/build/dist/Types/Monitor/MonitorStep.js +6 -1
- package/build/dist/Types/Monitor/MonitorStep.js.map +1 -1
- package/build/dist/Types/Monitor/MonitorStepMetricMonitor.js +32 -1
- package/build/dist/Types/Monitor/MonitorStepMetricMonitor.js.map +1 -1
- package/build/dist/Types/Monitor/Recommendation/MonitorRecommendationCatalog.js +294 -0
- package/build/dist/Types/Monitor/Recommendation/MonitorRecommendationCatalog.js.map +1 -0
- package/build/dist/Types/Monitor/Recommendation/MonitorRecommendationSeverityMapper.js +110 -0
- package/build/dist/Types/Monitor/Recommendation/MonitorRecommendationSeverityMapper.js.map +1 -0
- package/build/dist/Types/Monitor/Recommendation/MonitorRecommendationTypes.js +58 -0
- package/build/dist/Types/Monitor/Recommendation/MonitorRecommendationTypes.js.map +1 -0
- package/build/dist/Types/Monitor/Recommendation/MonitorRecommendationUtil.js +451 -0
- package/build/dist/Types/Monitor/Recommendation/MonitorRecommendationUtil.js.map +1 -0
- package/build/dist/Types/Permission.js +40 -0
- package/build/dist/Types/Permission.js.map +1 -1
- package/build/dist/Types/Recommendation/RecommendationType.js +21 -0
- package/build/dist/Types/Recommendation/RecommendationType.js.map +1 -0
- package/build/dist/Types/Runbook/RunbookExecutionDeadline.js +93 -0
- package/build/dist/Types/Runbook/RunbookExecutionDeadline.js.map +1 -0
- package/build/dist/Types/Runbook/RunbookStepTimeout.js +142 -0
- package/build/dist/Types/Runbook/RunbookStepTimeout.js.map +1 -0
- package/build/dist/Types/Telemetry/DropFilterSampling.js +75 -0
- package/build/dist/Types/Telemetry/DropFilterSampling.js.map +1 -0
- package/build/dist/UI/Components/AI/GenerateFromAIModal.js +1 -2
- package/build/dist/UI/Components/AI/GenerateFromAIModal.js.map +1 -1
- package/build/dist/UI/Components/Accordion/Accordion.js +9 -2
- package/build/dist/UI/Components/Accordion/Accordion.js.map +1 -1
- package/build/dist/UI/Components/BulkUpdate/BulkLabelActions.js +1 -1
- package/build/dist/UI/Components/BulkUpdate/BulkLabelActions.js.map +1 -1
- package/build/dist/UI/Components/CodeEditor/CodeEditor.js +27 -14
- package/build/dist/UI/Components/CodeEditor/CodeEditor.js.map +1 -1
- package/build/dist/UI/Components/Date/RangeStartAndEndDateView.js +1 -1
- package/build/dist/UI/Components/Date/RangeStartAndEndDateView.js.map +1 -1
- package/build/dist/UI/Components/EditionLabel/EditionLabel.js +2 -20
- package/build/dist/UI/Components/EditionLabel/EditionLabel.js.map +1 -1
- package/build/dist/UI/Components/Error/PageError.js +1 -3
- package/build/dist/UI/Components/Error/PageError.js.map +1 -1
- package/build/dist/UI/Components/ErrorBoundary.js +145 -11
- package/build/dist/UI/Components/ErrorBoundary.js.map +1 -1
- package/build/dist/UI/Components/InfoCard/InfoCard.js +28 -1
- package/build/dist/UI/Components/InfoCard/InfoCard.js.map +1 -1
- package/build/dist/UI/Components/LogsViewer/components/LogTimeRangePicker.js +13 -2
- package/build/dist/UI/Components/LogsViewer/components/LogTimeRangePicker.js.map +1 -1
- package/build/dist/UI/Components/MasterPage/MasterPage.js +50 -1
- package/build/dist/UI/Components/MasterPage/MasterPage.js.map +1 -1
- package/build/dist/UI/Components/Modal/Modal.js +4 -32
- package/build/dist/UI/Components/Modal/Modal.js.map +1 -1
- package/build/dist/UI/Components/ModelFormModal/ModelFormModal.js.map +1 -1
- package/build/dist/UI/Components/ModelTable/BaseModelTable.js +308 -40
- package/build/dist/UI/Components/ModelTable/BaseModelTable.js.map +1 -1
- package/build/dist/UI/Components/ModelTable/ColumnCustomizationModal.js +230 -0
- package/build/dist/UI/Components/ModelTable/ColumnCustomizationModal.js.map +1 -0
- package/build/dist/UI/Components/ModelTable/ColumnPreference.js +258 -0
- package/build/dist/UI/Components/ModelTable/ColumnPreference.js.map +1 -0
- package/build/dist/UI/Components/ModelTable/CustomFieldColumns.js +168 -0
- package/build/dist/UI/Components/ModelTable/CustomFieldColumns.js.map +1 -0
- package/build/dist/UI/Components/ModelTable/TableView.js +13 -2
- package/build/dist/UI/Components/ModelTable/TableView.js.map +1 -1
- package/build/dist/UI/Components/ModelTable/useCustomFieldColumns.js +84 -0
- package/build/dist/UI/Components/ModelTable/useCustomFieldColumns.js.map +1 -0
- package/build/dist/UI/Components/Runbook/StepTimeoutInput.js +101 -0
- package/build/dist/UI/Components/Runbook/StepTimeoutInput.js.map +1 -0
- package/build/dist/UI/Components/SideMenu/SideMenu.js +15 -5
- package/build/dist/UI/Components/SideMenu/SideMenu.js.map +1 -1
- package/build/dist/UI/Components/StatusPage/ResourceGroupSection.js +73 -0
- package/build/dist/UI/Components/StatusPage/ResourceGroupSection.js.map +1 -0
- package/build/dist/UI/Components/Table/Table.js +15 -2
- package/build/dist/UI/Components/Table/Table.js.map +1 -1
- package/build/dist/UI/Components/Table/TableRow.js +11 -6
- package/build/dist/UI/Components/Table/TableRow.js.map +1 -1
- package/build/dist/UI/Components/TelemetryViewer/components/TelemetryTimeRangePicker.js +13 -2
- package/build/dist/UI/Components/TelemetryViewer/components/TelemetryTimeRangePicker.js.map +1 -1
- package/build/dist/UI/Utils/DropdownAlignment.js +98 -0
- package/build/dist/UI/Utils/DropdownAlignment.js.map +1 -0
- package/build/dist/UI/Utils/TableFilterUrlState.js +48 -15
- package/build/dist/UI/Utils/TableFilterUrlState.js.map +1 -1
- package/build/dist/Utils/API.js +39 -2
- package/build/dist/Utils/API.js.map +1 -1
- package/build/dist/Utils/Monitor/MonitorSummaryProbeUtil.js +97 -0
- package/build/dist/Utils/Monitor/MonitorSummaryProbeUtil.js.map +1 -0
- package/build/dist/Utils/NetworkDiscovery/ScanTargetUtil.js +330 -0
- package/build/dist/Utils/NetworkDiscovery/ScanTargetUtil.js.map +1 -0
- package/build/dist/Utils/StatusPage/GroupNestingLayout.js +280 -0
- package/build/dist/Utils/StatusPage/GroupNestingLayout.js.map +1 -0
- package/build/dist/Utils/StatusPage/GroupTree.js +214 -0
- package/build/dist/Utils/StatusPage/GroupTree.js.map +1 -0
- package/build/dist/Utils/StatusPage/ResourceUptime.js +60 -16
- package/build/dist/Utils/StatusPage/ResourceUptime.js.map +1 -1
- package/build/dist/Utils/UserPreferences.js +33 -0
- package/build/dist/Utils/UserPreferences.js.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,427 @@
|
|
|
1
|
+
import { describe, expect, test } from "@jest/globals";
|
|
2
|
+
import { ChildProcess, spawn } from "child_process";
|
|
3
|
+
import fs from "fs";
|
|
4
|
+
import os from "os";
|
|
5
|
+
import path from "path";
|
|
6
|
+
|
|
7
|
+
/*
|
|
8
|
+
* Regression tests for graceful shutdown signal delivery.
|
|
9
|
+
*
|
|
10
|
+
* Kubernetes terminates a pod by sending SIGTERM to PID 1 and then SIGKILLing
|
|
11
|
+
* whatever is left at the end of terminationGracePeriodSeconds. Our services
|
|
12
|
+
* register SIGTERM handlers (Common/Server/Utils/GracefulShutdown.ts) that close
|
|
13
|
+
* the HTTP server, drain the Postgres pool and stop BullMQ consumers.
|
|
14
|
+
*
|
|
15
|
+
* Those handlers only run if the signal actually reaches the Node process. A
|
|
16
|
+
* start script shaped like:
|
|
17
|
+
*
|
|
18
|
+
* export NODE_OPTIONS="..." && node Index.ts
|
|
19
|
+
*
|
|
20
|
+
* is a COMPOUND command, so the shell cannot exec-optimise it: `sh` forks, Node
|
|
21
|
+
* becomes a grandchild, and `sh` does not forward signals to it. The SIGTERM
|
|
22
|
+
* stops at the shell, no handler runs, and every pod is hard-killed with its
|
|
23
|
+
* Postgres connections still open -- which surfaces downstream as a burst of
|
|
24
|
+
* pgbouncer "client unexpected eof" and 502s on every rolling update.
|
|
25
|
+
*
|
|
26
|
+
* Prefixing the final command with `exec` makes the shell REPLACE itself with
|
|
27
|
+
* Node, so Node becomes the direct child and receives the signal.
|
|
28
|
+
*/
|
|
29
|
+
|
|
30
|
+
const REPO_ROOT: string = path.resolve(__dirname, "..", "..", "..", "..");
|
|
31
|
+
|
|
32
|
+
// Every service whose container start script boots a long-lived process.
|
|
33
|
+
const LONG_RUNNING_SERVICES: Array<string> = [
|
|
34
|
+
"App",
|
|
35
|
+
"AIAgent",
|
|
36
|
+
"Home",
|
|
37
|
+
"Nginx",
|
|
38
|
+
"Probe",
|
|
39
|
+
"RunbookAgent",
|
|
40
|
+
"TestServer",
|
|
41
|
+
];
|
|
42
|
+
|
|
43
|
+
const BOOT_TIMEOUT_MS: number = 30000;
|
|
44
|
+
const SIGNAL_TIMEOUT_MS: number = 10000;
|
|
45
|
+
const TEST_TIMEOUT_MS: number = 90000;
|
|
46
|
+
|
|
47
|
+
type ShellShape = "fork" | "exec";
|
|
48
|
+
|
|
49
|
+
// The two shapes under test, matching the real production scripts.
|
|
50
|
+
const SHELL_SHAPES: Record<ShellShape, string> = {
|
|
51
|
+
fork: 'export NODE_OPTIONS="--max-old-space-size=512${NODE_OPTIONS:+ $NODE_OPTIONS}" && node child.js',
|
|
52
|
+
exec: 'export NODE_OPTIONS="--max-old-space-size=512${NODE_OPTIONS:+ $NODE_OPTIONS}" && exec node child.js',
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
interface Workspace {
|
|
56
|
+
dir: string;
|
|
57
|
+
cleanup: () => void;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
// Matches "&& node" but not "&& exec node".
|
|
61
|
+
const BARE_NODE_CHAIN: RegExp = /&&\s+node\s/;
|
|
62
|
+
|
|
63
|
+
/*
|
|
64
|
+
* A stand-in for a OneUptime service: it announces readiness by writing its PID,
|
|
65
|
+
* and on SIGTERM writes a marker -- the same thing GracefulShutdown does, minus
|
|
66
|
+
* the Postgres/Redis work.
|
|
67
|
+
*/
|
|
68
|
+
const CHILD_SOURCE: string = [
|
|
69
|
+
"const fs = require('fs');",
|
|
70
|
+
"process.on('SIGTERM', () => {",
|
|
71
|
+
" fs.writeFileSync(process.env.GRACEFUL_FILE, process.env.NODE_OPTIONS || '');",
|
|
72
|
+
" process.exit(0);",
|
|
73
|
+
"});",
|
|
74
|
+
"fs.writeFileSync(process.env.READY_FILE, String(process.pid));",
|
|
75
|
+
"setInterval(() => {}, 1000);",
|
|
76
|
+
].join("\n");
|
|
77
|
+
|
|
78
|
+
const createWorkspace: () => Workspace = (): Workspace => {
|
|
79
|
+
const dir: string = fs.mkdtempSync(
|
|
80
|
+
path.join(os.tmpdir(), "oneuptime-signal-"),
|
|
81
|
+
);
|
|
82
|
+
|
|
83
|
+
fs.writeFileSync(path.join(dir, "child.js"), CHILD_SOURCE);
|
|
84
|
+
fs.writeFileSync(
|
|
85
|
+
path.join(dir, "package.json"),
|
|
86
|
+
JSON.stringify({
|
|
87
|
+
name: "signal-delivery-fixture",
|
|
88
|
+
private: true,
|
|
89
|
+
scripts: SHELL_SHAPES,
|
|
90
|
+
}),
|
|
91
|
+
);
|
|
92
|
+
|
|
93
|
+
return {
|
|
94
|
+
dir,
|
|
95
|
+
cleanup: (): void => {
|
|
96
|
+
fs.rmSync(dir, { recursive: true, force: true });
|
|
97
|
+
},
|
|
98
|
+
};
|
|
99
|
+
};
|
|
100
|
+
|
|
101
|
+
const sleep: (ms: number) => Promise<void> = (ms: number): Promise<void> => {
|
|
102
|
+
return new Promise((resolve: () => void): void => {
|
|
103
|
+
setTimeout(resolve, ms);
|
|
104
|
+
});
|
|
105
|
+
};
|
|
106
|
+
|
|
107
|
+
const waitForFile: (
|
|
108
|
+
file: string,
|
|
109
|
+
timeoutMs: number,
|
|
110
|
+
) => Promise<boolean> = async (
|
|
111
|
+
file: string,
|
|
112
|
+
timeoutMs: number,
|
|
113
|
+
): Promise<boolean> => {
|
|
114
|
+
const deadline: number = Date.now() + timeoutMs;
|
|
115
|
+
while (Date.now() < deadline) {
|
|
116
|
+
if (fs.existsSync(file)) {
|
|
117
|
+
return true;
|
|
118
|
+
}
|
|
119
|
+
await sleep(50);
|
|
120
|
+
}
|
|
121
|
+
return false;
|
|
122
|
+
};
|
|
123
|
+
|
|
124
|
+
const killQuietly: (pid: number) => void = (pid: number): void => {
|
|
125
|
+
try {
|
|
126
|
+
/*
|
|
127
|
+
* Always SIGKILL when cleaning up: a SIGTERM here would run the child's
|
|
128
|
+
* handler and forge the very marker these tests assert on.
|
|
129
|
+
*/
|
|
130
|
+
process.kill(pid, "SIGKILL");
|
|
131
|
+
} catch {
|
|
132
|
+
// Already gone.
|
|
133
|
+
}
|
|
134
|
+
};
|
|
135
|
+
|
|
136
|
+
interface ShutdownOutcome {
|
|
137
|
+
// Did the child's SIGTERM handler run before the deadline?
|
|
138
|
+
gracefulShutdownRan: boolean;
|
|
139
|
+
// NODE_OPTIONS as the child observed it, captured by the handler.
|
|
140
|
+
observedNodeOptions: string | null;
|
|
141
|
+
// Did the child boot at all? Distinguishes a real failure from a flaky spawn.
|
|
142
|
+
booted: boolean;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
/*
|
|
146
|
+
* Boot `command`, wait until the child is genuinely up (no fixed sleeps), send
|
|
147
|
+
* SIGTERM to the process we spawned -- exactly what the kubelet does to PID 1 --
|
|
148
|
+
* and report whether the Node process ran its handler.
|
|
149
|
+
*/
|
|
150
|
+
const runAndTerminate: (
|
|
151
|
+
workspace: Workspace,
|
|
152
|
+
spawnChild: (env: NodeJS.ProcessEnv) => ChildProcess,
|
|
153
|
+
) => Promise<ShutdownOutcome> = async (
|
|
154
|
+
workspace: Workspace,
|
|
155
|
+
spawnChild: (env: NodeJS.ProcessEnv) => ChildProcess,
|
|
156
|
+
): Promise<ShutdownOutcome> => {
|
|
157
|
+
const unique: string = `${Date.now()}-${Math.random().toString(36).slice(2)}`;
|
|
158
|
+
const readyFile: string = path.join(workspace.dir, `ready-${unique}`);
|
|
159
|
+
const gracefulFile: string = path.join(workspace.dir, `graceful-${unique}`);
|
|
160
|
+
|
|
161
|
+
const child: ChildProcess = spawnChild({
|
|
162
|
+
...process.env,
|
|
163
|
+
READY_FILE: readyFile,
|
|
164
|
+
GRACEFUL_FILE: gracefulFile,
|
|
165
|
+
});
|
|
166
|
+
|
|
167
|
+
const booted: boolean = await waitForFile(readyFile, BOOT_TIMEOUT_MS);
|
|
168
|
+
if (!booted) {
|
|
169
|
+
if (child.pid !== undefined) {
|
|
170
|
+
killQuietly(child.pid);
|
|
171
|
+
}
|
|
172
|
+
return {
|
|
173
|
+
gracefulShutdownRan: false,
|
|
174
|
+
observedNodeOptions: null,
|
|
175
|
+
booted: false,
|
|
176
|
+
};
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
const nodePid: number = parseInt(fs.readFileSync(readyFile, "utf8"), 10);
|
|
180
|
+
|
|
181
|
+
child.kill("SIGTERM");
|
|
182
|
+
|
|
183
|
+
const gracefulShutdownRan: boolean = await waitForFile(
|
|
184
|
+
gracefulFile,
|
|
185
|
+
SIGNAL_TIMEOUT_MS,
|
|
186
|
+
);
|
|
187
|
+
|
|
188
|
+
const observedNodeOptions: string | null = gracefulShutdownRan
|
|
189
|
+
? fs.readFileSync(gracefulFile, "utf8")
|
|
190
|
+
: null;
|
|
191
|
+
|
|
192
|
+
killQuietly(nodePid);
|
|
193
|
+
if (child.pid !== undefined) {
|
|
194
|
+
killQuietly(child.pid);
|
|
195
|
+
}
|
|
196
|
+
await sleep(100);
|
|
197
|
+
|
|
198
|
+
return { gracefulShutdownRan, observedNodeOptions, booted: true };
|
|
199
|
+
};
|
|
200
|
+
|
|
201
|
+
describe("Graceful shutdown signal delivery", () => {
|
|
202
|
+
describe("shell semantics: why `exec` is required", () => {
|
|
203
|
+
test(
|
|
204
|
+
"WITHOUT exec, a compound `&&` command forks and SIGTERM never reaches Node",
|
|
205
|
+
async () => {
|
|
206
|
+
const workspace: Workspace = createWorkspace();
|
|
207
|
+
try {
|
|
208
|
+
const outcome: ShutdownOutcome = await runAndTerminate(
|
|
209
|
+
workspace,
|
|
210
|
+
(env: NodeJS.ProcessEnv): ChildProcess => {
|
|
211
|
+
return spawn("sh", ["-c", SHELL_SHAPES.fork], {
|
|
212
|
+
cwd: workspace.dir,
|
|
213
|
+
stdio: "ignore",
|
|
214
|
+
env,
|
|
215
|
+
});
|
|
216
|
+
},
|
|
217
|
+
);
|
|
218
|
+
|
|
219
|
+
expect(outcome.booted).toBe(true);
|
|
220
|
+
// This is the bug: the shell swallows the signal.
|
|
221
|
+
expect(outcome.gracefulShutdownRan).toBe(false);
|
|
222
|
+
} finally {
|
|
223
|
+
workspace.cleanup();
|
|
224
|
+
}
|
|
225
|
+
},
|
|
226
|
+
TEST_TIMEOUT_MS,
|
|
227
|
+
);
|
|
228
|
+
|
|
229
|
+
test(
|
|
230
|
+
"WITH exec, the shell is replaced by Node and SIGTERM is delivered",
|
|
231
|
+
async () => {
|
|
232
|
+
const workspace: Workspace = createWorkspace();
|
|
233
|
+
try {
|
|
234
|
+
const outcome: ShutdownOutcome = await runAndTerminate(
|
|
235
|
+
workspace,
|
|
236
|
+
(env: NodeJS.ProcessEnv): ChildProcess => {
|
|
237
|
+
return spawn("sh", ["-c", SHELL_SHAPES.exec], {
|
|
238
|
+
cwd: workspace.dir,
|
|
239
|
+
stdio: "ignore",
|
|
240
|
+
env,
|
|
241
|
+
});
|
|
242
|
+
},
|
|
243
|
+
);
|
|
244
|
+
|
|
245
|
+
expect(outcome.booted).toBe(true);
|
|
246
|
+
expect(outcome.gracefulShutdownRan).toBe(true);
|
|
247
|
+
} finally {
|
|
248
|
+
workspace.cleanup();
|
|
249
|
+
}
|
|
250
|
+
},
|
|
251
|
+
TEST_TIMEOUT_MS,
|
|
252
|
+
);
|
|
253
|
+
});
|
|
254
|
+
|
|
255
|
+
describe("the real container chain: npm run start", () => {
|
|
256
|
+
test(
|
|
257
|
+
"WITHOUT exec, npm -> sh -> node loses the signal",
|
|
258
|
+
async () => {
|
|
259
|
+
const workspace: Workspace = createWorkspace();
|
|
260
|
+
try {
|
|
261
|
+
const outcome: ShutdownOutcome = await runAndTerminate(
|
|
262
|
+
workspace,
|
|
263
|
+
(env: NodeJS.ProcessEnv): ChildProcess => {
|
|
264
|
+
return spawn("npm", ["run", "fork"], {
|
|
265
|
+
cwd: workspace.dir,
|
|
266
|
+
stdio: "ignore",
|
|
267
|
+
env,
|
|
268
|
+
});
|
|
269
|
+
},
|
|
270
|
+
);
|
|
271
|
+
|
|
272
|
+
expect(outcome.booted).toBe(true);
|
|
273
|
+
expect(outcome.gracefulShutdownRan).toBe(false);
|
|
274
|
+
} finally {
|
|
275
|
+
workspace.cleanup();
|
|
276
|
+
}
|
|
277
|
+
},
|
|
278
|
+
TEST_TIMEOUT_MS,
|
|
279
|
+
);
|
|
280
|
+
|
|
281
|
+
test(
|
|
282
|
+
"WITH exec, npm -> node delivers the signal and graceful shutdown runs",
|
|
283
|
+
async () => {
|
|
284
|
+
const workspace: Workspace = createWorkspace();
|
|
285
|
+
try {
|
|
286
|
+
const outcome: ShutdownOutcome = await runAndTerminate(
|
|
287
|
+
workspace,
|
|
288
|
+
(env: NodeJS.ProcessEnv): ChildProcess => {
|
|
289
|
+
return spawn("npm", ["run", "exec"], {
|
|
290
|
+
cwd: workspace.dir,
|
|
291
|
+
stdio: "ignore",
|
|
292
|
+
env,
|
|
293
|
+
});
|
|
294
|
+
},
|
|
295
|
+
);
|
|
296
|
+
|
|
297
|
+
expect(outcome.booted).toBe(true);
|
|
298
|
+
expect(outcome.gracefulShutdownRan).toBe(true);
|
|
299
|
+
} finally {
|
|
300
|
+
workspace.cleanup();
|
|
301
|
+
}
|
|
302
|
+
},
|
|
303
|
+
TEST_TIMEOUT_MS,
|
|
304
|
+
);
|
|
305
|
+
|
|
306
|
+
test(
|
|
307
|
+
"exec preserves the NODE_OPTIONS append semantics the images rely on",
|
|
308
|
+
async () => {
|
|
309
|
+
/*
|
|
310
|
+
* Probe, AIAgent and RunbookAgent set ENV NODE_OPTIONS="--use-openssl-ca"
|
|
311
|
+
* in their Dockerfiles; the start script appends the heap flag to it via
|
|
312
|
+
* ${NODE_OPTIONS:+ $NODE_OPTIONS}. Moving NODE_OPTIONS into the Dockerfile
|
|
313
|
+
* instead of using `exec` would silently drop --use-openssl-ca, so this
|
|
314
|
+
* guards the reason `exec` was chosen over that alternative.
|
|
315
|
+
*/
|
|
316
|
+
const workspace: Workspace = createWorkspace();
|
|
317
|
+
try {
|
|
318
|
+
const outcome: ShutdownOutcome = await runAndTerminate(
|
|
319
|
+
workspace,
|
|
320
|
+
(env: NodeJS.ProcessEnv): ChildProcess => {
|
|
321
|
+
return spawn("sh", ["-c", SHELL_SHAPES.exec], {
|
|
322
|
+
cwd: workspace.dir,
|
|
323
|
+
stdio: "ignore",
|
|
324
|
+
env: { ...env, NODE_OPTIONS: "--use-openssl-ca" },
|
|
325
|
+
});
|
|
326
|
+
},
|
|
327
|
+
);
|
|
328
|
+
|
|
329
|
+
expect(outcome.gracefulShutdownRan).toBe(true);
|
|
330
|
+
expect(outcome.observedNodeOptions).toContain("--use-openssl-ca");
|
|
331
|
+
expect(outcome.observedNodeOptions).toContain(
|
|
332
|
+
"--max-old-space-size=512",
|
|
333
|
+
);
|
|
334
|
+
} finally {
|
|
335
|
+
workspace.cleanup();
|
|
336
|
+
}
|
|
337
|
+
},
|
|
338
|
+
TEST_TIMEOUT_MS,
|
|
339
|
+
);
|
|
340
|
+
});
|
|
341
|
+
|
|
342
|
+
describe("repository invariant: every service start script is signal-safe", () => {
|
|
343
|
+
const readScript: (service: string, scriptName: string) => string | null = (
|
|
344
|
+
service: string,
|
|
345
|
+
scriptName: string,
|
|
346
|
+
): string | null => {
|
|
347
|
+
const packageJsonPath: string = path.join(
|
|
348
|
+
REPO_ROOT,
|
|
349
|
+
service,
|
|
350
|
+
"package.json",
|
|
351
|
+
);
|
|
352
|
+
const parsed: { scripts?: Record<string, string> } = JSON.parse(
|
|
353
|
+
fs.readFileSync(packageJsonPath, "utf8"),
|
|
354
|
+
) as { scripts?: Record<string, string> };
|
|
355
|
+
|
|
356
|
+
return parsed.scripts?.[scriptName] ?? null;
|
|
357
|
+
};
|
|
358
|
+
|
|
359
|
+
test.each(LONG_RUNNING_SERVICES)(
|
|
360
|
+
"%s start script hands the process to node via exec",
|
|
361
|
+
(service: string) => {
|
|
362
|
+
const startScript: string | null = readScript(service, "start");
|
|
363
|
+
|
|
364
|
+
expect(startScript).not.toBeNull();
|
|
365
|
+
|
|
366
|
+
/*
|
|
367
|
+
* Only chained scripts are at risk. A bare `node ...` is already exec'd
|
|
368
|
+
* by the shell, so it does not need the keyword.
|
|
369
|
+
*/
|
|
370
|
+
if (startScript !== null && startScript.includes("&&")) {
|
|
371
|
+
expect(startScript).toContain("&& exec node");
|
|
372
|
+
}
|
|
373
|
+
},
|
|
374
|
+
);
|
|
375
|
+
|
|
376
|
+
test("App migrate script is also signal-safe", () => {
|
|
377
|
+
/*
|
|
378
|
+
* The migration Job is long-running too, and a half-applied migration
|
|
379
|
+
* killed mid-statement is worse than a dropped HTTP request.
|
|
380
|
+
*/
|
|
381
|
+
const migrateScript: string | null = readScript("App", "migrate");
|
|
382
|
+
|
|
383
|
+
expect(migrateScript).not.toBeNull();
|
|
384
|
+
expect(migrateScript).toContain("&& exec node");
|
|
385
|
+
});
|
|
386
|
+
|
|
387
|
+
test("no service start script chains directly into a bare node invocation", () => {
|
|
388
|
+
const offenders: Array<string> = [];
|
|
389
|
+
|
|
390
|
+
for (const service of LONG_RUNNING_SERVICES) {
|
|
391
|
+
const startScript: string | null = readScript(service, "start");
|
|
392
|
+
if (startScript === null) {
|
|
393
|
+
continue;
|
|
394
|
+
}
|
|
395
|
+
if (BARE_NODE_CHAIN.test(startScript)) {
|
|
396
|
+
offenders.push(`${service}: ${startScript}`);
|
|
397
|
+
}
|
|
398
|
+
}
|
|
399
|
+
|
|
400
|
+
expect(offenders).toEqual([]);
|
|
401
|
+
});
|
|
402
|
+
});
|
|
403
|
+
|
|
404
|
+
describe("repository invariant: the nginx wrapper forwards signals", () => {
|
|
405
|
+
const runScript: string = fs.readFileSync(
|
|
406
|
+
path.join(REPO_ROOT, "Nginx", "run.sh"),
|
|
407
|
+
"utf8",
|
|
408
|
+
);
|
|
409
|
+
|
|
410
|
+
test("traps TERM so the wrapper does not swallow container termination", () => {
|
|
411
|
+
/*
|
|
412
|
+
* run.sh is PID 1 in the nginx image and backgrounds both children, so
|
|
413
|
+
* without a trap neither child is ever told to shut down.
|
|
414
|
+
*/
|
|
415
|
+
expect(runScript).toMatch(/trap\s+\w+\s+TERM/);
|
|
416
|
+
});
|
|
417
|
+
|
|
418
|
+
test("sends nginx SIGQUIT, not SIGTERM, so in-flight requests finish", () => {
|
|
419
|
+
// SIGTERM is nginx's *fast* shutdown and drops in-flight requests.
|
|
420
|
+
expect(runScript).toMatch(/kill\s+-QUIT\s+"?\$NGINX_PID/);
|
|
421
|
+
});
|
|
422
|
+
|
|
423
|
+
test("forwards SIGTERM to the node sidecar", () => {
|
|
424
|
+
expect(runScript).toMatch(/kill\s+-TERM\s+"?\$NODE_PID/);
|
|
425
|
+
});
|
|
426
|
+
});
|
|
427
|
+
});
|