fix: new way to update container statuses
This commit is contained in:
@@ -30,7 +30,7 @@ class GetContainersStatus
|
||||
$this->containerReplicates = $containerReplicates;
|
||||
$this->server = $server;
|
||||
if (! $this->server->isFunctional()) {
|
||||
return 'Server is not ready.';
|
||||
return 'Server is not functional.';
|
||||
}
|
||||
$this->applications = $this->server->applications();
|
||||
$skip_these_applications = collect([]);
|
||||
|
41
app/Actions/Server/ResourcesCheck.php
Normal file
41
app/Actions/Server/ResourcesCheck.php
Normal file
@@ -0,0 +1,41 @@
|
||||
<?php
|
||||
|
||||
namespace App\Actions\Server;
|
||||
|
||||
use App\Models\Application;
|
||||
use App\Models\ServiceApplication;
|
||||
use App\Models\ServiceDatabase;
|
||||
use App\Models\StandaloneClickhouse;
|
||||
use App\Models\StandaloneDragonfly;
|
||||
use App\Models\StandaloneKeydb;
|
||||
use App\Models\StandaloneMariadb;
|
||||
use App\Models\StandaloneMongodb;
|
||||
use App\Models\StandaloneMysql;
|
||||
use App\Models\StandalonePostgresql;
|
||||
use App\Models\StandaloneRedis;
|
||||
use Lorisleiva\Actions\Concerns\AsAction;
|
||||
|
||||
class ResourcesCheck
|
||||
{
|
||||
use AsAction;
|
||||
|
||||
public function handle()
|
||||
{
|
||||
$seconds = 60;
|
||||
try {
|
||||
Application::where('last_online_at', '<', now()->subSeconds($seconds))->update(['status' => 'exited']);
|
||||
ServiceApplication::where('last_online_at', '<', now()->subSeconds($seconds))->update(['status' => 'exited']);
|
||||
ServiceDatabase::where('last_online_at', '<', now()->subSeconds($seconds))->update(['status' => 'exited']);
|
||||
StandalonePostgresql::where('last_online_at', '<', now()->subSeconds($seconds))->update(['status' => 'exited']);
|
||||
StandaloneRedis::where('last_online_at', '<', now()->subSeconds($seconds))->update(['status' => 'exited']);
|
||||
StandaloneMongodb::where('last_online_at', '<', now()->subSeconds($seconds))->update(['status' => 'exited']);
|
||||
StandaloneMysql::where('last_online_at', '<', now()->subSeconds($seconds))->update(['status' => 'exited']);
|
||||
StandaloneMariadb::where('last_online_at', '<', now()->subSeconds($seconds))->update(['status' => 'exited']);
|
||||
StandaloneKeydb::where('last_online_at', '<', now()->subSeconds($seconds))->update(['status' => 'exited']);
|
||||
StandaloneDragonfly::where('last_online_at', '<', now()->subSeconds($seconds))->update(['status' => 'exited']);
|
||||
StandaloneClickhouse::where('last_online_at', '<', now()->subSeconds($seconds))->update(['status' => 'exited']);
|
||||
} catch (\Throwable $e) {
|
||||
return handleError($e);
|
||||
}
|
||||
}
|
||||
}
|
269
app/Actions/Server/ServerCheck.php
Normal file
269
app/Actions/Server/ServerCheck.php
Normal file
@@ -0,0 +1,269 @@
|
||||
<?php
|
||||
|
||||
namespace App\Actions\Server;
|
||||
|
||||
use App\Actions\Database\StartDatabaseProxy;
|
||||
use App\Actions\Proxy\CheckProxy;
|
||||
use App\Actions\Proxy\StartProxy;
|
||||
use App\Jobs\CheckAndStartSentinelJob;
|
||||
use App\Jobs\ServerStorageCheckJob;
|
||||
use App\Models\Application;
|
||||
use App\Models\ApplicationPreview;
|
||||
use App\Models\Server;
|
||||
use App\Models\Service;
|
||||
use App\Models\ServiceApplication;
|
||||
use App\Models\ServiceDatabase;
|
||||
use App\Notifications\Container\ContainerRestarted;
|
||||
use Arr;
|
||||
use Lorisleiva\Actions\Concerns\AsAction;
|
||||
|
||||
class ServerCheck
|
||||
{
|
||||
use AsAction;
|
||||
|
||||
public Server $server;
|
||||
|
||||
public bool $isSentinel = false;
|
||||
|
||||
public $containers;
|
||||
|
||||
public $databases;
|
||||
|
||||
public function handle(Server $server, $data = null)
|
||||
{
|
||||
$this->server = $server;
|
||||
try {
|
||||
if ($this->server->isFunctional() === false) {
|
||||
return 'Server is not functional.';
|
||||
}
|
||||
|
||||
if (! $this->server->isSwarmWorker() && ! $this->server->isBuildServer()) {
|
||||
|
||||
if (isset($data)) {
|
||||
$data = collect($data);
|
||||
|
||||
$this->server->sentinelHeartbeat();
|
||||
|
||||
$this->containers = collect(data_get($data, 'containers'));
|
||||
|
||||
$filesystemUsageRoot = data_get($data, 'filesystem_usage_root.used_percentage');
|
||||
ServerStorageCheckJob::dispatch($this->server, $filesystemUsageRoot);
|
||||
|
||||
$containerReplicates = null;
|
||||
$this->isSentinel = true;
|
||||
|
||||
} else {
|
||||
['containers' => $this->containers, 'containerReplicates' => $containerReplicates] = $this->server->getContainers();
|
||||
ServerStorageCheckJob::dispatch($this->server);
|
||||
}
|
||||
|
||||
if (is_null($this->containers)) {
|
||||
return 'No containers found.';
|
||||
}
|
||||
|
||||
if (isset($containerReplicates)) {
|
||||
foreach ($containerReplicates as $containerReplica) {
|
||||
$name = data_get($containerReplica, 'Name');
|
||||
$this->containers = $this->containers->map(function ($container) use ($name, $containerReplica) {
|
||||
if (data_get($container, 'Spec.Name') === $name) {
|
||||
$replicas = data_get($containerReplica, 'Replicas');
|
||||
$running = str($replicas)->explode('/')[0];
|
||||
$total = str($replicas)->explode('/')[1];
|
||||
if ($running === $total) {
|
||||
data_set($container, 'State.Status', 'running');
|
||||
data_set($container, 'State.Health.Status', 'healthy');
|
||||
} else {
|
||||
data_set($container, 'State.Status', 'starting');
|
||||
data_set($container, 'State.Health.Status', 'unhealthy');
|
||||
}
|
||||
}
|
||||
|
||||
return $container;
|
||||
});
|
||||
}
|
||||
}
|
||||
$this->checkContainers();
|
||||
|
||||
if ($this->server->isSentinelEnabled() && $this->isSentinel === false) {
|
||||
CheckAndStartSentinelJob::dispatch($this->server);
|
||||
}
|
||||
|
||||
if ($this->server->isLogDrainEnabled()) {
|
||||
$this->checkLogDrainContainer();
|
||||
}
|
||||
|
||||
if ($this->server->proxySet() && ! $this->server->proxy->force_stop) {
|
||||
$foundProxyContainer = $this->containers->filter(function ($value, $key) {
|
||||
if ($this->server->isSwarm()) {
|
||||
return data_get($value, 'Spec.Name') === 'coolify-proxy_traefik';
|
||||
} else {
|
||||
return data_get($value, 'Name') === '/coolify-proxy';
|
||||
}
|
||||
})->first();
|
||||
if (! $foundProxyContainer) {
|
||||
try {
|
||||
$shouldStart = CheckProxy::run($this->server);
|
||||
if ($shouldStart) {
|
||||
StartProxy::run($this->server, false);
|
||||
$this->server->team?->notify(new ContainerRestarted('coolify-proxy', $this->server));
|
||||
}
|
||||
} catch (\Throwable $e) {
|
||||
}
|
||||
} else {
|
||||
$this->server->proxy->status = data_get($foundProxyContainer, 'State.Status');
|
||||
$this->server->save();
|
||||
$connectProxyToDockerNetworks = connectProxyToNetworks($this->server);
|
||||
instant_remote_process($connectProxyToDockerNetworks, $this->server, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (\Throwable $e) {
|
||||
return handleError($e);
|
||||
}
|
||||
}
|
||||
|
||||
private function checkLogDrainContainer()
|
||||
{
|
||||
$foundLogDrainContainer = $this->containers->filter(function ($value, $key) {
|
||||
return data_get($value, 'Name') === '/coolify-log-drain';
|
||||
})->first();
|
||||
if ($foundLogDrainContainer) {
|
||||
$status = data_get($foundLogDrainContainer, 'State.Status');
|
||||
if ($status !== 'running') {
|
||||
StartLogDrain::dispatch($this->server);
|
||||
}
|
||||
} else {
|
||||
StartLogDrain::dispatch($this->server);
|
||||
}
|
||||
}
|
||||
|
||||
private function checkContainers()
|
||||
{
|
||||
foreach ($this->containers as $container) {
|
||||
if ($this->isSentinel) {
|
||||
$labels = Arr::undot(data_get($container, 'labels'));
|
||||
} else {
|
||||
if ($this->server->isSwarm()) {
|
||||
$labels = Arr::undot(data_get($container, 'Spec.Labels'));
|
||||
} else {
|
||||
$labels = Arr::undot(data_get($container, 'Config.Labels'));
|
||||
}
|
||||
|
||||
}
|
||||
$managed = data_get($labels, 'coolify.managed');
|
||||
if (! $managed) {
|
||||
continue;
|
||||
}
|
||||
$uuid = data_get($labels, 'coolify.name');
|
||||
if (! $uuid) {
|
||||
$uuid = data_get($labels, 'com.docker.compose.service');
|
||||
}
|
||||
|
||||
if ($this->isSentinel) {
|
||||
$containerStatus = data_get($container, 'state');
|
||||
$containerHealth = data_get($container, 'health_status');
|
||||
} else {
|
||||
$containerStatus = data_get($container, 'State.Status');
|
||||
$containerHealth = data_get($container, 'State.Health.Status', 'unhealthy');
|
||||
}
|
||||
$containerStatus = "$containerStatus ($containerHealth)";
|
||||
|
||||
$applicationId = data_get($labels, 'coolify.applicationId');
|
||||
$serviceId = data_get($labels, 'coolify.serviceId');
|
||||
$databaseId = data_get($labels, 'coolify.databaseId');
|
||||
$pullRequestId = data_get($labels, 'coolify.pullRequestId');
|
||||
|
||||
if ($applicationId) {
|
||||
// Application
|
||||
if ($pullRequestId != 0) {
|
||||
if (str($applicationId)->contains('-')) {
|
||||
$applicationId = str($applicationId)->before('-');
|
||||
}
|
||||
$preview = ApplicationPreview::where('application_id', $applicationId)->where('pull_request_id', $pullRequestId)->first();
|
||||
if ($preview) {
|
||||
$preview->update(['status' => $containerStatus]);
|
||||
}
|
||||
} else {
|
||||
$application = Application::where('id', $applicationId)->first();
|
||||
if ($application) {
|
||||
$application->update([
|
||||
'status' => $containerStatus,
|
||||
'last_online_at' => now(),
|
||||
]);
|
||||
}
|
||||
}
|
||||
} elseif (isset($serviceId)) {
|
||||
// Service
|
||||
$subType = data_get($labels, 'coolify.service.subType');
|
||||
$subId = data_get($labels, 'coolify.service.subId');
|
||||
$service = Service::where('id', $serviceId)->first();
|
||||
if (! $service) {
|
||||
continue;
|
||||
}
|
||||
if ($subType === 'application') {
|
||||
$service = ServiceApplication::where('id', $subId)->first();
|
||||
} else {
|
||||
$service = ServiceDatabase::where('id', $subId)->first();
|
||||
}
|
||||
if ($service) {
|
||||
$service->update([
|
||||
'status' => $containerStatus,
|
||||
'last_online_at' => now(),
|
||||
]);
|
||||
if ($subType === 'database') {
|
||||
$isPublic = data_get($service, 'is_public');
|
||||
if ($isPublic) {
|
||||
$foundTcpProxy = $this->containers->filter(function ($value, $key) use ($uuid) {
|
||||
if ($this->isSentinel) {
|
||||
return data_get($value, 'name') === $uuid.'-proxy';
|
||||
} else {
|
||||
|
||||
if ($this->server->isSwarm()) {
|
||||
return data_get($value, 'Spec.Name') === "coolify-proxy_$uuid";
|
||||
} else {
|
||||
return data_get($value, 'Name') === "/$uuid-proxy";
|
||||
}
|
||||
}
|
||||
})->first();
|
||||
if (! $foundTcpProxy) {
|
||||
StartDatabaseProxy::run($service);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Database
|
||||
if (is_null($this->databases)) {
|
||||
$this->databases = $this->server->databases();
|
||||
}
|
||||
$database = $this->databases->where('uuid', $uuid)->first();
|
||||
if ($database) {
|
||||
$database->update([
|
||||
'status' => $containerStatus,
|
||||
'last_online_at' => now(),
|
||||
]);
|
||||
|
||||
$isPublic = data_get($database, 'is_public');
|
||||
if ($isPublic) {
|
||||
$foundTcpProxy = $this->containers->filter(function ($value, $key) use ($uuid) {
|
||||
if ($this->isSentinel) {
|
||||
return data_get($value, 'name') === $uuid.'-proxy';
|
||||
} else {
|
||||
if ($this->server->isSwarm()) {
|
||||
return data_get($value, 'Spec.Name') === "coolify-proxy_$uuid";
|
||||
} else {
|
||||
|
||||
return data_get($value, 'Name') === "/$uuid-proxy";
|
||||
}
|
||||
}
|
||||
})->first();
|
||||
if (! $foundTcpProxy) {
|
||||
StartDatabaseProxy::run($database);
|
||||
$this->server->team?->notify(new ContainerRestarted("TCP Proxy for {$database->name}", $this->server));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
58
app/Console/Commands/Weird.php
Normal file
58
app/Console/Commands/Weird.php
Normal file
@@ -0,0 +1,58 @@
|
||||
<?php
|
||||
|
||||
namespace App\Console\Commands;
|
||||
|
||||
use App\Actions\Server\ServerCheck;
|
||||
use App\Enums\ProxyStatus;
|
||||
use App\Enums\ProxyTypes;
|
||||
use App\Models\Server;
|
||||
use Illuminate\Console\Command;
|
||||
use Str;
|
||||
|
||||
class Weird extends Command
|
||||
{
|
||||
protected $signature = 'weird {--number=1} {--run}';
|
||||
|
||||
protected $description = 'Weird stuff';
|
||||
|
||||
public function handle()
|
||||
{
|
||||
try {
|
||||
if (! isDev()) {
|
||||
$this->error('This command can only be run in development mode');
|
||||
|
||||
return;
|
||||
}
|
||||
$run = $this->option('run');
|
||||
if ($run) {
|
||||
$servers = Server::all();
|
||||
foreach ($servers as $server) {
|
||||
ServerCheck::dispatch($server);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
$number = $this->option('number');
|
||||
for ($i = 0; $i < $number; $i++) {
|
||||
$uuid = Str::uuid();
|
||||
$server = Server::create([
|
||||
'name' => 'localhost-'.$uuid,
|
||||
'description' => 'This is a test docker container in development mode',
|
||||
'ip' => 'coolify-testing-host',
|
||||
'team_id' => 0,
|
||||
'private_key_id' => 1,
|
||||
'proxy' => [
|
||||
'type' => ProxyTypes::NONE->value,
|
||||
'status' => ProxyStatus::EXITED->value,
|
||||
],
|
||||
]);
|
||||
$server->settings->update([
|
||||
'is_usable' => true,
|
||||
'is_reachable' => true,
|
||||
]);
|
||||
}
|
||||
} catch (\Exception $e) {
|
||||
$this->error($e->getMessage());
|
||||
}
|
||||
}
|
||||
}
|
@@ -2,6 +2,7 @@
|
||||
|
||||
namespace App\Console;
|
||||
|
||||
use App\Actions\Server\ResourcesCheck;
|
||||
use App\Jobs\CheckAndStartSentinelJob;
|
||||
use App\Jobs\CheckForUpdatesJob;
|
||||
use App\Jobs\CheckHelperImageJob;
|
||||
@@ -41,13 +42,16 @@ class Kernel extends ConsoleKernel
|
||||
// Instance Jobs
|
||||
$schedule->command('horizon:snapshot')->everyMinute();
|
||||
$schedule->job(new CleanupInstanceStuffsJob)->everyMinute()->onOneServer();
|
||||
$schedule->job(new CheckHelperImageJob)->everyFiveMinutes()->onOneServer();
|
||||
|
||||
// Server Jobs
|
||||
$this->checkScheduledBackups($schedule);
|
||||
$this->checkResources($schedule);
|
||||
|
||||
$this->checkScheduledBackups($schedule);
|
||||
$this->checkScheduledTasks($schedule);
|
||||
|
||||
$schedule->command('uploads:clear')->everyTwoMinutes();
|
||||
|
||||
$schedule->job(new CheckHelperImageJob)->everyFiveMinutes()->onOneServer();
|
||||
} else {
|
||||
// Instance Jobs
|
||||
$schedule->command('horizon:snapshot')->everyFiveMinutes();
|
||||
@@ -57,9 +61,11 @@ class Kernel extends ConsoleKernel
|
||||
$this->scheduleUpdates($schedule);
|
||||
|
||||
// Server Jobs
|
||||
$this->checkScheduledBackups($schedule);
|
||||
$this->checkResources($schedule);
|
||||
|
||||
$this->pullImages($schedule);
|
||||
|
||||
$this->checkScheduledBackups($schedule);
|
||||
$this->checkScheduledTasks($schedule);
|
||||
|
||||
$schedule->command('cleanup:database --yes')->daily();
|
||||
@@ -109,12 +115,17 @@ class Kernel extends ConsoleKernel
|
||||
} else {
|
||||
$servers = $this->allServers;
|
||||
}
|
||||
// $schedule->job(new ResourcesCheck)->everyMinute()->onOneServer();
|
||||
|
||||
foreach ($servers as $server) {
|
||||
$lastSentinelUpdate = $server->sentinel_updated_at;
|
||||
$serverTimezone = $server->settings->server_timezone;
|
||||
|
||||
// Sentinel check
|
||||
$lastSentinelUpdate = $server->sentinel_updated_at;
|
||||
if (Carbon::parse($lastSentinelUpdate)->isBefore(now()->subSeconds($server->waitBeforeDoingSshCheck()))) {
|
||||
$schedule->job(new ServerCheckJob($server))->everyMinute()->onOneServer();
|
||||
}
|
||||
|
||||
if ($server->settings->force_docker_cleanup) {
|
||||
$schedule->job(new DockerCleanupJob($server))->cron($server->settings->docker_cleanup_frequency)->timezone($serverTimezone)->onOneServer();
|
||||
} else {
|
||||
|
@@ -230,7 +230,7 @@ class ApplicationDeploymentJob implements ShouldBeEncrypted, ShouldQueue
|
||||
$this->application_deployment_queue->update([
|
||||
'status' => ApplicationDeploymentStatus::IN_PROGRESS->value,
|
||||
]);
|
||||
if (! $this->server->isFunctional()) {
|
||||
if ($this->server->isFunctional() === false) {
|
||||
$this->application_deployment_queue->addLogEntry('Server is not functional.');
|
||||
$this->fail('Server is not functional.');
|
||||
|
||||
|
32
app/Jobs/ServerCheckNewJob.php
Normal file
32
app/Jobs/ServerCheckNewJob.php
Normal file
@@ -0,0 +1,32 @@
|
||||
<?php
|
||||
|
||||
namespace App\Jobs;
|
||||
|
||||
use App\Actions\Server\ServerCheck;
|
||||
use App\Models\Server;
|
||||
use Illuminate\Bus\Queueable;
|
||||
use Illuminate\Contracts\Queue\ShouldBeEncrypted;
|
||||
use Illuminate\Contracts\Queue\ShouldQueue;
|
||||
use Illuminate\Foundation\Bus\Dispatchable;
|
||||
use Illuminate\Queue\InteractsWithQueue;
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
|
||||
class ServerCheckNewJob implements ShouldBeEncrypted, ShouldQueue
|
||||
{
|
||||
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
|
||||
|
||||
public $tries = 1;
|
||||
|
||||
public $timeout = 60;
|
||||
|
||||
public function __construct(public Server $server) {}
|
||||
|
||||
public function handle()
|
||||
{
|
||||
try {
|
||||
ServerCheck::dispatch($this->server);
|
||||
} catch (\Throwable $e) {
|
||||
return handleError($e);
|
||||
}
|
||||
}
|
||||
}
|
@@ -30,8 +30,8 @@ class ServerStorageCheckJob implements ShouldBeEncrypted, ShouldQueue
|
||||
public function handle()
|
||||
{
|
||||
try {
|
||||
if (! $this->server->isFunctional()) {
|
||||
return 'Server is not ready.';
|
||||
if ($this->server->isFunctional() === false) {
|
||||
return 'Server is not functional.';
|
||||
}
|
||||
$team = data_get($this->server, 'team');
|
||||
$serverDiskUsageNotificationThreshold = data_get($this->server, 'settings.server_disk_usage_notification_threshold');
|
||||
|
@@ -117,14 +117,31 @@ class Application extends BaseModel
|
||||
if ($application->fqdn === '') {
|
||||
$application->fqdn = null;
|
||||
}
|
||||
$application->forceFill([
|
||||
'fqdn' => $application->fqdn,
|
||||
'install_command' => str($application->install_command)->trim(),
|
||||
'build_command' => str($application->build_command)->trim(),
|
||||
'start_command' => str($application->start_command)->trim(),
|
||||
'base_directory' => str($application->base_directory)->trim(),
|
||||
'publish_directory' => str($application->publish_directory)->trim(),
|
||||
]);
|
||||
$payload = [];
|
||||
if ($application->isDirty('fqdn')) {
|
||||
$payload['fqdn'] = $application->fqdn;
|
||||
}
|
||||
if ($application->isDirty('install_command')) {
|
||||
$payload['install_command'] = str($application->install_command)->trim();
|
||||
}
|
||||
if ($application->isDirty('build_command')) {
|
||||
$payload['build_command'] = str($application->build_command)->trim();
|
||||
}
|
||||
if ($application->isDirty('start_command')) {
|
||||
$payload['start_command'] = str($application->start_command)->trim();
|
||||
}
|
||||
if ($application->isDirty('base_directory')) {
|
||||
$payload['base_directory'] = str($application->base_directory)->trim();
|
||||
}
|
||||
if ($application->isDirty('publish_directory')) {
|
||||
$payload['publish_directory'] = str($application->publish_directory)->trim();
|
||||
}
|
||||
if ($application->isDirty('status')) {
|
||||
$payload['last_online_at'] = now();
|
||||
}
|
||||
if (count($payload) > 0) {
|
||||
$application->forceFill($payload);
|
||||
}
|
||||
});
|
||||
static::created(function ($application) {
|
||||
ApplicationSetting::create([
|
||||
|
@@ -28,6 +28,11 @@ class ApplicationPreview extends BaseModel
|
||||
});
|
||||
}
|
||||
});
|
||||
static::saving(function ($preview) {
|
||||
if ($preview->isDirty('status')) {
|
||||
$preview->forceFill(['last_online_at' => now()]);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public static function findPreviewByApplicationAndPullId(int $application_id, int $pull_request_id)
|
||||
|
@@ -507,20 +507,6 @@ $schema://$host {
|
||||
return Server::whereTeamId($teamId)->whereRelation('settings', 'is_reachable', true)->whereRelation('settings', 'is_build_server', true);
|
||||
}
|
||||
|
||||
public function skipServer()
|
||||
{
|
||||
if ($this->ip === '1.2.3.4') {
|
||||
// ray('skipping 1.2.3.4');
|
||||
return true;
|
||||
}
|
||||
if ($this->settings->force_disabled === true) {
|
||||
// ray('force_disabled');
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public function isForceDisabled()
|
||||
{
|
||||
return $this->settings->force_disabled;
|
||||
@@ -691,7 +677,7 @@ $schema://$host {
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$containers = instant_remote_process(["docker container inspect $(docker container ls -q) --format '{{json .}}'"], $this, false);
|
||||
$containers = instant_remote_process(["docker container inspect $(docker container ls -aq) --format '{{json .}}'"], $this, false);
|
||||
$containers = format_docker_command_output_to_json($containers);
|
||||
$containerReplicates = collect([]);
|
||||
}
|
||||
@@ -919,9 +905,9 @@ $schema://$host {
|
||||
|
||||
public function isFunctional()
|
||||
{
|
||||
$isFunctional = $this->settings->is_reachable && $this->settings->is_usable && ! $this->settings->force_disabled;
|
||||
$isFunctional = $this->settings->is_reachable && $this->settings->is_usable && $this->settings->force_disabled === false && $this->ip !== '1.2.3.4';
|
||||
|
||||
if (! $isFunctional) {
|
||||
if ($isFunctional === false) {
|
||||
Storage::disk('ssh-mux')->delete($this->muxFilename());
|
||||
}
|
||||
|
||||
@@ -988,7 +974,7 @@ $schema://$host {
|
||||
|
||||
public function status(): bool
|
||||
{
|
||||
if ($this->skipServer()) {
|
||||
if ($this->isFunctional() === false) {
|
||||
return false;
|
||||
}
|
||||
['uptime' => $uptime] = $this->validateConnection(false);
|
||||
@@ -1058,7 +1044,7 @@ $schema://$host {
|
||||
{
|
||||
config()->set('constants.ssh.mux_enabled', ! $isManualCheck);
|
||||
|
||||
if ($this->skipServer()) {
|
||||
if ($this->isFunctional() === false) {
|
||||
return ['uptime' => false, 'error' => 'Server skipped.'];
|
||||
}
|
||||
try {
|
||||
|
@@ -19,6 +19,11 @@ class ServiceApplication extends BaseModel
|
||||
$service->persistentStorages()->delete();
|
||||
$service->fileStorages()->delete();
|
||||
});
|
||||
static::saving(function ($service) {
|
||||
if ($service->isDirty('status')) {
|
||||
$service->forceFill(['last_online_at' => now()]);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public function restart()
|
||||
|
@@ -17,6 +17,11 @@ class ServiceDatabase extends BaseModel
|
||||
$service->persistentStorages()->delete();
|
||||
$service->fileStorages()->delete();
|
||||
});
|
||||
static::saving(function ($service) {
|
||||
if ($service->isDirty('status')) {
|
||||
$service->forceFill(['last_online_at' => now()]);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public function restart()
|
||||
|
@@ -38,6 +38,11 @@ class StandaloneClickhouse extends BaseModel
|
||||
$database->environment_variables()->delete();
|
||||
$database->tags()->detach();
|
||||
});
|
||||
static::saving(function ($database) {
|
||||
if ($database->isDirty('status')) {
|
||||
$database->forceFill(['last_online_at' => now()]);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
protected function serverStatus(): Attribute
|
||||
|
@@ -38,6 +38,11 @@ class StandaloneDragonfly extends BaseModel
|
||||
$database->environment_variables()->delete();
|
||||
$database->tags()->detach();
|
||||
});
|
||||
static::saving(function ($database) {
|
||||
if ($database->isDirty('status')) {
|
||||
$database->forceFill(['last_online_at' => now()]);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
protected function serverStatus(): Attribute
|
||||
|
@@ -38,6 +38,11 @@ class StandaloneKeydb extends BaseModel
|
||||
$database->environment_variables()->delete();
|
||||
$database->tags()->detach();
|
||||
});
|
||||
static::saving(function ($database) {
|
||||
if ($database->isDirty('status')) {
|
||||
$database->forceFill(['last_online_at' => now()]);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
protected function serverStatus(): Attribute
|
||||
|
@@ -38,6 +38,11 @@ class StandaloneMariadb extends BaseModel
|
||||
$database->environment_variables()->delete();
|
||||
$database->tags()->detach();
|
||||
});
|
||||
static::saving(function ($database) {
|
||||
if ($database->isDirty('status')) {
|
||||
$database->forceFill(['last_online_at' => now()]);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
protected function serverStatus(): Attribute
|
||||
|
@@ -42,6 +42,11 @@ class StandaloneMongodb extends BaseModel
|
||||
$database->environment_variables()->delete();
|
||||
$database->tags()->detach();
|
||||
});
|
||||
static::saving(function ($database) {
|
||||
if ($database->isDirty('status')) {
|
||||
$database->forceFill(['last_online_at' => now()]);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
protected function serverStatus(): Attribute
|
||||
|
@@ -39,6 +39,11 @@ class StandaloneMysql extends BaseModel
|
||||
$database->environment_variables()->delete();
|
||||
$database->tags()->detach();
|
||||
});
|
||||
static::saving(function ($database) {
|
||||
if ($database->isDirty('status')) {
|
||||
$database->forceFill(['last_online_at' => now()]);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
protected function serverStatus(): Attribute
|
||||
|
@@ -39,6 +39,11 @@ class StandalonePostgresql extends BaseModel
|
||||
$database->environment_variables()->delete();
|
||||
$database->tags()->detach();
|
||||
});
|
||||
static::saving(function ($database) {
|
||||
if ($database->isDirty('status')) {
|
||||
$database->forceFill(['last_online_at' => now()]);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public function workdir()
|
||||
|
@@ -34,6 +34,11 @@ class StandaloneRedis extends BaseModel
|
||||
$database->environment_variables()->delete();
|
||||
$database->tags()->detach();
|
||||
});
|
||||
static::saving(function ($database) {
|
||||
if ($database->isDirty('status')) {
|
||||
$database->forceFill(['last_online_at' => now()]);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
protected function serverStatus(): Attribute
|
||||
|
@@ -0,0 +1,96 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*/
|
||||
public function up(): void
|
||||
{
|
||||
Schema::table('applications', function (Blueprint $table) {
|
||||
$table->timestamp('last_online_at')->default(now())->after('updated_at');
|
||||
});
|
||||
Schema::table('application_previews', function (Blueprint $table) {
|
||||
$table->timestamp('last_online_at')->default(now())->after('updated_at');
|
||||
});
|
||||
Schema::table('service_applications', function (Blueprint $table) {
|
||||
$table->timestamp('last_online_at')->default(now())->after('updated_at');
|
||||
});
|
||||
Schema::table('service_databases', function (Blueprint $table) {
|
||||
$table->timestamp('last_online_at')->default(now())->after('updated_at');
|
||||
});
|
||||
Schema::table('standalone_postgresqls', function (Blueprint $table) {
|
||||
$table->timestamp('last_online_at')->default(now())->after('updated_at');
|
||||
});
|
||||
Schema::table('standalone_redis', function (Blueprint $table) {
|
||||
$table->timestamp('last_online_at')->default(now())->after('updated_at');
|
||||
});
|
||||
Schema::table('standalone_mongodbs', function (Blueprint $table) {
|
||||
$table->timestamp('last_online_at')->default(now())->after('updated_at');
|
||||
});
|
||||
Schema::table('standalone_mysqls', function (Blueprint $table) {
|
||||
$table->timestamp('last_online_at')->default(now())->after('updated_at');
|
||||
});
|
||||
Schema::table('standalone_mariadbs', function (Blueprint $table) {
|
||||
$table->timestamp('last_online_at')->default(now())->after('updated_at');
|
||||
});
|
||||
Schema::table('standalone_keydbs', function (Blueprint $table) {
|
||||
$table->timestamp('last_online_at')->default(now())->after('updated_at');
|
||||
});
|
||||
Schema::table('standalone_dragonflies', function (Blueprint $table) {
|
||||
$table->timestamp('last_online_at')->default(now())->after('updated_at');
|
||||
});
|
||||
Schema::table('standalone_clickhouses', function (Blueprint $table) {
|
||||
$table->timestamp('last_online_at')->default(now())->after('updated_at');
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*/
|
||||
public function down(): void
|
||||
{
|
||||
Schema::table('applications', function (Blueprint $table) {
|
||||
$table->dropColumn('last_online_at');
|
||||
});
|
||||
Schema::table('application_previews', function (Blueprint $table) {
|
||||
$table->dropColumn('last_online_at');
|
||||
});
|
||||
Schema::table('service_applications', function (Blueprint $table) {
|
||||
$table->dropColumn('last_online_at');
|
||||
});
|
||||
Schema::table('service_databases', function (Blueprint $table) {
|
||||
$table->dropColumn('last_online_at');
|
||||
});
|
||||
Schema::table('standalone_postgresqls', function (Blueprint $table) {
|
||||
$table->dropColumn('last_online_at');
|
||||
});
|
||||
Schema::table('standalone_redis', function (Blueprint $table) {
|
||||
$table->dropColumn('last_online_at');
|
||||
});
|
||||
Schema::table('standalone_mongodbs', function (Blueprint $table) {
|
||||
$table->dropColumn('last_online_at');
|
||||
});
|
||||
Schema::table('standalone_mysqls', function (Blueprint $table) {
|
||||
$table->dropColumn('last_online_at');
|
||||
});
|
||||
Schema::table('standalone_mariadbs', function (Blueprint $table) {
|
||||
$table->dropColumn('last_online_at');
|
||||
});
|
||||
Schema::table('standalone_keydbs', function (Blueprint $table) {
|
||||
$table->dropColumn('last_online_at');
|
||||
});
|
||||
Schema::table('standalone_dragonflies', function (Blueprint $table) {
|
||||
$table->dropColumn('last_online_at');
|
||||
});
|
||||
Schema::table('standalone_clickhouses', function (Blueprint $table) {
|
||||
$table->dropColumn('last_online_at');
|
||||
});
|
||||
|
||||
}
|
||||
};
|
@@ -14,6 +14,7 @@ use App\Http\Middleware\ApiAllowed;
|
||||
use App\Http\Middleware\IgnoreReadOnlyApiToken;
|
||||
use App\Http\Middleware\OnlyRootApiToken;
|
||||
use App\Jobs\PushServerUpdateJob;
|
||||
use App\Jobs\ServerCheckNewJob;
|
||||
use App\Models\Server;
|
||||
use Illuminate\Support\Facades\Route;
|
||||
|
||||
@@ -151,6 +152,7 @@ Route::group([
|
||||
}
|
||||
$data = request()->all();
|
||||
|
||||
// ServerCheckNewJob::dispatch($server, $data);
|
||||
PushServerUpdateJob::dispatch($server, $data);
|
||||
|
||||
return response()->json(['message' => 'ok'], 200);
|
||||
|
Reference in New Issue
Block a user