diff --git a/README.md b/README.md
index b2a7c0b256..d3fa07fb71 100644
--- a/README.md
+++ b/README.md
@@ -71,7 +71,6 @@ Thank you so much!
### Huge Sponsors
-* [Context.dev](https://www.context.dev/) - Web scraping API for AI agents
* [Ginernet](https://ginernet.com/) - Hosting powerful servers in Spain
* [SerpAPI](https://serpapi.com) - Google Search API — Scrape Google and other search engines from our fast, easy, and complete API.
* [MVPS](https://www.mvps.net) - Cheap VPS servers at the highest possible quality
@@ -164,6 +163,7 @@ Thank you so much!
+
...and many more at [GitHub Sponsors](https://github.com/sponsors/coollabsio)
diff --git a/app/Http/Controllers/Api/ServerDockerRegistriesController.php b/app/Http/Controllers/Api/ServerDockerRegistriesController.php
index 2923335dcd..ce40571f14 100644
--- a/app/Http/Controllers/Api/ServerDockerRegistriesController.php
+++ b/app/Http/Controllers/Api/ServerDockerRegistriesController.php
@@ -231,7 +231,7 @@ class ServerDockerRegistriesController extends Controller
#[OA\Post(
summary: 'Check a registry login on a server',
- description: 'Check that the saved login of the server for a registry still works. Runs docker login with the saved credentials on the server.',
+ description: 'Check that the saved login of the server for a registry still works. Runs docker login with the saved credentials on the server. Needs a token with the write and deploy permissions.',
path: '/servers/{uuid}/registries/{registry}/check',
operationId: 'check-server-registry-login',
security: [['bearerAuth' => []]],
diff --git a/app/Livewire/Server/GithubRunners.php b/app/Livewire/Server/GithubRunners.php
index 598a8485fc..1da4a95f48 100644
--- a/app/Livewire/Server/GithubRunners.php
+++ b/app/Livewire/Server/GithubRunners.php
@@ -55,11 +55,6 @@ class GithubRunners extends Component
public bool $allowPullRequests = false;
- /** Null until checked over SSH. */
- public ?bool $isSysboxInstalled = null;
-
- protected $listeners = ['sysboxInstalled' => 'checkSysbox'];
-
public function mount(string $server_uuid)
{
try {
@@ -178,7 +173,6 @@ class GithubRunners extends Component
$githubApp = $this->selectedApp;
$this->authorize('update', $githubApp);
if ($this->dockerMode === GithubRunnerDockerMode::Sysbox->value && ! InstallSysbox::isInstalled($this->server)) {
- $this->isSysboxInstalled = false;
throw ValidationException::withMessages(['dockerMode' => 'Sysbox is not installed on this server. Install it, then save again.']);
}
@@ -258,25 +252,6 @@ class GithubRunners extends Component
}
}
- public function checkSysbox(): void
- {
- $this->authorize('view', $this->server);
- $this->isSysboxInstalled = InstallSysbox::isInstalled($this->server);
- }
-
- public function installSysbox()
- {
- $this->authorize('update', $this->server);
-
- try {
- $activity = InstallSysbox::run($this->server);
- $this->dispatch('sysbox-install-started');
- $this->dispatch('activityMonitor', $activity->id, 'sysboxInstalled');
- } catch (\Throwable $e) {
- return handleError($e, $this);
- }
- }
-
/**
* Creates the runner group when the App can run workflow jobs. An App that is not ready is saved anyway:
* the page lists what it misses, and the runner group is created when the first job is provisioned.
diff --git a/app/Livewire/Server/Show.php b/app/Livewire/Server/Show.php
index 45b617fab1..bf5d519018 100644
--- a/app/Livewire/Server/Show.php
+++ b/app/Livewire/Server/Show.php
@@ -850,8 +850,11 @@ class Show extends Component
{
try {
$this->authorize('update', $this->server);
+ $providerRefreshed = $this->refreshProviderStatus();
if (! $this->server->isFunctional()) {
- $this->dispatch('error', 'Validate the server connection before fetching details.');
+ $providerRefreshed
+ ? $this->dispatch('info', 'Provider status refreshed. Validate the server connection to fetch server details.')
+ : $this->dispatch('error', 'Validate the server connection before fetching details.');
return;
}
@@ -868,6 +871,30 @@ class Show extends Component
}
}
+ /**
+ * Refresh the state of the linked cloud provider server, if there is one.
+ */
+ private function refreshProviderStatus(): bool
+ {
+ if (! $this->server->cloudProviderToken || $this->server->isTransferredAway()) {
+ return false;
+ }
+
+ $check = match (true) {
+ filled($this->server->hetzner_server_id) => $this->checkHetznerServerStatus(...),
+ filled($this->server->digitalocean_droplet_id) => $this->checkDigitalOceanDropletStatus(...),
+ filled($this->server->vultr_instance_id) => $this->checkVultrInstanceStatus(...),
+ filled($this->server->hostinger_virtual_machine_id) => $this->checkHostingerVirtualMachineStatus(...),
+ default => null,
+ };
+ if (! $check) {
+ return false;
+ }
+ $check();
+
+ return true;
+ }
+
public function submit()
{
try {
diff --git a/app/Livewire/Server/SysboxStatus.php b/app/Livewire/Server/SysboxStatus.php
new file mode 100644
index 0000000000..06cb0549b3
--- /dev/null
+++ b/app/Livewire/Server/SysboxStatus.php
@@ -0,0 +1,62 @@
+ 'checkSysbox'];
+
+ public function mount(Server $server): void
+ {
+ $this->authorize('view', $server);
+ $this->server = $server;
+ $this->checkSysbox();
+ }
+
+ public function checkSysbox(): void
+ {
+ $this->authorize('view', $this->server);
+ $this->isInstalled = InstallSysbox::isInstalled($this->server);
+ }
+
+ public function installSysbox()
+ {
+ $this->authorize('update', $this->server);
+
+ try {
+ $activity = InstallSysbox::run($this->server);
+ $this->dispatch('sysbox-install-started');
+ $this->dispatch('activityMonitor', $activity->id, 'sysboxInstalled');
+ } catch (\Throwable $e) {
+ return handleError($e, $this);
+ }
+ }
+
+ public function placeholder(): View
+ {
+ return view('livewire.server.sysbox-status-placeholder');
+ }
+
+ public function render(): View
+ {
+ return view('livewire.server.sysbox-status');
+ }
+}
diff --git a/openapi.json b/openapi.json
index 19c828a514..11f73af9eb 100644
--- a/openapi.json
+++ b/openapi.json
@@ -18391,7 +18391,7 @@
"Servers"
],
"summary": "Check a registry login on a server",
- "description": "Check that the saved login of the server for a registry still works. Runs docker login with the saved credentials on the server.",
+ "description": "Check that the saved login of the server for a registry still works. Runs docker login with the saved credentials on the server. Needs a token with the write and deploy permissions.",
"operationId": "check-server-registry-login",
"parameters": [
{
diff --git a/openapi.yaml b/openapi.yaml
index 03d18b3832..05ef6d55cf 100644
--- a/openapi.yaml
+++ b/openapi.yaml
@@ -11705,7 +11705,7 @@ paths:
tags:
- Servers
summary: 'Check a registry login on a server'
- description: 'Check that the saved login of the server for a registry still works. Runs docker login with the saved credentials on the server.'
+ description: 'Check that the saved login of the server for a registry still works. Runs docker login with the saved credentials on the server. Needs a token with the write and deploy permissions.'
operationId: check-server-registry-login
parameters:
-
diff --git a/resources/views/components/status-badge.blade.php b/resources/views/components/status-badge.blade.php
index 1f1b3089b0..6cabaa1a40 100644
--- a/resources/views/components/status-badge.blade.php
+++ b/resources/views/components/status-badge.blade.php
@@ -6,6 +6,7 @@
'dynamic' => false,
'pulse' => false, // ping the dot for a state that is still in progress
'size' => 'md', // sm fits inline next to 12px table text without growing the row
+ 'spinning' => false, // show the loading spinner instead of the dot, e.g. for a running deployment
])
@php
@@ -29,12 +30,19 @@
@if ($dynamic)
{{ $slot }}
@else
+ @if ($spinning)
+
+ @else
@if ($pulse)
@endif
+ @endif
{{ collect([$label, $status])->filter()->join(' ') }}
@endif
@@ -43,12 +51,19 @@
@if ($dynamic)
{{ $slot }}
@else
+ @if ($spinning)
+
+ @else
@if ($pulse)
@endif
+ @endif
{{ collect([$label, $status])->filter()->join(' ') }}
@endif
@@ -57,12 +72,19 @@
@if ($dynamic)
{{ $slot }}
@else
+ @if ($spinning)
+
+ @else
@if ($pulse)
@endif
+ @endif
{{ collect([$label, $status])->filter()->join(' ') }}
@endif
diff --git a/resources/views/livewire/dashboard/active-deployments.blade.php b/resources/views/livewire/dashboard/active-deployments.blade.php
index dc3ab8ed93..451a7a7837 100644
--- a/resources/views/livewire/dashboard/active-deployments.blade.php
+++ b/resources/views/livewire/dashboard/active-deployments.blade.php
@@ -81,14 +81,14 @@
{{ $deployment->server_name ?: '-' }}
{{ $deployment->created_at?->diffForHumans() ?? '-' }}
{{ $environmentPath ?: '-' }} · @@ -141,14 +141,14 @@ {{ $deployment->server_name ?: '-' }}
-{{ $deployment->created_at?->diffForHumans() ?? '-' }}
{{ $environmentPath ?: '-' }} · diff --git a/resources/views/livewire/deployments-indicator.blade.php b/resources/views/livewire/deployments-indicator.blade.php index 7d745f7066..c325949389 100644 --- a/resources/views/livewire/deployments-indicator.blade.php +++ b/resources/views/livewire/deployments-indicator.blade.php @@ -48,7 +48,7 @@
{{ $deployment->application_name }}
-