feat(sentinel): make sentinel mandatory on regular servers

Remove the enable/disable toggle from the server UI, logs page, and
Sentinel API so is_sentinel_enabled is derived and read-only. Enable
existing regular servers via migration, start Sentinel after validate-
and-install, and drop the daily ServerManagerJob restart.
This commit is contained in:
Andras Bacsai
2026-09-09 06:30:32 +02:00
parent d71a72a45d
commit 424dbd36ff
23 changed files with 213 additions and 292 deletions
@@ -25,7 +25,7 @@
</a>
</x-slot:actions>
<x-callout type="info" title="Metrics are not enabled">
Enable Sentinel and metrics for this server before collecting application usage data.
Enable metrics for this server before collecting application usage data.
</x-callout>
</x-application.settings-section>
@elseif (!str($resource->status)->contains('running'))
@@ -276,14 +276,14 @@
@else
<x-application.settings-section id="server-metrics-overview-section" title="Metrics"
helper="Inspect recent CPU and memory usage reported by Sentinel.">
<x-empty size="sm" title="Sentinel is required"
description="Enable Sentinel before collecting CPU and memory metrics for this server."
<x-empty size="sm" title="Metrics unavailable"
description="Sentinel metrics are unavailable on build and Swarm servers."
icon-name="dashboard">
<x-slot:contents>
<a class="button"
href="{{ route('server.sentinel', ['server_uuid' => $server->uuid]) }}"
{{ wireNavigate() }}>
Configure Sentinel
View Sentinel
<x-external-link />
</a>
</x-slot:contents>
@@ -1,44 +1,31 @@
<div class="application-settings-form flex w-full flex-col gap-6">
<form wire:submit.prevent="submit" class="contents">
@if ($isSentinelEnabled)
{{-- Scope dirty tracking to savable form fields only. Without wire:target,
Livewire compares the entire component snapshot — so dev-only x-init
`$wire.set('sentinelCustomDockerImage', …)` (and similar) briefly
flashes this bar on every page open. --}}
<x-unsaved-bar action="submit"
targets="sentinelCustomUrl,sentinelToken,sentinelMetricsRefreshRateSeconds,sentinelMetricsHistoryDays,sentinelPushIntervalSeconds" />
@endif
{{-- Scope dirty tracking to savable form fields only. Without wire:target,
Livewire compares the entire component snapshot — so dev-only x-init
`$wire.set('sentinelCustomDockerImage', …)` (and similar) briefly
flashes this bar on every page open. --}}
<x-unsaved-bar action="submit"
targets="sentinelCustomUrl,sentinelToken,sentinelMetricsRefreshRateSeconds,sentinelMetricsHistoryDays,sentinelPushIntervalSeconds" />
<x-application.settings-section id="server-sentinel-overview-section" title="Sentinel"
helper="Monitor server and container health while collecting historical metrics.">
<x-slot:actions>
<div class="flex items-center gap-2">
@if (!$isSentinelEnabled)
<x-forms.button canGate="update" :canResource="$server" isHighlighted
wire:click="toggleSentinel">
Enable Sentinel
</x-forms.button>
@else
<x-status-badge :status="$server->isSentinelLive() ? 'In sync' : 'Out of sync'"
:type="$server->isSentinelLive() ? 'success' : 'warning'" />
<x-forms.button wire:click="restartSentinel" canGate="update"
:canResource="$server">
<x-reicon name="refresh" class="size-3.5" />
{{ $server->isSentinelLive() ? 'Restart' : 'Sync' }}
</x-forms.button>
<x-forms.button canGate="update" :canResource="$server"
wire:click="toggleSentinel">
Disable
</x-forms.button>
@endif
<x-status-badge :status="$server->isSentinelLive() ? 'In sync' : 'Out of sync'"
:type="$server->isSentinelLive() ? 'success' : 'warning'" />
<x-forms.button wire:click="restartSentinel" canGate="update"
:canResource="$server">
<x-reicon name="refresh" class="size-3.5" />
{{ $server->isSentinelLive() ? 'Restart' : 'Sync' }}
</x-forms.button>
</div>
</x-slot:actions>
@if ($isSentinelEnabled && !$server->isSentinelLive())
@if (!$server->isSentinelLive())
<x-callout type="warning" title="Sentinel is out of sync">
Sync Sentinel to apply its current configuration and restore health reporting.
</x-callout>
@elseif ($isSentinelEnabled)
@else
<div class="flex items-start gap-3">
<div
class="flex size-9 shrink-0 items-center justify-center rounded-lg bg-neutral-100 text-neutral-500 dark:bg-white/[0.06] dark:text-fg-dim">
@@ -51,10 +38,6 @@
</p>
</div>
</div>
@else
<x-empty size="sm" title="Sentinel is disabled"
description="Enable Sentinel to collect metrics and monitor server and container health."
icon-name="dashboard" />
@endif
</x-application.settings-section>
@@ -21,14 +21,8 @@
displayName="Sentinel" :collapsible="false" />
</div>
@else
<x-slot:actions>
<x-forms.button canGate="manageSentinel" :canResource="$server" isHighlighted
wire:click="enableSentinel">
Enable Sentinel
</x-forms.button>
</x-slot:actions>
<x-empty size="sm" title="Sentinel is disabled"
description="Enable Sentinel to view its logs."
<x-empty size="sm" title="Sentinel is unavailable"
description="Sentinel does not run on build or Swarm servers."
icon-name="dashboard" />
@endif
</x-application.settings-section>