diff --git a/app/Console/Kernel.php b/app/Console/Kernel.php index c6ee39524..fdfbc8aff 100644 --- a/app/Console/Kernel.php +++ b/app/Console/Kernel.php @@ -13,6 +13,7 @@ use App\Jobs\PullSentinelImageJob; use App\Jobs\PullTemplatesFromCDN; use App\Jobs\ScheduledTaskJob; use App\Jobs\ServerStatusJob; +use App\Models\InstanceSettings; use App\Models\ScheduledDatabaseBackup; use App\Models\ScheduledTask; use App\Models\Server; @@ -27,6 +28,8 @@ class Kernel extends ConsoleKernel protected function schedule(Schedule $schedule): void { $this->all_servers = Server::all(); + $settings = InstanceSettings::get(); + if (isDev()) { // Instance Jobs $schedule->command('horizon:snapshot')->everyMinute(); @@ -42,16 +45,17 @@ class Kernel extends ConsoleKernel // Instance Jobs $schedule->command('horizon:snapshot')->everyFiveMinutes(); $schedule->command('cleanup:unreachable-servers')->daily(); - $schedule->job(new PullCoolifyImageJob)->everyTenMinutes()->onOneServer(); + $schedule->job(new PullCoolifyImageJob)->cron($settings->update_check_frequency)->onOneServer(); $schedule->job(new PullTemplatesFromCDN)->everyThirtyMinutes()->onOneServer(); $schedule->job(new CleanupInstanceStuffsJob)->everyTwoMinutes()->onOneServer(); - // $schedule->job(new CheckResaleLicenseJob)->hourly()->onOneServer(); // Server Jobs - $this->check_scheduled_backups($schedule); - $this->check_resources($schedule); + $this->scheduleUpdates($schedule); $this->pull_images($schedule); + $this->check_resources($schedule); $this->check_scheduled_tasks($schedule); + $this->check_scheduled_backups($schedule); + $schedule->command('cleanup:database --yes')->daily(); $schedule->command('uploads:clear')->everyTwoMinutes(); @@ -60,12 +64,28 @@ class Kernel extends ConsoleKernel private function pull_images($schedule) { + $settings = InstanceSettings::get(); $servers = $this->all_servers->where('settings.is_usable', true)->where('settings.is_reachable', true)->where('ip', '!=', '1.2.3.4'); foreach ($servers as $server) { if ($server->isSentinelEnabled()) { - $schedule->job(new PullSentinelImageJob($server))->everyFiveMinutes()->onOneServer(); + $schedule->job(new PullSentinelImageJob($server))->cron($settings->update_check_frequency)->onOneServer(); } - $schedule->job(new PullHelperImageJob($server))->everyFiveMinutes()->onOneServer(); + $schedule->job(new PullHelperImageJob($server))->cron($settings->update_check_frequency)->onOneServer(); + } + } + + private function scheduleUpdates($schedule) + { + $settings = InstanceSettings::get(); + + // Schedule update check + if ($settings->update_check_frequency) { + $schedule->job(new CheckForUpdatesJob())->cron($settings->update_check_frequency)->onOneServer(); + } + + // Schedule auto-update + if ($settings->is_auto_update_enabled && $settings->auto_update_frequency) { + $schedule->job(new UpdateCoolifyJob())->cron($settings->auto_update_frequency)->onOneServer(); } } @@ -162,4 +182,4 @@ class Kernel extends ConsoleKernel require base_path('routes/console.php'); } -} +} \ No newline at end of file diff --git a/app/Jobs/CheckForUpdatesJob.php b/app/Jobs/CheckForUpdatesJob.php new file mode 100644 index 000000000..8141dd3fa --- /dev/null +++ b/app/Jobs/CheckForUpdatesJob.php @@ -0,0 +1,46 @@ +get('https://cdn.coollabs.io/coolify/versions.json'); + if ($response->successful()) { + $versions = $response->json(); + $latest_version = $versions['latest']; + $current_version = config('version'); + + if (version_compare($latest_version, $current_version, '>')) { + // New version available + $settings->update(['new_version_available' => true]); + // Optionally, you can trigger a notification here + } else { + $settings->update(['new_version_available' => false]); + } + } + } catch (\Throwable $e) { + // Log the error or send a notification + ray('CheckForUpdatesJob failed: ' . $e->getMessage()); + } + } +} \ No newline at end of file diff --git a/app/Jobs/PullCoolifyImageJob.php b/app/Jobs/PullCoolifyImageJob.php index 253b0b9f0..9c8145b70 100644 --- a/app/Jobs/PullCoolifyImageJob.php +++ b/app/Jobs/PullCoolifyImageJob.php @@ -2,6 +2,7 @@ namespace App\Jobs; +use App\Models\InstanceSettings; use App\Models\Server; use Illuminate\Bus\Queueable; use Illuminate\Contracts\Queue\ShouldBeEncrypted; @@ -16,16 +17,13 @@ class PullCoolifyImageJob implements ShouldBeEncrypted, ShouldQueue { use Dispatchable, InteractsWithQueue, Queueable, SerializesModels; - public $timeout = 1000; - - public function __construct() {} - public function handle(): void { try { if (isDev() || isCloud()) { return; } + $settings = InstanceSettings::get(); $server = Server::findOrFail(0); $response = Http::retry(3, 1000)->get('https://cdn.coollabs.io/coolify/versions.json'); if ($response->successful()) { @@ -35,7 +33,6 @@ class PullCoolifyImageJob implements ShouldBeEncrypted, ShouldQueue $latest_version = get_latest_version_of_coolify(); instant_remote_process(["docker pull -q ghcr.io/coollabsio/coolify:{$latest_version}"], $server, false); - $settings = \App\Models\InstanceSettings::get(); $current_version = config('version'); if (! $settings->is_auto_update_enabled) { return; @@ -46,12 +43,9 @@ class PullCoolifyImageJob implements ShouldBeEncrypted, ShouldQueue if (version_compare($latest_version, $current_version, '<')) { return; } - instant_remote_process([ - 'curl -fsSL https://cdn.coollabs.io/coolify/upgrade.sh -o /data/coolify/source/upgrade.sh', - "bash /data/coolify/source/upgrade.sh $latest_version", - ], $server); + // The actual update process will be handled by the UpdateCoolifyJob } catch (\Throwable $e) { throw $e; } } -} +} \ No newline at end of file diff --git a/app/Jobs/UpdateCoolifyJob.php b/app/Jobs/UpdateCoolifyJob.php new file mode 100644 index 000000000..243e3934f --- /dev/null +++ b/app/Jobs/UpdateCoolifyJob.php @@ -0,0 +1,44 @@ +is_auto_update_enabled || !$settings->new_version_available) { + return; + } + + $server = Server::findOrFail(0); + if (!$server) { + return; + } + + UpdateCoolify::run(false); // false means it's not a manual update + + // After successful update, reset the new_version_available flag + $settings->update(['new_version_available' => false]); + + } catch (\Throwable $e) { + // Log the error or send a notification + ray('UpdateCoolifyJob failed: ' . $e->getMessage()); + } + } +} \ No newline at end of file diff --git a/database/migrations/2024_08_05_142659_add_new_version_available_to_instance_settings_table.php b/database/migrations/2024_08_05_142659_add_new_version_available_to_instance_settings_table.php new file mode 100644 index 000000000..37cd93dc4 --- /dev/null +++ b/database/migrations/2024_08_05_142659_add_new_version_available_to_instance_settings_table.php @@ -0,0 +1,30 @@ +string('update_check_frequency')->nullable(); + $table->string('auto_update_frequency')->nullable(); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::table('instance_settings', function (Blueprint $table) { + $table->dropColumn('update_check_frequency'); + $table->dropColumn('auto_update_frequency'); + }); + } +};