fix: service navbar using new realtime events
This commit is contained in:
parent
86c2415210
commit
b55bd298f2
@ -39,7 +39,7 @@ public function __construct(CoolifyTaskArgs $remoteProcessArgs)
|
|||||||
|
|
||||||
public function __invoke(): Activity
|
public function __invoke(): Activity
|
||||||
{
|
{
|
||||||
$job = new CoolifyTask($this->activity, ignore_errors: $this->remoteProcessArgs->ignore_errors);
|
$job = new CoolifyTask($this->activity, ignore_errors: $this->remoteProcessArgs->ignore_errors, call_event_on_finish: $this->remoteProcessArgs->call_event_on_finish);
|
||||||
dispatch($job);
|
dispatch($job);
|
||||||
$this->activity->refresh();
|
$this->activity->refresh();
|
||||||
return $this->activity;
|
return $this->activity;
|
||||||
|
@ -21,6 +21,8 @@ class RunRemoteProcess
|
|||||||
|
|
||||||
public bool $ignore_errors;
|
public bool $ignore_errors;
|
||||||
|
|
||||||
|
public $call_event_on_finish = null;
|
||||||
|
|
||||||
protected $time_start;
|
protected $time_start;
|
||||||
|
|
||||||
protected $current_time;
|
protected $current_time;
|
||||||
@ -34,7 +36,7 @@ class RunRemoteProcess
|
|||||||
/**
|
/**
|
||||||
* Create a new job instance.
|
* Create a new job instance.
|
||||||
*/
|
*/
|
||||||
public function __construct(Activity $activity, bool $hide_from_output = false, bool $is_finished = false, bool $ignore_errors = false)
|
public function __construct(Activity $activity, bool $hide_from_output = false, bool $is_finished = false, bool $ignore_errors = false, $call_event_on_finish = null)
|
||||||
{
|
{
|
||||||
|
|
||||||
if ($activity->getExtraProperty('type') !== ActivityTypes::INLINE->value) {
|
if ($activity->getExtraProperty('type') !== ActivityTypes::INLINE->value) {
|
||||||
@ -45,6 +47,7 @@ public function __construct(Activity $activity, bool $hide_from_output = false,
|
|||||||
$this->hide_from_output = $hide_from_output;
|
$this->hide_from_output = $hide_from_output;
|
||||||
$this->is_finished = $is_finished;
|
$this->is_finished = $is_finished;
|
||||||
$this->ignore_errors = $ignore_errors;
|
$this->ignore_errors = $ignore_errors;
|
||||||
|
$this->call_event_on_finish = $call_event_on_finish;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function decodeOutput(?Activity $activity = null): string
|
public static function decodeOutput(?Activity $activity = null): string
|
||||||
@ -79,12 +82,18 @@ public function __invoke(): ProcessResult
|
|||||||
if ($this->activity->properties->get('status') === ProcessStatus::ERROR->value) {
|
if ($this->activity->properties->get('status') === ProcessStatus::ERROR->value) {
|
||||||
$status = ProcessStatus::ERROR;
|
$status = ProcessStatus::ERROR;
|
||||||
} else {
|
} else {
|
||||||
if (($processResult->exitCode() == 0 && $this->is_finished) || $this->activity->properties->get('status') === ProcessStatus::FINISHED->value) {
|
if ($processResult->exitCode() == 0 && $this->is_finished) {
|
||||||
$status = ProcessStatus::FINISHED;
|
$status = ProcessStatus::FINISHED;
|
||||||
}
|
}
|
||||||
if ($processResult->exitCode() != 0 && !$this->ignore_errors) {
|
if ($processResult->exitCode() != 0 && !$this->ignore_errors) {
|
||||||
$status = ProcessStatus::ERROR;
|
$status = ProcessStatus::ERROR;
|
||||||
}
|
}
|
||||||
|
// if (($processResult->exitCode() == 0 && $this->is_finished) || $this->activity->properties->get('status') === ProcessStatus::FINISHED->value) {
|
||||||
|
// $status = ProcessStatus::FINISHED;
|
||||||
|
// }
|
||||||
|
// if ($processResult->exitCode() != 0 && !$this->ignore_errors) {
|
||||||
|
// $status = ProcessStatus::ERROR;
|
||||||
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->activity->properties = $this->activity->properties->merge([
|
$this->activity->properties = $this->activity->properties->merge([
|
||||||
@ -97,7 +106,16 @@ public function __invoke(): ProcessResult
|
|||||||
if ($processResult->exitCode() != 0 && !$this->ignore_errors) {
|
if ($processResult->exitCode() != 0 && !$this->ignore_errors) {
|
||||||
throw new \RuntimeException($processResult->errorOutput(), $processResult->exitCode());
|
throw new \RuntimeException($processResult->errorOutput(), $processResult->exitCode());
|
||||||
}
|
}
|
||||||
|
if ($this->call_event_on_finish) {
|
||||||
|
try {
|
||||||
|
event(resolve("App\\Events\\$this->call_event_on_finish", [
|
||||||
|
'userId' => $this->activity->causer_id,
|
||||||
|
'typeUuid' => $this->activity->getExtraProperty('type_uuid'),
|
||||||
|
]));
|
||||||
|
} catch (\Throwable $e) {
|
||||||
|
ray($e);
|
||||||
|
}
|
||||||
|
}
|
||||||
return $processResult;
|
return $processResult;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -23,12 +23,12 @@ public function handle(Service $service)
|
|||||||
$commands[] = "echo 'Starting containers.'";
|
$commands[] = "echo 'Starting containers.'";
|
||||||
$commands[] = "docker compose up -d --remove-orphans --force-recreate --build";
|
$commands[] = "docker compose up -d --remove-orphans --force-recreate --build";
|
||||||
$commands[] = "docker network connect $service->uuid coolify-proxy >/dev/null 2>&1 || true";
|
$commands[] = "docker network connect $service->uuid coolify-proxy >/dev/null 2>&1 || true";
|
||||||
$compose = data_get($service,'docker_compose',[]);
|
$compose = data_get($service, 'docker_compose', []);
|
||||||
$serviceNames = data_get(Yaml::parse($compose),'services',[]);
|
$serviceNames = data_get(Yaml::parse($compose), 'services', []);
|
||||||
foreach($serviceNames as $serviceName => $serviceConfig){
|
foreach ($serviceNames as $serviceName => $serviceConfig) {
|
||||||
$commands[] = "docker network connect --alias {$serviceName}-{$service->uuid} $network {$serviceName}-{$service->uuid} || true";
|
$commands[] = "docker network connect --alias {$serviceName}-{$service->uuid} $network {$serviceName}-{$service->uuid} || true";
|
||||||
}
|
}
|
||||||
$activity = remote_process($commands, $service->server);
|
$activity = remote_process($commands, $service->server, type_uuid: $service->uuid, callEventOnFinish: 'ServiceStatusChanged');
|
||||||
return $activity;
|
return $activity;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -19,6 +19,7 @@ public function __construct(
|
|||||||
public ?Model $model = null,
|
public ?Model $model = null,
|
||||||
public ?string $status = null ,
|
public ?string $status = null ,
|
||||||
public bool $ignore_errors = false,
|
public bool $ignore_errors = false,
|
||||||
|
public $call_event_on_finish = null,
|
||||||
) {
|
) {
|
||||||
if(is_null($status)){
|
if(is_null($status)){
|
||||||
$this->status = ProcessStatus::QUEUED->value;
|
$this->status = ProcessStatus::QUEUED->value;
|
||||||
|
28
app/Events/ServiceStatusChanged.php
Normal file
28
app/Events/ServiceStatusChanged.php
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Events;
|
||||||
|
|
||||||
|
use Illuminate\Broadcasting\Channel;
|
||||||
|
use Illuminate\Broadcasting\InteractsWithSockets;
|
||||||
|
use Illuminate\Broadcasting\PresenceChannel;
|
||||||
|
use Illuminate\Broadcasting\PrivateChannel;
|
||||||
|
use Illuminate\Contracts\Broadcasting\ShouldBroadcast;
|
||||||
|
use Illuminate\Foundation\Events\Dispatchable;
|
||||||
|
use Illuminate\Queue\SerializesModels;
|
||||||
|
|
||||||
|
class ServiceStatusChanged implements ShouldBroadcast
|
||||||
|
{
|
||||||
|
use Dispatchable, InteractsWithSockets, SerializesModels;
|
||||||
|
public $userId;
|
||||||
|
public function __construct($userId = null)
|
||||||
|
{
|
||||||
|
$this->userId = $userId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function broadcastOn(): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
new PrivateChannel("custom.{$this->userId}"),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
@ -21,6 +21,7 @@ class CoolifyTask implements ShouldQueue, ShouldBeEncrypted
|
|||||||
public function __construct(
|
public function __construct(
|
||||||
public Activity $activity,
|
public Activity $activity,
|
||||||
public bool $ignore_errors = false,
|
public bool $ignore_errors = false,
|
||||||
|
public $call_event_on_finish = null
|
||||||
) {
|
) {
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -32,6 +33,7 @@ public function handle(): void
|
|||||||
$remote_process = resolve(RunRemoteProcess::class, [
|
$remote_process = resolve(RunRemoteProcess::class, [
|
||||||
'activity' => $this->activity,
|
'activity' => $this->activity,
|
||||||
'ignore_errors' => $this->ignore_errors,
|
'ignore_errors' => $this->ignore_errors,
|
||||||
|
'call_event_on_finish' => $this->call_event_on_finish
|
||||||
]);
|
]);
|
||||||
|
|
||||||
$remote_process();
|
$remote_process();
|
||||||
|
@ -3,7 +3,6 @@
|
|||||||
namespace App\Livewire\Modal;
|
namespace App\Livewire\Modal;
|
||||||
|
|
||||||
use App\Models\Service;
|
use App\Models\Service;
|
||||||
use Livewire\Component;
|
|
||||||
use LivewireUI\Modal\ModalComponent;
|
use LivewireUI\Modal\ModalComponent;
|
||||||
|
|
||||||
class EditCompose extends ModalComponent
|
class EditCompose extends ModalComponent
|
||||||
|
@ -133,13 +133,13 @@ public function setServer(Server $server)
|
|||||||
public function setDestination(string $destination_uuid)
|
public function setDestination(string $destination_uuid)
|
||||||
{
|
{
|
||||||
$this->destination_uuid = $destination_uuid;
|
$this->destination_uuid = $destination_uuid;
|
||||||
return $this->redirectRoute('project.resources.new', [
|
return redirect()->route('project.resources.new', [
|
||||||
'project_uuid' => $this->parameters['project_uuid'],
|
'project_uuid' => $this->parameters['project_uuid'],
|
||||||
'environment_name' => $this->parameters['environment_name'],
|
'environment_name' => $this->parameters['environment_name'],
|
||||||
'type' => $this->type,
|
'type' => $this->type,
|
||||||
'destination' => $this->destination_uuid,
|
'destination' => $this->destination_uuid,
|
||||||
'server_id' => $this->server_id,
|
'server_id' => $this->server_id,
|
||||||
], navigate: true);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function loadServers()
|
public function loadServers()
|
||||||
|
@ -13,7 +13,15 @@ class Index extends Component
|
|||||||
public $databases;
|
public $databases;
|
||||||
public array $parameters;
|
public array $parameters;
|
||||||
public array $query;
|
public array $query;
|
||||||
protected $listeners = ["refreshStacks", "checkStatus"];
|
public function getListeners()
|
||||||
|
{
|
||||||
|
$userId = auth()->user()->id;
|
||||||
|
return [
|
||||||
|
"echo-private:custom.{$userId},ServiceStatusChanged" => 'checkStatus',
|
||||||
|
"refreshStacks",
|
||||||
|
"checkStatus",
|
||||||
|
];
|
||||||
|
}
|
||||||
public function render()
|
public function render()
|
||||||
{
|
{
|
||||||
return view('livewire.project.service.index');
|
return view('livewire.project.service.index');
|
||||||
@ -28,7 +36,7 @@ public function mount()
|
|||||||
}
|
}
|
||||||
public function checkStatus()
|
public function checkStatus()
|
||||||
{
|
{
|
||||||
dispatch(new ContainerStatusJob($this->service->server));
|
dispatch_sync(new ContainerStatusJob($this->service->server));
|
||||||
$this->refreshStacks();
|
$this->refreshStacks();
|
||||||
}
|
}
|
||||||
public function refreshStacks()
|
public function refreshStacks()
|
||||||
|
@ -6,9 +6,6 @@
|
|||||||
|
|
||||||
class Modal extends Component
|
class Modal extends Component
|
||||||
{
|
{
|
||||||
public function checkStatus() {
|
|
||||||
$this->dispatch('checkStatus');
|
|
||||||
}
|
|
||||||
public function render()
|
public function render()
|
||||||
{
|
{
|
||||||
return view('livewire.project.service.modal');
|
return view('livewire.project.service.modal');
|
||||||
|
@ -4,25 +4,53 @@
|
|||||||
|
|
||||||
use App\Actions\Service\StartService;
|
use App\Actions\Service\StartService;
|
||||||
use App\Actions\Service\StopService;
|
use App\Actions\Service\StopService;
|
||||||
|
use App\Jobs\ContainerStatusJob;
|
||||||
use App\Models\Service;
|
use App\Models\Service;
|
||||||
use Livewire\Component;
|
use Livewire\Component;
|
||||||
|
use Spatie\Activitylog\Models\Activity;
|
||||||
|
|
||||||
class Navbar extends Component
|
class Navbar extends Component
|
||||||
{
|
{
|
||||||
public Service $service;
|
public Service $service;
|
||||||
public array $parameters;
|
public array $parameters;
|
||||||
public array $query;
|
public array $query;
|
||||||
protected $listeners = ["checkStatus"];
|
public $isDeploymentProgress = false;
|
||||||
|
|
||||||
|
public function checkDeployments() {
|
||||||
|
$activity = Activity::where('properties->type_uuid', $this->service->uuid)->latest()->first();
|
||||||
|
$status = data_get($activity, 'properties.status');
|
||||||
|
if ($status === 'queued' || $status === 'in_progress') {
|
||||||
|
$this->isDeploymentProgress = true;
|
||||||
|
} else {
|
||||||
|
$this->isDeploymentProgress = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public function getListeners()
|
||||||
|
{
|
||||||
|
$userId = auth()->user()->id;
|
||||||
|
return [
|
||||||
|
"echo-private:custom.{$userId},ServiceStatusChanged" => 'serviceStatusChanged',
|
||||||
|
];
|
||||||
|
}
|
||||||
|
public function serviceStatusChanged()
|
||||||
|
{
|
||||||
|
$this->service->refresh();
|
||||||
|
}
|
||||||
public function render()
|
public function render()
|
||||||
{
|
{
|
||||||
return view('livewire.project.service.navbar');
|
return view('livewire.project.service.navbar');
|
||||||
}
|
}
|
||||||
public function checkStatus() {
|
public function checkStatus()
|
||||||
|
{
|
||||||
$this->service->refresh();
|
$this->service->refresh();
|
||||||
}
|
}
|
||||||
public function deploy()
|
public function deploy()
|
||||||
{
|
{
|
||||||
|
$this->checkDeployments();
|
||||||
|
if ($this->isDeploymentProgress) {
|
||||||
|
$this->dispatch('error', 'There is a deployment in progress.');
|
||||||
|
return;
|
||||||
|
}
|
||||||
$this->service->parse();
|
$this->service->parse();
|
||||||
$activity = StartService::run($this->service);
|
$activity = StartService::run($this->service);
|
||||||
$this->dispatch('newMonitorActivity', $activity->id);
|
$this->dispatch('newMonitorActivity', $activity->id);
|
||||||
|
@ -8,12 +8,12 @@ class Sponsorship extends Component
|
|||||||
{
|
{
|
||||||
public function getListeners()
|
public function getListeners()
|
||||||
{
|
{
|
||||||
$teamId = auth()->user()->currentTeam()->id;
|
$userId = auth()->user()->id;
|
||||||
return [
|
return [
|
||||||
"echo-private:custom.{$teamId},TestEvent" => 'testEvent',
|
"echo-private:custom.{$userId},TestEvent" => 'testEvent',
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
public function testEvent()
|
public function testEvent($asd)
|
||||||
{
|
{
|
||||||
$this->dispatch('success', 'Realtime events configured!');
|
$this->dispatch('success', 'Realtime events configured!');
|
||||||
}
|
}
|
||||||
|
@ -5,7 +5,6 @@
|
|||||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||||
use Illuminate\Database\Eloquent\Relations\HasMany;
|
use Illuminate\Database\Eloquent\Relations\HasMany;
|
||||||
use Illuminate\Support\Collection;
|
use Illuminate\Support\Collection;
|
||||||
use Symfony\Component\Yaml\Yaml;
|
|
||||||
use Illuminate\Support\Str;
|
use Illuminate\Support\Str;
|
||||||
|
|
||||||
class Service extends BaseModel
|
class Service extends BaseModel
|
||||||
@ -207,7 +206,6 @@ public function extraFields()
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ray($fields);
|
|
||||||
$databases = $this->databases()->get();
|
$databases = $this->databases()->get();
|
||||||
|
|
||||||
foreach ($databases as $database) {
|
foreach ($databases as $database) {
|
||||||
|
@ -24,6 +24,7 @@ function remote_process(
|
|||||||
?string $type_uuid = null,
|
?string $type_uuid = null,
|
||||||
?Model $model = null,
|
?Model $model = null,
|
||||||
bool $ignore_errors = false,
|
bool $ignore_errors = false,
|
||||||
|
$callEventOnFinish = null
|
||||||
): Activity {
|
): Activity {
|
||||||
if (is_null($type)) {
|
if (is_null($type)) {
|
||||||
$type = ActivityTypes::INLINE->value;
|
$type = ActivityTypes::INLINE->value;
|
||||||
@ -47,18 +48,12 @@ function remote_process(
|
|||||||
type: $type,
|
type: $type,
|
||||||
type_uuid: $type_uuid,
|
type_uuid: $type_uuid,
|
||||||
model: $model,
|
model: $model,
|
||||||
ignore_errors: $ignore_errors
|
ignore_errors: $ignore_errors,
|
||||||
|
call_event_on_finish: $callEventOnFinish,
|
||||||
),
|
),
|
||||||
])();
|
])();
|
||||||
}
|
}
|
||||||
|
|
||||||
// function removePrivateKeyFromSshAgent(Server $server)
|
|
||||||
// {
|
|
||||||
// if (data_get($server, 'privateKey.private_key') === null) {
|
|
||||||
// throw new \Exception("Server {$server->name} does not have a private key");
|
|
||||||
// }
|
|
||||||
// // processWithEnv()->run("echo '{$server->privateKey->private_key}' | ssh-add -d -");
|
|
||||||
// }
|
|
||||||
function savePrivateKeyToFs(Server $server)
|
function savePrivateKeyToFs(Server $server)
|
||||||
{
|
{
|
||||||
if (data_get($server, 'privateKey.private_key') === null) {
|
if (data_get($server, 'privateKey.private_key') === null) {
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
<div>
|
<div>
|
||||||
<x-modal submitWireAction="checkStatus" modalId="startService">
|
<x-modal noSubmit modalId="startService">
|
||||||
<x-slot:modalBody>
|
<x-slot:modalBody>
|
||||||
<livewire:activity-monitor header="Service Startup Logs" />
|
<livewire:activity-monitor header="Service Startup Logs" />
|
||||||
</x-slot:modalBody>
|
</x-slot:modalBody>
|
||||||
|
@ -48,7 +48,7 @@
|
|||||||
if (auth()->user()?->currentTeam()->id !== 0) {
|
if (auth()->user()?->currentTeam()->id !== 0) {
|
||||||
return redirect('/');
|
return redirect('/');
|
||||||
}
|
}
|
||||||
event(new \App\Events\TestEvent());
|
event(new \App\Events\TestEvent('asd'));
|
||||||
return 'Look at your other tab.';
|
return 'Look at your other tab.';
|
||||||
})->middleware('auth');
|
})->middleware('auth');
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user