mirror of
https://github.com/vitodeploy/vito.git
synced 2025-04-17 17:01:37 +00:00
enable/disable cronjobs (#203)
This commit is contained in:
parent
1067a5fd33
commit
88223a61f9
@ -2,6 +2,7 @@
|
||||
|
||||
namespace App\Actions\CronJob;
|
||||
|
||||
use App\Enums\CronjobStatus;
|
||||
use App\Models\CronJob;
|
||||
use App\Models\Server;
|
||||
|
||||
@ -10,7 +11,9 @@ class DeleteCronJob
|
||||
public function delete(Server $server, CronJob $cronJob): void
|
||||
{
|
||||
$user = $cronJob->user;
|
||||
$cronJob->delete();
|
||||
$cronJob->status = CronjobStatus::DELETING;
|
||||
$cronJob->save();
|
||||
$server->cron()->update($cronJob->user, CronJob::crontab($server, $user));
|
||||
$cronJob->delete();
|
||||
}
|
||||
}
|
||||
|
20
app/Actions/CronJob/DisableCronJob.php
Executable file
20
app/Actions/CronJob/DisableCronJob.php
Executable file
@ -0,0 +1,20 @@
|
||||
<?php
|
||||
|
||||
namespace App\Actions\CronJob;
|
||||
|
||||
use App\Enums\CronjobStatus;
|
||||
use App\Models\CronJob;
|
||||
use App\Models\Server;
|
||||
|
||||
class DisableCronJob
|
||||
{
|
||||
public function disable(Server $server, CronJob $cronJob): void
|
||||
{
|
||||
$cronJob->status = CronjobStatus::DISABLING;
|
||||
$cronJob->save();
|
||||
|
||||
$server->cron()->update($cronJob->user, CronJob::crontab($server, $cronJob->user));
|
||||
$cronJob->status = CronjobStatus::DISABLED;
|
||||
$cronJob->save();
|
||||
}
|
||||
}
|
20
app/Actions/CronJob/EnableCronJob.php
Executable file
20
app/Actions/CronJob/EnableCronJob.php
Executable file
@ -0,0 +1,20 @@
|
||||
<?php
|
||||
|
||||
namespace App\Actions\CronJob;
|
||||
|
||||
use App\Enums\CronjobStatus;
|
||||
use App\Models\CronJob;
|
||||
use App\Models\Server;
|
||||
|
||||
class EnableCronJob
|
||||
{
|
||||
public function enable(Server $server, CronJob $cronJob): void
|
||||
{
|
||||
$cronJob->status = CronjobStatus::ENABLING;
|
||||
$cronJob->save();
|
||||
|
||||
$server->cron()->update($cronJob->user, CronJob::crontab($server, $cronJob->user));
|
||||
$cronJob->status = CronjobStatus::READY;
|
||||
$cronJob->save();
|
||||
}
|
||||
}
|
@ -9,4 +9,10 @@ final class CronjobStatus
|
||||
const READY = 'ready';
|
||||
|
||||
const DELETING = 'deleting';
|
||||
|
||||
const ENABLING = 'enabling';
|
||||
|
||||
const DISABLING = 'disabling';
|
||||
|
||||
const DISABLED = 'disabled';
|
||||
}
|
||||
|
@ -4,6 +4,8 @@
|
||||
|
||||
use App\Actions\CronJob\CreateCronJob;
|
||||
use App\Actions\CronJob\DeleteCronJob;
|
||||
use App\Actions\CronJob\DisableCronJob;
|
||||
use App\Actions\CronJob\EnableCronJob;
|
||||
use App\Facades\Toast;
|
||||
use App\Helpers\HtmxResponse;
|
||||
use App\Models\CronJob;
|
||||
@ -45,4 +47,26 @@ public function destroy(Server $server, CronJob $cronJob): RedirectResponse
|
||||
|
||||
return back();
|
||||
}
|
||||
|
||||
public function enable(Server $server, CronJob $cronJob): RedirectResponse
|
||||
{
|
||||
$this->authorize('manage', $server);
|
||||
|
||||
app(EnableCronJob::class)->enable($server, $cronJob);
|
||||
|
||||
Toast::success('Cronjob enabled successfully.');
|
||||
|
||||
return back();
|
||||
}
|
||||
|
||||
public function disable(Server $server, CronJob $cronJob): RedirectResponse
|
||||
{
|
||||
$this->authorize('manage', $server);
|
||||
|
||||
app(DisableCronJob::class)->disable($server, $cronJob);
|
||||
|
||||
Toast::success('Cronjob disabled successfully.');
|
||||
|
||||
return back();
|
||||
}
|
||||
}
|
||||
|
@ -2,6 +2,7 @@
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use App\Enums\CronjobStatus;
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
|
||||
@ -41,7 +42,14 @@ public function server(): BelongsTo
|
||||
public static function crontab(Server $server, string $user): string
|
||||
{
|
||||
$data = '';
|
||||
$cronJobs = $server->cronJobs()->where('user', $user)->get();
|
||||
$cronJobs = $server->cronJobs()
|
||||
->where('user', $user)
|
||||
->whereIn('status', [
|
||||
CronjobStatus::READY,
|
||||
CronjobStatus::CREATING,
|
||||
CronjobStatus::ENABLING,
|
||||
])
|
||||
->get();
|
||||
foreach ($cronJobs as $key => $cronJob) {
|
||||
$data .= $cronJob->frequency.' '.$cronJob->command;
|
||||
if ($key != count($cronJobs) - 1) {
|
||||
|
File diff suppressed because one or more lines are too long
@ -1,6 +1,6 @@
|
||||
{
|
||||
"resources/css/app.css": {
|
||||
"file": "assets/app-1c10ca5c.css",
|
||||
"file": "assets/app-4e6a754c.css",
|
||||
"isEntry": true,
|
||||
"src": "resources/css/app.css"
|
||||
},
|
||||
|
@ -432,7 +432,7 @@ class="-ml-1 mr-1.5 h-[18px] w-[18px]"
|
||||
></path>
|
||||
</svg>
|
||||
<p
|
||||
class="font-medium leading-none text-gray-800 dark:text-white"
|
||||
class="text-sm font-medium leading-none text-gray-800 dark:text-white"
|
||||
x-text="toast.message"
|
||||
></p>
|
||||
</div>
|
||||
|
@ -30,6 +30,11 @@ class="p-6"
|
||||
type="text"
|
||||
class="mt-1 w-full"
|
||||
/>
|
||||
<x-input-help class="mt-2">
|
||||
<a href="https://vitodeploy.com/servers/cronjobs.html" target="_blank" class="text-primary-500">
|
||||
How the command should look like?
|
||||
</a>
|
||||
</x-input-help>
|
||||
@error("command")
|
||||
<x-input-error class="mt-2" :messages="$message" />
|
||||
@enderror
|
||||
|
@ -12,19 +12,50 @@
|
||||
<div x-data="" class="space-y-3">
|
||||
@if (count($cronjobs) > 0)
|
||||
@foreach ($cronjobs as $cronjob)
|
||||
<x-item-card>
|
||||
<x-item-card id="cronjob-{{ $cronjob->id }}">
|
||||
<div class="flex flex-grow flex-col items-start justify-center">
|
||||
<span class="mb-1 flex items-center lowercase text-red-600">
|
||||
<div class="mb-1 text-left text-xs lowercase text-red-600 md:text-sm">
|
||||
{{ $cronjob->command }}
|
||||
</span>
|
||||
<span class="text-sm text-gray-400">
|
||||
</div>
|
||||
<div class="text-xs text-gray-400 md:text-sm">
|
||||
{{ $cronjob->frequencyLabel() }}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex items-center">
|
||||
@include("cronjobs.partials.status", ["status" => $cronjob->status])
|
||||
<div class="inline">
|
||||
<div class="ml-1 inline">
|
||||
@if ($cronjob->status == \App\Enums\CronjobStatus::READY)
|
||||
<x-icon-button
|
||||
id="disable-cronjob-{{ $cronjob->id }}"
|
||||
data-tooltip="Disable Cronjob"
|
||||
hx-post="{{ route('servers.cronjobs.disable', ['server' => $server, 'cronJob' => $cronjob]) }}"
|
||||
hx-target="#cronjob-{{ $cronjob->id }}"
|
||||
hx-select="#cronjob-{{ $cronjob->id }}"
|
||||
hx-swap="outerHTML"
|
||||
hx-ext="disable-element"
|
||||
hx-disable-element="#disable-cronjob-{{ $cronjob->id }}"
|
||||
>
|
||||
<x-heroicon name="o-stop" class="h-5 w-5" />
|
||||
</x-icon-button>
|
||||
@endif
|
||||
|
||||
@if ($cronjob->status == \App\Enums\CronjobStatus::DISABLED)
|
||||
<x-icon-button
|
||||
id="enable-cronjob-{{ $cronjob->id }}"
|
||||
data-tooltip="Enable Cronjob"
|
||||
hx-post="{{ route('servers.cronjobs.enable', ['server' => $server, 'cronJob' => $cronjob]) }}"
|
||||
hx-target="#cronjob-{{ $cronjob->id }}"
|
||||
hx-select="#cronjob-{{ $cronjob->id }}"
|
||||
hx-swap="outerHTML"
|
||||
hx-ext="disable-element"
|
||||
hx-disable-element="#enable-cronjob-{{ $cronjob->id }}"
|
||||
>
|
||||
<x-heroicon name="o-play" class="h-5 w-5" />
|
||||
</x-icon-button>
|
||||
@endif
|
||||
|
||||
<x-icon-button
|
||||
data-tooltip="Delete Cronjob"
|
||||
x-on:click="deleteAction = '{{ route('servers.cronjobs.destroy', ['server' => $server, 'cronJob' => $cronjob]) }}'; $dispatch('open-modal', 'delete-cronjob')"
|
||||
>
|
||||
<x-heroicon name="o-trash" class="h-5 w-5" />
|
||||
|
@ -6,6 +6,18 @@
|
||||
<x-status status="warning">{{ $status }}</x-status>
|
||||
@endif
|
||||
|
||||
@if ($status == \App\Enums\CronjobStatus::DISABLING)
|
||||
<x-status status="warning">{{ $status }}</x-status>
|
||||
@endif
|
||||
|
||||
@if ($status == \App\Enums\CronjobStatus::DISABLED)
|
||||
<x-status status="disabled">{{ $status }}</x-status>
|
||||
@endif
|
||||
|
||||
@if ($status == \App\Enums\CronjobStatus::ENABLING)
|
||||
<x-status status="warning">{{ $status }}</x-status>
|
||||
@endif
|
||||
|
||||
@if ($status == \App\Enums\CronjobStatus::DELETING)
|
||||
<x-status status="danger">{{ $status }}</x-status>
|
||||
@endif
|
||||
|
@ -113,6 +113,8 @@
|
||||
Route::get('/{server}/cronjobs', [CronjobController::class, 'index'])->name('servers.cronjobs');
|
||||
Route::post('/{server}/cronjobs', [CronjobController::class, 'store'])->name('servers.cronjobs.store');
|
||||
Route::delete('/{server}/cronjobs/{cronJob}', [CronjobController::class, 'destroy'])->name('servers.cronjobs.destroy');
|
||||
Route::post('/{server}/cronjobs/{cronJob}/enable', [CronjobController::class, 'enable'])->name('servers.cronjobs.enable');
|
||||
Route::post('/{server}/cronjobs/{cronJob}/disable', [CronjobController::class, 'disable'])->name('servers.cronjobs.disable');
|
||||
|
||||
// ssh keys
|
||||
Route::get('/{server}/ssh-keys', [SSHKeyController::class, 'index'])->name('servers.ssh-keys');
|
||||
|
@ -99,4 +99,60 @@ public function test_create_custom_cronjob()
|
||||
SSH::assertExecutedContains("echo '* * * 1 1 ls -la' | sudo -u vito crontab -");
|
||||
SSH::assertExecutedContains('sudo -u vito crontab -l');
|
||||
}
|
||||
|
||||
public function test_enable_cronjob()
|
||||
{
|
||||
SSH::fake();
|
||||
|
||||
$this->actingAs($this->user);
|
||||
|
||||
/** @var CronJob $cronjob */
|
||||
$cronjob = CronJob::factory()->create([
|
||||
'server_id' => $this->server->id,
|
||||
'user' => 'vito',
|
||||
'command' => 'ls -la',
|
||||
'frequency' => '* * * 1 1',
|
||||
'status' => CronjobStatus::DISABLED,
|
||||
]);
|
||||
|
||||
$this->post(route('servers.cronjobs.enable', [
|
||||
'server' => $this->server,
|
||||
'cronJob' => $cronjob,
|
||||
]))->assertSessionDoesntHaveErrors();
|
||||
|
||||
$cronjob->refresh();
|
||||
|
||||
$this->assertEquals(CronjobStatus::READY, $cronjob->status);
|
||||
|
||||
SSH::assertExecutedContains("echo '* * * 1 1 ls -la' | sudo -u vito crontab -");
|
||||
SSH::assertExecutedContains('sudo -u vito crontab -l');
|
||||
}
|
||||
|
||||
public function test_disable_cronjob()
|
||||
{
|
||||
SSH::fake();
|
||||
|
||||
$this->actingAs($this->user);
|
||||
|
||||
/** @var CronJob $cronjob */
|
||||
$cronjob = CronJob::factory()->create([
|
||||
'server_id' => $this->server->id,
|
||||
'user' => 'vito',
|
||||
'command' => 'ls -la',
|
||||
'frequency' => '* * * 1 1',
|
||||
'status' => CronjobStatus::READY,
|
||||
]);
|
||||
|
||||
$this->post(route('servers.cronjobs.disable', [
|
||||
'server' => $this->server,
|
||||
'cronJob' => $cronjob,
|
||||
]))->assertSessionDoesntHaveErrors();
|
||||
|
||||
$cronjob->refresh();
|
||||
|
||||
$this->assertEquals(CronjobStatus::DISABLED, $cronjob->status);
|
||||
|
||||
SSH::assertExecutedContains("echo '' | sudo -u vito crontab -");
|
||||
SSH::assertExecutedContains('sudo -u vito crontab -l');
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user