Refactor for CoolifyTask.

This commit is contained in:
Joao Patricio 2023-05-03 06:15:45 +01:00
parent c3f13b54c1
commit e7763f3b73
17 changed files with 75 additions and 63 deletions

1
.gitignore vendored
View File

@ -23,3 +23,4 @@ yarn-error.log
.lesshst .lesshst
psysh_history psysh_history
.psql_history

View File

@ -1,16 +1,16 @@
<?php <?php
namespace App\Actions\RemoteProcess; namespace App\Actions\CoolifyTask;
use App\Data\RemoteProcessArgs; use App\Data\CoolifyTaskArgs;
use App\Jobs\ExecuteRemoteProcess; use App\Jobs\HandleCoolifyTaskInQueue;
use Spatie\Activitylog\Models\Activity; use Spatie\Activitylog\Models\Activity;
class DispatchRemoteProcess class PrepareCoolifyTask
{ {
protected Activity $activity; protected Activity $activity;
public function __construct(RemoteProcessArgs $remoteProcessArgs) public function __construct(CoolifyTaskArgs $remoteProcessArgs)
{ {
if ($remoteProcessArgs->model) { if ($remoteProcessArgs->model) {
$properties = $remoteProcessArgs->toArray(); $properties = $remoteProcessArgs->toArray();
@ -31,7 +31,7 @@ public function __construct(RemoteProcessArgs $remoteProcessArgs)
public function __invoke(): Activity public function __invoke(): Activity
{ {
$job = new ExecuteRemoteProcess($this->activity); $job = new HandleCoolifyTaskInQueue($this->activity);
dispatch($job); dispatch($job);
$this->activity->refresh(); $this->activity->refresh();
return $this->activity; return $this->activity;

View File

@ -1,6 +1,6 @@
<?php <?php
namespace App\Actions\RemoteProcess; namespace App\Actions\CoolifyTask;
use App\Enums\ActivityTypes; use App\Enums\ActivityTypes;
use App\Enums\ProcessStatus; use App\Enums\ProcessStatus;

View File

@ -0,0 +1,23 @@
<?php
namespace App\Data;
use App\Enums\ProcessStatus;
use Illuminate\Database\Eloquent\Model;
use Spatie\LaravelData\Data;
class CoolifyTaskArgs extends Data
{
public function __construct(
public string $server_ip,
public string $private_key_location,
public string $command,
public int $port,
public string $user,
public string $type,
public ?string $type_uuid = null,
public ?Model $model = null,
public string $status = ProcessStatus::HOLDING->value,
) {
}
}

View File

@ -1,24 +0,0 @@
<?php
namespace App\Data;
use App\Enums\ActivityTypes;
use App\Enums\ProcessStatus;
use Illuminate\Database\Eloquent\Model;
use Spatie\LaravelData\Data;
class RemoteProcessArgs extends Data
{
public function __construct(
public string $server_ip,
public string $private_key_location,
public string|null $deployment_uuid,
public string $command,
public int $port,
public string $user,
public string $type = ActivityTypes::REMOTE_PROCESS->value,
public string $status = ProcessStatus::HOLDING->value,
public ?Model $model = null,
) {
}
}

View File

@ -62,7 +62,10 @@ public function deployment()
if (!$application) { if (!$application) {
return redirect()->route('home'); return redirect()->route('home');
} }
$activity = Activity::where('properties->deployment_uuid', '=', $deployment_uuid)->first(); $activity = Activity::query()
->where('properties->type', '=', 'deployment')
->where('properties->uuid', '=', $deployment_uuid)
->first();
return view('project.deployment', [ return view('project.deployment', [
'activity' => $activity, 'activity' => $activity,

View File

@ -48,13 +48,13 @@ public function start()
public function stop() public function stop()
{ {
runRemoteCommandSync($this->destination->server, ["docker stop -t 0 {$this->application->uuid} >/dev/null 2>&1"]); instantRemoteProcess($this->destination->server, ["docker stop -t 0 {$this->application->uuid} >/dev/null 2>&1"]);
$this->application->status = 'stopped'; $this->application->status = 'stopped';
$this->application->save(); $this->application->save();
} }
public function kill() public function kill()
{ {
runRemoteCommandSync($this->destination->server, ["docker rm -f {$this->application->uuid}"]); instantRemoteProcess($this->destination->server, ["docker rm -f {$this->application->uuid}"]);
if ($this->application->status != 'exited') { if ($this->application->status != 'exited') {
$this->application->status = 'exited'; $this->application->status = 'exited';
$this->application->save(); $this->application->save();

View File

@ -2,6 +2,7 @@
namespace App\Http\Livewire; namespace App\Http\Livewire;
use App\Enums\ActivityTypes;
use Livewire\Component; use Livewire\Component;
use Spatie\Activitylog\Models\Activity; use Spatie\Activitylog\Models\Activity;
@ -14,7 +15,9 @@ class PollActivity extends Component
public function polling() public function polling()
{ {
if ( is_null($this->activity) && isset($this->deployment_uuid)) { if ( is_null($this->activity) && isset($this->deployment_uuid)) {
$this->activity = Activity::where('properties->deployment_uuid', '=', $this->deployment_uuid) $this->activity = Activity::query()
->where('properties->type', '=', ActivityTypes::DEPLOYMENT->value)
->where('properties->type_uuid', '=', $this->deployment_uuid)
->first(); ->first();
} else { } else {
$this->activity?->refresh(); $this->activity?->refresh();

View File

@ -35,7 +35,7 @@ protected function checkAllServers()
$not_found_applications = $applications; $not_found_applications = $applications;
$containers = collect(); $containers = collect();
foreach ($servers as $server) { foreach ($servers as $server) {
$output = runRemoteCommandSync($server, ['docker ps -a -q --format \'{{json .}}\'']); $output = instantRemoteProcess($server, ['docker ps -a -q --format \'{{json .}}\'']);
$containers = $containers->concat(formatDockerCmdOutputToJson($output)); $containers = $containers->concat(formatDockerCmdOutputToJson($output));
} }
foreach ($containers as $container) { foreach ($containers as $container) {
@ -68,7 +68,7 @@ protected function checkContainerStatus()
return; return;
} }
if ($application->destination->server) { if ($application->destination->server) {
$container = runRemoteCommandSync($application->destination->server, ["docker inspect --format '{{json .State}}' {$this->container_id}"]); $container = instantRemoteProcess($application->destination->server, ["docker inspect --format '{{json .State}}' {$this->container_id}"]);
$container = formatDockerCmdOutputToJson($container); $container = formatDockerCmdOutputToJson($container);
$application->status = $container[0]['Status']; $application->status = $container[0]['Status'];
$application->save(); $application->save();

View File

@ -2,8 +2,8 @@
namespace App\Jobs; namespace App\Jobs;
use App\Actions\RemoteProcess\RunRemoteProcess; use App\Actions\CoolifyTask\RunRemoteProcess;
use App\Data\RemoteProcessArgs; use App\Data\CoolifyTaskArgs;
use App\Enums\ActivityTypes; use App\Enums\ActivityTypes;
use App\Models\Application; use App\Models\Application;
use App\Models\CoolifyInstanceSettings; use App\Models\CoolifyInstanceSettings;
@ -53,14 +53,14 @@ public function __construct(
$private_key_location = savePrivateKeyForServer($server); $private_key_location = savePrivateKeyForServer($server);
$remoteProcessArgs = new RemoteProcessArgs( $remoteProcessArgs = new CoolifyTaskArgs(
server_ip: $server->ip, server_ip: $server->ip,
private_key_location: $private_key_location, private_key_location: $private_key_location,
deployment_uuid: $this->deployment_uuid,
command: 'overwritten-later', command: 'overwritten-later',
port: $server->port, port: $server->port,
user: $server->user, user: $server->user,
type: ActivityTypes::DEPLOYMENT->value, type: ActivityTypes::DEPLOYMENT->value,
type_uuid: $this->deployment_uuid,
); );
$this->activity = activity() $this->activity = activity()

View File

@ -2,7 +2,7 @@
namespace App\Jobs; namespace App\Jobs;
use App\Actions\RemoteProcess\RunRemoteProcess; use App\Actions\CoolifyTask\RunRemoteProcess;
use Illuminate\Bus\Queueable; use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue; use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable; use Illuminate\Foundation\Bus\Dispatchable;
@ -10,7 +10,7 @@
use Illuminate\Queue\SerializesModels; use Illuminate\Queue\SerializesModels;
use Spatie\Activitylog\Models\Activity; use Spatie\Activitylog\Models\Activity;
class ExecuteRemoteProcess implements ShouldQueue class HandleCoolifyTaskInQueue implements ShouldQueue
{ {
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels; use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;

View File

@ -2,6 +2,7 @@
namespace App\Providers; namespace App\Providers;
use App\Jobs\HandleCoolifyTaskInQueue;
use Illuminate\Queue\Events\JobProcessed; use Illuminate\Queue\Events\JobProcessed;
use Illuminate\Support\Facades\Process; use Illuminate\Support\Facades\Process;
use Illuminate\Support\Facades\Queue; use Illuminate\Support\Facades\Queue;
@ -31,7 +32,7 @@ public function boot(): void
{ {
Queue::after(function (JobProcessed $event) { Queue::after(function (JobProcessed $event) {
// @TODO: Remove `coolify-builder` container after the remoteProcess job is finishged and remoteProcess->type == `deployment`. // @TODO: Remove `coolify-builder` container after the remoteProcess job is finishged and remoteProcess->type == `deployment`.
if ($event->job->resolveName() === 'App\Jobs\ExecuteRemoteProcess') { if ($event->job->resolveName() === HandleCoolifyTaskInQueue::class) {
} }
}); });

View File

@ -1,8 +1,7 @@
<?php <?php
use App\Actions\RemoteProcess\DispatchRemoteProcess; use App\Actions\CoolifyTask\PrepareCoolifyTask;
use App\Data\RemoteProcessArgs; use App\Data\CoolifyTaskArgs;
use App\Enums\ActivityTypes;
use App\Models\Server; use App\Models\Server;
use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Collection; use Illuminate\Support\Collection;
@ -18,10 +17,10 @@
* *
*/ */
function remoteProcess( function remoteProcess(
array $command, array $command,
Server $server, Server $server,
?string $deployment_uuid = null, ?string $type_uuid = null,
?Model $model = null, ?Model $model = null,
): Activity { ): Activity {
$command_string = implode("\n", $command); $command_string = implode("\n", $command);
@ -31,17 +30,17 @@ function remoteProcess(
$private_key_location = savePrivateKeyForServer($server); $private_key_location = savePrivateKeyForServer($server);
return resolve(DispatchRemoteProcess::class, [ return resolve(PrepareCoolifyTask::class, [
'remoteProcessArgs' => new RemoteProcessArgs( 'remoteProcessArgs' => new CoolifyTaskArgs(
server_ip: $server->ip, server_ip: $server->ip,
private_key_location: $private_key_location, private_key_location: $private_key_location,
deployment_uuid: $deployment_uuid,
command: <<<EOT command: <<<EOT
{$command_string} {$command_string}
EOT, EOT,
port: $server->port, port: $server->port,
user: $server->user, user: $server->user,
type: $deployment_uuid ? ActivityTypes::DEPLOYMENT->value : ActivityTypes::REMOTE_PROCESS->value, type: $type_uuid,
type_uuid: $type_uuid,
model: $model, model: $model,
), ),
])(); ])();
@ -117,8 +116,8 @@ function formatDockerLabelsToJson($rawOutput): Collection
})[0]; })[0];
} }
} }
if (!function_exists('runRemoteCommandSync')) { if (!function_exists('instantRemoteProcess')) {
function runRemoteCommandSync($server, array $command) function instantRemoteProcess($server, array $command)
{ {
$command_string = implode("\n", $command); $command_string = implode("\n", $command);
$private_key_location = savePrivateKeyForServer($server); $private_key_location = savePrivateKeyForServer($server);

View File

@ -1,3 +1,6 @@
<div> <div>
<pre style="width: 100%;overflow-y: scroll;" @if ($isKeepAliveOn) wire:poll.750ms="polling" @endif>{{ \App\Actions\RemoteProcess\RunRemoteProcess::decodeOutput($activity) }}</pre> <pre
style="width: 100%;overflow-y: scroll;"
@if ($isKeepAliveOn) wire:poll.750ms="polling" @endif
>{{ \App\Actions\CoolifyTask\RunRemoteProcess::decodeOutput($activity) }}</pre>
</div> </div>

View File

@ -1,7 +1,7 @@
<div> <div>
<div> <div>
<label for="command"> <label for="command">
<input autofocus id="command" wire:model.defer="command" type="text" wire:keydown.enter="runCommand" /> <input autofocus id="command" wire:model.defer="command" type="text" wire:keydown.enter="runCommand"/>
<select wire:model.defer="server"> <select wire:model.defer="server">
@foreach ($servers as $server) @foreach ($servers as $server)
<option value="{{ $server->uuid }}">{{ $server->name }}</option> <option value="{{ $server->uuid }}">{{ $server->name }}</option>
@ -21,6 +21,9 @@
@endif @endif
</div> </div>
@isset($activity?->id) @isset($activity?->id)
<pre style="width: 100%;overflow-y: scroll;" @if ($isKeepAliveOn || $manualKeepAlive) wire:poll.750ms="polling" @endif>{{ data_get($activity, 'description') }}</pre> <pre
style="width: 100%;overflow-y: scroll;"
@if ($isKeepAliveOn) wire:poll.750ms="polling" @endif
>{{ \App\Actions\CoolifyTask\RunRemoteProcess::decodeOutput($activity) }}</pre>
@endisset @endisset
</div> </div>

View File

@ -1,7 +1,7 @@
<?php <?php
use App\Actions\RemoteProcess\RunRemoteProcess; use App\Actions\CoolifyTask\RunRemoteProcess;
use App\Actions\RemoteProcess\TidyOutput; use App\Actions\CoolifyTask\TidyOutput;
use App\Models\User; use App\Models\User;
use App\Models\Server; use App\Models\Server;
use Database\Seeders\DatabaseSeeder; use Database\Seeders\DatabaseSeeder;

View File

@ -1,6 +1,6 @@
<?php <?php
use App\Actions\RemoteProcess\RunRemoteProcess; use App\Actions\CoolifyTask\RunRemoteProcess;
use App\Models\Server; use App\Models\Server;
use Database\Seeders\DatabaseSeeder; use Database\Seeders\DatabaseSeeder;
use Illuminate\Foundation\Testing\DatabaseMigrations; use Illuminate\Foundation\Testing\DatabaseMigrations;